cubing 0.32.2 → 0.33.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.
@@ -1244,12 +1244,20 @@ button:enabled {
1244
1244
  background-color: rgba(196, 196, 196, 0.75)
1245
1245
  }
1246
1246
 
1247
+ .dark-mode button:enabled {
1248
+ background-color: #88888888;
1249
+ }
1250
+
1247
1251
  button:disabled {
1248
1252
  background-color: rgba(0, 0, 0, 0.4);
1249
1253
  opacity: 0.25;
1250
1254
  pointer-events: none;
1251
1255
  }
1252
1256
 
1257
+ .dark-mode button:disabled {
1258
+ background-color: #ffffff44;
1259
+ }
1260
+
1253
1261
  button:enabled:hover {
1254
1262
  background-color: rgba(255, 255, 255, 0.75);
1255
1263
  box-shadow: 0 0 1em rgba(0, 0, 0, 0.25);
@@ -1398,11 +1406,11 @@ var buttonCommands = {
1398
1406
  "twizzle-link": true
1399
1407
  };
1400
1408
  var TwistyButtons = class extends ManagedCustomElement {
1401
- constructor(model, controller, fullscreenElement) {
1409
+ constructor(model, controller, defaultFullscreenElement) {
1402
1410
  super();
1403
1411
  this.model = model;
1404
1412
  this.controller = controller;
1405
- this.fullscreenElement = fullscreenElement;
1413
+ this.defaultFullscreenElement = defaultFullscreenElement;
1406
1414
  this.buttons = null;
1407
1415
  }
1408
1416
  connectedCallback() {
@@ -1419,6 +1427,9 @@ var TwistyButtons = class extends ManagedCustomElement {
1419
1427
  }
1420
1428
  this.buttons = buttons;
1421
1429
  this.model?.buttonAppearance.addFreshListener(this.update.bind(this));
1430
+ this.model?.twistySceneModel.darkMode.addFreshListener(
1431
+ this.updateDarkMode.bind(this)
1432
+ );
1422
1433
  }
1423
1434
  #onCommand(command) {
1424
1435
  switch (command) {
@@ -1461,16 +1472,18 @@ var TwistyButtons = class extends ManagedCustomElement {
1461
1472
  }
1462
1473
  }
1463
1474
  async onFullscreenButton() {
1464
- if (!this.fullscreenElement) {
1475
+ if (!this.defaultFullscreenElement) {
1465
1476
  throw new Error("Attempted to go fullscreen without an element.");
1466
1477
  }
1467
- if (documentFullscreenElement() === this.fullscreenElement) {
1478
+ if (documentFullscreenElement() === this.defaultFullscreenElement) {
1468
1479
  documentExitFullscreen();
1469
1480
  } else {
1470
1481
  this.buttons?.fullscreen.setIcon("exit-fullscreen");
1471
- requestFullscreen(this.fullscreenElement);
1482
+ requestFullscreen(
1483
+ await this.model?.twistySceneModel.fullscreenElement.get() ?? this.defaultFullscreenElement
1484
+ );
1472
1485
  const onFullscreen = () => {
1473
- if (documentFullscreenElement() !== this.fullscreenElement) {
1486
+ if (documentFullscreenElement() !== this.defaultFullscreenElement) {
1474
1487
  this.buttons?.fullscreen.setIcon("enter-fullscreen");
1475
1488
  window.removeEventListener("fullscreenchange", onFullscreen);
1476
1489
  }
@@ -1488,6 +1501,11 @@ var TwistyButtons = class extends ManagedCustomElement {
1488
1501
  button.hidden = !!info.hidden;
1489
1502
  }
1490
1503
  }
1504
+ updateDarkMode(darkMode) {
1505
+ for (const button of Object.values(this.buttons ?? {})) {
1506
+ button.updateDarkMode(darkMode);
1507
+ }
1508
+ }
1491
1509
  };
1492
1510
  customElementsShim.define("twisty-buttons", TwistyButtons);
1493
1511
  var TwistyButton = class extends ManagedCustomElement {
@@ -1500,6 +1518,9 @@ var TwistyButton = class extends ManagedCustomElement {
1500
1518
  buttonIcons
1501
1519
  );
1502
1520
  }
1521
+ updateDarkMode(darkMode) {
1522
+ this.contentWrapper.classList.toggle("dark-mode", darkMode === "dark");
1523
+ }
1503
1524
  connectedCallback() {
1504
1525
  this.addCSS(buttonCSS);
1505
1526
  this.addElement(this.htmlButton);
@@ -1527,12 +1548,16 @@ var twistyScrubberCSS = new CSSSource(
1527
1548
  overflow: hidden;
1528
1549
  backdrop-filter: blur(4px);
1529
1550
  -webkit-backdrop-filter: blur(4px);
1530
- background: rgba(196, 196, 196, 0.75)
1551
+ background: rgba(196, 196, 196, 0.75);
1531
1552
  }
1532
1553
 
1533
1554
  input:not(:disabled) {
1534
1555
  cursor: ew-resize;
1535
1556
  }
1557
+
1558
+ .wrapper.dark-mode {
1559
+ background: #666666;
1560
+ }
1536
1561
  `
1537
1562
  );
1538
1563
 
@@ -1591,6 +1616,12 @@ var TwistyScrubber = class extends ManagedCustomElement {
1591
1616
  async connectedCallback() {
1592
1617
  this.addCSS(twistyScrubberCSS);
1593
1618
  this.addElement(await this.inputElem());
1619
+ this.model?.twistySceneModel.darkMode.addFreshListener(
1620
+ this.updateDarkMode.bind(this)
1621
+ );
1622
+ }
1623
+ updateDarkMode(darkMode) {
1624
+ this.contentWrapper.classList.toggle("dark-mode", darkMode === "dark");
1594
1625
  }
1595
1626
  #inputElem = null;
1596
1627
  async inputElem() {
@@ -1768,7 +1799,8 @@ twisty-scrubber {
1768
1799
  background: rgba(196, 196, 196, 0.5);
1769
1800
  }
1770
1801
 
1771
- .wrapper.checkered {
1802
+ .wrapper.checkered,
1803
+ .wrapper.checkered-transparent {
1772
1804
  background-color: #EAEAEA;
1773
1805
  background-image: linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD),
1774
1806
  linear-gradient(45deg, #DDD 25%, transparent 25%, transparent 75%, #DDD 75%, #DDD);
@@ -1776,6 +1808,18 @@ twisty-scrubber {
1776
1808
  background-position: 0 0, 16px 16px;
1777
1809
  }
1778
1810
 
1811
+ .wrapper.checkered-transparent {
1812
+ background-color: #F4F4F4;
1813
+ background-image: linear-gradient(45deg, #DDDDDD88 25%, transparent 25%, transparent 75%, #DDDDDD88 75%, #DDDDDD88),
1814
+ linear-gradient(45deg, #DDDDDD88 25%, transparent 25%, transparent 75%, #DDDDDD88 75%, #DDDDDD88);
1815
+ }
1816
+
1817
+ .wrapper.dark-mode {
1818
+ background-color: #444;
1819
+ background-image: linear-gradient(45deg, #DDDDDD0b 25%, transparent 25%, transparent 75%, #DDDDDD0b 75%, #DDDDDD0b),
1820
+ linear-gradient(45deg, #DDDDDD0b 25%, transparent 25%, transparent 75%, #DDDDDD0b 75%, #DDDDDD0b);
1821
+ }
1822
+
1779
1823
  .visualization-wrapper > * {
1780
1824
  width: 100%;
1781
1825
  height: 100%;
@@ -3096,6 +3140,8 @@ var DetailedTimelineInfoProp = class extends TwistyPropDerived {
3096
3140
  }
3097
3141
  #requestedTimestampToMilliseconds(inputs) {
3098
3142
  switch (inputs.timestampRequest) {
3143
+ case "auto":
3144
+ return inputs.setupAnchor === "start" && inputs.setupAlg.alg.experimentalIsEmpty() ? inputs.timeRange.end : inputs.timeRange.start;
3099
3145
  case "start":
3100
3146
  return inputs.timeRange.start;
3101
3147
  case "end":
@@ -3146,6 +3192,7 @@ var TempoScaleProp = class extends TwistyPropSource {
3146
3192
 
3147
3193
  // src/cubing/twisty/model/props/timeline/TimestampRequestProp.ts
3148
3194
  var smartTimestamps = {
3195
+ auto: true,
3149
3196
  start: true,
3150
3197
  end: true,
3151
3198
  anchor: true,
@@ -3153,7 +3200,7 @@ var smartTimestamps = {
3153
3200
  };
3154
3201
  var TimestampRequestProp = class extends SimpleTwistyPropSource {
3155
3202
  getDefaultValue() {
3156
- return "opposite-anchor";
3203
+ return "auto";
3157
3204
  }
3158
3205
  set(v) {
3159
3206
  if (!this.validInput(v)) {
@@ -3244,6 +3291,13 @@ var VisualizationStrategyProp = class extends TwistyPropDerived {
3244
3291
  }
3245
3292
  };
3246
3293
 
3294
+ // src/cubing/twisty/model/props/puzzle/display/FaceletScaleProp.ts
3295
+ var FaceletScaleProp = class extends SimpleTwistyPropSource {
3296
+ getDefaultValue() {
3297
+ return "auto";
3298
+ }
3299
+ };
3300
+
3247
3301
  // src/cubing/twisty/model/props/puzzle/display/FoundationDisplayProp.ts
3248
3302
  var FoundationDisplayProp = class extends SimpleTwistyPropSource {
3249
3303
  getDefaultValue() {
@@ -3379,13 +3433,6 @@ var StickeringRequestProp = class extends SimpleTwistyPropSource {
3379
3433
  }
3380
3434
  };
3381
3435
 
3382
- // src/cubing/twisty/model/props/puzzle/display/FaceletScaleProp.ts
3383
- var FaceletScaleProp = class extends SimpleTwistyPropSource {
3384
- getDefaultValue() {
3385
- return "auto";
3386
- }
3387
- };
3388
-
3389
3436
  // src/cubing/twisty/model/props/puzzle/state/DragInputProp.ts
3390
3437
  var DragInputProp = class extends SimpleTwistyPropSource {
3391
3438
  getDefaultValue() {
@@ -3414,6 +3461,27 @@ var BackgroundProp = class extends SimpleTwistyPropSource {
3414
3461
  }
3415
3462
  };
3416
3463
 
3464
+ // src/cubing/twisty/model/props/viewer/DarkModeProp.ts
3465
+ var DarkModeProp = class extends TwistyPropDerived {
3466
+ derive(inputs) {
3467
+ return inputs.darkModeRequest === "dark" ? "dark" : "light";
3468
+ }
3469
+ };
3470
+
3471
+ // src/cubing/twisty/model/props/viewer/DarkModeRequestProp.ts
3472
+ var DarkModeRequstProp = class extends SimpleTwistyPropSource {
3473
+ getDefaultValue() {
3474
+ return "auto";
3475
+ }
3476
+ };
3477
+
3478
+ // src/cubing/twisty/model/props/viewer/DOMElementReferenceProp.ts
3479
+ var DOMElementReferenceProp = class extends SimpleTwistyPropSource {
3480
+ getDefaultValue() {
3481
+ return null;
3482
+ }
3483
+ };
3484
+
3417
3485
  // src/cubing/twisty/model/props/viewer/LatitudeLimit.ts
3418
3486
  var DEFAULT_LATITUDE_LIMIT = 35;
3419
3487
  var LatitudeLimitProp = class extends SimpleTwistyPropSource {
@@ -3534,9 +3602,11 @@ var TwistySceneModel = class {
3534
3602
  constructor(twistyPlayerModel) {
3535
3603
  this.twistyPlayerModel = twistyPlayerModel;
3536
3604
  this.background = new BackgroundProp();
3605
+ this.darkModeRequest = new DarkModeRequstProp();
3537
3606
  this.dragInput = new DragInputProp();
3538
3607
  this.foundationDisplay = new FoundationDisplayProp();
3539
3608
  this.foundationStickerSpriteURL = new URLProp();
3609
+ this.fullscreenElement = new DOMElementReferenceProp();
3540
3610
  this.hintFacelet = new HintFaceletProp();
3541
3611
  this.hintStickerSpriteURL = new URLProp();
3542
3612
  this.initialHintFaceletsAnimation = new InitialHintFaceletsAnimationProp();
@@ -3547,6 +3617,7 @@ var TwistySceneModel = class {
3547
3617
  this.stickeringMaskRequest = new StickeringMaskRequestProp();
3548
3618
  this.stickeringRequest = new StickeringRequestProp();
3549
3619
  this.faceletScale = new FaceletScaleProp();
3620
+ this.darkMode = new DarkModeProp({ darkModeRequest: this.darkModeRequest });
3550
3621
  this.foundationStickerSprite = new SpriteProp({
3551
3622
  spriteURL: this.foundationStickerSpriteURL
3552
3623
  });
@@ -3653,7 +3724,8 @@ var TwistyPlayerModel = class {
3653
3724
  {
3654
3725
  timestampRequest: this.timestampRequest,
3655
3726
  timeRange: this.timeRange,
3656
- setupAnchor: this.setupAnchor
3727
+ setupAnchor: this.setupAnchor,
3728
+ setupAlg: this.setupAlg
3657
3729
  }
3658
3730
  );
3659
3731
  this.coarseTimelineInfo = new CoarseTimelineInfoProp({
@@ -3691,7 +3763,8 @@ var TwistyPlayerModel = class {
3691
3763
  alg,
3692
3764
  setup,
3693
3765
  anchor,
3694
- experimentalStickeringRequest
3766
+ experimentalStickeringRequest,
3767
+ experimentalTitle
3695
3768
  ] = await Promise.all([
3696
3769
  this.viewerLink.get(),
3697
3770
  this.puzzleID.get(),
@@ -3699,7 +3772,8 @@ var TwistyPlayerModel = class {
3699
3772
  this.alg.get(),
3700
3773
  this.setupAlg.get(),
3701
3774
  this.setupAnchor.get(),
3702
- this.twistySceneModel.stickeringRequest.get()
3775
+ this.twistySceneModel.stickeringRequest.get(),
3776
+ this.twistySceneModel.twistyPlayerModel.title.get()
3703
3777
  ]);
3704
3778
  const isExplorer = viewerLink === "experimental-twizzle-explorer";
3705
3779
  const url = new URL(
@@ -3725,6 +3799,9 @@ var TwistyPlayerModel = class {
3725
3799
  } else if (puzzleID !== "3x3x3") {
3726
3800
  url.searchParams.set("puzzle", puzzleID);
3727
3801
  }
3802
+ if (experimentalTitle) {
3803
+ url.searchParams.set("title", experimentalTitle);
3804
+ }
3728
3805
  return url.toString();
3729
3806
  }
3730
3807
  experimentalAddAlgLeaf(algLeaf, options) {
@@ -3874,6 +3951,12 @@ var TwistyPlayerSettable = class extends ManagedCustomElement {
3874
3951
  get background() {
3875
3952
  throw err("background");
3876
3953
  }
3954
+ set darkMode(darkMode) {
3955
+ this.experimentalModel.twistySceneModel.darkModeRequest.set(darkMode);
3956
+ }
3957
+ get darkMode() {
3958
+ throw err("darkMode");
3959
+ }
3877
3960
  set controlPanel(newControlPanel) {
3878
3961
  this.experimentalModel.controlPanel.set(newControlPanel);
3879
3962
  }
@@ -3978,6 +4061,12 @@ var TwistyPlayerSettable = class extends ManagedCustomElement {
3978
4061
  get experimentalHintSprite() {
3979
4062
  throw err("experimentalHintSprite");
3980
4063
  }
4064
+ set fullscreenElement(element) {
4065
+ this.experimentalModel.twistySceneModel.fullscreenElement.set(element);
4066
+ }
4067
+ get fullscreenElement() {
4068
+ throw err("fullscreenElement");
4069
+ }
3981
4070
  set experimentalInitialHintFaceletsAnimation(anim) {
3982
4071
  this.experimentalModel.twistySceneModel.initialHintFaceletsAnimation.set(
3983
4072
  anim
@@ -4024,6 +4113,7 @@ var twistyPlayerAttributeMap = {
4024
4113
  "experimental-stickering": "experimentalStickering",
4025
4114
  "experimental-stickering-mask-orbits": "experimentalStickeringMaskOrbits",
4026
4115
  background: "background",
4116
+ "dark-mode": "darkMode",
4027
4117
  "control-panel": "controlPanel",
4028
4118
  "back-view": "backView",
4029
4119
  "experimental-initial-hint-facelets-animation": "experimentalInitialHintFaceletsAnimation",
@@ -4117,7 +4207,19 @@ var TwistyPlayer = class extends TwistyPlayerSettable {
4117
4207
  (backgroundTheme) => {
4118
4208
  this.contentWrapper.classList.toggle(
4119
4209
  "checkered",
4120
- backgroundTheme !== "none"
4210
+ ["auto", "checkered"].includes(backgroundTheme)
4211
+ );
4212
+ this.contentWrapper.classList.toggle(
4213
+ "checkered-transparent",
4214
+ backgroundTheme === "checkered-transparent"
4215
+ );
4216
+ }
4217
+ );
4218
+ this.experimentalModel.twistySceneModel.darkMode.addFreshListener(
4219
+ (darkModeTheme) => {
4220
+ this.contentWrapper.classList.toggle(
4221
+ "dark-mode",
4222
+ ["dark"].includes(darkModeTheme)
4121
4223
  );
4122
4224
  }
4123
4225
  );
@@ -5140,7 +5242,7 @@ var TwistyAlgEditor = class extends ManagedCustomElement {
5140
5242
  await twistyPlayer.experimentalModel.indexer.get(),
5141
5243
  await twistyPlayer.experimentalModel.timestampRequest.get()
5142
5244
  ]);
5143
- if (timestampRequest === "opposite-anchor" && !this.#onInputHasFired) {
5245
+ if (timestampRequest === "auto" && !this.#onInputHasFired) {
5144
5246
  return;
5145
5247
  }
5146
5248
  const moveStartTimestamp = indexer.indexToMoveStartTimestamp(
@@ -5237,7 +5339,8 @@ var twizzleLinkCSS = new CSSSource(
5237
5339
  .heading {
5238
5340
  background: rgba(255, 230, 210, 1);
5239
5341
  font-weight: bold;
5240
- padding: 0.25em 0.5em; display: grid;
5342
+ padding: 0.25em 0.5em;
5343
+ display: grid;
5241
5344
  grid-template-columns: 1fr auto;
5242
5345
  }
5243
5346
 
@@ -5261,8 +5364,55 @@ twisty-player {
5261
5364
  twisty-player + .heading {
5262
5365
  padding-top: 0.5em;
5263
5366
  }
5367
+
5368
+ twisty-alg-viewer {
5369
+ display: inline-block;
5370
+ }
5371
+
5372
+ .wrapper:fullscreen {
5373
+ width: 100%;
5374
+ height: 100%;
5375
+ display: grid;
5376
+ grid-template-rows: 1fr 1fr;
5377
+ }
5378
+
5379
+ .wrapper:fullscreen twisty-player,
5380
+ .wrapper:fullscreen .scrollable-region {
5381
+ height: unset;
5382
+ max-height: unset
5383
+ }
5264
5384
  `
5265
5385
  );
5386
+ var twizzleLinkForumTweaksCSS = new CSSSource(`
5387
+ .wrapper {
5388
+ background: white;
5389
+ }
5390
+
5391
+ .heading {
5392
+ background: #4285f422;
5393
+ }
5394
+
5395
+ .scrollable-region {
5396
+ max-height: 280px;
5397
+ overflow-y: auto;
5398
+ }
5399
+
5400
+ .wrapper.dark-mode {
5401
+ background: #262626;
5402
+ color: #929292;
5403
+ border-color: #FFFFFF44;
5404
+ color-scheme: dark;
5405
+ }
5406
+
5407
+ .wrapper.dark-mode .heading {
5408
+ background: #1d1d1d;
5409
+ color: #ececec;
5410
+ }
5411
+
5412
+ .heading.title {
5413
+ background: none;
5414
+ }
5415
+ `);
5266
5416
 
5267
5417
  // src/cubing/twisty/views/twizzle/url-params.ts
5268
5418
  function getConfigFromURL(prefix = "", url = location.href) {
@@ -5291,8 +5441,9 @@ function getConfigFromURL(prefix = "", url = location.href) {
5291
5441
 
5292
5442
  // src/cubing/twisty/views/twizzle/TwizzleLink.ts
5293
5443
  var TwizzleLink = class extends ManagedCustomElement {
5294
- constructor() {
5444
+ constructor(options) {
5295
5445
  super({ mode: "open" });
5446
+ this.options = options;
5296
5447
  this.twistyPlayer = null;
5297
5448
  this.a = null;
5298
5449
  }
@@ -5306,13 +5457,20 @@ var TwizzleLink = class extends ManagedCustomElement {
5306
5457
  span.title = "Could not show a player for link";
5307
5458
  this.addElement(this.a);
5308
5459
  }
5309
- if (this.#cssElem) {
5310
- this.#cssElem.remove();
5311
- }
5460
+ this.#cssElem?.remove();
5461
+ this.#cssCDNForumTweaksElem?.remove();
5312
5462
  }
5313
5463
  #cssElem;
5464
+ #cssCDNForumTweaksElem;
5465
+ #scrollableRegion;
5314
5466
  async connectedCallback() {
5467
+ if (this.options?.darkMode) {
5468
+ this.contentWrapper.classList.add("dark-mode");
5469
+ }
5315
5470
  this.#cssElem = this.addCSS(twizzleLinkCSS);
5471
+ if (this.options?.cdnForumTweaks) {
5472
+ this.addCSS(twizzleLinkForumTweaksCSS);
5473
+ }
5316
5474
  this.a = this.querySelector("a");
5317
5475
  if (!this.a) {
5318
5476
  return;
@@ -5333,10 +5491,18 @@ var TwizzleLink = class extends ManagedCustomElement {
5333
5491
  }
5334
5492
  this.twistyPlayer = this.addElement(
5335
5493
  new TwistyPlayer({
5494
+ background: this.options?.cdnForumTweaks ? "checkered-transparent" : "checkered",
5495
+ darkMode: this.options?.darkMode ? "dark" : "light",
5336
5496
  ...config,
5337
5497
  viewerLink: isExplorer ? "experimental-twizzle-explorer" : "auto"
5338
5498
  })
5339
5499
  );
5500
+ this.twistyPlayer.fullscreenElement = this.contentWrapper;
5501
+ if (config.experimentalTitle) {
5502
+ this.twistyPlayer.experimentalTitle = config.experimentalTitle;
5503
+ }
5504
+ this.#scrollableRegion = this.addElement(document.createElement("div"));
5505
+ this.#scrollableRegion.classList.add("scrollable-region");
5340
5506
  if (config.experimentalTitle) {
5341
5507
  this.addHeading(config.experimentalTitle).classList.add("title");
5342
5508
  }
@@ -5345,7 +5511,9 @@ var TwizzleLink = class extends ManagedCustomElement {
5345
5511
  "Setup",
5346
5512
  async () => (await this.twistyPlayer?.experimentalModel.setupAlg.get())?.alg.toString() ?? null
5347
5513
  );
5348
- const setupAlgDiv = this.addElement(document.createElement("div"));
5514
+ const setupAlgDiv = this.#scrollableRegion.appendChild(
5515
+ document.createElement("div")
5516
+ );
5349
5517
  setupAlgDiv.classList.add("setup-alg");
5350
5518
  setupAlgDiv.textContent = new Alg(
5351
5519
  config.experimentalSetupAlg
@@ -5355,7 +5523,7 @@ var TwizzleLink = class extends ManagedCustomElement {
5355
5523
  "Moves",
5356
5524
  async () => (await this.twistyPlayer?.experimentalModel.alg.get())?.alg.toString() ?? null
5357
5525
  );
5358
- const twistyAlgViewer = this.addElement(
5526
+ const twistyAlgViewer = this.#scrollableRegion.appendChild(
5359
5527
  new TwistyAlgViewer({ twistyPlayer: this.twistyPlayer })
5360
5528
  );
5361
5529
  twistyAlgViewer.part.add("twisty-alg-viewer");
@@ -5364,7 +5532,9 @@ var TwizzleLink = class extends ManagedCustomElement {
5364
5532
  }
5365
5533
  }
5366
5534
  addHeading(text, getTextToCopy) {
5367
- const headingDiv = this.addElement(document.createElement("div"));
5535
+ const headingDiv = this.#scrollableRegion.appendChild(
5536
+ document.createElement("div")
5537
+ );
5368
5538
  headingDiv.classList.add("heading");
5369
5539
  headingDiv.textContent = text;
5370
5540
  if (getTextToCopy) {
@@ -5382,18 +5552,18 @@ var TwizzleLink = class extends ManagedCustomElement {
5382
5552
  }
5383
5553
  a.addEventListener("click", async (e) => {
5384
5554
  e.preventDefault();
5385
- a.textContent = "\u{1F4CB}\u2026";
5555
+ a.textContent = "\u2026\u{1F4CB}";
5386
5556
  const textToCopy = await getTextToCopy();
5387
5557
  if (textToCopy) {
5388
5558
  try {
5389
5559
  await navigator.clipboard.writeText(textToCopy);
5390
- setAndClear("\u{1F4CB}\u2705");
5560
+ setAndClear("\u2705\u{1F4CB}");
5391
5561
  } catch (e2) {
5392
- setAndClear("\u{1F4CB}\u274C");
5562
+ setAndClear("\u274C\u{1F4CB}");
5393
5563
  throw e2;
5394
5564
  }
5395
5565
  } else {
5396
- setAndClear("\u{1F4CB}\u274C");
5566
+ setAndClear("\u274C\u{1F4CB}");
5397
5567
  }
5398
5568
  });
5399
5569
  }
@@ -5401,6 +5571,15 @@ var TwizzleLink = class extends ManagedCustomElement {
5401
5571
  }
5402
5572
  };
5403
5573
  customElementsShim.define("twizzle-link", TwizzleLink);
5574
+ var TwizzleForumLink = class extends TwizzleLink {
5575
+ constructor() {
5576
+ super({
5577
+ cdnForumTweaks: true,
5578
+ darkMode: document.documentElement.classList.contains("style-dark")
5579
+ });
5580
+ }
5581
+ };
5582
+ customElementsShim.define("twizzle-forum-link", TwizzleForumLink);
5404
5583
  export {
5405
5584
  NO_VALUE as EXPERIMENTAL_PROP_NO_VALUE,
5406
5585
  KPuzzleSVGWrapper as ExperimentalKPuzzleSVGWrapper,
@@ -5409,7 +5588,7 @@ export {
5409
5588
  TwistyAlgEditor,
5410
5589
  TwistyAlgViewer,
5411
5590
  TwistyPlayer,
5412
- TwizzleLink,
5591
+ TwizzleForumLink as TwizzleLink,
5413
5592
  backViewLayouts,
5414
5593
  setTwistyDebug
5415
5594
  };