@openfairygui/cli 0.3.0-alpha.4 → 0.3.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/dist/cli.mjs CHANGED
@@ -730,6 +730,14 @@ var Property = class extends GraphNode {
730
730
  if (Array.isArray(value)) value = value.slice();
731
731
  return super.set(attribute, value);
732
732
  }
733
+ /** @hidden */
734
+ getExtendedLiteral(attribute) {
735
+ return super.get(attribute);
736
+ }
737
+ /** @hidden */
738
+ setExtendedLiteral(attribute, value) {
739
+ return super.set(attribute, value.slice());
740
+ }
733
741
  getName() {
734
742
  return this.get("name");
735
743
  }
@@ -737,10 +745,10 @@ var Property = class extends GraphNode {
737
745
  return this.set("name", name);
738
746
  }
739
747
  getExtras() {
740
- return this.get("extras");
748
+ return structuredClone(this.get("extras"));
741
749
  }
742
750
  setExtras(extras) {
743
- return this.set("extras", extras);
751
+ return this.set("extras", structuredClone(extras));
744
752
  }
745
753
  clone() {
746
754
  const PropertyClass = this.constructor;
@@ -821,7 +829,7 @@ var ExtensibleProperty = class extends Property {
821
829
  };
822
830
  //#endregion
823
831
  //#region ../core/src/constants.ts
824
- const VERSION = `v0.3.0-alpha.4`;
832
+ const VERSION = `v0.3.1`;
825
833
  /** Binary package file magic number: "FGUI" as uint32. */
826
834
  const FGUI_MAGIC = 1179080009;
827
835
  /** Null string index in the binary string table. */
@@ -837,6 +845,7 @@ let PropertyType = /* @__PURE__ */ function(PropertyType) {
837
845
  PropertyType["SOUND_RESOURCE"] = "SoundResource";
838
846
  PropertyType["FONT_RESOURCE"] = "FontResource";
839
847
  PropertyType["MOVIE_CLIP_RESOURCE"] = "MovieClipResource";
848
+ PropertyType["SWF_RESOURCE"] = "SwfResource";
840
849
  PropertyType["SPINE_RESOURCE"] = "SpineResource";
841
850
  PropertyType["DRAGON_BONES_RESOURCE"] = "DragonBonesResource";
842
851
  PropertyType["COMPONENT"] = "Component";
@@ -1210,10 +1219,10 @@ var Root = class extends ExtensibleProperty {
1210
1219
  return this.setBranches([...this.listBranches(), branch]);
1211
1220
  }
1212
1221
  getSettings() {
1213
- return this.get("settings");
1222
+ return structuredClone(this.get("settings"));
1214
1223
  }
1215
1224
  setSettings(settings) {
1216
- return this.set("settings", settings);
1225
+ return this.set("settings", structuredClone(settings));
1217
1226
  }
1218
1227
  /****** Extensions ******/
1219
1228
  listExtensionsUsed() {
@@ -1479,10 +1488,10 @@ var ImageResource = class extends ExtensibleProperty {
1479
1488
  return this.set("branchItemIds", [...ids]);
1480
1489
  }
1481
1490
  getHighResolutionItemIds() {
1482
- return [...this.get("highResolutionItemIds")];
1491
+ return [...this.getExtendedLiteral("highResolutionItemIds")];
1483
1492
  }
1484
1493
  setHighResolutionItemIds(ids) {
1485
- return this.set("highResolutionItemIds", [...ids]);
1494
+ return this.setExtendedLiteral("highResolutionItemIds", ids);
1486
1495
  }
1487
1496
  getWidth() {
1488
1497
  return this.get("width");
@@ -1955,10 +1964,10 @@ var MovieClipResource = class extends ExtensibleProperty {
1955
1964
  return this.set("branchItemIds", [...ids]);
1956
1965
  }
1957
1966
  getHighResolutionItemIds() {
1958
- return [...this.get("highResolutionItemIds")];
1967
+ return [...this.getExtendedLiteral("highResolutionItemIds")];
1959
1968
  }
1960
1969
  setHighResolutionItemIds(ids) {
1961
- return this.set("highResolutionItemIds", [...ids]);
1970
+ return this.setExtendedLiteral("highResolutionItemIds", ids);
1962
1971
  }
1963
1972
  getFileName() {
1964
1973
  return this.get("fileName");
@@ -2038,6 +2047,74 @@ var MovieClipResource = class extends ExtensibleProperty {
2038
2047
  }
2039
2048
  };
2040
2049
  //#endregion
2050
+ //#region ../core/src/properties/swf-resource.ts
2051
+ /** A SWF resource within a FairyGUI package. */
2052
+ var SwfResource = class extends ExtensibleProperty {
2053
+ init() {
2054
+ this.propertyType = PropertyType.SWF_RESOURCE;
2055
+ }
2056
+ getDefaults() {
2057
+ return Object.assign(super.getDefaults(), {
2058
+ id: "",
2059
+ path: "",
2060
+ branch: "",
2061
+ branchItemIds: [],
2062
+ file: "",
2063
+ exported: false,
2064
+ favorite: false,
2065
+ resourceData: null
2066
+ });
2067
+ }
2068
+ getId() {
2069
+ return this.get("id");
2070
+ }
2071
+ setId(id) {
2072
+ return this.set("id", id);
2073
+ }
2074
+ getPath() {
2075
+ return this.get("path");
2076
+ }
2077
+ setPath(path) {
2078
+ return this.set("path", path);
2079
+ }
2080
+ getBranch() {
2081
+ return this.get("branch");
2082
+ }
2083
+ setBranch(branch) {
2084
+ return this.set("branch", branch);
2085
+ }
2086
+ getBranchItemIds() {
2087
+ return [...this.get("branchItemIds")];
2088
+ }
2089
+ setBranchItemIds(ids) {
2090
+ return this.set("branchItemIds", [...ids]);
2091
+ }
2092
+ getFile() {
2093
+ return this.get("file");
2094
+ }
2095
+ setFile(file) {
2096
+ return this.set("file", file);
2097
+ }
2098
+ getExported() {
2099
+ return this.get("exported");
2100
+ }
2101
+ setExported(value) {
2102
+ return this.set("exported", value);
2103
+ }
2104
+ getFavorite() {
2105
+ return this.get("favorite");
2106
+ }
2107
+ setFavorite(value) {
2108
+ return this.set("favorite", value);
2109
+ }
2110
+ getSourceData() {
2111
+ return this.getRef("resourceData");
2112
+ }
2113
+ setSourceData(buffer) {
2114
+ return this.setRef("resourceData", buffer);
2115
+ }
2116
+ };
2117
+ //#endregion
2041
2118
  //#region ../core/src/properties/skeleton-resource-base.ts
2042
2119
  /**
2043
2120
  * Shared base for skeleton-style package resources.
@@ -2186,9 +2263,24 @@ var DragonBonesResource = class extends SkeletonResourceBase {
2186
2263
  * @category Properties
2187
2264
  */
2188
2265
  var Component = class extends ExtensibleProperty {
2266
+ _binaryDirty = true;
2189
2267
  init() {
2190
2268
  this.propertyType = PropertyType.COMPONENT;
2191
2269
  }
2270
+ /** @internal */
2271
+ _markBinaryClean() {
2272
+ this._binaryDirty = false;
2273
+ return this;
2274
+ }
2275
+ /** @internal */
2276
+ _markBinaryDirty() {
2277
+ this._binaryDirty = true;
2278
+ return this;
2279
+ }
2280
+ /** @internal */
2281
+ _isBinaryDirty() {
2282
+ return this._binaryDirty;
2283
+ }
2192
2284
  getDefaults() {
2193
2285
  return Object.assign(super.getDefaults(), {
2194
2286
  id: "",
@@ -2234,13 +2326,17 @@ var Component = class extends ExtensibleProperty {
2234
2326
  footerRes: "",
2235
2327
  bgColor: "",
2236
2328
  bgColorEnabled: false,
2237
- designImageAlpha: 0,
2329
+ designImageAlpha: 50,
2238
2330
  designImageLayer: 0,
2239
2331
  designImageOffsetX: 0,
2240
2332
  designImageOffsetY: 0,
2333
+ designImage: "",
2334
+ designImageForTest: false,
2335
+ pageController: "",
2241
2336
  idNum: 0,
2242
2337
  initName: "",
2243
2338
  remark: "",
2339
+ customExtensionId: "",
2244
2340
  extensionType: "",
2245
2341
  buttonMode: 0,
2246
2342
  sound: "",
@@ -2527,6 +2623,24 @@ var Component = class extends ExtensibleProperty {
2527
2623
  setDesignImageOffsetY(v) {
2528
2624
  return this.set("designImageOffsetY", v);
2529
2625
  }
2626
+ getDesignImage() {
2627
+ return this.get("designImage");
2628
+ }
2629
+ setDesignImage(v) {
2630
+ return this.set("designImage", v);
2631
+ }
2632
+ getDesignImageForTest() {
2633
+ return this.get("designImageForTest");
2634
+ }
2635
+ setDesignImageForTest(v) {
2636
+ return this.set("designImageForTest", v);
2637
+ }
2638
+ getPageController() {
2639
+ return this.get("pageController");
2640
+ }
2641
+ setPageController(v) {
2642
+ return this.set("pageController", v);
2643
+ }
2530
2644
  getIdNum() {
2531
2645
  return this.get("idNum");
2532
2646
  }
@@ -2545,6 +2659,12 @@ var Component = class extends ExtensibleProperty {
2545
2659
  setRemark(v) {
2546
2660
  return this.set("remark", v);
2547
2661
  }
2662
+ getCustomExtensionId() {
2663
+ return this.get("customExtensionId");
2664
+ }
2665
+ setCustomExtensionId(v) {
2666
+ return this.set("customExtensionId", v);
2667
+ }
2548
2668
  getExtensionType() {
2549
2669
  return this.get("extensionType");
2550
2670
  }
@@ -3542,6 +3662,7 @@ var GTextField = class extends GObject {
3542
3662
  demoText: "",
3543
3663
  templateVarsEnabled: false,
3544
3664
  faceDilate: 0,
3665
+ outlineSoftness: 0,
3545
3666
  underlaySoftness: 0,
3546
3667
  ubbEnabled: false,
3547
3668
  underline: false,
@@ -3762,6 +3883,12 @@ var GTextField = class extends GObject {
3762
3883
  setFaceDilate(v) {
3763
3884
  return this.setTextFieldProp("faceDilate", v);
3764
3885
  }
3886
+ getOutlineSoftness() {
3887
+ return this.getTextFieldProp("outlineSoftness");
3888
+ }
3889
+ setOutlineSoftness(v) {
3890
+ return this.setTextFieldProp("outlineSoftness", v);
3891
+ }
3765
3892
  getUnderlaySoftness() {
3766
3893
  return this.getTextFieldProp("underlaySoftness");
3767
3894
  }
@@ -4293,6 +4420,7 @@ var GLoader = class extends GObject {
4293
4420
  shrinkOnly: false,
4294
4421
  autoSize: false,
4295
4422
  useResize: false,
4423
+ showErrorSign: false,
4296
4424
  align: 0,
4297
4425
  vAlign: 0,
4298
4426
  frame: 0,
@@ -4430,6 +4558,12 @@ var GLoader = class extends GObject {
4430
4558
  setUseResize(v) {
4431
4559
  return this.set("useResize", v);
4432
4560
  }
4561
+ getShowErrorSign() {
4562
+ return this.get("showErrorSign");
4563
+ }
4564
+ setShowErrorSign(v) {
4565
+ return this.set("showErrorSign", v);
4566
+ }
4433
4567
  getAlign() {
4434
4568
  return this.get("align");
4435
4569
  }
@@ -4894,6 +5028,7 @@ var GComponent = class extends GObject {
4894
5028
  instanceChecked: false,
4895
5029
  instanceSound: "",
4896
5030
  instanceSoundVolumeScale: 1,
5031
+ instancePopupDirection: 0,
4897
5032
  instancePromptText: "",
4898
5033
  instanceSelectionController: "",
4899
5034
  instanceVisibleItemCount: 0,
@@ -5180,6 +5315,12 @@ var GComponent = class extends GObject {
5180
5315
  setInstanceSoundVolumeScale(v) {
5181
5316
  return this.setComponentProp("instanceSoundVolumeScale", v);
5182
5317
  }
5318
+ getInstancePopupDirection() {
5319
+ return this.getComponentProp("instancePopupDirection");
5320
+ }
5321
+ setInstancePopupDirection(v) {
5322
+ return this.setComponentProp("instancePopupDirection", v);
5323
+ }
5183
5324
  getInstancePromptText() {
5184
5325
  return firstString$1(this.getComponentProp("instancePromptText"));
5185
5326
  }
@@ -5243,6 +5384,9 @@ var GComponent = class extends GObject {
5243
5384
  };
5244
5385
  //#endregion
5245
5386
  //#region ../core/src/properties/g-list.ts
5387
+ function getDefaultListAutoResizeItem(layout) {
5388
+ return layout === ListLayoutType.SingleColumn || layout === ListLayoutType.SingleRow;
5389
+ }
5246
5390
  function firstString(value) {
5247
5391
  if (Array.isArray(value)) return String(value[0] ?? "");
5248
5392
  return String(value ?? "");
@@ -5275,12 +5419,13 @@ var GListBase = class extends GObject {
5275
5419
  columnCount: 0,
5276
5420
  selectionMode: ListSelectionMode.Single,
5277
5421
  defaultItem: "",
5278
- autoResizeItem: true,
5422
+ autoResizeItem: getDefaultListAutoResizeItem(ListLayoutType.SingleColumn),
5279
5423
  childrenRenderOrder: 0,
5280
5424
  apexIndex: 0,
5281
5425
  src: "",
5282
5426
  overflow: 0,
5283
5427
  scrollType: 1,
5428
+ scrollBarDisplay: 0,
5284
5429
  scrollBarFlags: 0,
5285
5430
  scrollBarMargin: [
5286
5431
  0,
@@ -5483,6 +5628,12 @@ var GListBase = class extends GObject {
5483
5628
  setScrollType(v) {
5484
5629
  return this.setListProp("scrollType", v);
5485
5630
  }
5631
+ getScrollBarDisplay() {
5632
+ return this.getListProp("scrollBarDisplay");
5633
+ }
5634
+ setScrollBarDisplay(v) {
5635
+ return this.setListProp("scrollBarDisplay", v);
5636
+ }
5486
5637
  getScrollBarFlags() {
5487
5638
  return this.getListProp("scrollBarFlags");
5488
5639
  }
@@ -6441,6 +6592,10 @@ var Controller = class extends ExtensibleProperty {
6441
6592
  return Object.assign(super.getDefaults(), {
6442
6593
  selectedIndex: 0,
6443
6594
  autoRadioGroupDepth: false,
6595
+ alias: "",
6596
+ exported: false,
6597
+ homePageType: "default",
6598
+ homePage: "",
6444
6599
  pages: new RefList(),
6445
6600
  actions: new RefList()
6446
6601
  });
@@ -6457,6 +6612,30 @@ var Controller = class extends ExtensibleProperty {
6457
6612
  setAutoRadioGroupDepth(v) {
6458
6613
  return this.set("autoRadioGroupDepth", v);
6459
6614
  }
6615
+ getAlias() {
6616
+ return this.get("alias");
6617
+ }
6618
+ setAlias(v) {
6619
+ return this.set("alias", v);
6620
+ }
6621
+ getExported() {
6622
+ return this.get("exported");
6623
+ }
6624
+ setExported(v) {
6625
+ return this.set("exported", v);
6626
+ }
6627
+ getHomePageType() {
6628
+ return this.get("homePageType");
6629
+ }
6630
+ setHomePageType(v) {
6631
+ return this.set("homePageType", v);
6632
+ }
6633
+ getHomePage() {
6634
+ return this.get("homePage");
6635
+ }
6636
+ setHomePage(v) {
6637
+ return this.set("homePage", v);
6638
+ }
6460
6639
  addPage(page) {
6461
6640
  return this.addRef("pages", page);
6462
6641
  }
@@ -6490,7 +6669,10 @@ var ControllerPage = class extends Property {
6490
6669
  this.propertyType = PropertyType.CONTROLLER_PAGE;
6491
6670
  }
6492
6671
  getDefaults() {
6493
- return Object.assign(super.getDefaults(), { id: "" });
6672
+ return Object.assign(super.getDefaults(), {
6673
+ id: "",
6674
+ remark: ""
6675
+ });
6494
6676
  }
6495
6677
  getId() {
6496
6678
  return this.get("id");
@@ -6498,6 +6680,12 @@ var ControllerPage = class extends Property {
6498
6680
  setId(id) {
6499
6681
  return this.set("id", id);
6500
6682
  }
6683
+ getRemark() {
6684
+ return this.get("remark");
6685
+ }
6686
+ setRemark(remark) {
6687
+ return this.set("remark", remark);
6688
+ }
6501
6689
  };
6502
6690
  //#endregion
6503
6691
  //#region ../core/src/properties/controller-action.ts
@@ -15611,7 +15799,6 @@ const { Deflate, deflate, deflateRaw, gzip } = deflate_1$1;
15611
15799
  const { Inflate, inflate, inflateRaw, ungzip } = inflate_1$1;
15612
15800
  var deflateRaw_1 = deflateRaw;
15613
15801
  var Inflate_1 = Inflate;
15614
- var inflateRaw_1 = inflateRaw;
15615
15802
  //#endregion
15616
15803
  //#region ../core/src/utils/image-info.ts
15617
15804
  var import_jpeg_js = require_jpeg_js();
@@ -16007,6 +16194,99 @@ function probeRasterImageDimensions(data) {
16007
16194
  return readPngInfo(data, false) ?? readJpegInfo(data, false);
16008
16195
  }
16009
16196
  //#endregion
16197
+ //#region ../core/src/utils/svg-validation.ts
16198
+ const MAX_SVG_SOURCE_BYTES = 8 * 1024 * 1024;
16199
+ const MAX_SVG_NODES = 5e4;
16200
+ const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
16201
+ const XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
16202
+ const UNSAFE_SVG_ELEMENTS = new Set([
16203
+ "a",
16204
+ "animate",
16205
+ "animatecolor",
16206
+ "animatemotion",
16207
+ "animatetransform",
16208
+ "audio",
16209
+ "canvas",
16210
+ "discard",
16211
+ "embed",
16212
+ "feimage",
16213
+ "foreignobject",
16214
+ "iframe",
16215
+ "image",
16216
+ "object",
16217
+ "script",
16218
+ "set",
16219
+ "style",
16220
+ "video"
16221
+ ]);
16222
+ function invalidSvg(message) {
16223
+ throw new Error(`Invalid or unsafe SVG source (${message}).`);
16224
+ }
16225
+ function validateAttribute(name, value) {
16226
+ const normalizedName = name.toLowerCase();
16227
+ if (normalizedName === "xmlns") {
16228
+ if (value !== SVG_NAMESPACE) invalidSvg("the default namespace must be SVG");
16229
+ return;
16230
+ }
16231
+ if (normalizedName === "xmlns:xlink") {
16232
+ if (value !== XLINK_NAMESPACE) invalidSvg("the xlink namespace is invalid");
16233
+ return;
16234
+ }
16235
+ if (normalizedName.includes(":") && normalizedName !== "xlink:href" && normalizedName !== "xml:space") invalidSvg(`qualified attribute "${name}" is not allowed`);
16236
+ const localName = normalizedName.split(":").at(-1);
16237
+ const text = String(value);
16238
+ if (localName.startsWith("on")) invalidSvg(`event attribute "${name}" is not allowed`);
16239
+ if (localName === "style" || localName === "src") invalidSvg(`attribute "${name}" is not allowed`);
16240
+ if (localName === "href" && !/^#[A-Za-z_][\w:.-]*$/u.test(text)) invalidSvg(`external reference in "${name}" is not allowed`);
16241
+ if (/(?:^|[\s("'=])(?:https?:|file:|javascript:|data:|\/\/)/iu.test(text)) invalidSvg(`external URL in "${name}" is not allowed`);
16242
+ for (const match of text.matchAll(/url\s*\(([^)]*)\)/giu)) {
16243
+ const reference = (match[1] ?? "").trim().replace(/^(['"])(.*)\1$/u, "$2");
16244
+ if (!/^#[A-Za-z_][\w:.-]*$/u.test(reference)) invalidSvg(`external url() in "${name}" is not allowed`);
16245
+ }
16246
+ }
16247
+ /** Validate SVG bytes before handing them to a host image decoder. */
16248
+ function validateSafeSvgSource(bytes) {
16249
+ if (bytes.byteLength === 0 || bytes.byteLength > MAX_SVG_SOURCE_BYTES) invalidSvg("source size is unsupported");
16250
+ let source;
16251
+ try {
16252
+ source = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
16253
+ } catch {
16254
+ invalidSvg("source is not valid UTF-8");
16255
+ }
16256
+ if (/<!\s*(?:doctype|entity)\b|<\?xml-stylesheet\b/iu.test(source)) invalidSvg("DTD, entities, and stylesheets are not allowed");
16257
+ if (XMLValidator.validate(source, { allowBooleanAttributes: false }) !== true) invalidSvg("source is not well-formed XML");
16258
+ const roots = new XMLParser({
16259
+ preserveOrder: true,
16260
+ ignoreAttributes: false,
16261
+ attributeNamePrefix: "",
16262
+ parseAttributeValue: false,
16263
+ parseTagValue: false,
16264
+ processEntities: false,
16265
+ trimValues: false
16266
+ }).parse(source).flatMap((entry) => Object.keys(entry).filter((name) => name !== ":@" && !name.startsWith("#") && !name.startsWith("?")).map((name) => ({
16267
+ entry,
16268
+ name
16269
+ })));
16270
+ if (roots.length !== 1 || roots[0].name !== "svg") invalidSvg("a single unqualified <svg> root is required");
16271
+ if (roots[0].entry[":@"]?.xmlns !== SVG_NAMESPACE) invalidSvg("the SVG namespace is required");
16272
+ const pending = [roots[0].entry];
16273
+ let nodeCount = 0;
16274
+ while (pending.length > 0) {
16275
+ const current = pending.pop();
16276
+ for (const [name, value] of Object.entries(current)) {
16277
+ if (name === ":@" || name.startsWith("#") || name.startsWith("?")) continue;
16278
+ if (++nodeCount > MAX_SVG_NODES) invalidSvg("node count exceeds the supported limit");
16279
+ if (name.includes(":")) invalidSvg(`qualified element <${name}> is not allowed`);
16280
+ if (UNSAFE_SVG_ELEMENTS.has(name.toLowerCase())) invalidSvg(`element <${name}> is not allowed`);
16281
+ for (const [attributeName, attributeValue] of Object.entries(current[":@"] ?? {})) validateAttribute(attributeName, attributeValue);
16282
+ if (Array.isArray(value)) {
16283
+ for (const child of value) if (child && typeof child === "object" && !Array.isArray(child)) pending.push(child);
16284
+ }
16285
+ }
16286
+ }
16287
+ return source;
16288
+ }
16289
+ //#endregion
16010
16290
  //#region ../core/src/document.ts
16011
16291
  /**
16012
16292
  * Wraps a FairyGUI project and its resources for easier modification.
@@ -16033,12 +16313,32 @@ var Document = class Document {
16033
16313
  _root = new Root(this._graph);
16034
16314
  _logger = Logger.DEFAULT_INSTANCE;
16035
16315
  _projectDir = "";
16316
+ _hasBinaryComponents = false;
16036
16317
  static _GRAPH_DOCUMENTS = /* @__PURE__ */ new WeakMap();
16037
16318
  static fromGraph(graph) {
16038
16319
  return Document._GRAPH_DOCUMENTS.get(graph) || null;
16039
16320
  }
16040
16321
  constructor() {
16041
16322
  Document._GRAPH_DOCUMENTS.set(this._graph, this);
16323
+ this._graph.addEventListener("node:change", (event) => {
16324
+ if (!this._hasBinaryComponents) return;
16325
+ const pending = [event.target];
16326
+ const visited = /* @__PURE__ */ new Set();
16327
+ while (pending.length > 0) {
16328
+ const current = pending.pop();
16329
+ if (visited.has(current)) continue;
16330
+ visited.add(current);
16331
+ if (current instanceof Component) {
16332
+ current._markBinaryDirty();
16333
+ continue;
16334
+ }
16335
+ pending.push(...current.listParents());
16336
+ }
16337
+ });
16338
+ }
16339
+ /** @internal */
16340
+ _trackBinaryComponent() {
16341
+ this._hasBinaryComponents = true;
16042
16342
  }
16043
16343
  getRoot() {
16044
16344
  return this._root;
@@ -16090,6 +16390,9 @@ var Document = class Document {
16090
16390
  createMovieClipResource(name = "") {
16091
16391
  return new MovieClipResource(this._graph, name);
16092
16392
  }
16393
+ createSwfResource(name = "") {
16394
+ return new SwfResource(this._graph, name);
16395
+ }
16093
16396
  createSpineResource(name = "") {
16094
16397
  return new SpineResource(this._graph, name);
16095
16398
  }
@@ -16345,6 +16648,7 @@ const TEXT_PROPERTY_KEYS = [
16345
16648
  "autoSize",
16346
16649
  "singleLine",
16347
16650
  "autoClearText",
16651
+ "outlineSoftness",
16348
16652
  "underlaySoftness",
16349
16653
  "ubbEnabled",
16350
16654
  "underline",
@@ -16376,7 +16680,7 @@ function isValidUamTextProperties(value, nodeKind) {
16376
16680
  properties.italic,
16377
16681
  properties.bold,
16378
16682
  properties.strikethrough
16379
- ].every((item) => typeof item === "boolean") && typeof properties.underlaySoftness === "number" && Number.isFinite(properties.underlaySoftness) && typeof properties.strokeSize === "number" && Number.isFinite(properties.strokeSize) && properties.strokeSize >= 0 && (properties.strokeColor === null ? properties.strokeSize === 1 : isTextColor(properties.strokeColor)) && isFiniteUamPoint(properties.shadowOffset) && (properties.shadowColor === null ? properties.shadowOffset.x === 0 && properties.shadowOffset.y === 0 : isTextColor(properties.shadowColor));
16683
+ ].every((item) => typeof item === "boolean") && typeof properties.outlineSoftness === "number" && Number.isFinite(properties.outlineSoftness) && typeof properties.underlaySoftness === "number" && Number.isFinite(properties.underlaySoftness) && typeof properties.strokeSize === "number" && Number.isFinite(properties.strokeSize) && properties.strokeSize >= 0 && (properties.strokeColor === null ? properties.strokeSize === 1 : isTextColor(properties.strokeColor)) && isFiniteUamPoint(properties.shadowOffset) && (properties.shadowColor === null ? properties.shadowOffset.x === 0 && properties.shadowOffset.y === 0 : isTextColor(properties.shadowColor));
16380
16684
  if (!commonValid || nodeKind === "richText") return commonValid;
16381
16685
  return typeof properties.demoText === "string" && typeof properties.templateVarsEnabled === "boolean" && typeof properties.faceDilate === "number" && Number.isFinite(properties.faceDilate);
16382
16686
  }
@@ -16393,6 +16697,7 @@ function textPropertiesFromNode(node) {
16393
16697
  autoSize: node.autoSize,
16394
16698
  singleLine: node.singleLine,
16395
16699
  autoClearText: node.autoClearText,
16700
+ outlineSoftness: node.outlineSoftness,
16396
16701
  underlaySoftness: node.underlaySoftness,
16397
16702
  ubbEnabled: node.ubbEnabled,
16398
16703
  underline: node.underline,
@@ -16412,6 +16717,29 @@ function textPropertiesFromNode(node) {
16412
16717
  faceDilate: node.faceDilate
16413
16718
  };
16414
16719
  }
16720
+ const IMAGE_PROPERTY_KEYS = [
16721
+ "color",
16722
+ "flip",
16723
+ "fillMethod",
16724
+ "fillOrigin",
16725
+ "fillClockwise",
16726
+ "fillAmount"
16727
+ ];
16728
+ function isValidUamImageProperties(value) {
16729
+ if (typeof value !== "object" || value === null || !hasExactKeys(value, IMAGE_PROPERTY_KEYS)) return false;
16730
+ const properties = value;
16731
+ return isTextColor(properties.color) && Number.isInteger(properties.flip) && properties.flip >= 0 && properties.flip <= 3 && Number.isInteger(properties.fillMethod) && properties.fillMethod >= 0 && properties.fillMethod <= 5 && Number.isInteger(properties.fillOrigin) && properties.fillOrigin >= 0 && properties.fillOrigin <= 3 && typeof properties.fillClockwise === "boolean" && typeof properties.fillAmount === "number" && Number.isFinite(properties.fillAmount) && (properties.fillMethod === 0 ? properties.fillOrigin === 0 && properties.fillClockwise && properties.fillAmount === 100 : properties.fillAmount >= 0 && properties.fillAmount <= 1);
16732
+ }
16733
+ const MOVIE_CLIP_PROPERTY_KEYS = [
16734
+ "playing",
16735
+ "frame",
16736
+ "color"
16737
+ ];
16738
+ function isValidUamMovieClipProperties(value) {
16739
+ if (typeof value !== "object" || value === null || !hasExactKeys(value, MOVIE_CLIP_PROPERTY_KEYS)) return false;
16740
+ const properties = value;
16741
+ return typeof properties.playing === "boolean" && Number.isInteger(properties.frame) && properties.frame >= 0 && isTextColor(properties.color);
16742
+ }
16415
16743
  const COMPONENT_PROPERTY_KEYS = [
16416
16744
  "minSize",
16417
16745
  "maxSize",
@@ -16436,9 +16764,15 @@ const COMPONENT_PROPERTY_KEYS = [
16436
16764
  "designImageAlpha",
16437
16765
  "designImageLayer",
16438
16766
  "designImageOffset",
16767
+ "designImage",
16768
+ "designImageForTest",
16769
+ "pageController",
16770
+ "showSound",
16771
+ "hideSound",
16439
16772
  "idNum",
16440
16773
  "initName",
16441
16774
  "remark",
16775
+ "customExtensionId",
16442
16776
  "extensionType",
16443
16777
  "opaque",
16444
16778
  "buttonMode",
@@ -16470,6 +16804,8 @@ function isValidUamComponentProperties(value) {
16470
16804
  properties.bgColor,
16471
16805
  properties.initName,
16472
16806
  properties.remark,
16807
+ properties.customExtensionId,
16808
+ properties.pageController,
16473
16809
  properties.extensionType,
16474
16810
  properties.sound,
16475
16811
  properties.dropdown,
@@ -16480,6 +16816,7 @@ function isValidUamComponentProperties(value) {
16480
16816
  properties.pivotAsAnchor,
16481
16817
  properties.reversedMask,
16482
16818
  properties.bgColorEnabled,
16819
+ properties.designImageForTest,
16483
16820
  properties.opaque,
16484
16821
  properties.reverse,
16485
16822
  properties.wholeNumbers,
@@ -16492,8 +16829,6 @@ function isValidUamComponentProperties(value) {
16492
16829
  properties.scrollType,
16493
16830
  properties.scrollBarDisplay,
16494
16831
  properties.scrollBarFlags,
16495
- properties.designImageAlpha,
16496
- properties.designImageLayer,
16497
16832
  properties.idNum,
16498
16833
  properties.buttonMode,
16499
16834
  properties.soundVolumeScale,
@@ -16501,7 +16836,7 @@ function isValidUamComponentProperties(value) {
16501
16836
  properties.downEffectValue,
16502
16837
  properties.titleType
16503
16838
  ];
16504
- return isFiniteUamSize(properties.minSize) && isFiniteUamSize(properties.maxSize) && isFiniteUamPoint(properties.pivot) && isFiniteUamEdgeInsets(properties.margin) && isFiniteUamPoint(properties.clipSoftness) && isFiniteUamEdgeInsets(properties.scrollBarMargin) && isFiniteUamPoint(properties.designImageOffset) && strings.every((item) => typeof item === "string") && booleans.every((item) => typeof item === "boolean") && numbers.every((item) => typeof item === "number" && Number.isFinite(item)) && Array.isArray(properties.customProperties) && properties.customProperties.every((property) => property && typeof property === "object" && hasExactKeys(property, [
16839
+ return isFiniteUamSize(properties.minSize) && isFiniteUamSize(properties.maxSize) && isFiniteUamPoint(properties.pivot) && isFiniteUamEdgeInsets(properties.margin) && isFiniteUamPoint(properties.clipSoftness) && isFiniteUamEdgeInsets(properties.scrollBarMargin) && isFiniteUamPoint(properties.designImageOffset) && strings.every((item) => typeof item === "string") && booleans.every((item) => typeof item === "boolean") && numbers.every((item) => typeof item === "number" && Number.isFinite(item)) && isUiResourceReference(properties.designImage) && isSoundReference(properties.showSound) && isSoundReference(properties.hideSound) && Number.isInteger(properties.designImageAlpha) && properties.designImageAlpha >= 0 && properties.designImageAlpha <= 100 && Number.isInteger(properties.designImageLayer) && properties.designImageLayer >= 0 && properties.designImageLayer <= 1 && Array.isArray(properties.customProperties) && properties.customProperties.every((property) => property && typeof property === "object" && hasExactKeys(property, [
16505
16840
  "target",
16506
16841
  "propertyId",
16507
16842
  "label"
@@ -16510,6 +16845,13 @@ function isValidUamComponentProperties(value) {
16510
16845
  function isNullableString(value) {
16511
16846
  return value === null || typeof value === "string";
16512
16847
  }
16848
+ function isUiResourceReference(value) {
16849
+ return typeof value === "string" && (value === "" || value.startsWith("ui://") && value.length > 5 && !/\s/.test(value));
16850
+ }
16851
+ const isSoundReference = isUiResourceReference;
16852
+ function isSoundVolume(value) {
16853
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
16854
+ }
16513
16855
  function isValidUamComponentInstanceProperties(value) {
16514
16856
  if (typeof value !== "object" || value === null || !("extensionType" in value)) return false;
16515
16857
  const properties = value;
@@ -16537,24 +16879,29 @@ function isValidUamComponentInstanceProperties(value) {
16537
16879
  properties.controller,
16538
16880
  properties.page,
16539
16881
  properties.sound
16540
- ].every((item) => typeof item === "string") && finite(properties.titleFontSize) && typeof properties.checked === "boolean" && finite(properties.soundVolumeScale);
16882
+ ].every((item) => typeof item === "string") && finite(properties.titleFontSize) && typeof properties.checked === "boolean" && isSoundReference(properties.sound) && isSoundVolume(properties.soundVolumeScale);
16541
16883
  case "Label": return hasExactKeys(properties, [
16542
16884
  "extensionType",
16543
16885
  "title",
16544
16886
  "icon",
16545
16887
  "titleColor",
16546
16888
  "titleFontSize",
16547
- "promptText"
16889
+ "promptText",
16890
+ "sound",
16891
+ "soundVolumeScale"
16548
16892
  ]) && [
16549
16893
  properties.title,
16550
16894
  properties.icon,
16551
- properties.titleColor,
16552
16895
  properties.promptText
16553
- ].every((item) => typeof item === "string") && finite(properties.titleFontSize);
16896
+ ].every((item) => typeof item === "string") && (properties.titleColor === "" || isTextColor(properties.titleColor)) && finite(properties.titleFontSize) && isSoundReference(properties.sound) && isSoundVolume(properties.soundVolumeScale);
16554
16897
  case "ComboBox": return hasExactKeys(properties, [
16555
16898
  "extensionType",
16556
16899
  "title",
16557
16900
  "icon",
16901
+ "titleColor",
16902
+ "popupDirection",
16903
+ "sound",
16904
+ "soundVolumeScale",
16558
16905
  "visibleItemCount",
16559
16906
  "selectionController",
16560
16907
  "autoClearItems",
@@ -16563,12 +16910,23 @@ function isValidUamComponentInstanceProperties(value) {
16563
16910
  properties.title,
16564
16911
  properties.icon,
16565
16912
  properties.selectionController
16566
- ].every((item) => typeof item === "string") && finite(properties.visibleItemCount) && typeof properties.autoClearItems === "boolean" && Array.isArray(properties.items) && properties.items.every((item) => item && typeof item === "object" && hasExactKeys(item, [
16913
+ ].every((item) => typeof item === "string") && (properties.titleColor === "" || isTextColor(properties.titleColor)) && Number.isInteger(properties.popupDirection) && properties.popupDirection >= 0 && properties.popupDirection <= 2 && isSoundReference(properties.sound) && isSoundVolume(properties.soundVolumeScale) && finite(properties.visibleItemCount) && typeof properties.autoClearItems === "boolean" && Array.isArray(properties.items) && properties.items.every((item) => item && typeof item === "object" && hasExactKeys(item, [
16567
16914
  "title",
16568
16915
  "value",
16569
16916
  "icon"
16570
16917
  ]) && isNullableString(item.title) && isNullableString(item.value) && isNullableString(item.icon));
16571
- case "ProgressBar":
16918
+ case "ProgressBar": return hasExactKeys(properties, [
16919
+ "extensionType",
16920
+ "value",
16921
+ "max",
16922
+ "min",
16923
+ "sound",
16924
+ "soundVolumeScale"
16925
+ ]) && [
16926
+ properties.value,
16927
+ properties.max,
16928
+ properties.min
16929
+ ].every(finite) && isSoundReference(properties.sound) && isSoundVolume(properties.soundVolumeScale);
16572
16930
  case "Slider": return hasExactKeys(properties, [
16573
16931
  "extensionType",
16574
16932
  "value",
@@ -16624,7 +16982,7 @@ function isSafeRelativePath(value) {
16624
16982
  return segments.length > 0 && segments.every(isSafePathSegment);
16625
16983
  }
16626
16984
  function assetFileName$1(resource) {
16627
- return resource.fileName || (resource.kind === "image" ? "" : resource.file) || resource.name;
16985
+ return resource.fileName || ("file" in resource ? resource.file : "") || resource.name;
16628
16986
  }
16629
16987
  function validatePackageOutputTargets(pkg, pkgPath, issues) {
16630
16988
  if (!isSafePathSegment(pkg.name)) pushIssue(issues, `${pkgPath}.name`, `Invalid package output name "${pkg.name}".`, "unsafe_path");
@@ -16714,9 +17072,23 @@ function validateDisplayNode(node, controllerMap, knownChildIds, knownGroupIds,
16714
17072
  }
16715
17073
  if (node.kind === "component" && node.propertyOverrides !== void 0 && (!Array.isArray(node.propertyOverrides) || !node.propertyOverrides.every(isValidUamComponentPropertyOverride))) pushIssue(issues, `${path}.propertyOverrides`, "Component property overrides must contain a non-empty target, a non-negative integer propertyId, and a string value.");
16716
17074
  if (node.kind === "list" || node.kind === "tree") {
17075
+ if (!Number.isInteger(node.scrollBarDisplay) || node.scrollBarDisplay < 0 || node.scrollBarDisplay > 3) pushIssue(issues, `${path}.scrollBarDisplay`, "List scrollBarDisplay must be an integer between 0 and 3.");
16717
17076
  for (const [itemIndex, item] of node.listItems.entries()) if (item.propertyOverrides !== void 0 && (!Array.isArray(item.propertyOverrides) || !item.propertyOverrides.every(isValidUamComponentPropertyOverride))) pushIssue(issues, `${path}.listItems[${itemIndex}].propertyOverrides`, "List item property overrides must contain a non-empty target, a non-negative integer propertyId, and a string value.");
16718
17077
  }
16719
17078
  if ((node.kind === "text" || node.kind === "richText" || node.kind === "textInput") && !isValidUamTextProperties(textPropertiesFromNode(node), node.kind)) pushIssue(issues, path, "Text properties must be a complete valid snapshot matching the display node kind.");
17079
+ if (node.kind === "image" && !isValidUamImageProperties({
17080
+ color: node.color,
17081
+ flip: node.flip,
17082
+ fillMethod: node.fillMethod,
17083
+ fillOrigin: node.fillOrigin,
17084
+ fillClockwise: node.fillClockwise,
17085
+ fillAmount: node.fillAmount
17086
+ })) pushIssue(issues, path, "Image properties must be a complete valid property snapshot.");
17087
+ if (node.kind === "movieClip" && !isValidUamMovieClipProperties({
17088
+ playing: node.playing,
17089
+ frame: node.frame,
17090
+ color: node.color
17091
+ })) pushIssue(issues, path, "MovieClip properties must be a complete valid property snapshot.");
16720
17092
  if (node.kind === "loader" || node.kind === "loader3D") {
16721
17093
  if ("group" in node) pushIssue(issues, `${path}.group`, `${node.kind} display nodes must not declare a group reference.`);
16722
17094
  } else if (!("group" in node) || typeof node.group !== "string") pushIssue(issues, `${path}.group`, "Display node group must be a string.");
@@ -16787,8 +17159,22 @@ function validateUamProject(project) {
16787
17159
  if (pageIds.has(page.id)) pushIssue(issues, `${pagePath}.id`, `Duplicate controller page id "${page.id}".`);
16788
17160
  pageIds.add(page.id);
16789
17161
  }
17162
+ if (typeof controller.autoRadioGroupDepth !== "boolean") pushIssue(issues, `${controllerPath}.autoRadioGroupDepth`, "Controller autoRadioGroupDepth must be boolean.");
17163
+ if (typeof controller.alias !== "string") pushIssue(issues, `${controllerPath}.alias`, "Controller alias must be a string.");
17164
+ if (typeof controller.exported !== "boolean") pushIssue(issues, `${controllerPath}.exported`, "Controller exported must be boolean.");
17165
+ if (![
17166
+ "default",
17167
+ "specific",
17168
+ "branch",
17169
+ "variable"
17170
+ ].includes(controller.homePageType)) pushIssue(issues, `${controllerPath}.homePageType`, `Unknown controller home page type "${controller.homePageType}".`);
17171
+ else if (typeof controller.homePage !== "string") pushIssue(issues, `${controllerPath}.homePage`, "Controller homePage must be a string.");
17172
+ else if (controller.homePageType === "specific" && !pageIds.has(controller.homePage)) pushIssue(issues, `${controllerPath}.homePage`, `Unknown controller home page id "${controller.homePage}".`);
17173
+ else if (controller.homePageType === "variable" && !controller.homePage) pushIssue(issues, `${controllerPath}.homePage`, "Variable controller home page requires a custom property key.");
17174
+ else if ((controller.homePageType === "default" || controller.homePageType === "branch") && controller.homePage) pushIssue(issues, `${controllerPath}.homePage`, `Controller home page must be empty for "${controller.homePageType}".`);
16790
17175
  for (const [actionIndex, action] of controller.actions.entries()) validateControllerAction(action, pageIds, childIds, `${controllerPath}.actions[${actionIndex}]`, issues);
16791
17176
  }
17177
+ if (component.properties.pageController && !controllerMap.has(component.properties.pageController)) pushIssue(issues, `${resourcePath}.component.properties.pageController`, `Unknown page controller "${component.properties.pageController}".`);
16792
17178
  for (const [childIndex, child] of component.displayList.entries()) {
16793
17179
  if (child.kind === "component" && child.instanceProperties !== void 0 && !isValidUamComponentInstanceProperties(child.instanceProperties)) pushIssue(issues, `${resourcePath}.component.displayList[${childIndex}].instanceProperties`, "Component instance properties must be a complete valid extension snapshot.");
16794
17180
  validateDisplayNode(child, controllerMap, childIds, groupIds, `${resourcePath}.component.displayList[${childIndex}]`, issues);
@@ -16855,6 +17241,7 @@ function validateUamReferences(project) {
16855
17241
  "image",
16856
17242
  "sound",
16857
17243
  "misc",
17244
+ "swf",
16858
17245
  "font",
16859
17246
  "movieClip",
16860
17247
  "spine",
@@ -16885,6 +17272,8 @@ function validateUamReferences(project) {
16885
17272
  ["dropdown", resource.component.properties.dropdown]
16886
17273
  ]) pushMissingUi(`${componentPath}.properties.${field}`, value, componentKinds, owner);
16887
17274
  pushMissingUi(`${componentPath}.properties.sound`, resource.component.properties.sound, ["sound"], owner);
17275
+ pushMissingUi(`${componentPath}.properties.designImage`, resource.component.properties.designImage, ["image"], owner);
17276
+ for (const field of ["showSound", "hideSound"]) pushMissingUi(`${componentPath}.properties.${field}`, resource.component.properties[field], ["sound"], owner);
16888
17277
  for (const [nodeIndex, node] of resource.component.displayList.entries()) {
16889
17278
  const nodePath = `${componentPath}.displayList[${nodeIndex}]`;
16890
17279
  const nodeOwner = {
@@ -16918,10 +17307,8 @@ function validateUamReferences(project) {
16918
17307
  if (node.kind === "component" && node.instanceProperties) {
16919
17308
  const instance = node.instanceProperties;
16920
17309
  if ("icon" in instance) pushMissingUi(`${nodePath}.instanceProperties.icon`, instance.icon, visualKinds, nodeOwner);
16921
- if (instance.extensionType === "Button") {
16922
- pushMissingUi(`${nodePath}.instanceProperties.selectedIcon`, instance.selectedIcon, visualKinds, nodeOwner);
16923
- pushMissingUi(`${nodePath}.instanceProperties.sound`, instance.sound, ["sound"], nodeOwner);
16924
- }
17310
+ if (instance.extensionType === "Button") pushMissingUi(`${nodePath}.instanceProperties.selectedIcon`, instance.selectedIcon, visualKinds, nodeOwner);
17311
+ if (instance.extensionType === "Button" || instance.extensionType === "Label" || instance.extensionType === "ComboBox" || instance.extensionType === "ProgressBar") pushMissingUi(`${nodePath}.instanceProperties.sound`, instance.sound, ["sound"], nodeOwner);
16925
17312
  if (instance.extensionType === "ComboBox") for (const [itemIndex, item] of instance.items.entries()) pushMissingUi(`${nodePath}.instanceProperties.items[${itemIndex}].icon`, item.icon ?? "", visualKinds, nodeOwner);
16926
17313
  }
16927
17314
  if ("icon" in node) pushMissingUi(`${nodePath}.icon`, node.icon, visualKinds, nodeOwner);
@@ -16937,13 +17324,13 @@ function validateUamReferences(project) {
16937
17324
  //#endregion
16938
17325
  //#region ../core/src/uam/project-source-files.ts
16939
17326
  function defaultAssetSourcePath(resource) {
16940
- const fileName = resource.fileName ?? (resource.kind === "image" ? "" : resource.file) ?? "";
17327
+ const fileName = resource.fileName ?? ("file" in resource ? resource.file : "") ?? "";
16941
17328
  return `/${[resource.path.replace(/\\/g, "/").replace(/^\/+|\/+$/g, ""), fileName].filter(Boolean).join("/")}`;
16942
17329
  }
16943
17330
  //#endregion
16944
17331
  //#region ../core/src/uam/source-validation.ts
16945
17332
  function assetFileName(resource) {
16946
- return resource.fileName ?? (resource.kind === "image" ? "" : resource.file) ?? resource.name;
17333
+ return resource.fileName ?? ("file" in resource ? resource.file : "") ?? resource.name;
16947
17334
  }
16948
17335
  function sourceExtension(resource) {
16949
17336
  const fileName = assetFileName(resource);
@@ -16952,15 +17339,8 @@ function sourceExtension(resource) {
16952
17339
  }
16953
17340
  function validSvg(bytes) {
16954
17341
  try {
16955
- if (bytes.byteLength === 0 || bytes.byteLength > 8 * 1024 * 1024) return false;
16956
- const source = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
16957
- if (XMLValidator.validate(source, { allowBooleanAttributes: false }) !== true) return false;
16958
- if (!/<svg(?:\s|>)/i.test(source)) return false;
16959
- if (/<!\s*(?:doctype|entity)\b|<\?xml-stylesheet\b/iu.test(source)) return false;
16960
- if (/<(?:a|animate|animatecolor|animatemotion|animatetransform|audio|canvas|discard|embed|feimage|foreignobject|iframe|image|object|script|set|style|video)(?:\s|>)/iu.test(source)) return false;
16961
- if (/\s(?:on[\w:-]*|style|src)\s*=/iu.test(source)) return false;
16962
- if (/\s(?:href|xlink:href)\s*=\s*['"](?!#[A-Za-z_][\w:.-]*['"])/iu.test(source)) return false;
16963
- return !/(?:https?:|file:|javascript:|data:|\/\/)|url\s*\(\s*(?!['"]?#[A-Za-z_])/iu.test(source);
17342
+ validateSafeSvgSource(bytes);
17343
+ return true;
16964
17344
  } catch {
16965
17345
  return false;
16966
17346
  }
@@ -17273,6 +17653,13 @@ function liftAssetResource(resource) {
17273
17653
  file: misc.getFile()
17274
17654
  };
17275
17655
  }
17656
+ if (resource.propertyType === PropertyType.SWF_RESOURCE) {
17657
+ const swf = resource;
17658
+ return {
17659
+ ...baseAssetResource("swf", swf),
17660
+ file: swf.getFile()
17661
+ };
17662
+ }
17276
17663
  if (resource.propertyType === PropertyType.FONT_RESOURCE) {
17277
17664
  const font = resource;
17278
17665
  return {
@@ -17420,7 +17807,16 @@ function liftDisplayNode(child) {
17420
17807
  kind: "image",
17421
17808
  ...liftDisplayNodeBase(image),
17422
17809
  group: image.getGroup(),
17423
- resource: { resourceId: image.getSrc() }
17810
+ resource: {
17811
+ packageId: image.getPackageId(),
17812
+ resourceId: image.getSrc()
17813
+ },
17814
+ color: image.getColor(),
17815
+ flip: image.getFlip(),
17816
+ fillMethod: image.getFillMethod(),
17817
+ fillOrigin: image.getFillOrigin(),
17818
+ fillClockwise: image.getFillClockwise(),
17819
+ fillAmount: image.getFillAmount()
17424
17820
  };
17425
17821
  }
17426
17822
  if (child.propertyType === PropertyType.G_TEXT_FIELD || child.propertyType === PropertyType.G_RICH_TEXT_FIELD || child.propertyType === PropertyType.G_TEXT_INPUT) {
@@ -17437,6 +17833,7 @@ function liftDisplayNode(child) {
17437
17833
  autoSize: text.getAutoSize(),
17438
17834
  singleLine: text.getSingleLine(),
17439
17835
  autoClearText: text.getAutoClearText(),
17836
+ outlineSoftness: text.getOutlineSoftness(),
17440
17837
  underlaySoftness: text.getUnderlaySoftness(),
17441
17838
  ubbEnabled: text.getUbbEnabled(),
17442
17839
  underline: text.getUnderline(),
@@ -17518,6 +17915,7 @@ function liftDisplayNode(child) {
17518
17915
  src: list.getSrc(),
17519
17916
  overflow: list.getOverflow(),
17520
17917
  scrollType: list.getScrollType(),
17918
+ scrollBarDisplay: list.getScrollBarDisplay(),
17521
17919
  scrollBarFlags: list.getScrollBarFlags(),
17522
17920
  scrollBarMargin: liftEdgeInsets(list.getScrollBarMargin()),
17523
17921
  vtScrollBarRes: list.getVtScrollBarRes(),
@@ -17600,6 +17998,7 @@ function liftDisplayNode(child) {
17600
17998
  shrinkOnly: loader.getShrinkOnly(),
17601
17999
  autoSize: loader.getAutoSize(),
17602
18000
  useResize: loader.getUseResize(),
18001
+ showErrorSign: loader.getShowErrorSign(),
17603
18002
  align: loader.getAlign(),
17604
18003
  vAlign: loader.getVAlign(),
17605
18004
  frame: loader.getFrame(),
@@ -17735,20 +18134,33 @@ function liftComponentInstanceProperties(component) {
17735
18134
  icon: component.getInstanceIcon(),
17736
18135
  titleColor: component.getInstanceTitleColor(),
17737
18136
  titleFontSize: component.getInstanceTitleFontSize(),
17738
- promptText: component.getInstancePromptText()
18137
+ promptText: component.getInstancePromptText(),
18138
+ sound: component.getInstanceSound(),
18139
+ soundVolumeScale: component.getInstanceSoundVolumeScale()
17739
18140
  };
17740
18141
  case "ComboBox": return {
17741
18142
  extensionType: "ComboBox",
17742
18143
  title: component.getInstanceTitle(),
17743
18144
  icon: component.getInstanceIcon(),
18145
+ titleColor: component.getInstanceTitleColor(),
18146
+ popupDirection: component.getInstancePopupDirection(),
18147
+ sound: component.getInstanceSound(),
18148
+ soundVolumeScale: component.getInstanceSoundVolumeScale(),
17744
18149
  visibleItemCount: component.getInstanceVisibleItemCount(),
17745
18150
  selectionController: component.getInstanceSelectionController(),
17746
18151
  autoClearItems: component.getInstanceAutoClearItems(),
17747
18152
  items: component.getInstanceComboItems().map((item) => ({ ...item }))
17748
18153
  };
17749
- case "ProgressBar":
18154
+ case "ProgressBar": return {
18155
+ extensionType: "ProgressBar",
18156
+ value: component.getInstanceValue(),
18157
+ max: component.getInstanceMax(),
18158
+ min: component.getInstanceMin(),
18159
+ sound: component.getInstanceSound(),
18160
+ soundVolumeScale: component.getInstanceSoundVolumeScale()
18161
+ };
17750
18162
  case "Slider": return {
17751
- extensionType: component.getInstanceExtType(),
18163
+ extensionType: "Slider",
17752
18164
  value: component.getInstanceValue(),
17753
18165
  max: component.getInstanceMax(),
17754
18166
  min: component.getInstanceMin()
@@ -17762,9 +18174,14 @@ function liftControllers(component) {
17762
18174
  name: controller.getName(),
17763
18175
  selectedIndex: controller.getSelectedIndex(),
17764
18176
  autoRadioGroupDepth: controller.getAutoRadioGroupDepth(),
18177
+ alias: controller.getAlias(),
18178
+ exported: controller.getExported(),
18179
+ homePageType: controller.getHomePageType(),
18180
+ homePage: controller.getHomePage(),
17765
18181
  pages: controller.listPages().map((page) => ({
17766
18182
  id: page.getId(),
17767
- name: page.getName()
18183
+ name: page.getName(),
18184
+ remark: page.getRemark()
17768
18185
  })),
17769
18186
  actions: controller.listActions().map((action) => ({
17770
18187
  name: action.getName(),
@@ -17868,9 +18285,15 @@ function liftComponentProperties(resource) {
17868
18285
  x: resource.getDesignImageOffsetX(),
17869
18286
  y: resource.getDesignImageOffsetY()
17870
18287
  },
18288
+ designImage: resource.getDesignImage(),
18289
+ designImageForTest: resource.getDesignImageForTest(),
18290
+ pageController: resource.getPageController(),
18291
+ showSound: resource.getAddedToStageSound(),
18292
+ hideSound: resource.getRemovedFromStageSound(),
17871
18293
  idNum: resource.getIdNum(),
17872
18294
  initName: resource.getInitName(),
17873
18295
  remark: resource.getRemark(),
18296
+ customExtensionId: resource.getCustomExtensionId(),
17874
18297
  extensionType: resource.getExtensionType(),
17875
18298
  opaque: resource.getOpaque(),
17876
18299
  buttonMode: resource.getButtonMode(),
@@ -18076,10 +18499,16 @@ const ROOT_COMPONENT_PANEL_ATTRS = {
18076
18499
  bgColor: { canonical: "bgColor" },
18077
18500
  bgColorEnabled: { canonical: "bgColorEnabled" },
18078
18501
  idnum: { canonical: "idnum" },
18079
- initName: { canonical: "initName" }
18502
+ initName: { canonical: "initName" },
18503
+ customExtention: { canonical: "customExtention" },
18504
+ pageController: { canonical: "pageController" },
18505
+ showSound: { canonical: "showSound" },
18506
+ hideSound: { canonical: "hideSound" }
18080
18507
  };
18081
18508
  const ROOT_MISC_PANEL_ATTRS = { remark: { canonical: "remark" } };
18082
18509
  const ROOT_DESIGN_PANEL_ATTRS = {
18510
+ designImage: { canonical: "designImage" },
18511
+ designImageForTest: { canonical: "designImageForTest" },
18083
18512
  designImageAlpha: { canonical: "designImageAlpha" },
18084
18513
  designImageLayer: { canonical: "designImageLayer" },
18085
18514
  designImageOffsetX: { canonical: "designImageOffsetX" },
@@ -18124,6 +18553,7 @@ const LOADER_PANEL_ATTRS = {
18124
18553
  shrinkOnly: { canonical: "shrinkOnly" },
18125
18554
  autoSize: { canonical: "autoSize" },
18126
18555
  useResize: { canonical: "useResize" },
18556
+ errorSign: { canonical: "errorSign" },
18127
18557
  color: { canonical: "color" },
18128
18558
  playing: { canonical: "playing" },
18129
18559
  frame: { canonical: "frame" },
@@ -18178,6 +18608,7 @@ const TEXT_PANEL_ATTRS = {
18178
18608
  autoClearText: { canonical: "autoClearText" },
18179
18609
  demoText: { canonical: "demoText" },
18180
18610
  faceDilate: { canonical: "faceDilate" },
18611
+ outlineSoftness: { canonical: "outlineSoftness" },
18181
18612
  underlaySoftness: { canonical: "underlaySoftness" },
18182
18613
  vars: { canonical: "vars" }
18183
18614
  };
@@ -18193,6 +18624,7 @@ const TEXT_INPUT_PANEL_ATTRS = {
18193
18624
  };
18194
18625
  const RICH_TEXT_PANEL_ATTRS = {
18195
18626
  restrictSize: { canonical: "restrictSize" },
18627
+ outlineSoftness: { canonical: "outlineSoftness" },
18196
18628
  underlaySoftness: { canonical: "underlaySoftness" }
18197
18629
  };
18198
18630
  const GROUP_PANEL_ATTRS = {
@@ -18249,10 +18681,7 @@ const LIST_PANEL_ATTRS = {
18249
18681
  const BUTTON_EXTENSION_ATTRS = {
18250
18682
  mode: { canonical: "mode" },
18251
18683
  sound: { canonical: "sound" },
18252
- soundVolumeScale: {
18253
- canonical: "soundVolumeScale",
18254
- aliases: ["volume"]
18255
- },
18684
+ soundVolumeScale: { canonical: "volume" },
18256
18685
  downEffect: { canonical: "downEffect" },
18257
18686
  downEffectValue: { canonical: "downEffectValue" },
18258
18687
  title: { canonical: "title" },
@@ -18270,12 +18699,18 @@ const LABEL_EXTENSION_ATTRS = {
18270
18699
  icon: { canonical: "icon" },
18271
18700
  titleColor: { canonical: "titleColor" },
18272
18701
  titleFontSize: { canonical: "titleFontSize" },
18273
- prompt: { canonical: "prompt" }
18702
+ prompt: { canonical: "prompt" },
18703
+ sound: { canonical: "sound" },
18704
+ soundVolumeScale: { canonical: "volume" }
18274
18705
  };
18275
18706
  const COMBOBOX_EXTENSION_ATTRS = {
18276
18707
  dropdown: { canonical: "dropdown" },
18277
18708
  title: { canonical: "title" },
18278
18709
  icon: { canonical: "icon" },
18710
+ titleColor: { canonical: "titleColor" },
18711
+ popupDirection: { canonical: "direction" },
18712
+ sound: { canonical: "sound" },
18713
+ soundVolumeScale: { canonical: "volume" },
18279
18714
  visibleItemCount: { canonical: "visibleItemCount" },
18280
18715
  selectionController: { canonical: "selectionController" },
18281
18716
  autoClearItems: { canonical: "autoClearItems" }
@@ -18285,7 +18720,9 @@ const PROGRESSBAR_EXTENSION_ATTRS = {
18285
18720
  reverse: { canonical: "reverse" },
18286
18721
  value: { canonical: "value" },
18287
18722
  max: { canonical: "max" },
18288
- min: { canonical: "min" }
18723
+ min: { canonical: "min" },
18724
+ sound: { canonical: "sound" },
18725
+ soundVolumeScale: { canonical: "volume" }
18289
18726
  };
18290
18727
  const SLIDER_EXTENSION_ATTRS = {
18291
18728
  titleType: { canonical: "titleType" },
@@ -18325,7 +18762,12 @@ const GEAR_ATTRS = {
18325
18762
  const CONTROLLER_ATTRS = {
18326
18763
  name: { canonical: "name" },
18327
18764
  pages: { canonical: "pages" },
18328
- selected: { canonical: "selected" }
18765
+ selected: { canonical: "selected" },
18766
+ alias: { canonical: "alias" },
18767
+ autoRadioGroupDepth: { canonical: "autoRadioGroupDepth" },
18768
+ exported: { canonical: "exported" },
18769
+ homePageType: { canonical: "homePageType" },
18770
+ homePage: { canonical: "homePage" }
18329
18771
  };
18330
18772
  const CONTROLLER_ACTION_ATTRS = {
18331
18773
  type: { canonical: "type" },
@@ -18339,6 +18781,10 @@ const CONTROLLER_ACTION_ATTRS = {
18339
18781
  controller: { canonical: "controller" },
18340
18782
  targetPage: { canonical: "targetPage" }
18341
18783
  };
18784
+ const CONTROLLER_REMARK_ATTRS = {
18785
+ page: { canonical: "page" },
18786
+ value: { canonical: "value" }
18787
+ };
18342
18788
  const TRANSITION_ATTRS = {
18343
18789
  name: { canonical: "name" },
18344
18790
  autoPlay: { canonical: "autoPlay" },
@@ -18348,7 +18794,7 @@ const TRANSITION_ATTRS = {
18348
18794
  },
18349
18795
  autoPlayDelay: { canonical: "autoPlayDelay" },
18350
18796
  options: { canonical: "options" },
18351
- fps: { canonical: "fps" }
18797
+ fps: { canonical: "frameRate" }
18352
18798
  };
18353
18799
  const TRANSITION_ITEM_ATTRS = {
18354
18800
  time: { canonical: "time" },
@@ -18404,6 +18850,7 @@ const CUSTOM_PROPERTY_NODE = defineNode(CUSTOM_PROPERTY_ATTRS);
18404
18850
  const PROPERTY_OVERRIDE_NODE = defineNode(PROPERTY_OVERRIDE_ATTRS);
18405
18851
  const GEAR_NODE = defineNode(GEAR_ATTRS);
18406
18852
  const CONTROLLER_ACTION_NODE = defineNode(CONTROLLER_ACTION_ATTRS);
18853
+ const CONTROLLER_REMARK_NODE = defineNode(CONTROLLER_REMARK_ATTRS);
18407
18854
  const TRANSITION_ITEM_NODE = defineNode(TRANSITION_ITEM_ATTRS);
18408
18855
  const LIST_ITEM_NODE = defineNode(LIST_ITEM_ATTRS, { property: PROPERTY_OVERRIDE_NODE });
18409
18856
  const COMBOBOX_ITEM_NODE = defineNode(COMBOBOX_ITEM_ATTRS);
@@ -18428,7 +18875,10 @@ const WITH_GROUP_GEAR_CHILDREN = {
18428
18875
  gearIcon: GEAR_NODE,
18429
18876
  gearDisplay2: GEAR_NODE
18430
18877
  };
18431
- const WITH_CONTROLLER_ACTION_CHILDREN = { action: CONTROLLER_ACTION_NODE };
18878
+ const WITH_CONTROLLER_ACTION_CHILDREN = {
18879
+ action: CONTROLLER_ACTION_NODE,
18880
+ remark: CONTROLLER_REMARK_NODE
18881
+ };
18432
18882
  const WITH_TRANSITION_ITEM_CHILDREN = { item: TRANSITION_ITEM_NODE };
18433
18883
  const WITH_LIST_ITEM_CHILDREN = { item: LIST_ITEM_NODE };
18434
18884
  const COMBOBOX_EXTENSION_NODE = defineNode(mergeAttrs(COMBOBOX_EXTENSION_ATTRS), mergeChildren({ item: COMBOBOX_ITEM_NODE }));
@@ -18984,6 +19434,8 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
18984
19434
  if (textVars !== void 0) g.setTemplateVarsEnabled?.(parseBool$1(textVars));
18985
19435
  const textFaceDilate = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.faceDilate);
18986
19436
  if (textFaceDilate !== void 0) g.setFaceDilate?.(parseFloat2(textFaceDilate));
19437
+ const textOutlineSoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.outlineSoftness);
19438
+ if (textOutlineSoftness !== void 0) g.setOutlineSoftness?.(parseFloat2(textOutlineSoftness));
18987
19439
  const textUnderlaySoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underlaySoftness);
18988
19440
  if (textUnderlaySoftness !== void 0) g.setUnderlaySoftness?.(parseFloat2(textUnderlaySoftness));
18989
19441
  const textUbb = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.ubb);
@@ -19108,6 +19560,8 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19108
19560
  if (richTextSingleLine !== void 0) g.setSingleLine?.(parseBool$1(richTextSingleLine));
19109
19561
  const richTextAutoClearText = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.autoClearText);
19110
19562
  if (richTextAutoClearText !== void 0) g.setAutoClearText?.(parseBool$1(richTextAutoClearText));
19563
+ const richTextOutlineSoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.outlineSoftness);
19564
+ if (richTextOutlineSoftness !== void 0) g.setOutlineSoftness?.(parseFloat2(richTextOutlineSoftness));
19111
19565
  const richTextUnderlaySoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.underlaySoftness);
19112
19566
  if (richTextUnderlaySoftness !== void 0) g.setUnderlaySoftness?.(parseFloat2(richTextUnderlaySoftness));
19113
19567
  const richTextUnderline = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underline);
@@ -19217,6 +19671,8 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19217
19671
  if (inputVars !== void 0) g.setTemplateVarsEnabled?.(parseBool$1(inputVars));
19218
19672
  const inputFaceDilate = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.faceDilate);
19219
19673
  if (inputFaceDilate !== void 0) g.setFaceDilate?.(parseFloat2(inputFaceDilate));
19674
+ const inputOutlineSoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.outlineSoftness);
19675
+ if (inputOutlineSoftness !== void 0) g.setOutlineSoftness?.(parseFloat2(inputOutlineSoftness));
19220
19676
  const inputUnderlaySoftness = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underlaySoftness);
19221
19677
  if (inputUnderlaySoftness !== void 0) g.setUnderlaySoftness?.(parseFloat2(inputUnderlaySoftness));
19222
19678
  const inputUbb = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.ubb);
@@ -19440,6 +19896,8 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19440
19896
  if (loaderAutoSize !== void 0) g.setAutoSize?.(parseBool$1(loaderAutoSize));
19441
19897
  const useResize = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.useResize);
19442
19898
  if (useResize !== void 0) g.setUseResize?.(parseBool$1(useResize));
19899
+ const errorSign = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.errorSign);
19900
+ if (errorSign !== void 0) g.setShowErrorSign(parseBool$1(errorSign));
19443
19901
  const clearOnPublish = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.clearOnPublish);
19444
19902
  if (clearOnPublish !== void 0) g.setClearOnPublish?.(parseBool$1(clearOnPublish));
19445
19903
  const loaderColor = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.color);
@@ -19745,7 +20203,7 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19745
20203
  if (resolvedLayout === 4 && lineItemCount2 !== void 0) g.setLineCount?.(parseInt2(lineItemCount2));
19746
20204
  }
19747
20205
  const autoResizeItem = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.autoResizeItem);
19748
- if (autoResizeItem !== void 0) g.setAutoResizeItem?.(parseBool$1(autoResizeItem));
20206
+ g.setAutoResizeItem?.(autoResizeItem === void 0 ? getDefaultListAutoResizeItem(g.getLayout?.() ?? 0) : parseBool$1(autoResizeItem));
19749
20207
  const childrenRenderOrder = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.childrenRenderOrder);
19750
20208
  if (childrenRenderOrder) g.setChildrenRenderOrder?.({
19751
20209
  ascent: 0,
@@ -19765,9 +20223,10 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19765
20223
  if (selectionController !== void 0) g.setSelectionController?.(selectionController);
19766
20224
  const overflow = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.overflow);
19767
20225
  const scroll = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scroll);
20226
+ const scrollBar = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scrollBar);
19768
20227
  const scrollBarFlags = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scrollBarFlags);
19769
20228
  const margin = readXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.margin);
19770
- if (overflow || scroll || scrollBarFlags !== void 0 || margin) {
20229
+ if (overflow || scroll || scrollBar || scrollBarFlags !== void 0 || margin) {
19771
20230
  if (overflow) g.setOverflow({
19772
20231
  visible: 0,
19773
20232
  hidden: 1,
@@ -19778,6 +20237,12 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19778
20237
  vertical: 1,
19779
20238
  both: 2
19780
20239
  }[scroll] ?? 1);
20240
+ if (scrollBar) g.setScrollBarDisplay({
20241
+ default: 0,
20242
+ visible: 1,
20243
+ auto: 2,
20244
+ hidden: 3
20245
+ }[scrollBar] ?? 0);
19781
20246
  if (scrollBarFlags !== void 0) g.setScrollBarFlags(parseInt2(scrollBarFlags));
19782
20247
  if (margin) {
19783
20248
  const parts = margin.split(",").map(Number);
@@ -19881,7 +20346,13 @@ function createDisplayObject$1(ctx, doc, tagName, attrs, localControllers) {
19881
20346
  const sound = extSpecs.sound ? readXmlAttr(extAttrs, extSpecs.sound) : void 0;
19882
20347
  if (sound !== void 0) componentObj.setInstanceSound?.(sound);
19883
20348
  const soundVolumeScale = extSpecs.soundVolumeScale ? readXmlAttr(extAttrs, extSpecs.soundVolumeScale) : void 0;
19884
- if (soundVolumeScale !== void 0) componentObj.setInstanceSoundVolumeScale?.(parseFloat2(soundVolumeScale, 1));
20349
+ if (soundVolumeScale !== void 0) componentObj.setInstanceSoundVolumeScale?.(parseFloat2(soundVolumeScale, 100) / 100);
20350
+ const popupDirection = extSpecs.popupDirection ? readXmlAttr(extAttrs, extSpecs.popupDirection) : void 0;
20351
+ if (popupDirection !== void 0) componentObj.setInstancePopupDirection?.({
20352
+ auto: 0,
20353
+ up: 1,
20354
+ down: 2
20355
+ }[popupDirection] ?? 0);
19885
20356
  const prompt = extSpecs.prompt ? readXmlAttr(extAttrs, extSpecs.prompt) : void 0;
19886
20357
  if (prompt !== void 0) componentObj.setInstancePromptText?.(prompt);
19887
20358
  const selectionController = extSpecs.selectionController ? readXmlAttr(extAttrs, extSpecs.selectionController) : void 0;
@@ -19979,6 +20450,12 @@ const EXTENSION_TYPE_MAP = {
19979
20450
  Slider: "GSlider",
19980
20451
  ScrollBar: "GScrollBar"
19981
20452
  };
20453
+ const CONTROLLER_HOME_PAGE_TYPES = new Set([
20454
+ "default",
20455
+ "specific",
20456
+ "branch",
20457
+ "variable"
20458
+ ]);
19982
20459
  const EXTENSION_PROTOCOL_MAP$1 = {
19983
20460
  Button: PROJECT_XML_PROTOCOL.buttonExtension,
19984
20461
  Label: PROJECT_XML_PROTOCOL.labelExtension,
@@ -20084,6 +20561,13 @@ function parseButtonMode(value) {
20084
20561
  const parsed = Number(normalized);
20085
20562
  return map[normalized] ?? (Number.isFinite(parsed) ? parsed : 0);
20086
20563
  }
20564
+ function parseButtonDownEffect(value) {
20565
+ return {
20566
+ none: 0,
20567
+ dark: 1,
20568
+ scale: 2
20569
+ }[String(value ?? "").trim().toLowerCase()] ?? 0;
20570
+ }
20087
20571
  function parseTitleType(value) {
20088
20572
  if (typeof value === "number") return value;
20089
20573
  const normalized = String(value ?? "").trim().toLowerCase();
@@ -20161,6 +20645,10 @@ function readComponentXml(ctx, comp, xmlContent) {
20161
20645
  if (bgColor !== void 0) comp.setBgColor?.(bgColor);
20162
20646
  const bgColorEnabled = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.bgColorEnabled);
20163
20647
  if (bgColorEnabled !== void 0) comp.setBgColorEnabled?.(parseBool$1(bgColorEnabled));
20648
+ const designImage = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImage);
20649
+ if (designImage !== void 0) comp.setDesignImage?.(designImage);
20650
+ const designImageForTest = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageForTest);
20651
+ if (designImageForTest !== void 0) comp.setDesignImageForTest?.(parseBool$1(designImageForTest));
20164
20652
  const designImageAlpha = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageAlpha);
20165
20653
  if (designImageAlpha !== void 0) comp.setDesignImageAlpha?.(parseInt2(designImageAlpha));
20166
20654
  const designImageLayer = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageLayer);
@@ -20175,6 +20663,14 @@ function readComponentXml(ctx, comp, xmlContent) {
20175
20663
  if (initName !== void 0) comp.setInitName?.(initName);
20176
20664
  const remark = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.remark);
20177
20665
  if (remark !== void 0) comp.setRemark?.(remark);
20666
+ const customExtensionId = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.customExtention);
20667
+ if (customExtensionId !== void 0) comp.setCustomExtensionId?.(customExtensionId);
20668
+ const pageController = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.pageController);
20669
+ if (pageController !== void 0) comp.setPageController?.(pageController);
20670
+ const showSound = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.showSound);
20671
+ if (showSound !== void 0) comp.setAddedToStageSound?.(showSound);
20672
+ const hideSound = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.hideSound);
20673
+ if (hideSound !== void 0) comp.setRemovedFromStageSound?.(hideSound);
20178
20674
  const clipSoftness = readXmlAttr(compNode, PROJECT_XML_PROTOCOL.componentRoot.attrs.clipSoftness);
20179
20675
  if (clipSoftness) {
20180
20676
  const parts = clipSoftness.split(",").map(Number);
@@ -20244,8 +20740,8 @@ function readComponentXml(ctx, comp, xmlContent) {
20244
20740
  case "Button":
20245
20741
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.mode) !== void 0) comp.setButtonMode?.(parseButtonMode(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.mode)));
20246
20742
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.sound) !== void 0) comp.setSound?.(String(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.sound)));
20247
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.soundVolumeScale) !== void 0) comp.setSoundVolumeScale?.(parseFloat2(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.soundVolumeScale), 1));
20248
- if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.downEffect) !== void 0) comp.setDownEffect?.(parseInt2(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.downEffect)));
20743
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.soundVolumeScale) !== void 0) comp.setSoundVolumeScale?.(parseFloat2(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.soundVolumeScale), 100) / 100);
20744
+ if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.downEffect) !== void 0) comp.setDownEffect?.(parseButtonDownEffect(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.downEffect)));
20249
20745
  if (readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.downEffectValue) !== void 0) comp.setDownEffectValue?.(parseFloat2(readXmlAttr(extAttrs, EXTENSION_PROTOCOL_MAP$1.Button.attrs.downEffectValue), .8));
20250
20746
  break;
20251
20747
  case "ComboBox":
@@ -20276,7 +20772,7 @@ function readComponentXml(ctx, comp, xmlContent) {
20276
20772
  }
20277
20773
  const customPropertyChildName = getProtocolChildName$1(PROJECT_XML_PROTOCOL.componentRoot, "customProperty");
20278
20774
  const customProperties = customPropertyChildName ? ensureArray(compNode[customPropertyChildName]) : [];
20279
- const customPropertyProtocol = PROJECT_XML_PROTOCOL.componentRoot.children?.customProperty;
20775
+ const customPropertyProtocol = PROJECT_XML_PROTOCOL.componentRoot.children.customProperty;
20280
20776
  comp.setCustomProperties(customProperties.flatMap((value) => {
20281
20777
  const property = getXmlNode$1(value);
20282
20778
  const propertyId = property ? parseInt2(readXmlAttr(property, customPropertyProtocol?.attrs.propertyId), -1) : -1;
@@ -20293,13 +20789,24 @@ function readComponentXml(ctx, comp, xmlContent) {
20293
20789
  const ctrlName = readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.name) ?? "";
20294
20790
  const ctrl = doc.createController(ctrlName);
20295
20791
  const selected = readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.selected);
20296
- ctrl.setSelectedIndex(parseInt2(selected));
20792
+ const homePageType = readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.homePageType) ?? "default";
20793
+ if (!CONTROLLER_HOME_PAGE_TYPES.has(homePageType)) throw new Error(`Controller "${ctrlName}" has unsupported homePageType "${homePageType}".`);
20794
+ ctrl.setSelectedIndex(parseInt2(selected)).setAlias(readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.alias) ?? "").setAutoRadioGroupDepth(parseBool$1(readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.autoRadioGroupDepth))).setExported(parseBool$1(readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.exported))).setHomePageType(homePageType).setHomePage(readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.homePage) ?? "");
20297
20795
  const pages = parseControllerPages(readXmlAttr(ctrlDef, PROJECT_XML_PROTOCOL.controller.attrs.pages) ?? "");
20298
20796
  for (const page of pages) {
20299
20797
  const p = doc.createControllerPage(page.name);
20300
20798
  p.setId(page.id);
20301
20799
  ctrl.addPage(p);
20302
20800
  }
20801
+ const controllerRemarkChildName = getProtocolChildName$1(PROJECT_XML_PROTOCOL.controller, "remark");
20802
+ const controllerRemarkProtocol = PROJECT_XML_PROTOCOL.controller.children.remark;
20803
+ const remarks = controllerRemarkChildName ? ensureArray(ctrlDef[controllerRemarkChildName]) : [];
20804
+ for (const remarkDef of remarks) {
20805
+ const pageIndex = parseInt2(readXmlAttr(remarkDef, controllerRemarkProtocol.attrs.page), -1);
20806
+ const page = ctrl.listPages()[pageIndex];
20807
+ if (!page) continue;
20808
+ page.setRemark(readXmlAttr(remarkDef, controllerRemarkProtocol.attrs.value) ?? "");
20809
+ }
20303
20810
  const controllerActionChildName = getProtocolChildName$1(PROJECT_XML_PROTOCOL.controller, "action");
20304
20811
  const actions = controllerActionChildName ? ensureArray(ctrlDef[controllerActionChildName]) : [];
20305
20812
  for (let actionIndex = 0; actionIndex < actions.length; actionIndex += 1) {
@@ -21265,6 +21772,7 @@ var ProjectReader = class {
21265
21772
  case "MovieClipResource": return resource.getFileName();
21266
21773
  case "SoundResource":
21267
21774
  case "MiscResource":
21775
+ case "SwfResource":
21268
21776
  case "SpineResource":
21269
21777
  case "DragonBonesResource": return resource.getFile();
21270
21778
  default: return "";
@@ -21360,6 +21868,18 @@ var ProjectReader = class {
21360
21868
  ctx.registerResource(pkg.getId(), id, res);
21361
21869
  return res;
21362
21870
  }
21871
+ case "swf": {
21872
+ const res = doc.createSwfResource(name.replace(/\.swf$/i, ""));
21873
+ res.setId(id);
21874
+ res.setPath(path);
21875
+ res.setBranch(branchName);
21876
+ res.setFile(name);
21877
+ res.setExported(exported);
21878
+ res.setFavorite(favorite);
21879
+ pkg.addResource(res);
21880
+ ctx.registerResource(pkg.getId(), id, res);
21881
+ return res;
21882
+ }
21363
21883
  case "font": {
21364
21884
  const res = doc.createFontResource(name.replace(/\.\w+$/, ""));
21365
21885
  res.setId(id);
@@ -21440,6 +21960,7 @@ var ProjectReader = class {
21440
21960
  ctx.registerResource(pkg.getId(), id, res);
21441
21961
  return res;
21442
21962
  }
21963
+ case "atlas": return null;
21443
21964
  default:
21444
21965
  ctx.addDiagnostic({
21445
21966
  severity: "error",
@@ -21832,6 +22353,13 @@ function formatButtonMode(mode) {
21832
22353
  2: "Radio"
21833
22354
  }[mode] ?? "Common";
21834
22355
  }
22356
+ function formatButtonDownEffect(effect) {
22357
+ return [
22358
+ "none",
22359
+ "dark",
22360
+ "scale"
22361
+ ][effect] ?? "none";
22362
+ }
21835
22363
  function formatTitleType(titleType) {
21836
22364
  return {
21837
22365
  0: "percent",
@@ -22094,6 +22622,7 @@ function serializeChild(obj) {
22094
22622
  if (typedObj.getShrinkOnly?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.shrinkOnly, "1");
22095
22623
  if (typedObj.getAutoSize?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.autoSize, "1");
22096
22624
  if (typedObj.getUseResize?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.useResize, "1");
22625
+ if (typedObj.getShowErrorSign?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.errorSign, "true");
22097
22626
  const loaderColor = typedObj.getColor?.();
22098
22627
  if (loaderColor && !isDefaultWhiteColor(loaderColor)) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.color, loaderColor);
22099
22628
  if (typedObj.getFilter?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.loader.attrs.filter, typedObj.getFilter?.());
@@ -22155,10 +22684,14 @@ function serializeChild(obj) {
22155
22684
  if (typedObj.getTemplateVarsEnabled?.()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.vars, "true");
22156
22685
  const faceDilate = typedObj.getFaceDilate?.() ?? 0;
22157
22686
  if (faceDilate !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.faceDilate, String(faceDilate));
22687
+ const outlineSoftness = typedObj.getOutlineSoftness?.() ?? 0;
22688
+ if (outlineSoftness !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.outlineSoftness, String(outlineSoftness));
22158
22689
  const underlaySoftness = typedObj.getUnderlaySoftness?.() ?? 0;
22159
22690
  if (underlaySoftness !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.text.attrs.underlaySoftness, String(underlaySoftness));
22160
22691
  }
22161
22692
  if (type === "GRichTextField") {
22693
+ const outlineSoftness = typedObj.getOutlineSoftness?.() ?? 0;
22694
+ if (outlineSoftness !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.outlineSoftness, String(outlineSoftness));
22162
22695
  const underlaySoftness = typedObj.getUnderlaySoftness?.() ?? 0;
22163
22696
  if (underlaySoftness !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.richText.attrs.underlaySoftness, String(underlaySoftness));
22164
22697
  }
@@ -22287,7 +22820,8 @@ function serializeChild(obj) {
22287
22820
  if ((layout === 2 || layout === 4) && columnCount !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.lineItemCount, String(columnCount));
22288
22821
  else if (layout === 3 && lineCount !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.lineItemCount, String(lineCount));
22289
22822
  if (layout === 4 && lineCount !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.lineItemCount2, String(lineCount));
22290
- if (typedObj.getAutoResizeItem?.() === false) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.autoResizeItem, "false");
22823
+ const autoResizeItem = typedObj.getAutoResizeItem?.() ?? true;
22824
+ if (autoResizeItem !== getDefaultListAutoResizeItem(layout ?? 0)) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.autoResizeItem, String(autoResizeItem));
22291
22825
  const childrenRenderOrder = typedObj.getChildrenRenderOrder?.() ?? 0;
22292
22826
  if (childrenRenderOrder !== 0) {
22293
22827
  writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.childrenRenderOrder, {
@@ -22328,6 +22862,13 @@ function serializeChild(obj) {
22328
22862
  1: "vertical",
22329
22863
  2: "both"
22330
22864
  }[scrollType] ?? "vertical");
22865
+ const scrollBarDisplay = typedObj.getScrollBarDisplay?.() ?? 0;
22866
+ if (overflow === 2 && scrollBarDisplay !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scrollBar, {
22867
+ 0: "default",
22868
+ 1: "visible",
22869
+ 2: "auto",
22870
+ 3: "hidden"
22871
+ }[scrollBarDisplay] ?? "default");
22331
22872
  const scrollBarFlags = typedObj.getScrollBarFlags?.() ?? 0;
22332
22873
  if (scrollBarFlags !== 0) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.list.attrs.scrollBarFlags, String(scrollBarFlags));
22333
22874
  const scrollBarMargin = typedObj.getScrollBarMargin?.();
@@ -22428,8 +22969,13 @@ function serializeChild(obj) {
22428
22969
  if (typedObj.getInstanceController?.() && extSpecs.controller) writeXmlAttr(extAttrs, extSpecs.controller, typedObj.getInstanceController?.());
22429
22970
  if (typedObj.getInstancePage?.() && extSpecs.page) writeXmlAttr(extAttrs, extSpecs.page, typedObj.getInstancePage?.());
22430
22971
  if (typedObj.getInstanceChecked?.() && extSpecs.checked) writeXmlAttr(extAttrs, extSpecs.checked, "1");
22972
+ const popupDirection = typedObj.getInstancePopupDirection?.() ?? 0;
22973
+ if (popupDirection !== 0 && extSpecs.popupDirection) writeXmlAttr(extAttrs, extSpecs.popupDirection, {
22974
+ 1: "up",
22975
+ 2: "down"
22976
+ }[popupDirection]);
22431
22977
  if (typedObj.getInstanceSound?.() && extSpecs.sound) writeXmlAttr(extAttrs, extSpecs.sound, typedObj.getInstanceSound?.());
22432
- if ((typedObj.getInstanceSoundVolumeScale?.() ?? 1) !== 1 && extSpecs.soundVolumeScale) writeXmlAttr(extAttrs, extSpecs.soundVolumeScale, String(typedObj.getInstanceSoundVolumeScale?.() ?? 1));
22978
+ if ((typedObj.getInstanceSoundVolumeScale?.() ?? 1) !== 1 && extSpecs.soundVolumeScale) writeXmlAttr(extAttrs, extSpecs.soundVolumeScale, formatProjectInt32(Math.round((typedObj.getInstanceSoundVolumeScale?.() ?? 1) * 100), "component instance volume"));
22433
22979
  if (typedObj.getInstancePromptText?.() && extSpecs.prompt) writeXmlAttr(extAttrs, extSpecs.prompt, typedObj.getInstancePromptText?.());
22434
22980
  if (typedObj.getInstanceSelectionController?.() && extSpecs.selectionController) writeXmlAttr(extAttrs, extSpecs.selectionController, typedObj.getInstanceSelectionController?.());
22435
22981
  if ((typedObj.getInstanceVisibleItemCount?.() ?? 0) > 0 && extSpecs.visibleItemCount) writeXmlAttr(extAttrs, extSpecs.visibleItemCount, String(typedObj.getInstanceVisibleItemCount?.() ?? 0));
@@ -22607,8 +23153,11 @@ async function writeComponent(fs, comp, pkgDir, sourceRelativePath) {
22607
23153
  if (typedComp.getBgColorEnabled?.()) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.bgColorEnabled, "true");
22608
23154
  const bgColor = typedComp.getBgColor?.();
22609
23155
  if (bgColor) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.bgColor, bgColor);
22610
- const designImageAlpha = typedComp.getDesignImageAlpha?.() ?? 0;
22611
- if (designImageAlpha !== 0) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageAlpha, String(designImageAlpha));
23156
+ const designImage = typedComp.getDesignImage?.();
23157
+ if (designImage) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImage, designImage);
23158
+ if (typedComp.getDesignImageForTest?.()) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageForTest, "true");
23159
+ const designImageAlpha = typedComp.getDesignImageAlpha?.() ?? 50;
23160
+ if (designImageAlpha !== 50) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageAlpha, String(designImageAlpha));
22612
23161
  const designImageLayer = typedComp.getDesignImageLayer?.() ?? 0;
22613
23162
  if (designImageLayer !== 0) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.designImageLayer, String(designImageLayer));
22614
23163
  const designImageOffsetX = typedComp.getDesignImageOffsetX?.() ?? 0;
@@ -22621,6 +23170,14 @@ async function writeComponent(fs, comp, pkgDir, sourceRelativePath) {
22621
23170
  if (initName) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.initName, initName);
22622
23171
  const remark = typedComp.getRemark?.();
22623
23172
  if (remark) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.remark, remark);
23173
+ const customExtensionId = typedComp.getCustomExtensionId?.();
23174
+ if (customExtensionId) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.customExtention, customExtensionId);
23175
+ const pageController = typedComp.getPageController?.();
23176
+ if (pageController) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.pageController, pageController);
23177
+ const showSound = typedComp.getAddedToStageSound?.();
23178
+ if (showSound) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.showSound, showSound);
23179
+ const hideSound = typedComp.getRemovedFromStageSound?.();
23180
+ if (hideSound) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.hideSound, hideSound);
22624
23181
  const clipSoftness = typedComp.getClipSoftness?.();
22625
23182
  if (clipSoftness && ((clipSoftness.x ?? 0) !== 0 || (clipSoftness.y ?? 0) !== 0)) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.clipSoftness, formatProjectInt32List([clipSoftness.x ?? 0, clipSoftness.y ?? 0], "component clipSoftness"));
22626
23183
  if (typedComp.getOpaque?.() === false) writeXmlAttr(compAttrs, PROJECT_XML_PROTOCOL.componentRoot.attrs.opaque, "false");
@@ -22677,7 +23234,7 @@ async function writeComponent(fs, comp, pkgDir, sourceRelativePath) {
22677
23234
  }
22678
23235
  const customProperties = typedComp.getCustomProperties?.() ?? [];
22679
23236
  const customPropertyChildName = getProtocolChildName(PROJECT_XML_PROTOCOL.componentRoot, "customProperty");
22680
- const customPropertyProtocol = PROJECT_XML_PROTOCOL.componentRoot.children?.customProperty;
23237
+ const customPropertyProtocol = PROJECT_XML_PROTOCOL.componentRoot.children.customProperty;
22681
23238
  if (customProperties.length > 0 && customPropertyChildName) compNode[customPropertyChildName] = customProperties.map((property) => {
22682
23239
  const attrs = {};
22683
23240
  writeXmlAttr(attrs, customPropertyProtocol?.attrs.target, property.target);
@@ -22692,10 +23249,10 @@ async function writeComponent(fs, comp, pkgDir, sourceRelativePath) {
22692
23249
  case "Button": {
22693
23250
  if ((typedComp.getButtonMode?.() ?? 0) !== 0) writeXmlAttr(extAttrs, extSpecs.mode, formatButtonMode(typedComp.getButtonMode?.() ?? 0));
22694
23251
  if (typedComp.getSound?.()) writeXmlAttr(extAttrs, extSpecs.sound, typedComp.getSound?.());
22695
- if ((typedComp.getSoundVolumeScale?.() ?? 1) !== 1) writeXmlAttr(extAttrs, extSpecs.soundVolumeScale, String(typedComp.getSoundVolumeScale?.() ?? 1));
23252
+ if ((typedComp.getSoundVolumeScale?.() ?? 1) !== 1) writeXmlAttr(extAttrs, extSpecs.soundVolumeScale, String(Math.round((typedComp.getSoundVolumeScale?.() ?? 1) * 100)));
22696
23253
  const downEffect = typedComp.getDownEffect?.() ?? 0;
22697
23254
  if (downEffect !== 0) {
22698
- writeXmlAttr(extAttrs, extSpecs.downEffect, String(downEffect));
23255
+ writeXmlAttr(extAttrs, extSpecs.downEffect, formatButtonDownEffect(downEffect));
22699
23256
  writeXmlAttr(extAttrs, extSpecs.downEffectValue, formatButtonDownEffectValue(typedComp.getDownEffectValue?.() ?? .8));
22700
23257
  }
22701
23258
  break;
@@ -22736,11 +23293,27 @@ async function writeComponent(fs, comp, pkgDir, sourceRelativePath) {
22736
23293
  await fs.writeFile(targetPath, builder.build(xmlObj));
22737
23294
  }
22738
23295
  function serializeController(ctrl) {
22739
- const pagesStr = ctrl.listPages().map((p) => `${p.getId()},${p.getName()}`).join(",");
23296
+ const pages = ctrl.listPages();
23297
+ const pagesStr = pages.map((p) => `${p.getId()},${p.getName()}`).join(",");
22740
23298
  const attrs = {};
22741
23299
  writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.name, ctrl.getName());
22742
23300
  writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.pages, pagesStr);
22743
23301
  writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.selected, String(ctrl.getSelectedIndex()));
23302
+ if (ctrl.getAlias()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.alias, ctrl.getAlias());
23303
+ if (ctrl.getAutoRadioGroupDepth()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.autoRadioGroupDepth, "true");
23304
+ if (ctrl.getExported()) writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.exported, "true");
23305
+ if (ctrl.getHomePageType() !== "default") writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.homePageType, ctrl.getHomePageType());
23306
+ if (ctrl.getHomePageType() === "specific" || ctrl.getHomePageType() === "variable") writeXmlAttr(attrs, PROJECT_XML_PROTOCOL.controller.attrs.homePage, ctrl.getHomePage());
23307
+ const remarkProtocol = PROJECT_XML_PROTOCOL.controller.children.remark;
23308
+ const remarks = pages.flatMap((page, pageIndex) => {
23309
+ if (!page.getRemark()) return [];
23310
+ const remarkAttrs = {};
23311
+ writeXmlAttr(remarkAttrs, remarkProtocol.attrs.page, String(pageIndex));
23312
+ writeXmlAttr(remarkAttrs, remarkProtocol.attrs.value, page.getRemark());
23313
+ return [remarkAttrs];
23314
+ });
23315
+ const remarkChildName = getProtocolChildName(PROJECT_XML_PROTOCOL.controller, "remark");
23316
+ if (remarks.length > 0 && remarkChildName) attrs[remarkChildName] = remarks;
22744
23317
  const actions = ctrl.listActions().map((action) => serializeControllerAction(action));
22745
23318
  const actionChildName = getProtocolChildName(PROJECT_XML_PROTOCOL.controller, "action");
22746
23319
  if (actions.length > 0 && actionChildName) attrs[actionChildName] = actions;
@@ -22855,7 +23428,11 @@ var ProjectWriter = class {
22855
23428
  if (settings[key] === void 0 && await fs.exists(filePath)) staleOptionalSettings.push(filePath);
22856
23429
  }
22857
23430
  if (staleOptionalSettings.length > 0 && !fs.unlink) throw new Error("Project settings cleanup requires a FileSystem.unlink() implementation.");
22858
- const fairyXml = `<?xml version="1.0" encoding="utf-8"?>\n<projectDescription id="${root.getProjectId()}" type="${this._projectTypeName(root.getProjectType())}" version="${root.getVersion() || "3.0"}"/>\n`;
23431
+ const fairyXml = `<?xml version="1.0" encoding="utf-8"?>\n<projectDescription${renderXmlAttrs({
23432
+ id: root.getProjectId(),
23433
+ type: this._projectTypeName(root.getProjectType()),
23434
+ version: root.getVersion() || "3.0"
23435
+ })}/>\n`;
22859
23436
  await fs.writeFile(projectPath, fairyXml);
22860
23437
  await fs.mkdir(settingsPath);
22861
23438
  for (const [fileName, key] of Object.entries({
@@ -23272,6 +23849,7 @@ var ProjectWriter = class {
23272
23849
  SoundResource: "sound",
23273
23850
  FontResource: "font",
23274
23851
  MovieClipResource: "movieclip",
23852
+ SwfResource: "swf",
23275
23853
  SpineResource: "spine",
23276
23854
  DragonBonesResource: "dragonbones"
23277
23855
  }[propertyType] ?? null;
@@ -23284,7 +23862,7 @@ var ProjectWriter = class {
23284
23862
  const fileName = res.getFileName?.() ?? "";
23285
23863
  if (fileName) return fileName;
23286
23864
  }
23287
- if (type === "SoundResource" || type === "MiscResource" || type === "SpineResource" || type === "DragonBonesResource") {
23865
+ if (type === "SoundResource" || type === "MiscResource" || type === "SwfResource" || type === "SpineResource" || type === "DragonBonesResource") {
23288
23866
  const fileName = res.getFile?.() ?? "";
23289
23867
  if (fileName) return fileName;
23290
23868
  }
@@ -23531,21 +24109,31 @@ function decodeComponentControllers(doc, resource, buf) {
23531
24109
  controller.addPage(page);
23532
24110
  }
23533
24111
  let homePageIndex = 0;
24112
+ let homePageType = controller.getHomePageType();
24113
+ let homePage = "";
23534
24114
  if (controllerBuf.version >= 2 && remainingBytes(controllerBuf) >= 1) switch (controllerBuf.getUint8()) {
23535
24115
  case 1:
23536
- if (remainingBytes(controllerBuf) >= 2) homePageIndex = controllerBuf.getInt16();
24116
+ homePageType = "specific";
24117
+ if (remainingBytes(controllerBuf) >= 2) {
24118
+ homePageIndex = controllerBuf.getInt16();
24119
+ homePage = controller.listPages()[homePageIndex]?.getId() ?? "";
24120
+ }
23537
24121
  break;
23538
24122
  case 2:
24123
+ homePageType = "branch";
23539
24124
  homePageIndex = 0;
23540
24125
  break;
23541
24126
  case 3:
23542
- if (remainingBytes(controllerBuf) >= 2) controllerBuf.readS();
24127
+ homePageType = "variable";
24128
+ if (remainingBytes(controllerBuf) >= 2) homePage = controllerBuf.readS() ?? "";
23543
24129
  homePageIndex = 0;
23544
24130
  break;
23545
24131
  default:
24132
+ homePageType = "default";
23546
24133
  homePageIndex = 0;
23547
24134
  break;
23548
24135
  }
24136
+ controller.setHomePageType(homePageType).setHomePage(homePage);
23549
24137
  if (controller.listPages().length > 0) {
23550
24138
  const maxIndex = controller.listPages().length - 1;
23551
24139
  controller.setSelectedIndex(Math.min(Math.max(homePageIndex, 0), maxIndex));
@@ -23908,6 +24496,10 @@ function decodeChildBlock4ComponentLike(resource, child, childBuf) {
23908
24496
  const controller = resource.listControllers()[pageControllerIndex];
23909
24497
  if (controller && "setPageController" in child && typeof child.setPageController === "function") child.setPageController(controller.getName());
23910
24498
  }
24499
+ if (childBuf.version >= 2 && remainingBytes(childBuf) >= 2) {
24500
+ const propertyOverrides = decodePropertyOverrides(childBuf);
24501
+ if ("setPropertyOverrides" in child && typeof child.setPropertyOverrides === "function") child.setPropertyOverrides(propertyOverrides);
24502
+ }
23911
24503
  }
23912
24504
  function decodeChildBlock4TextInput(child, childBuf) {
23913
24505
  if (!childBuf.seek(0, 4) || remainingBytes(childBuf) < 10) return;
@@ -23923,16 +24515,12 @@ function decodeTextChildSpecific(child, childBuf) {
23923
24515
  y: childBuf.getFloat32()
23924
24516
  });
23925
24517
  if (childBuf.readBool()) {}
23926
- if (childBuf.version >= 3 && remainingBytes(childBuf) >= 13) {
23927
- textChild.setStrikethrough(childBuf.readBool());
23928
- childBuf.skip(12);
23929
- }
24518
+ if (childBuf.version >= 3 && remainingBytes(childBuf) >= 13) textChild.setStrikethrough(childBuf.readBool()).setFaceDilate(childBuf.getFloat32()).setOutlineSoftness(childBuf.getFloat32()).setUnderlaySoftness(childBuf.getFloat32());
23930
24519
  }
23931
24520
  function decodeListScrollPane(child, childBuf) {
23932
24521
  if (!childBuf.seek(0, 7) || remainingBytes(childBuf) < 10) return;
23933
24522
  const listLike = child;
23934
- listLike.setScrollType(childBuf.getUint8());
23935
- childBuf.getUint8();
24523
+ listLike.setScrollType(childBuf.getUint8()).setScrollBarDisplay(childBuf.getUint8());
23936
24524
  listLike.setScrollBarFlags(childBuf.getInt32());
23937
24525
  if (childBuf.readBool() && remainingBytes(childBuf) >= 16) listLike.setScrollBarMargin([
23938
24526
  childBuf.getInt32(),
@@ -23942,20 +24530,26 @@ function decodeListScrollPane(child, childBuf) {
23942
24530
  ]);
23943
24531
  listLike.setVtScrollBarRes(childBuf.readS() ?? "").setHzScrollBarRes(childBuf.readS() ?? "").setHeaderRes(childBuf.readS() ?? "").setFooterRes(childBuf.readS() ?? "");
23944
24532
  }
24533
+ function decodePropertyOverrides(buf) {
24534
+ const count = buf.getInt16();
24535
+ const properties = [];
24536
+ for (let index = 0; index < count && remainingBytes(buf) >= 6; index += 1) properties.push({
24537
+ target: buf.readS() ?? "",
24538
+ propertyId: buf.getInt16(),
24539
+ value: buf.readS() ?? ""
24540
+ });
24541
+ return properties;
24542
+ }
23945
24543
  function decodeListItemOverrides(buf, version) {
23946
- if (remainingBytes(buf) < 2) return null;
24544
+ if (remainingBytes(buf) < 2) return {};
23947
24545
  const controllerOverrideCount = buf.getInt16();
23948
24546
  const controllerParts = [];
23949
24547
  for (let index = 0; index < controllerOverrideCount && remainingBytes(buf) >= 4; index += 1) controllerParts.push(buf.readS() ?? "", buf.readS() ?? "");
23950
- if (version >= 2 && remainingBytes(buf) >= 2) {
23951
- const propertyOverrideCount = buf.getInt16();
23952
- for (let index = 0; index < propertyOverrideCount && remainingBytes(buf) >= 6; index += 1) {
23953
- buf.readS();
23954
- buf.getInt16();
23955
- buf.readS();
23956
- }
23957
- }
23958
- return controllerParts.length > 0 ? controllerParts.join(",") : null;
24548
+ const propertyOverrides = version >= 2 && remainingBytes(buf) >= 2 ? decodePropertyOverrides(buf) : [];
24549
+ return {
24550
+ ...controllerParts.length > 0 ? { controllers: controllerParts.join(",") } : {},
24551
+ ...propertyOverrides.length > 0 ? { propertyOverrides } : {}
24552
+ };
23959
24553
  }
23960
24554
  function decodeListItems(child, childBuf) {
23961
24555
  if (!childBuf.seek(0, 8) || remainingBytes(childBuf) < 4) return;
@@ -23984,10 +24578,9 @@ function decodeListItems(child, childBuf) {
23984
24578
  level,
23985
24579
  isFolder
23986
24580
  };
23987
- const controllers = decodeListItemOverrides(childBuf, childBuf.version);
23988
- items.push(controllers === null ? item : {
24581
+ items.push({
23989
24582
  ...item,
23990
- controllers
24583
+ ...decodeListItemOverrides(childBuf, childBuf.version)
23991
24584
  });
23992
24585
  childBuf.pos = nextPos;
23993
24586
  }
@@ -24050,7 +24643,7 @@ function decodeChildBlock5(child, childBuf) {
24050
24643
  if (remainingBytes(childBuf) < 15) return;
24051
24644
  const loader = child;
24052
24645
  loader.setUrl(childBuf.readS() ?? "").setAlign(childBuf.getUint8()).setVAlign(childBuf.getUint8()).setFill(childBuf.getUint8()).setShrinkOnly(childBuf.readBool()).setAutoSize(childBuf.readBool());
24053
- childBuf.readBool();
24646
+ loader.setShowErrorSign(childBuf.readBool());
24054
24647
  loader.setPlaying(childBuf.readBool()).setFrame(childBuf.getInt32());
24055
24648
  if (childBuf.readBool()) loader.setColor(readColorValue(childBuf, false));
24056
24649
  loader.setFillMethod(childBuf.getUint8());
@@ -24139,10 +24732,7 @@ function decodeChildBlock6(resource, child, childBuf) {
24139
24732
  childBuf.readBool();
24140
24733
  }
24141
24734
  }
24142
- if (childBuf.version >= 5 && remainingBytes(childBuf) >= 6) {
24143
- childBuf.readS();
24144
- childBuf.getFloat32();
24145
- }
24735
+ if (childBuf.version >= 5 && remainingBytes(childBuf) >= 6) component.setInstanceSound(childBuf.readS() ?? "").setInstanceSoundVolumeScale(childBuf.getFloat32());
24146
24736
  break;
24147
24737
  case "ComboBox": {
24148
24738
  if (remainingBytes(childBuf) < 2) return;
@@ -24160,24 +24750,17 @@ function decodeChildBlock6(resource, child, childBuf) {
24160
24750
  }
24161
24751
  component.setInstanceComboItems(items).setInstanceTitle(childBuf.readS() ?? "").setInstanceIcon(childBuf.readS() ?? "");
24162
24752
  if (childBuf.readBool()) component.setInstanceTitleColor(readColorValue(childBuf, true));
24163
- component.setInstanceVisibleItemCount(childBuf.getInt32());
24164
- childBuf.getUint8();
24753
+ component.setInstanceVisibleItemCount(childBuf.getInt32()).setInstancePopupDirection(childBuf.getUint8());
24165
24754
  const selectionControllerIndex = childBuf.getInt16();
24166
24755
  if (selectionControllerIndex >= 0) component.setInstanceSelectionController(resource.listControllers()[selectionControllerIndex]?.getName() ?? "");
24167
- if (childBuf.version >= 5 && remainingBytes(childBuf) >= 6) {
24168
- childBuf.readS();
24169
- childBuf.getFloat32();
24170
- }
24756
+ if (childBuf.version >= 5 && remainingBytes(childBuf) >= 6) component.setInstanceSound(childBuf.readS() ?? "").setInstanceSoundVolumeScale(childBuf.getFloat32());
24171
24757
  break;
24172
24758
  }
24173
24759
  case "ProgressBar":
24174
24760
  case "Slider":
24175
24761
  if (remainingBytes(childBuf) < 12) return;
24176
24762
  component.setInstanceValue(childBuf.getInt32()).setInstanceMax(childBuf.getInt32()).setInstanceMin(childBuf.getInt32());
24177
- if (extTypeName === "ProgressBar" && childBuf.version >= 5 && remainingBytes(childBuf) >= 6) {
24178
- childBuf.readS();
24179
- childBuf.getFloat32();
24180
- }
24763
+ if (extTypeName === "ProgressBar" && childBuf.version >= 5 && remainingBytes(childBuf) >= 6) component.setInstanceSound(childBuf.readS() ?? "").setInstanceSoundVolumeScale(childBuf.getFloat32());
24181
24764
  break;
24182
24765
  default: break;
24183
24766
  }
@@ -24398,6 +24981,41 @@ function decodeComponentDefinition(resource, rawData, extensionTypeCode, doc) {
24398
24981
  }
24399
24982
  //#endregion
24400
24983
  //#region ../core/src/io/binary-reader.ts
24984
+ const DEFAULT_BINARY_READ_LIMITS = {
24985
+ maxCompressedBytes: 64 * 1024 * 1024,
24986
+ maxDecompressedBytes: 256 * 1024 * 1024,
24987
+ maxCompressionRatio: 200
24988
+ };
24989
+ function readLimits(options) {
24990
+ const limits = {
24991
+ ...DEFAULT_BINARY_READ_LIMITS,
24992
+ ...options.limits
24993
+ };
24994
+ for (const [name, value] of Object.entries(limits)) if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${name} must be a positive finite number.`);
24995
+ return limits;
24996
+ }
24997
+ function inflateRawWithLimits(input, limits) {
24998
+ if (input.byteLength > limits.maxCompressedBytes) throw new Error(`FairyGUI binary compressed data exceeds ${limits.maxCompressedBytes} bytes.`);
24999
+ const maxOutputBytes = Math.min(limits.maxDecompressedBytes, Math.floor(input.byteLength * limits.maxCompressionRatio));
25000
+ const chunks = [];
25001
+ let outputLength = 0;
25002
+ const inflater = new Inflate_1({ raw: true });
25003
+ inflater.onData = (chunk) => {
25004
+ if (!(chunk instanceof Uint8Array)) throw new Error("FairyGUI binary inflate returned non-binary data.");
25005
+ outputLength += chunk.byteLength;
25006
+ if (outputLength > maxOutputBytes) throw new Error(`FairyGUI binary decompressed data exceeds the configured ${maxOutputBytes} byte budget.`);
25007
+ chunks.push(chunk);
25008
+ };
25009
+ inflater.push(input, true);
25010
+ if (inflater.err !== 0) throw new Error(`Invalid compressed FairyGUI binary data: ${inflater.msg}`);
25011
+ const output = new Uint8Array(outputLength);
25012
+ let offset = 0;
25013
+ for (const chunk of chunks) {
25014
+ output.set(chunk, offset);
25015
+ offset += chunk.byteLength;
25016
+ }
25017
+ return output;
25018
+ }
24401
25019
  /**
24402
25020
  * Binary item type codes as used in the .fui format.
24403
25021
  * @internal
@@ -24498,7 +25116,7 @@ function decodeFontGlyphs(doc, resource, buf) {
24498
25116
  for (let index = 0; index < glyphCount; index += 1) {
24499
25117
  const chunkSize = buf.getInt16();
24500
25118
  const nextPos = buf.pos + chunkSize;
24501
- const charId = buf.getInt16();
25119
+ const charId = buf.getUint16();
24502
25120
  const glyph = doc.createFontGlyph(`${resource.getId()}_${charId || index}`);
24503
25121
  glyph.setCharId(charId).setChar(decodeChar(charId)).setImg(buf.readS() ?? "").setX(buf.getInt32()).setY(buf.getInt32()).setXOffset(buf.getInt32()).setYOffset(buf.getInt32()).setWidth(buf.getInt32()).setHeight(buf.getInt32()).setAdvance(buf.getInt32()).setChannel(buf.getUint8());
24504
25122
  resource.addGlyph(glyph);
@@ -24517,8 +25135,10 @@ function decodeFontGlyphs(doc, resource, buf) {
24517
25135
  */
24518
25136
  var BinaryReader = class {
24519
25137
  _fs;
24520
- constructor(fs) {
25138
+ _limits;
25139
+ constructor(fs, options = {}) {
24521
25140
  this._fs = fs;
25141
+ this._limits = readLimits(options);
24522
25142
  }
24523
25143
  async read(filePath) {
24524
25144
  const doc = new Document();
@@ -24544,9 +25164,12 @@ var BinaryReader = class {
24544
25164
  outer.skip(20);
24545
25165
  let buf;
24546
25166
  if (compressed) {
24547
- const decompressed = inflateRaw_1(new Uint8Array(outer.buffer, outer.byteOffset + outer.pos, outer.byteLength - outer.pos));
25167
+ const decompressed = inflateRawWithLimits(new Uint8Array(outer.buffer, outer.byteOffset + outer.pos, outer.byteLength - outer.pos), this._limits);
24548
25168
  buf = new ByteBuffer(decompressed.buffer, 0, decompressed.byteLength);
24549
- } else buf = outer;
25169
+ } else {
25170
+ if (outer.byteLength - outer.pos > this._limits.maxDecompressedBytes) throw new Error(`FairyGUI binary data exceeds ${this._limits.maxDecompressedBytes} bytes.`);
25171
+ buf = outer;
25172
+ }
24550
25173
  buf.version = outer.version;
24551
25174
  const indexTablePos = buf.pos;
24552
25175
  const ver2 = buf.version >= 2;
@@ -24610,13 +25233,13 @@ var BinaryReader = class {
24610
25233
  if (scaleOpt === 1) {
24611
25234
  const x = buf.getInt32(), y = buf.getInt32();
24612
25235
  const w = buf.getInt32(), h = buf.getInt32();
24613
- buf.getInt32();
25236
+ const tileGridIndice = buf.getInt32();
24614
25237
  res.setScaleOption(1).setScale9Grid([
24615
25238
  x,
24616
25239
  y,
24617
25240
  w,
24618
25241
  h
24619
- ]);
25242
+ ]).setTileGridIndice(tileGridIndice);
24620
25243
  } else if (scaleOpt === 2) res.setScaleOption(2);
24621
25244
  res.setSmoothing(buf.readBool());
24622
25245
  pkg.addResource(res);
@@ -24654,6 +25277,17 @@ var BinaryReader = class {
24654
25277
  createdResource = res;
24655
25278
  break;
24656
25279
  }
25280
+ case BinItemType$1.Swf: {
25281
+ const res = doc.createSwfResource(itemName);
25282
+ res.setId(itemId).setPath(itemPath).setFile(itemFile).setExported(exported);
25283
+ res.setExtras({
25284
+ ...res.getExtras(),
25285
+ _publishedFile: itemFile
25286
+ });
25287
+ pkg.addResource(res);
25288
+ createdResource = res;
25289
+ break;
25290
+ }
24657
25291
  case BinItemType$1.Component: {
24658
25292
  const res = doc.createComponent(itemName);
24659
25293
  res.setId(itemId).setPath(itemPath).setExported(exported).setSize(width, height);
@@ -24664,6 +25298,8 @@ var BinaryReader = class {
24664
25298
  ...getComponentExtras(res),
24665
25299
  _rawBinary: toRawBinarySlice(rawData)
24666
25300
  });
25301
+ res._markBinaryClean();
25302
+ doc._trackBinaryComponent();
24667
25303
  pkg.addResource(res);
24668
25304
  createdResource = res;
24669
25305
  break;
@@ -24815,7 +25451,7 @@ var BinaryReader = class {
24815
25451
  *
24816
25452
  * @internal
24817
25453
  */
24818
- var WriteBuffer = class {
25454
+ var WriteBuffer = class WriteBuffer {
24819
25455
  _buf;
24820
25456
  _view;
24821
25457
  _pos = 0;
@@ -24825,6 +25461,9 @@ var WriteBuffer = class {
24825
25461
  _strings;
24826
25462
  /** Raw custom strings written to block 5, keyed by string table index. */
24827
25463
  _customStrings;
25464
+ static _assertInteger(value, min, max, type) {
25465
+ if (!Number.isSafeInteger(value) || value < min || value > max) throw new RangeError(`${type} value is out of range: ${value}`);
25466
+ }
24828
25467
  constructor(initialSize = 4096, parent) {
24829
25468
  this._buf = new ArrayBuffer(initialSize);
24830
25469
  this._view = new DataView(this._buf);
@@ -24859,34 +25498,41 @@ var WriteBuffer = class {
24859
25498
  this._view = new DataView(this._buf);
24860
25499
  }
24861
25500
  writeUint8(v) {
25501
+ WriteBuffer._assertInteger(v, 0, 255, "uint8");
24862
25502
  this._ensure(1);
24863
25503
  this._view.setUint8(this._pos++, v);
24864
25504
  }
24865
25505
  writeInt8(v) {
25506
+ WriteBuffer._assertInteger(v, -128, 127, "int8");
24866
25507
  this._ensure(1);
24867
25508
  this._view.setInt8(this._pos++, v);
24868
25509
  }
24869
25510
  writeUint16(v) {
25511
+ WriteBuffer._assertInteger(v, 0, 65535, "uint16");
24870
25512
  this._ensure(2);
24871
25513
  this._view.setUint16(this._pos, v, false);
24872
25514
  this._pos += 2;
24873
25515
  }
24874
25516
  writeInt16(v) {
25517
+ WriteBuffer._assertInteger(v, -32768, 32767, "int16");
24875
25518
  this._ensure(2);
24876
25519
  this._view.setInt16(this._pos, v, false);
24877
25520
  this._pos += 2;
24878
25521
  }
24879
25522
  writeUint32(v) {
25523
+ WriteBuffer._assertInteger(v, 0, 4294967295, "uint32");
24880
25524
  this._ensure(4);
24881
25525
  this._view.setUint32(this._pos, v, false);
24882
25526
  this._pos += 4;
24883
25527
  }
24884
25528
  writeInt32(v) {
25529
+ WriteBuffer._assertInteger(v, -2147483648, 2147483647, "int32");
24885
25530
  this._ensure(4);
24886
25531
  this._view.setInt32(this._pos, v, false);
24887
25532
  this._pos += 4;
24888
25533
  }
24889
25534
  writeFloat32(v) {
25535
+ if (!Number.isFinite(v)) throw new RangeError(`float32 value must be finite: ${v}`);
24890
25536
  this._ensure(4);
24891
25537
  this._view.setFloat32(this._pos, v, false);
24892
25538
  this._pos += 4;
@@ -24897,6 +25543,7 @@ var WriteBuffer = class {
24897
25543
  /** Write a uint16-prefixed UTF-8 string. */
24898
25544
  writeUTFString(s) {
24899
25545
  const encoded = new TextEncoder().encode(s);
25546
+ if (encoded.byteLength > 65535) throw new RangeError(`UTF string exceeds uint16 byte length: ${encoded.byteLength}`);
24900
25547
  this.writeUint16(encoded.byteLength);
24901
25548
  this._ensure(encoded.byteLength);
24902
25549
  new Uint8Array(this._buf, this._pos, encoded.byteLength).set(encoded);
@@ -24923,6 +25570,7 @@ var WriteBuffer = class {
24923
25570
  const existing = this._stringMap.get(s);
24924
25571
  if (existing !== void 0) return existing;
24925
25572
  const index = this._strings.length;
25573
+ if (index >= 65533) throw new RangeError(`String table exceeds protocol index limit: ${index + 1}`);
24926
25574
  this._strings.push(s);
24927
25575
  this._stringMap.set(s, index);
24928
25576
  return index;
@@ -24959,6 +25607,7 @@ var WriteBuffer = class {
24959
25607
  if (!noCache) this.writeUint16(this.addString(s));
24960
25608
  else {
24961
25609
  const index = this._strings.length;
25610
+ if (index >= 65533) throw new RangeError(`String table exceeds protocol index limit: ${index + 1}`);
24962
25611
  this._strings.push(s);
24963
25612
  this.writeUint16(index);
24964
25613
  }
@@ -25187,7 +25836,27 @@ function _writeControllers(buf, comp) {
25187
25836
  buf.writeSEx(page.getId?.() ?? "", false, false);
25188
25837
  buf.writeSEx(page.getName?.() ?? "", false, false);
25189
25838
  }
25190
- buf.writeUint8(0);
25839
+ switch (ctrl.getHomePageType()) {
25840
+ case "default":
25841
+ buf.writeUint8(0);
25842
+ break;
25843
+ case "specific": {
25844
+ const homePageIndex = pages.findIndex((page) => page.getId() === ctrl.getHomePage());
25845
+ if (homePageIndex < 0) throw new Error(`Controller "${ctrl.getName()}" references unknown home page id "${ctrl.getHomePage()}".`);
25846
+ buf.writeUint8(1);
25847
+ buf.writeInt16(homePageIndex);
25848
+ break;
25849
+ }
25850
+ case "branch":
25851
+ buf.writeUint8(2);
25852
+ break;
25853
+ case "variable":
25854
+ if (!ctrl.getHomePage()) throw new Error(`Controller "${ctrl.getName()}" requires a custom property key.`);
25855
+ buf.writeUint8(3);
25856
+ buf.writeS(ctrl.getHomePage());
25857
+ break;
25858
+ default: throw new Error(`Controller "${ctrl.getName()}" has unsupported home page type.`);
25859
+ }
25191
25860
  const cb2 = buf.pos - ctrlIndexPos;
25192
25861
  const actions = ctrl.listActions?.() ?? [];
25193
25862
  buf.writeInt16(actions.length);
@@ -25888,7 +26557,7 @@ function _writeDisplayList(buf, comp, _doc, pkg, version) {
25888
26557
  const isTextInput = childType === "GTextInput";
25889
26558
  if (isCompOrList) {
25890
26559
  cb4 = buf.pos - childIndexPos;
25891
- _writeChildBlock4Component(buf, child, comp, pkg);
26560
+ _writeChildBlock4Component(buf, child, comp, pkg, version);
25892
26561
  } else if (isTextInput) {
25893
26562
  cb4 = buf.pos - childIndexPos;
25894
26563
  _writeChildBlock4TextInput(buf, child);
@@ -25982,9 +26651,9 @@ function _writeChildSpecific(buf, child, pkg, version) {
25982
26651
  buf.writeBool(false);
25983
26652
  if (version >= 3) {
25984
26653
  buf.writeBool(child.getStrikethrough?.() ?? false);
25985
- buf.writeFloat32(0);
25986
- buf.writeFloat32(0);
25987
- buf.writeFloat32(0);
26654
+ buf.writeFloat32(child.getFaceDilate?.() ?? 0);
26655
+ buf.writeFloat32(child.getOutlineSoftness?.() ?? 0);
26656
+ buf.writeFloat32(child.getUnderlaySoftness?.() ?? 0);
25988
26657
  }
25989
26658
  break;
25990
26659
  }
@@ -26036,13 +26705,13 @@ function _writeChildSpecific(buf, child, pkg, version) {
26036
26705
  buf.writeInt16(child.getMainGridIndex?.() ?? -1);
26037
26706
  break;
26038
26707
  case "GLoader": {
26039
- buf.writeS(remapLocalUiUrl(pkg, child.getUrl?.() ?? null));
26708
+ buf.writeS(remapLocalUiUrl(pkg, child.getClearOnPublish?.() ? null : child.getUrl?.() ?? null));
26040
26709
  buf.writeUint8(child.getAlign?.() ?? 0);
26041
26710
  buf.writeUint8(child.getVAlign?.() ?? 0);
26042
26711
  buf.writeUint8(child.getFill?.() ?? 0);
26043
26712
  buf.writeBool(child.getShrinkOnly?.() ?? false);
26044
26713
  buf.writeBool(_boolVal(child.getAutoSize?.(), false));
26045
- buf.writeBool(false);
26714
+ buf.writeBool(child.getShowErrorSign?.() ?? false);
26046
26715
  buf.writeBool(child.getPlaying?.() ?? true);
26047
26716
  buf.writeInt32(child.getFrame?.() ?? 0);
26048
26717
  const loaderColor = child.getColor?.() ?? null;
@@ -26061,7 +26730,7 @@ function _writeChildSpecific(buf, child, pkg, version) {
26061
26730
  break;
26062
26731
  }
26063
26732
  case "GLoader3D": {
26064
- buf.writeS(remapLocalUiUrl(pkg, child.getUrl?.() ?? null));
26733
+ buf.writeS(remapLocalUiUrl(pkg, child.getClearOnPublish?.() ? null : child.getUrl?.() ?? null));
26065
26734
  buf.writeUint8(child.getAlign?.() ?? 0);
26066
26735
  buf.writeUint8(child.getVAlign?.() ?? 0);
26067
26736
  buf.writeUint8(child.getFill?.() ?? 0);
@@ -26141,7 +26810,7 @@ function _writeChildAfterAdd(buf, child, comp, pkg, version) {
26141
26810
  case "GTextField":
26142
26811
  case "GRichTextField":
26143
26812
  case "GTextInput":
26144
- buf.writeSEx(remapLocalUiRefsInText(pkg, child.getText?.() ?? null), true);
26813
+ buf.writeSEx(remapLocalUiRefsInText(pkg, child.getAutoClearText?.() ? null : child.getText?.() ?? null), true);
26145
26814
  break;
26146
26815
  case "GButton": {
26147
26816
  buf.writeUint8(12);
@@ -26206,7 +26875,9 @@ function _writeChildAfterAdd(buf, child, comp, pkg, version) {
26206
26875
  }
26207
26876
  buf.writeSEx(child.getTitle?.() ?? null, true);
26208
26877
  buf.writeS(remapLocalUiUrl(pkg, child.getIcon?.() ?? null));
26209
- buf.writeBool(false);
26878
+ const comboTitleColor = child.getTitleColor?.() ?? null;
26879
+ buf.writeBool(!!comboTitleColor);
26880
+ if (comboTitleColor) buf.writeColor(comboTitleColor, true);
26210
26881
  buf.writeInt32(child.getVisibleItemCount?.() ?? 10);
26211
26882
  buf.writeUint8(child.getPopupDirection?.() ?? 0);
26212
26883
  buf.writeInt16(-1);
@@ -26288,13 +26959,13 @@ function _writeExtensionInstanceData(buf, extType, child, comp, pkg, version) {
26288
26959
  buf.writeInt32(child.getInstanceTitleFontSize?.() ?? 0);
26289
26960
  buf.writeBool(false);
26290
26961
  if (version >= 5) {
26291
- buf.writeS(null);
26292
- buf.writeFloat32(1);
26962
+ buf.writeS(remapLocalUiUrl(pkg, child.getInstanceSound?.() ?? null));
26963
+ buf.writeFloat32(child.getInstanceSoundVolumeScale?.() ?? 1);
26293
26964
  }
26294
26965
  break;
26295
26966
  }
26296
26967
  case "ComboBox": {
26297
- const comboItems = child.getInstanceComboItems?.() ?? [];
26968
+ const comboItems = child.getInstanceAutoClearItems?.() ? [] : child.getInstanceComboItems?.() ?? [];
26298
26969
  buf.writeInt16(comboItems.length);
26299
26970
  for (const item of comboItems) {
26300
26971
  const itemStart = buf.pos;
@@ -26314,11 +26985,11 @@ function _writeExtensionInstanceData(buf, extType, child, comp, pkg, version) {
26314
26985
  buf.writeBool(!!comboTitleColor);
26315
26986
  if (comboTitleColor) buf.writeColor(comboTitleColor, true);
26316
26987
  buf.writeInt32(child.getInstanceVisibleItemCount?.() ?? 10);
26317
- buf.writeUint8(0);
26988
+ buf.writeUint8(child.getInstancePopupDirection?.() ?? 0);
26318
26989
  buf.writeInt16(-1);
26319
26990
  if (version >= 5) {
26320
- buf.writeS(null);
26321
- buf.writeFloat32(1);
26991
+ buf.writeS(remapLocalUiUrl(pkg, child.getInstanceSound?.() ?? null));
26992
+ buf.writeFloat32(child.getInstanceSoundVolumeScale?.() ?? 1);
26322
26993
  }
26323
26994
  break;
26324
26995
  }
@@ -26328,8 +26999,8 @@ function _writeExtensionInstanceData(buf, extType, child, comp, pkg, version) {
26328
26999
  buf.writeInt32(child.getInstanceMax?.() ?? 100);
26329
27000
  buf.writeInt32(child.getInstanceMin?.() ?? 0);
26330
27001
  if (version >= 5 && extType === "ProgressBar") {
26331
- buf.writeS(null);
26332
- buf.writeFloat32(1);
27002
+ buf.writeS(remapLocalUiUrl(pkg, child.getInstanceSound?.() ?? null));
27003
+ buf.writeFloat32(child.getInstanceSoundVolumeScale?.() ?? 1);
26333
27004
  }
26334
27005
  break;
26335
27006
  default: break;
@@ -26337,7 +27008,7 @@ function _writeExtensionInstanceData(buf, extType, child, comp, pkg, version) {
26337
27008
  }
26338
27009
  function _writeScrollPane(buf, child, pkg) {
26339
27010
  buf.writeUint8(child.getScrollType?.() ?? 1);
26340
- buf.writeUint8(0);
27011
+ buf.writeUint8(child.getScrollBarDisplay?.() ?? 0);
26341
27012
  buf.writeInt32(child.getScrollBarFlags?.() ?? 0);
26342
27013
  const sbMargin = child.getScrollBarMargin?.();
26343
27014
  buf.writeBool(!!sbMargin);
@@ -26355,7 +27026,7 @@ function _writeScrollPane(buf, child, pkg) {
26355
27026
  function _writeListItems(buf, child, pkg, version) {
26356
27027
  buf.writeS(remapLocalUiUrl(pkg, child.getDefaultItem?.() ?? null));
26357
27028
  const isTree = child.propertyType === "GTree";
26358
- const listItems = child.getListItems?.() ?? [];
27029
+ const listItems = child.getAutoClearItems?.() ? [] : child.getListItems?.() ?? [];
26359
27030
  buf.writeInt16(listItems.length);
26360
27031
  for (const [index, item] of listItems.entries()) {
26361
27032
  const itemStart = buf.pos;
@@ -26385,7 +27056,7 @@ function _writeListItems(buf, child, pkg, version) {
26385
27056
  buf.pos = controllerCountPos;
26386
27057
  buf.writeInt16(controllerCount);
26387
27058
  buf.pos = controllerEnd;
26388
- if (version >= 2) buf.writeInt16(0);
27059
+ if (version >= 2) _writePropertyOverrides(buf, item.propertyOverrides ?? []);
26389
27060
  const itemEnd = buf.pos;
26390
27061
  const saved = buf.pos;
26391
27062
  buf.pos = itemStart;
@@ -26397,7 +27068,7 @@ function _writeTreeSettings(buf, child) {
26397
27068
  buf.writeInt32(child.getIndent?.() ?? 0);
26398
27069
  buf.writeUint8(child.getClickToExpand?.() ?? 0);
26399
27070
  }
26400
- function _writeChildBlock4Component(buf, child, comp, _pkg) {
27071
+ function _writeChildBlock4Component(buf, child, comp, _pkg, version) {
26401
27072
  const pageCtrlName = child.getPageController?.() ?? null;
26402
27073
  if (pageCtrlName) {
26403
27074
  const ctrlIdx = comp.listControllers().findIndex((c) => c.getName() === pageCtrlName);
@@ -26419,7 +27090,15 @@ function _writeChildBlock4Component(buf, child, comp, _pkg) {
26419
27090
  buf.writeInt16(count);
26420
27091
  buf.pos = saved;
26421
27092
  } else buf.writeInt16(0);
26422
- buf.writeInt16(0);
27093
+ if (version >= 2) _writePropertyOverrides(buf, child.getPropertyOverrides?.() ?? []);
27094
+ }
27095
+ function _writePropertyOverrides(buf, overrides) {
27096
+ buf.writeInt16(overrides.length);
27097
+ for (const property of overrides) {
27098
+ buf.writeS(property.target);
27099
+ buf.writeInt16(property.propertyId);
27100
+ buf.writeSEx(property.value, true);
27101
+ }
26423
27102
  }
26424
27103
  function _writeChildBlock4TextInput(buf, child) {
26425
27104
  buf.writeSEx(child.getPromptText?.() ?? child.getPrompt?.() ?? null);
@@ -26484,6 +27163,7 @@ const BinItemType = {
26484
27163
  Component: 3,
26485
27164
  Atlas: 4,
26486
27165
  Font: 5,
27166
+ Swf: 6,
26487
27167
  Misc: 7,
26488
27168
  Unknown: 8,
26489
27169
  Spine: 9,
@@ -26501,6 +27181,7 @@ const EDITOR_TYPE_STRING = {
26501
27181
  SoundResource: "sound",
26502
27182
  Component: "component",
26503
27183
  FontResource: "font",
27184
+ SwfResource: "swf",
26504
27185
  SpineResource: "spine",
26505
27186
  DragonBonesResource: "dragonbones"
26506
27187
  };
@@ -26649,7 +27330,7 @@ var BinaryWriter = class {
26649
27330
  data.writeInt32(grid[1]);
26650
27331
  data.writeInt32(grid[2]);
26651
27332
  data.writeInt32(grid[3]);
26652
- data.writeInt32(0);
27333
+ data.writeInt32(res.getTileGridIndice());
26653
27334
  }
26654
27335
  data.writeBool(res.getSmoothing());
26655
27336
  break;
@@ -26703,6 +27384,16 @@ var BinaryWriter = class {
26703
27384
  data.writeInt32(0);
26704
27385
  data.writeInt32(0);
26705
27386
  break;
27387
+ case "SwfResource":
27388
+ data.writeUint8(BinItemType.Swf);
27389
+ data.writeS(getPublishedItemId$1(res));
27390
+ data.writeS(res.getName());
27391
+ data.writeS(res.getPath());
27392
+ data.writeS(getPublishedFileName(res));
27393
+ data.writeBool(res.getExported());
27394
+ data.writeInt32(0);
27395
+ data.writeInt32(0);
27396
+ break;
26706
27397
  case "Component": {
26707
27398
  data.writeUint8(BinItemType.Component);
26708
27399
  data.writeS(getPublishedItemId$1(res));
@@ -26723,7 +27414,7 @@ var BinaryWriter = class {
26723
27414
  const compExtras = res.getExtras();
26724
27415
  const extType = res.getExtensionType?.() ?? compExtras.extensionType;
26725
27416
  data.writeUint8(extType ? extTypeMap[extType] ?? 0 : 0);
26726
- if (compExtras?._rawBinary) data.writeBuffer(toUint8Array(compExtras._rawBinary));
27417
+ if (compExtras?._rawBinary && !res._isBinaryDirty()) data.writeBuffer(toUint8Array(compExtras._rawBinary));
26727
27418
  else {
26728
27419
  const encoded = encodeComponent(res, doc, pkg, version, data);
26729
27420
  data.writeBuffer(encoded);
@@ -26846,13 +27537,15 @@ var BinaryWriter = class {
26846
27537
  const oh = sp.originalHeight ?? 0;
26847
27538
  const isPackageItemSprite = packageItemIds.has(sp.itemId);
26848
27539
  const isZeroSizedDirectOutput = isPackageItemSprite && sp.w === 0 && sp.h === 0;
26849
- const hasOriginal = isPackageItemSprite && sp.rotated || ox !== 0 || oy !== 0 || isZeroSizedDirectOutput;
27540
+ const originalWidth = ow || (sp.rotated ? sp.h : sp.w);
27541
+ const originalHeight = oh || (sp.rotated ? sp.w : sp.h);
27542
+ const hasOriginal = isPackageItemSprite && sp.rotated || ox !== 0 || oy !== 0 || originalWidth !== (sp.rotated ? sp.h : sp.w) || originalHeight !== (sp.rotated ? sp.w : sp.h) || isZeroSizedDirectOutput;
26850
27543
  data.writeBool(hasOriginal);
26851
27544
  if (hasOriginal) {
26852
27545
  data.writeInt32(ox);
26853
27546
  data.writeInt32(oy);
26854
- data.writeInt32(ow || (sp.rotated ? sp.h : sp.w));
26855
- data.writeInt32(oh || (sp.rotated ? sp.w : sp.h));
27547
+ data.writeInt32(originalWidth);
27548
+ data.writeInt32(originalHeight);
26856
27549
  }
26857
27550
  }
26858
27551
  const spriteNextPos = data.pos;
@@ -27010,7 +27703,7 @@ function _encodeFontGlyphs(fntData, parentBuf) {
27010
27703
  for (const glyph of fntData.glyphs) {
27011
27704
  const glyphStart = buf.pos;
27012
27705
  buf.writeInt16(0);
27013
- buf.writeInt16(glyph.charId);
27706
+ buf.writeUint16(glyph.charId);
27014
27707
  buf.writeS(glyph.img);
27015
27708
  buf.writeInt32(glyph.x);
27016
27709
  buf.writeInt32(glyph.y);
@@ -27144,8 +27837,8 @@ var PlatformIO = class {
27144
27837
  async writeProject(doc, projectPath, options) {
27145
27838
  return new ProjectWriter(this.createFileSystem()).write(doc, projectPath, options);
27146
27839
  }
27147
- async readBinary(filePath) {
27148
- return new BinaryReader(this.createFileSystem()).read(filePath);
27840
+ async readBinary(filePath, options) {
27841
+ return new BinaryReader(this.createFileSystem(), options).read(filePath);
27149
27842
  }
27150
27843
  async writeBinary(doc, filePath, options) {
27151
27844
  return new BinaryWriter(this.createFileSystem()).write(doc, filePath, options);
@@ -27177,7 +27870,7 @@ function createTransform(name, fn) {
27177
27870
  Object.defineProperty(fn, "name", { value: name });
27178
27871
  return fn;
27179
27872
  }
27180
- function parseTextureSetMode(value) {
27873
+ function parseTextureSetMode(value, maxAtlasIndex = 10) {
27181
27874
  const raw = value?.trim() ?? "";
27182
27875
  if (!raw) return {
27183
27876
  kind: "auto",
@@ -27200,7 +27893,7 @@ function parseTextureSetMode(value) {
27200
27893
  };
27201
27894
  if (/^\d+$/.test(raw)) {
27202
27895
  const pageIndex = Number(raw);
27203
- if (pageIndex >= 0 && pageIndex <= 10) return {
27896
+ if (pageIndex >= 0 && pageIndex <= maxAtlasIndex) return {
27204
27897
  kind: "page",
27205
27898
  raw,
27206
27899
  pageIndex
@@ -27258,9 +27951,9 @@ function collectComponentReferences(target, ownerPackageId, component) {
27258
27951
  const sourcePackageId = child.getPackageId?.()?.trim();
27259
27952
  if (sourcePackageId && sourcePackageId !== ownerPackageId) target.packageIds.add(sourcePackageId);
27260
27953
  addFontReferences(target, ownerPackageId, child.getFont?.());
27261
- addTextReferences(target, ownerPackageId, child.getText?.());
27954
+ if (!child.getAutoClearText?.()) addTextReferences(target, ownerPackageId, child.getText?.());
27262
27955
  for (const reference of [
27263
- child.getUrl?.(),
27956
+ child.getClearOnPublish?.() ? void 0 : child.getUrl?.(),
27264
27957
  child.getDefaultItem?.(),
27265
27958
  child.getIcon?.(),
27266
27959
  child.getSelectedIcon?.(),
@@ -27274,11 +27967,14 @@ function collectComponentReferences(target, ownerPackageId, component) {
27274
27967
  child.getHeaderRes?.(),
27275
27968
  child.getFooterRes?.()
27276
27969
  ]) addUiReference(target, ownerPackageId, reference);
27277
- for (const item of child.getInstanceComboItems?.() ?? []) addUiReference(target, ownerPackageId, item.icon);
27278
- for (const item of child.getListItems?.() ?? []) {
27970
+ for (const item of child.getInstanceAutoClearItems?.() ? [] : child.getInstanceComboItems?.() ?? []) addUiReference(target, ownerPackageId, item.icon);
27971
+ for (const item of child.getAutoClearItems?.() ? [] : child.getListItems?.() ?? []) {
27279
27972
  addUiReference(target, ownerPackageId, item.icon);
27973
+ addUiReference(target, ownerPackageId, item.selectedIcon);
27280
27974
  addUiReference(target, ownerPackageId, item.url);
27975
+ addUnknownReferences(target, ownerPackageId, item.propertyOverrides?.map((property) => property.value));
27281
27976
  }
27977
+ addUnknownReferences(target, ownerPackageId, child.getPropertyOverrides?.().map((property) => property.value));
27282
27978
  for (const gear of child.listGears?.() ?? []) {
27283
27979
  addUnknownReferences(target, ownerPackageId, gear.getValues?.());
27284
27980
  addUnknownReferences(target, ownerPackageId, gear.getDefaultValue?.());
@@ -27308,7 +28004,8 @@ function collectPackageResourceReferences(pkg) {
27308
28004
  localResourceIds: /* @__PURE__ */ new Set(),
27309
28005
  packageIds: /* @__PURE__ */ new Set()
27310
28006
  };
27311
- for (const resource of pkg.listResources()) if (resource.propertyType === "Component") collectComponentReferences(references, pkg.getId(), resource);
28007
+ const excludedResourceIds = new Set(pkg.getSourceAtlasSettings().excludedResourceIds);
28008
+ for (const resource of pkg.listResources()) if (resource.propertyType === "Component" && !excludedResourceIds.has(resource.getId())) collectComponentReferences(references, pkg.getId(), resource);
27312
28009
  return references;
27313
28010
  }
27314
28011
  //#endregion
@@ -27335,6 +28032,9 @@ function isFontResource(resource) {
27335
28032
  function isSoundResource(resource) {
27336
28033
  return resource.propertyType === "SoundResource";
27337
28034
  }
28035
+ function isSwfResource(resource) {
28036
+ return resource.propertyType === "SwfResource";
28037
+ }
27338
28038
  function isSpineResource(resource) {
27339
28039
  return resource.propertyType === "SpineResource";
27340
28040
  }
@@ -27376,10 +28076,12 @@ function extname(fileName) {
27376
28076
  return normalized.slice(lastDot);
27377
28077
  }
27378
28078
  function resolvePublishedMiscFileName(resource, projectType) {
27379
- const file = resource.getFile();
27380
- if (projectType !== UNITY_PROJECT_TYPE$1) return file;
27381
- if (file.toLowerCase().endsWith(".atlas")) return `${file}.txt`;
27382
- return file;
28079
+ const fileName = `${getPublishedId(resource)}${extname(resource.getFile())}`;
28080
+ if (projectType === UNITY_PROJECT_TYPE$1 && fileName.toLowerCase().endsWith(".atlas")) return `${fileName}.txt`;
28081
+ return fileName;
28082
+ }
28083
+ function resolvePublishedSwfFileName(resource) {
28084
+ return `${getPublishedId(resource)}${extname(resource.getFile()) || ".swf"}`;
27383
28085
  }
27384
28086
  function resolvePublishedSkeletonFileName(resource, projectType) {
27385
28087
  if (projectType === UNITY_PROJECT_TYPE$1 && isSpineResource(resource) && resource.getFile().toLowerCase().endsWith(".skel")) return `${resource.getFile()}.bytes`;
@@ -27446,16 +28148,16 @@ function trimTrailingMissingHighResolutionIds(ids) {
27446
28148
  while (ids.length > 0 && !ids[ids.length - 1]) ids.pop();
27447
28149
  return ids;
27448
28150
  }
27449
- function collectHighResolutionItemIds(resources, publishedResourceIds, includeHighResolution) {
28151
+ function collectHighResolutionItemIds(resources, publishedResourceIds, includeHighResolution, excludedResourceIds) {
27450
28152
  const result = /* @__PURE__ */ new Map();
27451
28153
  if (includeHighResolution <= 0) return result;
27452
28154
  const highResolutionResourceByKey = /* @__PURE__ */ new Map();
27453
28155
  for (const resource of resources) {
27454
- if (!isHighResolutionResource(resource)) continue;
28156
+ if (!isHighResolutionResource(resource) || excludedResourceIds.has(resource.getId())) continue;
27455
28157
  highResolutionResourceByKey.set(buildHighResolutionResourceKey(resource), resource);
27456
28158
  }
27457
28159
  for (const resource of resources) {
27458
- if (!isHighResolutionResource(resource)) continue;
28160
+ if (!isHighResolutionResource(resource) || excludedResourceIds.has(resource.getId())) continue;
27459
28161
  if (!publishedResourceIds.has(resource.getId())) continue;
27460
28162
  if (isHighResolutionVariantName(resource.getName())) continue;
27461
28163
  const ids = [];
@@ -27480,6 +28182,7 @@ function collectHighResolutionItemIds(resources, publishedResourceIds, includeHi
27480
28182
  }
27481
28183
  function collectPackagePublishContext(pkg, options) {
27482
28184
  const resources = pkg.listResources();
28185
+ const excludedResourceIds = new Set(pkg.getSourceAtlasSettings().excludedResourceIds);
27483
28186
  const resourceMap = new Map(resources.map((resource) => [resource.getId(), resource]));
27484
28187
  const referencedIds = collectPackageResourceReferences(pkg).localResourceIds;
27485
28188
  const pixelHitTestImageIds = /* @__PURE__ */ new Set();
@@ -27491,10 +28194,15 @@ function collectPackagePublishContext(pkg, options) {
27491
28194
  while (changed) {
27492
28195
  changed = false;
27493
28196
  for (const resourceId of [...exportedResourceIds]) {
28197
+ if (excludedResourceIds.has(resourceId)) {
28198
+ exportedResourceIds.delete(resourceId);
28199
+ changed = true;
28200
+ continue;
28201
+ }
27494
28202
  const resource = resourcesById.get(resourceId);
27495
28203
  if (!resource || !isSkeletonResource(resource)) continue;
27496
28204
  for (const requiredId of resource.getRequireIds()) {
27497
- if (!requiredId || exportedResourceIds.has(requiredId)) continue;
28205
+ if (!requiredId || excludedResourceIds.has(requiredId) || exportedResourceIds.has(requiredId)) continue;
27498
28206
  exportedResourceIds.add(requiredId);
27499
28207
  changed = true;
27500
28208
  }
@@ -27502,7 +28210,7 @@ function collectPackagePublishContext(pkg, options) {
27502
28210
  }
27503
28211
  return exportedResourceIds;
27504
28212
  };
27505
- for (const atlas of pkg.listAtlases()) for (const sprite of atlas.listSprites()) spriteItemIds.add(sprite.getItemId());
28213
+ for (const atlas of pkg.listAtlases()) for (const sprite of atlas.listSprites()) if (!excludedResourceIds.has(sprite.getItemId())) spriteItemIds.add(sprite.getItemId());
27506
28214
  for (const resource of resources) {
27507
28215
  if (!isComponentResource(resource)) continue;
27508
28216
  const component = resource;
@@ -27511,7 +28219,7 @@ function collectPackagePublishContext(pkg, options) {
27511
28219
  const hitTest = component.getHitTest?.()?.trim();
27512
28220
  if (hitTest && !hitTest.includes(",")) {
27513
28221
  const sourceId = childMap.get(hitTest)?.getSrc?.();
27514
- if (sourceId) {
28222
+ if (sourceId && !excludedResourceIds.has(sourceId)) {
27515
28223
  const sourceResource = resourceMap.get(sourceId);
27516
28224
  if (sourceResource && isImageResource(sourceResource)) pixelHitTestImageIds.add(sourceId);
27517
28225
  }
@@ -27520,7 +28228,7 @@ function collectPackagePublishContext(pkg, options) {
27520
28228
  const publishedResourceIds = new Set(spriteItemIds);
27521
28229
  for (const resource of resources) {
27522
28230
  const resourceId = resource.getId();
27523
- if (!resourceId) continue;
28231
+ if (!resourceId || excludedResourceIds.has(resourceId)) continue;
27524
28232
  if (isComponentResource(resource)) {
27525
28233
  if (resource.getExported() || referencedIds.has(resourceId)) publishedResourceIds.add(resourceId);
27526
28234
  continue;
@@ -27544,7 +28252,7 @@ function collectPackagePublishContext(pkg, options) {
27544
28252
  if (resource.getExported() || referencedIds.has(resourceId)) publishedResourceIds.add(resourceId);
27545
28253
  }
27546
28254
  for (const resourceId of collectExportedResourceIds(resources, publishedResourceIds)) publishedResourceIds.add(resourceId);
27547
- const highResolutionItemIds = collectHighResolutionItemIds(resources, publishedResourceIds, options.includeHighResolution);
28255
+ const highResolutionItemIds = collectHighResolutionItemIds(resources, publishedResourceIds, options.includeHighResolution, excludedResourceIds);
27548
28256
  if (!options.includeBranches) {
27549
28257
  const mainByKey = /* @__PURE__ */ new Map();
27550
28258
  const activeBranchByKey = /* @__PURE__ */ new Map();
@@ -27672,6 +28380,10 @@ async function annotatePackagePublishArtifacts(pkg, basePath, encoder, options)
27672
28380
  setPublishedFileExtra(resource, resolvePublishedMiscFileName(resource, options.projectType));
27673
28381
  continue;
27674
28382
  }
28383
+ if (isSwfResource(resource)) {
28384
+ setPublishedFileExtra(resource, resolvePublishedSwfFileName(resource));
28385
+ continue;
28386
+ }
27675
28387
  if (isSkeletonResource(resource)) setPublishedFileExtra(resource, resolvePublishedSkeletonFileName(resource, options.projectType));
27676
28388
  }
27677
28389
  }
@@ -28930,7 +29642,7 @@ function packAtlasPages(inputs, options, forceSinglePage, sizeOverrides) {
28930
29642
  });
28931
29643
  return new MaxRectsPackerCompat({
28932
29644
  pot: sizeOverrides?.powerOfTwo ?? options.powerOfTwo,
28933
- mof: sizeOverrides?.multipleOfFour ?? !options.powerOfTwo,
29645
+ mof: sizeOverrides?.multipleOfFour ?? options.multipleOfFour,
28934
29646
  padding: options.padding,
28935
29647
  rotation: options.allowRotation,
28936
29648
  minWidth: 16,
@@ -29030,7 +29742,7 @@ async function writeAtlasPageImage(pkg, inputs, page, atlasFileName, encoder, op
29030
29742
  }
29031
29743
  }
29032
29744
  const outputFile = `${options.outputPath}/${atlasFileName}`;
29033
- await encoder({ create: {
29745
+ const atlasPipeline = encoder({ create: {
29034
29746
  width: page.width,
29035
29747
  height: page.height,
29036
29748
  channels: 4,
@@ -29040,7 +29752,13 @@ async function writeAtlasPageImage(pkg, inputs, page, atlasFileName, encoder, op
29040
29752
  b: 0,
29041
29753
  alpha: 0
29042
29754
  }
29043
- } }).composite(compositeInputs).toFile(outputFile);
29755
+ } }).composite(compositeInputs);
29756
+ if (options.extractAlpha) {
29757
+ const atlasBuffer = await atlasPipeline.png().toBuffer();
29758
+ await encoder(atlasBuffer).removeAlpha().png().toFile(outputFile);
29759
+ const alphaBuffer = await encoder(atlasBuffer).extractChannel("alpha").png().toBuffer();
29760
+ await encoder(alphaBuffer).joinChannel([alphaBuffer, alphaBuffer]).png().toFile(`${options.outputPath}/${insertFileNameSuffix(atlasFileName, "!a")}`);
29761
+ } else await atlasPipeline.toFile(outputFile);
29044
29762
  logger.info(`atlas: Generated ${atlasFileName} (${page.width}x${page.height}, ${page.outputRects.length} sprites)`);
29045
29763
  }
29046
29764
  function inputToCompatRect(input, index) {
@@ -29090,6 +29808,9 @@ function resolveDirectOutputAtlasSize(width, height, options) {
29090
29808
  if (options.powerOfTwo) {
29091
29809
  resolvedWidth = nextPow2(resolvedWidth);
29092
29810
  resolvedHeight = nextPow2(resolvedHeight);
29811
+ } else if (options.multipleOfFour) {
29812
+ resolvedWidth = roundUpToMultiple(resolvedWidth, 4);
29813
+ resolvedHeight = roundUpToMultiple(resolvedHeight, 4);
29093
29814
  }
29094
29815
  return {
29095
29816
  width: resolvedWidth,
@@ -29204,9 +29925,8 @@ function sortResourcesByOrder(resources, orderMap, inputOrderMap) {
29204
29925
  });
29205
29926
  return ordered;
29206
29927
  }
29207
- function getResourceTextureSetMode(resource) {
29208
- if (isImageResource(resource)) return parseTextureSetMode(resource.getTextureSetMode?.());
29209
- return parseTextureSetMode(resource.getTextureSetMode?.());
29928
+ function getResourceTextureSetMode(resource, maxAtlasIndex) {
29929
+ return parseTextureSetMode(resource.getTextureSetMode?.(), maxAtlasIndex);
29210
29930
  }
29211
29931
  function groupStandaloneInputs(doc, inputs, options) {
29212
29932
  const autoInputs = [];
@@ -29225,7 +29945,7 @@ function groupStandaloneInputs(doc, inputs, options) {
29225
29945
  for (const input of inputs) {
29226
29946
  const branchName = getInputBranchName(input);
29227
29947
  const branchOrdinal = branchOrdinalByName.get(branchName) ?? 0;
29228
- const mode = getResourceTextureSetMode(input.resource);
29948
+ const mode = getResourceTextureSetMode(input.resource, options.maxAtlasIndex ?? 10);
29229
29949
  if (mode.kind === "standalone") {
29230
29950
  const key = `${branchName}\u0000${getPublishedItemId(input.resource)}`;
29231
29951
  const existing = standaloneGroups.get(key);
@@ -29269,6 +29989,8 @@ const ATLAS_DEFAULTS = {
29269
29989
  allowRotation: true,
29270
29990
  padding: 1,
29271
29991
  powerOfTwo: false,
29992
+ maxAtlasIndex: 10,
29993
+ multipleOfFour: false,
29272
29994
  square: false,
29273
29995
  multiPage: true,
29274
29996
  trimImage: false,
@@ -29352,7 +30074,7 @@ async function resolveEditorCompatibleResourceOrder(pkg, allResources, options)
29352
30074
  const refChild = child;
29353
30075
  await addResource(resourceMap.get(refChild.getSrc?.() ?? ""));
29354
30076
  for (const ref of [
29355
- refChild.getUrl?.(),
30077
+ refChild.getClearOnPublish?.() ? void 0 : refChild.getUrl?.(),
29356
30078
  refChild.getDefaultItem?.(),
29357
30079
  refChild.getIcon?.(),
29358
30080
  refChild.getSelectedIcon?.(),
@@ -29366,11 +30088,14 @@ async function resolveEditorCompatibleResourceOrder(pkg, allResources, options)
29366
30088
  refChild.getInstanceIcon?.(),
29367
30089
  refChild.getInstanceSelectedIcon?.()
29368
30090
  ]) await addResourceByLocalUiUrl(ref);
29369
- for (const item of refChild.getInstanceComboItems?.() ?? []) await addResourceByLocalUiUrl(item.icon ?? void 0);
29370
- for (const item of refChild.getListItems?.() ?? []) {
30091
+ for (const item of refChild.getInstanceAutoClearItems?.() ? [] : refChild.getInstanceComboItems?.() ?? []) await addResourceByLocalUiUrl(item.icon ?? void 0);
30092
+ for (const item of refChild.getAutoClearItems?.() ? [] : refChild.getListItems?.() ?? []) {
29371
30093
  await addResourceByLocalUiUrl(item.icon ?? void 0);
30094
+ await addResourceByLocalUiUrl(item.selectedIcon ?? void 0);
29372
30095
  await addResourceByLocalUiUrl(item.url ?? void 0);
30096
+ for (const property of item.propertyOverrides ?? []) await addResourceByLocalUiUrl(property.value);
29373
30097
  }
30098
+ for (const property of refChild.getPropertyOverrides?.() ?? []) await addResourceByLocalUiUrl(property.value);
29374
30099
  for (const gear of refChild.listGears?.() ?? []) await addGearIconResources(gear);
29375
30100
  }
29376
30101
  for (const ref of [
@@ -29560,6 +30285,9 @@ const FGUI_TYPESCRIPT_BINDER_TEMPLATE = `{{generatedMark}}
29560
30285
  function formatPluginError(error) {
29561
30286
  return error instanceof Error ? error.message : String(error);
29562
30287
  }
30288
+ function shouldAbortPluginFailure(plugin) {
30289
+ return plugin.failureMode !== "warn";
30290
+ }
29563
30291
  //#endregion
29564
30292
  //#region ../functions/src/path-utils.ts
29565
30293
  function trimTrailingSlashes(value) {
@@ -29621,23 +30349,34 @@ const FGUI_TYPESCRIPT_RUNTIME_TYPES = new Set([
29621
30349
  "GTree",
29622
30350
  "Transition"
29623
30351
  ]);
29624
- const SHARED_FGUI_TYPESCRIPT_VARIANT = {
30352
+ const LAYABOX_TYPESCRIPT_VARIANT = {
29625
30353
  binderMethod: "setExtension",
29626
- runtimeNamespace: "fgui"
30354
+ runtimeNamespace: "fgui",
30355
+ runtimeImport: ""
30356
+ };
30357
+ const COCOS_CREATOR_TYPESCRIPT_VARIANT = {
30358
+ ...LAYABOX_TYPESCRIPT_VARIANT,
30359
+ runtimeImport: "import * as fgui from \"fairygui-cc\";"
29627
30360
  };
29628
30361
  async function publishCodeGeneration(doc, options) {
29629
30362
  const logger = doc.getLogger();
29630
30363
  const settings = resolveCodeGenerationSettings(doc);
29631
30364
  if (!settings.allowGenCode) return;
29632
- const plugins = options.plugins?.filter((plugin) => typeof plugin.plugin.genCode === "function") ?? [];
30365
+ const plugins = options.plugins ?? [];
29633
30366
  if (plugins.length > 0) {
29634
30367
  let handled = false;
29635
- for (const plugin of plugins) try {
29636
- await plugin.plugin.genCode(doc, settings, options);
29637
- handled = true;
29638
- logger.info(`publish: Generated code using plugin "${plugin.name}"`);
29639
- } catch (error) {
29640
- logger.warn(`publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`);
30368
+ for (const plugin of plugins) {
30369
+ const genCode = plugin.plugin.genCode;
30370
+ if (!genCode) continue;
30371
+ try {
30372
+ await genCode(doc, settings, options);
30373
+ handled = true;
30374
+ logger.info(`publish: Generated code using plugin "${plugin.name}"`);
30375
+ } catch (error) {
30376
+ const message = `publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`;
30377
+ if (shouldAbortPluginFailure(plugin)) throw new Error(message);
30378
+ logger.warn(message);
30379
+ }
29641
30380
  }
29642
30381
  if (handled) return;
29643
30382
  }
@@ -29701,8 +30440,9 @@ function supportsCodeGenerationLane(doc, codeType) {
29701
30440
  }
29702
30441
  function resolveFguiTypescriptVariant(doc) {
29703
30442
  const projectType = doc.getRoot().getProjectType();
29704
- if (projectType !== ProjectType.LayaBox && projectType !== ProjectType.CocosCreator) return null;
29705
- return SHARED_FGUI_TYPESCRIPT_VARIANT;
30443
+ if (projectType === ProjectType.LayaBox) return LAYABOX_TYPESCRIPT_VARIANT;
30444
+ if (projectType === ProjectType.CocosCreator) return COCOS_CREATOR_TYPESCRIPT_VARIANT;
30445
+ return null;
29706
30446
  }
29707
30447
  async function generateUnityCode(doc, pkg, plan, fs) {
29708
30448
  const packageDir = fs.join(plan.outputDir, plan.packageFolderName);
@@ -29885,7 +30625,8 @@ function renderFguiTypescriptComponentClass(classInfo, plan, variant) {
29885
30625
  }
29886
30626
  function renderFguiTypescriptBinder(classes, plan, variant) {
29887
30627
  const bindLines = classes.map((classInfo) => `\t\t${variant.runtimeNamespace}.UIObjectFactory.${variant.binderMethod}(${classInfo.encodedClassName}.URL, ${classInfo.encodedClassName});`).join("\n");
29888
- const importLines = classes.map((classInfo) => `import ${classInfo.encodedClassName} from "./${classInfo.encodedClassName}";`).join("\n");
30628
+ const classImports = classes.map((classInfo) => `import ${classInfo.encodedClassName} from "./${classInfo.encodedClassName}";`).join("\n");
30629
+ const importLines = [variant.runtimeImport, classImports].filter(Boolean).join("\n");
29889
30630
  return renderTemplate(FGUI_TYPESCRIPT_BINDER_TEMPLATE, {
29890
30631
  binderClassName: plan.binderClassName,
29891
30632
  bindLines: bindLines ? `${bindLines}\n` : "",
@@ -29949,6 +30690,7 @@ function normalizeTypeName(value) {
29949
30690
  }
29950
30691
  function collectFguiTypescriptImports(classInfo, variant) {
29951
30692
  const imports = /* @__PURE__ */ new Set();
30693
+ if (variant.runtimeImport) imports.add(variant.runtimeImport);
29952
30694
  for (const member of classInfo.members) {
29953
30695
  if (member.ignored) continue;
29954
30696
  const translated = translateFguiTypescriptType(member.type, variant);
@@ -30922,23 +31664,24 @@ async function exportPackageExternalResources(pkg, outputDir, basePath, fs, read
30922
31664
  if (exportedResourceIds.size === 0) return;
30923
31665
  if (!basePath || !readFileRaw) {
30924
31666
  if (pkg.listResources().some((resource) => {
30925
- return (isMiscResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
31667
+ return (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource)) && exportedResourceIds.has(resource.getId()) || skeletonDependencyImageIds.has(resource.getId());
30926
31668
  })) throw new Error(`publish: External resources in package "${pkg.getName()}" require basePath and readFileRaw for output.`);
30927
31669
  return;
30928
31670
  }
30929
31671
  for (const resource of pkg.listResources()) {
30930
31672
  const resourceId = resource.getId();
30931
- const isSkeletonExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSkeletonResource(resource));
31673
+ const isExternal = exportedResourceIds.has(resourceId) && (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource));
30932
31674
  const isSkeletonImageDependency = skeletonDependencyImageIds.has(resourceId) && isImageResource(resource);
30933
- if (!isSkeletonExternal && !isSkeletonImageDependency) continue;
31675
+ if (!isExternal && !isSkeletonImageDependency) continue;
30934
31676
  let sourcePath;
30935
31677
  let targetName;
30936
31678
  if (isSkeletonImageDependency) {
30937
31679
  sourcePath = resolveImagePath(resource, pkg, basePath);
30938
31680
  targetName = resolveImageFileName(resource);
30939
- } else if (isMiscResource(resource) || isSkeletonResource(resource)) {
31681
+ } else if (isMiscResource(resource) || isSwfResource(resource) || isSkeletonResource(resource)) {
30940
31682
  sourcePath = resolveGenericResourcePath(resource, pkg, basePath);
30941
- targetName = (resource.getExtras() ?? {})._publishedFile ?? resource.getFile();
31683
+ const publishedFile = (resource.getExtras() ?? {})._publishedFile ?? resource.getFile();
31684
+ targetName = isMiscResource(resource) || isSwfResource(resource) ? `${pkg.getPublishName() || pkg.getName()}_${publishedFile}` : publishedFile;
30942
31685
  } else continue;
30943
31686
  const targetPath = fs.join(outputDir, targetName);
30944
31687
  try {
@@ -30978,16 +31721,20 @@ function resolvePublishOptions(doc, overrides = {}) {
30978
31721
  const root = doc.getRoot();
30979
31722
  const publishSettings = (root.getSettings?.() ?? {}).publish ?? {};
30980
31723
  const atlasSetting = publishSettings.atlasSetting ?? {};
30981
- const projectType = root.getProjectType();
30982
- const fileExtension = overrides.fileExtension ?? resolveDefaultPublishFileExtension(projectType, publishSettings);
30983
- let compressed = overrides.compressed ?? publishSettings.compressDesc ?? false;
30984
- if (projectType === UNITY_PROJECT_TYPE) compressed = overrides.compressed ?? false;
31724
+ const projectType = overrides.targetProjectType ?? root.getProjectType();
31725
+ const explicitLayaboxTarget = overrides.targetProjectType === ProjectType.LayaBox;
31726
+ const fileExtension = overrides.fileExtension ?? (explicitLayaboxTarget ? "fui" : resolveDefaultPublishFileExtension(projectType, publishSettings));
31727
+ const runtimeRejectsCompression = projectType === UNITY_PROJECT_TYPE || projectType === COCOS_CREATOR_PROJECT_TYPE;
31728
+ if (runtimeRejectsCompression && overrides.compressed === true) throw new Error("publish: The selected target runtime does not support compressed package data.");
31729
+ const compressed = runtimeRejectsCompression ? false : overrides.compressed ?? publishSettings.compressDesc ?? false;
30985
31730
  const atlasOptions = {
30986
31731
  maxSize: overrides.atlas?.maxSize ?? atlasSetting.maxSize ?? 2048,
30987
31732
  fast: overrides.atlas?.fast ?? atlasSetting.fast ?? true,
30988
- allowRotation: overrides.atlas?.allowRotation ?? atlasSetting.allowRotation ?? false,
31733
+ allowRotation: overrides.atlas?.allowRotation ?? (explicitLayaboxTarget ? false : atlasSetting.allowRotation ?? false),
30989
31734
  padding: overrides.atlas?.padding ?? atlasSetting.padding ?? 2,
30990
31735
  powerOfTwo: overrides.atlas?.powerOfTwo ?? atlasSetting.sizeOption === "pot",
31736
+ maxAtlasIndex: overrides.atlas?.maxAtlasIndex ?? 10,
31737
+ multipleOfFour: overrides.atlas?.multipleOfFour ?? atlasSetting.sizeOption === "mof",
30991
31738
  square: overrides.atlas?.square ?? atlasSetting.forceSquare ?? false,
30992
31739
  multiPage: overrides.atlas?.multiPage ?? atlasSetting.paging ?? true,
30993
31740
  trimImage: overrides.atlas?.trimImage ?? atlasSetting.trimImage ?? false,
@@ -31010,7 +31757,9 @@ async function runPublishPluginHook(plugins, hook, doc, options) {
31010
31757
  try {
31011
31758
  await fn(doc, options);
31012
31759
  } catch (error) {
31013
- logger.warn(`publish: Plugin "${plugin.name}" ${hook} failed: ${formatPluginError(error)}`);
31760
+ const message = `publish: Plugin "${plugin.name}" ${hook} failed: ${formatPluginError(error)}`;
31761
+ if (shouldAbortPluginFailure(plugin)) throw new Error(message);
31762
+ logger.warn(message);
31014
31763
  }
31015
31764
  }
31016
31765
  }
@@ -31107,6 +31856,19 @@ function publish(options) {
31107
31856
  }
31108
31857
  }
31109
31858
  const publishName = pkg.getPublishName() || pkg.getName();
31859
+ const sourceAtlas = pkg.getSourceAtlasSettings();
31860
+ const usePackageAtlas = !sourceAtlas.useGlobal;
31861
+ const atlas = {
31862
+ ...config.atlas,
31863
+ maxSize: options.atlas?.maxSize ?? (usePackageAtlas ? sourceAtlas.maxSize : config.atlas.maxSize),
31864
+ allowRotation: config.projectType === ProjectType.LayaBox ? false : options.atlas?.allowRotation ?? (usePackageAtlas ? sourceAtlas.allowRotation : config.atlas.allowRotation),
31865
+ powerOfTwo: options.atlas?.powerOfTwo ?? (usePackageAtlas ? sourceAtlas.sizeOption === "pot" : config.atlas.powerOfTwo),
31866
+ maxAtlasIndex: options.atlas?.maxAtlasIndex ?? sourceAtlas.maxIndex,
31867
+ multipleOfFour: options.atlas?.multipleOfFour ?? (usePackageAtlas ? sourceAtlas.sizeOption === "mof" : config.atlas.multipleOfFour),
31868
+ square: options.atlas?.square ?? (usePackageAtlas ? sourceAtlas.forceSquare : config.atlas.square),
31869
+ multiPage: options.atlas?.multiPage ?? (usePackageAtlas ? sourceAtlas.paging : config.atlas.multiPage),
31870
+ extractAlpha: config.projectType === ProjectType.Unity && (options.atlas?.extractAlpha ?? (usePackageAtlas || sourceAtlas.extractAlpha ? sourceAtlas.extractAlpha : config.atlas.extractAlpha))
31871
+ };
31110
31872
  return {
31111
31873
  pkg,
31112
31874
  outputDir,
@@ -31118,7 +31880,7 @@ function publish(options) {
31118
31880
  activeBranch: config.activeBranch,
31119
31881
  includeHighResolution: config.includeHighResolution,
31120
31882
  separatedAtlasForBranch: config.separatedAtlasForBranch,
31121
- atlas: config.atlas
31883
+ atlas
31122
31884
  };
31123
31885
  };
31124
31886
  const createNoopPublishFs = () => ({
@@ -31138,7 +31900,6 @@ function publish(options) {
31138
31900
  const atlasRuntimeOptions = resolvePublishAtlasRuntimeOptions(plan.fileExtension);
31139
31901
  await atlas({
31140
31902
  ...plan.atlas,
31141
- ...options.atlas ?? {},
31142
31903
  separatedAtlasForBranch: plan.separatedAtlasForBranch,
31143
31904
  encoder: options.encoder,
31144
31905
  basePath: options.basePath,
@@ -31290,15 +32051,9 @@ var NodeIO = class extends PlatformIO {
31290
32051
  },
31291
32052
  async readdir(dirPath) {
31292
32053
  const entries = await fs$1.readdir(dirPath, { withFileTypes: true });
31293
- return (await Promise.all(entries.map(async (entry) => {
31294
- if (entry.isDirectory()) return entry.name;
31295
- if (!entry.isSymbolicLink()) return null;
31296
- try {
31297
- return (await fs$1.stat(path$1.join(dirPath, entry.name))).isDirectory() ? entry.name : null;
31298
- } catch {
31299
- return null;
31300
- }
31301
- }))).filter((entry) => entry !== null);
32054
+ const symlink = entries.find((entry) => entry.isSymbolicLink());
32055
+ if (symlink) throw new Error(`Symbolic links are not supported in project directories: ${path$1.join(dirPath, symlink.name)}`);
32056
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
31302
32057
  },
31303
32058
  async exists(filePath) {
31304
32059
  try {
@@ -31383,16 +32138,33 @@ async function loadPlugins(doc, pluginsDir) {
31383
32138
  for (const entry of entries) {
31384
32139
  if (!entry.isDirectory()) continue;
31385
32140
  const pluginDir = path.join(pluginsDir, entry.name);
32141
+ let manifest;
32142
+ try {
32143
+ manifest = await readPluginManifest(fs, path, pluginDir);
32144
+ } catch (error) {
32145
+ doc.getLogger().warn(`publish: Plugin "${entry.name}" was skipped: ${formatPluginError(error)}`);
32146
+ continue;
32147
+ }
32148
+ if (!manifest) continue;
32149
+ if (!manifest.main) {
32150
+ const error = /* @__PURE__ */ new Error(`Codegen plugin "${manifest.name}" is missing package.json main.`);
32151
+ if (manifest.required) throw error;
32152
+ doc.getLogger().warn(`publish: Plugin "${manifest.name}" was skipped: ${error.message}`);
32153
+ continue;
32154
+ }
31386
32155
  try {
31387
- const manifest = await readPluginManifest(fs, path, pluginDir);
31388
- if (!manifest) continue;
31389
32156
  const plugin = await loadPlugin(resolvePluginMain(path, pluginDir, manifest));
31390
32157
  plugins.push({
31391
32158
  name: manifest.name,
31392
- plugin
32159
+ plugin,
32160
+ failureMode: manifest.required ? "abort" : manifest.failureMode
31393
32161
  });
31394
32162
  } catch (error) {
31395
- doc.getLogger().warn(`publish: Plugin "${entry.name}" was skipped: ${formatPluginError(error)}`);
32163
+ if (!manifest.required && manifest.failureMode === "warn") {
32164
+ doc.getLogger().warn(`publish: Plugin "${manifest.name}" was skipped: ${formatPluginError(error)}`);
32165
+ continue;
32166
+ }
32167
+ throw new Error(`publish: Failed to load plugin "${manifest.name}": ${formatPluginError(error)}`);
31396
32168
  }
31397
32169
  }
31398
32170
  return plugins;
@@ -31402,7 +32174,6 @@ async function readPluginManifest(fs, path, pluginDir) {
31402
32174
  const content = await fs.readFile(manifestPath, "utf-8");
31403
32175
  const manifest = JSON.parse(content);
31404
32176
  if (!manifest.name) throw new Error(`Codegen plugin at ${pluginDir} is missing package.json name.`);
31405
- if (!manifest.main) throw new Error(`Codegen plugin "${manifest.name}" is missing package.json main.`);
31406
32177
  return manifest;
31407
32178
  }
31408
32179
  function resolvePluginMain(path, pluginDir, manifest) {
@@ -31467,6 +32238,77 @@ async function loadNodePublishPlugins(document, assetsPath) {
31467
32238
  if (!projectDir) return [];
31468
32239
  return loadPlugins(document, (await importNative$2("node:path")).join(projectDir, "plugins"));
31469
32240
  }
32241
+ async function publishToStagedOutput(output, run) {
32242
+ const [fs, path, { randomUUID }] = await Promise.all([
32243
+ importNative$2("node:fs/promises"),
32244
+ importNative$2("node:path"),
32245
+ importNative$2("node:crypto")
32246
+ ]);
32247
+ const target = path.resolve(output);
32248
+ const parent = path.dirname(target);
32249
+ const name = path.basename(target);
32250
+ const staging = path.join(parent, `.${name}.publish-${randomUUID()}`);
32251
+ const backup = path.join(parent, `.${name}.publish-backup-${randomUUID()}`);
32252
+ await fs.mkdir(parent, { recursive: true });
32253
+ let existed = false;
32254
+ try {
32255
+ const stat = await fs.lstat(target);
32256
+ if (stat.isSymbolicLink() || !stat.isDirectory()) throw new Error(`publishNode: output must be a regular directory: ${target}`);
32257
+ await assertNoSymlinks(fs, path, target);
32258
+ existed = true;
32259
+ } catch (error) {
32260
+ if (error.code !== "ENOENT") throw error;
32261
+ }
32262
+ try {
32263
+ if (existed) await fs.cp(target, staging, {
32264
+ recursive: true,
32265
+ errorOnExist: true,
32266
+ force: false
32267
+ });
32268
+ else await fs.mkdir(staging);
32269
+ } catch (error) {
32270
+ await fs.rm(staging, {
32271
+ recursive: true,
32272
+ force: true
32273
+ });
32274
+ throw error;
32275
+ }
32276
+ try {
32277
+ await run(staging);
32278
+ } catch (error) {
32279
+ await fs.rm(staging, {
32280
+ recursive: true,
32281
+ force: true
32282
+ });
32283
+ throw error;
32284
+ }
32285
+ if (!existed) {
32286
+ await fs.rename(staging, target);
32287
+ return;
32288
+ }
32289
+ await fs.rename(target, backup);
32290
+ try {
32291
+ await fs.rename(staging, target);
32292
+ } catch (error) {
32293
+ await fs.rename(backup, target);
32294
+ await fs.rm(staging, {
32295
+ recursive: true,
32296
+ force: true
32297
+ });
32298
+ throw error;
32299
+ }
32300
+ await fs.rm(backup, {
32301
+ recursive: true,
32302
+ force: true
32303
+ }).catch(() => void 0);
32304
+ }
32305
+ async function assertNoSymlinks(fs, path, directory) {
32306
+ for (const entry of await fs.readdir(directory, { withFileTypes: true })) {
32307
+ const entryPath = path.join(directory, entry.name);
32308
+ if (entry.isSymbolicLink()) throw new Error(`publishNode: symbolic links are not supported in output directories: ${entryPath}`);
32309
+ if (entry.isDirectory()) await assertNoSymlinks(fs, path, entryPath);
32310
+ }
32311
+ }
31470
32312
  /**
31471
32313
  * Publish a FairyGUI project through the standard Node host adapter.
31472
32314
  *
@@ -31479,17 +32321,25 @@ async function publishNode(options) {
31479
32321
  const [fileSystem, assetsPath] = await Promise.all([createNodePublishFileSystem(), resolveNodeAssetsPath(document, configuredAssetsPath)]);
31480
32322
  const [encoder, plugins] = await Promise.all([configuredEncoder === void 0 ? loadSharpBackend() : Promise.resolve(configuredEncoder), configuredPlugins === void 0 ? loadNodePublishPlugins(document, assetsPath) : Promise.resolve(configuredPlugins)]);
31481
32323
  if (!encoder) throw new Error("publishNode: Sharp is required for a complete publish. Install sharp or provide an encoder.");
31482
- await document.transform(publish({
31483
- ...publishOptions,
31484
- basePath: assetsPath,
31485
- encoder,
31486
- atlas: {
31487
- ...atlas,
31488
- readFileRaw: fileSystem.readFileRaw
31489
- },
31490
- fs: fileSystem,
31491
- plugins
31492
- }));
32324
+ const run = async (output) => {
32325
+ await document.transform(publish({
32326
+ ...publishOptions,
32327
+ output,
32328
+ basePath: assetsPath,
32329
+ encoder,
32330
+ atlas: {
32331
+ ...atlas,
32332
+ readFileRaw: fileSystem.readFileRaw
32333
+ },
32334
+ fs: fileSystem,
32335
+ plugins
32336
+ }));
32337
+ };
32338
+ if (publishOptions.output) {
32339
+ await publishToStagedOutput(publishOptions.output, run);
32340
+ return;
32341
+ }
32342
+ await run(void 0);
31493
32343
  }
31494
32344
  //#endregion
31495
32345
  //#region ../functions/src/adapters/node/restore.ts
@@ -31666,18 +32516,21 @@ async function validateProjectNode(projectPath) {
31666
32516
  }
31667
32517
  const decodedPaths = new Set(images.map(({ packageIndex, resourceIndex }) => `packages[${packageIndex}].resources[${resourceIndex}]`));
31668
32518
  diagnostics = diagnostics.filter((diagnostic) => diagnostic.code !== "decode_capability_unavailable" || !decodedPaths.has(diagnostic.path));
31669
- for (const { pkg, packageIndex, resource, resourceIndex } of images) try {
31670
- await sharp(resource.sourceBytes).raw().toBuffer();
31671
- } catch (error) {
31672
- diagnostics.push({
31673
- severity: "error",
31674
- code: "corrupt_source",
31675
- path: `packages[${packageIndex}].resources[${resourceIndex}]`,
31676
- message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
31677
- packageId: pkg.id,
31678
- resourceId: resource.id,
31679
- sourcePath: sourceName(resource)
31680
- });
32519
+ for (const { pkg, packageIndex, resource, resourceIndex } of images) {
32520
+ if (resource.kind !== "image") continue;
32521
+ try {
32522
+ await sharp(resource.sourceBytes).raw().toBuffer();
32523
+ } catch (error) {
32524
+ diagnostics.push({
32525
+ severity: "error",
32526
+ code: "corrupt_source",
32527
+ path: `packages[${packageIndex}].resources[${resourceIndex}]`,
32528
+ message: `Image source cannot be decoded: ${error instanceof Error ? error.message : String(error)}`,
32529
+ packageId: pkg.id,
32530
+ resourceId: resource.id,
32531
+ sourcePath: sourceName(resource)
32532
+ });
32533
+ }
31681
32534
  }
31682
32535
  return createProjectValidationReport(diagnostics, read.complete && !diagnostics.some((diagnostic) => diagnostic.code === "decode_capability_unavailable"));
31683
32536
  }
@@ -31724,7 +32577,8 @@ function registerPublishCommand(program) {
31724
32577
  const pkgFilter = options.packages?.split(",").map((value) => value.trim());
31725
32578
  const resolved = resolvePublishOptions(doc, {
31726
32579
  compressed: options.compressed,
31727
- packages: pkgFilter
32580
+ packages: pkgFilter,
32581
+ targetProjectType: projectType
31728
32582
  });
31729
32583
  console.log(`Settings: ext=${resolved.fileExtension}, compressed=${resolved.compressed}`);
31730
32584
  if (options.branch) console.log(`Active branch: ${options.branch}`);
@@ -31784,7 +32638,7 @@ function registerValidateCommand(program) {
31784
32638
  //#region src/utils/package-version.ts
31785
32639
  const require$1 = createRequire(import.meta.url);
31786
32640
  function getInjectedPackageVersion() {
31787
- const version = "0.3.0-alpha.4";
32641
+ const version = "0.3.1";
31788
32642
  return typeof version === "string" && true ? version : null;
31789
32643
  }
31790
32644
  function readPackageVersion() {
@@ -31813,7 +32667,7 @@ function createProgram() {
31813
32667
  " openfairygui",
31814
32668
  "",
31815
32669
  "Input can be a .fairy file or a project root directory (auto-discovers .fairy file).",
31816
- "File extension and binary format are read from project settings."
32670
+ "Publish settings are read from the project; --project-type applies target-specific output rules."
31817
32671
  ].join("\n"));
31818
32672
  return program;
31819
32673
  }