lexgui 0.5.2 → 0.5.4

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/build/lexgui.js CHANGED
@@ -12,7 +12,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
12
12
  */
13
13
 
14
14
  var LX = {
15
- version: "0.5.2",
15
+ version: "0.5.4",
16
16
  ready: false,
17
17
  components: [], // Specific pre-build components
18
18
  signals: {}, // Events and triggers
@@ -783,7 +783,7 @@ function _createCommandbar( root )
783
783
  className: "gs-tabs"
784
784
  } );
785
785
 
786
- const gsTabs = tabArea.addTabs();
786
+ const gsTabs = tabArea.addTabs( { parentClass: "p-2" } );
787
787
  let gsFilter = null;
788
788
 
789
789
  // These tabs will serve as buttons by now
@@ -939,6 +939,7 @@ function _createCommandbar( root )
939
939
  * @param {Object} options
940
940
  * container: Root location for the gui (default is the document body)
941
941
  * id: Id of the main area
942
+ * rootClass: Extra class to the root container
942
943
  * skipRoot: Skip adding LX root container
943
944
  * skipDefaultArea: Skip creation of main area
944
945
  * strictViewport: Use only window area
@@ -955,8 +956,14 @@ function init( options = { } )
955
956
 
956
957
  var root = document.createElement( 'div' );
957
958
  root.id = "lexroot";
959
+ root.className = "lexcontainer";
958
960
  root.tabIndex = -1;
959
961
 
962
+ if( options.rootClass )
963
+ {
964
+ root.className += ` ${ options.rootClass }`;
965
+ }
966
+
960
967
  var modal = document.createElement( 'div' );
961
968
  modal.id = "modal";
962
969
 
@@ -969,7 +976,7 @@ function init( options = { } )
969
976
 
970
977
  if( options.container )
971
978
  {
972
- this.container = document.getElementById( options.container );
979
+ this.container = options.container.constructor === String ? document.getElementById( options.container ) : options.container;
973
980
  }
974
981
 
975
982
  this.usingStrictViewport = options.strictViewport ?? true;
@@ -1007,7 +1014,7 @@ function init( options = { } )
1007
1014
  this.notifications.className = "";
1008
1015
  this.notifications.iWidth = 0;
1009
1016
  notifSection.appendChild( this.notifications );
1010
- this.container.appendChild( notifSection );
1017
+ document.body.appendChild( notifSection );
1011
1018
 
1012
1019
  this.notifications.addEventListener( "mouseenter", () => {
1013
1020
  this.notifications.classList.add( "list" );
@@ -1324,6 +1331,7 @@ LX.toast = toast;
1324
1331
  * @param {String} className
1325
1332
  * @param {Object} options
1326
1333
  * style: Style attributes to override
1334
+ * asElement: Returns the badge as HTMLElement [false]
1327
1335
  */
1328
1336
 
1329
1337
  function badge( text, className, options = {} )
@@ -1332,7 +1340,7 @@ function badge( text, className, options = {} )
1332
1340
  container.innerHTML = text;
1333
1341
  container.className = "lexbadge " + ( className ?? "" );
1334
1342
  Object.assign( container.style, options.style ?? {} );
1335
- return container.outerHTML;
1343
+ return ( options.asElement ?? false ) ? container : container.outerHTML;
1336
1344
  }
1337
1345
 
1338
1346
  LX.badge = badge;
@@ -1341,21 +1349,84 @@ LX.badge = badge;
1341
1349
  * @method makeContainer
1342
1350
  * @param {Array} size
1343
1351
  * @param {String} className
1352
+ * @param {String} innerHTML
1353
+ * @param {HTMLElement} parent
1344
1354
  * @param {Object} overrideStyle
1345
1355
  */
1346
1356
 
1347
- function makeContainer( size, className, overrideStyle = {} )
1357
+ function makeContainer( size, className, innerHTML, parent, overrideStyle = {} )
1348
1358
  {
1349
1359
  const container = document.createElement( "div" );
1350
1360
  container.className = "lexcontainer " + ( className ?? "" );
1361
+ container.innerHTML = innerHTML ?? "";
1351
1362
  container.style.width = size && size[ 0 ] ? size[ 0 ] : "100%";
1352
1363
  container.style.height = size && size[ 1 ] ? size[ 1 ] : "100%";
1353
1364
  Object.assign( container.style, overrideStyle );
1365
+
1366
+ if( parent )
1367
+ {
1368
+ if( parent.attach ) // Use attach method if possible
1369
+ {
1370
+ parent.attach( container );
1371
+ }
1372
+ else // its a native HTMLElement
1373
+ {
1374
+ parent.appendChild( container );
1375
+ }
1376
+ }
1377
+
1354
1378
  return container;
1355
1379
  }
1356
1380
 
1357
1381
  LX.makeContainer = makeContainer;
1358
1382
 
1383
+ /**
1384
+ * @method asTooltip
1385
+ * @param {HTMLElement} trigger
1386
+ * @param {String} content
1387
+ */
1388
+
1389
+ function asTooltip( trigger, content )
1390
+ {
1391
+ console.assert( trigger, "You need a trigger to generate a tooltip!" );
1392
+
1393
+ let tooltipDom = null;
1394
+
1395
+ trigger.addEventListener( "mouseenter", function(e) {
1396
+
1397
+ console.log(e.target);
1398
+
1399
+ LX.root.querySelectorAll( ".lextooltip" ).forEach( e => e.remove() );
1400
+
1401
+ let rect = this.getBoundingClientRect();
1402
+ rect.x += document.scrollingElement.scrollLeft;
1403
+ rect.y += document.scrollingElement.scrollTop;
1404
+
1405
+ tooltipDom = document.createElement( "div" );
1406
+ tooltipDom.className = "lextooltip";
1407
+ tooltipDom.innerHTML = content;
1408
+
1409
+ doAsync( () => {
1410
+ tooltipDom.style.top = ( rect.y - tooltipDom.offsetHeight - 6 ) + "px";
1411
+ tooltipDom.style.left = ( rect.x + rect.width * 0.5 - tooltipDom.offsetWidth * 0.5 ) + "px";
1412
+ } )
1413
+
1414
+ LX.root.appendChild( tooltipDom );
1415
+ } );
1416
+
1417
+ trigger.addEventListener( "mouseleave", function(e) {
1418
+ if( !tooltipDom ) return;
1419
+
1420
+ tooltipDom.dataset[ "closed" ] = true;
1421
+
1422
+ doAsync( () => {
1423
+ tooltipDom.remove();
1424
+ }, 300 )
1425
+ } )
1426
+ }
1427
+
1428
+ LX.asTooltip = asTooltip;
1429
+
1359
1430
  /*
1360
1431
  * Events and Signals
1361
1432
  */
@@ -1598,7 +1669,7 @@ class DropdownMenu {
1598
1669
  }
1599
1670
 
1600
1671
  const menuItem = document.createElement('div');
1601
- menuItem.className = "lexdropdownmenuitem" + ( item.name ? "" : " label" ) + ( item.disabled ?? false ? " disabled" : "" );
1672
+ menuItem.className = "lexdropdownmenuitem" + ( item.name ? "" : " label" ) + ( item.disabled ?? false ? " disabled" : "" ) + ( ` ${ item.className ?? "" }` );
1602
1673
  menuItem.id = pKey;
1603
1674
  menuItem.innerHTML = `<span>${ key }</span>`;
1604
1675
 
@@ -1631,7 +1702,7 @@ class DropdownMenu {
1631
1702
  {
1632
1703
  f.call( this, key, menuItem, v );
1633
1704
  }
1634
- });
1705
+ }, { className: "accent" });
1635
1706
  const input = checkbox.root.querySelector( "input" );
1636
1707
  menuItem.prepend( input );
1637
1708
 
@@ -1795,7 +1866,7 @@ class Area {
1795
1866
  root.className += " " + options.className;
1796
1867
  }
1797
1868
 
1798
- var width = options.width || "calc( 100% )";
1869
+ var width = options.width || "100%";
1799
1870
  var height = options.height || "100%";
1800
1871
 
1801
1872
  // This has default options..
@@ -1819,9 +1890,9 @@ class Area {
1819
1890
  this.sections = [];
1820
1891
  this.panels = [];
1821
1892
 
1822
- if( !options.skipAppend )
1893
+ let lexroot = document.getElementById("lexroot");
1894
+ if( lexroot && !options.skipAppend )
1823
1895
  {
1824
- let lexroot = document.getElementById("lexroot");
1825
1896
  lexroot.appendChild( this.root );
1826
1897
  }
1827
1898
 
@@ -1968,7 +2039,7 @@ class Area {
1968
2039
  attach( content ) {
1969
2040
 
1970
2041
  // Append to last split section if area has been split
1971
- if( this.sections.length)
2042
+ if( this.sections.length )
1972
2043
  {
1973
2044
  this.sections[ 1 ].attach( content );
1974
2045
  return;
@@ -2004,7 +2075,7 @@ class Area {
2004
2075
 
2005
2076
  const type = options.type || "horizontal";
2006
2077
  const sizes = options.sizes || [ "50%", "50%" ];
2007
- const auto = (options.sizes === 'auto');
2078
+ const auto = (options.sizes === 'auto') || ( options.sizes && options.sizes[ 0 ] == "auto" && options.sizes[ 1 ] == "auto" );
2008
2079
 
2009
2080
  if( !sizes[ 1 ] )
2010
2081
  {
@@ -2108,8 +2179,8 @@ class Area {
2108
2179
  const resizeObserver = new ResizeObserver( entries => {
2109
2180
  for ( const entry of entries )
2110
2181
  {
2111
- const bb = entry.contentRect;
2112
- area2.root.style.height = "calc(100% - " + ( bb.height + 4) + "px )";
2182
+ const size = entry.target.getComputedSize();
2183
+ area2.root.style.height = "calc(100% - " + ( size.height ) + "px )";
2113
2184
  }
2114
2185
  });
2115
2186
 
@@ -2387,7 +2458,12 @@ class Area {
2387
2458
 
2388
2459
  if( options.sticky ?? true )
2389
2460
  {
2390
- bar.root.classList.add( "sticky" );
2461
+ bar.root.className += " sticky top-0";
2462
+ }
2463
+
2464
+ if( options.parentClass )
2465
+ {
2466
+ bar.root.className += ` ${ options.parentClass }`;
2391
2467
  }
2392
2468
 
2393
2469
  return menubar;
@@ -2421,6 +2497,11 @@ class Area {
2421
2497
  bar.attach( sidebar );
2422
2498
  bar.isSidebar = true;
2423
2499
 
2500
+ if( options.parentClass )
2501
+ {
2502
+ bar.root.className += ` ${ options.parentClass }`;
2503
+ }
2504
+
2424
2505
  return sidebar;
2425
2506
  }
2426
2507
 
@@ -2484,7 +2565,8 @@ class Area {
2484
2565
  selected: b.selected,
2485
2566
  icon: b.icon,
2486
2567
  img: b.img,
2487
- className: b.class
2568
+ className: b.class ?? "",
2569
+ title: b.name
2488
2570
  };
2489
2571
 
2490
2572
  if( group )
@@ -2522,7 +2604,10 @@ class Area {
2522
2604
  }
2523
2605
  }
2524
2606
 
2525
- callback( value, event, button.root );
2607
+ if( callback )
2608
+ {
2609
+ callback( value, event, button.root );
2610
+ }
2526
2611
 
2527
2612
  }, _options );
2528
2613
  }
@@ -2579,6 +2664,7 @@ class Area {
2579
2664
  /**
2580
2665
  * @method addTabs
2581
2666
  * @param {Object} options:
2667
+ * parentClass: Add extra class to tab buttons container
2582
2668
  */
2583
2669
 
2584
2670
  addTabs( options = {} ) {
@@ -2698,7 +2784,6 @@ function flushCss(element) {
2698
2784
 
2699
2785
  class Tabs {
2700
2786
 
2701
- static TAB_SIZE = 28;
2702
2787
  static TAB_ID = 0;
2703
2788
 
2704
2789
  constructor( area, options = {} ) {
@@ -2706,10 +2791,10 @@ class Tabs {
2706
2791
  this.onclose = options.onclose;
2707
2792
 
2708
2793
  let container = document.createElement('div');
2709
- container.className = "lexareatabs " + (options.fit ? "fit" : "row");
2794
+ container.className = "lexareatabs " + ( options.fit ? "fit" : "row" );
2710
2795
 
2711
2796
  const folding = options.folding ?? false;
2712
- if(folding) container.classList.add("folding");
2797
+ if( folding ) container.classList.add("folding");
2713
2798
 
2714
2799
  let that = this;
2715
2800
 
@@ -2782,11 +2867,22 @@ class Tabs {
2782
2867
 
2783
2868
  area.root.classList.add( "lexareatabscontainer" );
2784
2869
 
2785
- area.split({ type: 'vertical', sizes: options.sizes ?? "auto", resize: false, top: 6 });
2786
- area.sections[ 0 ].attach( container );
2870
+ const [ tabButtons, content ] = area.split({ type: 'vertical', sizes: options.sizes ?? "auto", resize: false, top: 2 });
2871
+ tabButtons.attach( container );
2872
+
2873
+ if( options.parentClass )
2874
+ {
2875
+ container.parentElement.className += ` ${ options.parentClass }`;
2876
+ }
2787
2877
 
2788
- this.area = area.sections[1];
2878
+ this.area = content;
2789
2879
  this.area.root.className += " lexareatabscontent";
2880
+
2881
+ if( options.contentClass )
2882
+ {
2883
+ this.area.root.className += ` ${ options.contentClass }`;
2884
+ }
2885
+
2790
2886
  this.selected = null;
2791
2887
  this.root = container;
2792
2888
  this.tabs = {};
@@ -2806,8 +2902,7 @@ class Tabs {
2806
2902
  var transition = this.thumb.style.transition;
2807
2903
  this.thumb.style.transition = "none";
2808
2904
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2809
- this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
2810
- this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
2905
+ this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2811
2906
  flushCss( this.thumb );
2812
2907
  this.thumb.style.transition = transition;
2813
2908
  });
@@ -2849,7 +2944,7 @@ class Tabs {
2849
2944
  if( isSelected )
2850
2945
  {
2851
2946
  this.root.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ) );
2852
- this.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
2947
+ this.area.root.querySelectorAll( ':scope > .lextabcontent' ).forEach( c => c.style.display = 'none' );
2853
2948
  }
2854
2949
 
2855
2950
  isSelected = !Object.keys( this.tabs ).length && !this.folding ? true : isSelected;
@@ -2907,7 +3002,7 @@ class Tabs {
2907
3002
  tabEl.parentElement.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ));
2908
3003
  tabEl.classList.toggle('selected', ( this.folding && tabEl.selected ));
2909
3004
  // Manage visibility
2910
- scope.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
3005
+ scope.area.root.querySelectorAll( ':scope > .lextabcontent' ).forEach( c => c.style.display = 'none' );
2911
3006
  contentEl.style.display = contentEl.originalDisplay;
2912
3007
  scope.selected = tabEl.dataset.name;
2913
3008
  }
@@ -2926,8 +3021,7 @@ class Tabs {
2926
3021
  if( scope.thumb )
2927
3022
  {
2928
3023
  scope.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2929
- scope.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
2930
- scope.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
3024
+ scope.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2931
3025
  scope.thumb.item = tabEl;
2932
3026
  }
2933
3027
  });
@@ -2979,8 +3073,7 @@ class Tabs {
2979
3073
  if( isSelected && this.thumb )
2980
3074
  {
2981
3075
  this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
2982
- this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
2983
- this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
3076
+ this.thumb.style.width = ( tabEl.offsetWidth ) + "px";
2984
3077
  this.thumb.item = tabEl;
2985
3078
  }
2986
3079
 
@@ -3112,7 +3205,7 @@ class Menubar {
3112
3205
  const hasSubmenu = subitem[ subkey ].length;
3113
3206
  const isCheckbox = subitem[ 'type' ] == 'checkbox';
3114
3207
  let subentry = document.createElement('div');
3115
- subentry.tabIndex = "1";
3208
+ subentry.tabIndex = "-1";
3116
3209
  subentry.className = "lexmenuboxentry";
3117
3210
  subentry.className += (i == o[k].length - 1 ? " last" : "") + ( subitem.disabled ? " disabled" : "" );
3118
3211
 
@@ -3199,12 +3292,10 @@ class Menubar {
3199
3292
  });
3200
3293
 
3201
3294
  subentry.addEventListener("blur", e => {
3202
-
3203
- if( e.target && e.target.className.includes( "lexmenu" ) )
3295
+ if( e.relatedTarget && !e.relatedTarget.className.includes( "lexmenu" ) )
3204
3296
  {
3205
- return;
3297
+ this._resetMenubar();
3206
3298
  }
3207
- this._resetMenubar();
3208
3299
  });
3209
3300
 
3210
3301
  // Add icon if has submenu, else check for shortcut
@@ -3660,6 +3751,7 @@ class SideBar {
3660
3751
 
3661
3752
  /**
3662
3753
  * @param {Object} options
3754
+ * className: Extra class to customize root element
3663
3755
  * filter: Add search bar to filter entries [false]
3664
3756
  * displaySelected: Indicate if an entry is displayed as selected
3665
3757
  * skipHeader: Do not use sidebar header [false]
@@ -3683,7 +3775,7 @@ class SideBar {
3683
3775
  constructor( options = {} ) {
3684
3776
 
3685
3777
  this.root = document.createElement( "div" );
3686
- this.root.className = "lexsidebar";
3778
+ this.root.className = "lexsidebar " + ( options.className ?? "" );
3687
3779
 
3688
3780
  this._displaySelected = options.displaySelected ?? false;
3689
3781
 
@@ -3744,12 +3836,11 @@ class SideBar {
3744
3836
  // Entry filter
3745
3837
  if( ( options.filter ?? false ) )
3746
3838
  {
3747
- const panel = new Panel();
3748
- panel.addText(null, "", (value, event) => {
3839
+ const filterTextInput = new TextInput(null, "", (value, event) => {
3749
3840
  this.filterString = value;
3750
3841
  this.update();
3751
- }, { placeholder: "Search...", icon: "fa-solid fa-magnifying-glass" });
3752
- this.filter = panel.root.childNodes[ 0 ];
3842
+ }, { inputClass: "outline", placeholder: "Search...", icon: "fa-solid fa-magnifying-glass", className: "lexsidebarfilter" });
3843
+ this.filter = filterTextInput.root;
3753
3844
  this.root.appendChild( this.filter );
3754
3845
  }
3755
3846
 
@@ -3771,10 +3862,10 @@ class SideBar {
3771
3862
 
3772
3863
  // Set width depending on header/footer
3773
3864
  doAsync( () => {
3774
- // This account for header, footer and all inner paddings
3775
- const contentOffset = 32 + ( this.header?.offsetHeight ?? 0 ) +
3776
- ( this.filter?.offsetHeight ?? 0 ) +
3777
- ( this.footer?.offsetHeight ?? 0 );
3865
+ // This account for header, footer and all inner margins
3866
+ const contentOffset = ( parseInt( this.header?.getComputedSize().height ) ?? 0 ) +
3867
+ ( parseInt( this.filter?.getComputedSize().height ) ?? 0 ) +
3868
+ ( parseInt( this.footer?.getComputedSize().height ) ?? 0 );
3778
3869
  this.content.style.height = `calc(100% - ${ contentOffset }px)`;
3779
3870
  }, 10 );
3780
3871
 
@@ -4060,8 +4151,13 @@ class SideBar {
4060
4151
  let currentGroup = null;
4061
4152
 
4062
4153
  let entry = document.createElement( 'div' );
4063
- entry.className = "lexsidebarentry " + ( options.className ?? "" );
4064
4154
  entry.id = item.name = pKey;
4155
+ entry.className = "lexsidebarentry " + ( options.className ?? "" );
4156
+
4157
+ if( this.displaySelected && options.selected )
4158
+ {
4159
+ entry.classList.add( "selected" );
4160
+ }
4065
4161
 
4066
4162
  if( item.group )
4067
4163
  {
@@ -4131,6 +4227,7 @@ class SideBar {
4131
4227
  }
4132
4228
 
4133
4229
  let itemDom = document.createElement( 'div' );
4230
+ itemDom.className = "lexsidebarentrycontent";
4134
4231
  entry.appendChild( itemDom );
4135
4232
  item.dom = entry;
4136
4233
 
@@ -4144,21 +4241,38 @@ class SideBar {
4144
4241
  const f = options.callback;
4145
4242
  item.value = value;
4146
4243
  if( f ) f.call( this, key, value, event );
4147
- }, { label: key, signal: ( "@checkbox_" + key ) });
4244
+ }, { className: "accent", label: key, signal: ( "@checkbox_" + key ) });
4148
4245
  itemDom.appendChild( panel.root.childNodes[ 0 ] );
4149
4246
  }
4150
4247
  else
4151
4248
  {
4152
4249
  if( options.icon )
4153
4250
  {
4154
- let itemIcon = document.createElement( 'i' );
4155
- itemIcon.className = options.icon;
4251
+ let itemIcon = null;
4252
+
4253
+ // @legacy
4254
+ if( options.icon.includes( "fa-" ) )
4255
+ {
4256
+ itemIcon = document.createElement( 'i' );
4257
+ itemIcon.className = options.icon;
4258
+ }
4259
+ else
4260
+ {
4261
+ itemIcon = LX.makeIcon( options.icon );
4262
+ }
4263
+
4264
+ itemIcon.classList.add( "lexsidebarentryicon" );
4156
4265
  itemDom.appendChild( itemIcon );
4157
4266
  }
4158
4267
 
4159
4268
  let itemName = document.createElement( 'a' );
4160
4269
  itemName.innerHTML = key;
4161
4270
  itemDom.appendChild( itemName );
4271
+
4272
+ if( options.content )
4273
+ {
4274
+ itemDom.appendChild( options.content );
4275
+ }
4162
4276
  }
4163
4277
 
4164
4278
  const isCollapsable = options.collapsable != undefined ? options.collapsable : ( options.collapsable || item[ key ].length );
@@ -4384,8 +4498,6 @@ class Widget {
4384
4498
 
4385
4499
  if( type != Widget.TITLE )
4386
4500
  {
4387
- // root.style.width = "calc(100% - " + (this._currentBranch || type == Widget.FILE || type == Widget.TREE ? 10 : 20) + "px)";
4388
-
4389
4501
  if( options.width )
4390
4502
  {
4391
4503
  root.style.width = root.style.minWidth = options.width;
@@ -4421,6 +4533,7 @@ class Widget {
4421
4533
  domName.innerHTML = name;
4422
4534
  domName.title = options.title ?? domName.innerHTML;
4423
4535
  domName.style.width = options.nameWidth || LX.DEFAULT_NAME_WIDTH;
4536
+ domName.style.minWidth = domName.style.width;
4424
4537
 
4425
4538
  root.appendChild( domName );
4426
4539
  root.domName = domName;
@@ -4651,16 +4764,18 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
4651
4764
  container.className = "lexcustomcontainer";
4652
4765
  container.style.width = "100%";
4653
4766
  element.appendChild( container );
4767
+ element.dataset["opened"] = false;
4654
4768
 
4655
- let buttonName = "<a class='fa-solid " + (options.icon ?? "fa-cube") + "' style='float:left'></a>";
4769
+ let buttonName = "<a class='fa-solid " + (options.icon ?? "fa-cube") + "'></a>";
4656
4770
  buttonName += customWidgetName + (!instance ? " [empty]" : "");
4657
4771
  // Add always icon to keep spacing right
4658
- buttonName += "<a class='fa-solid " + (instance ? "fa-bars-staggered" : " ") + " menu' style='float:right; width:5%;'></a>";
4772
+ buttonName += "<a class='fa-solid " + (instance ? "fa-bars-staggered" : " ") + " menu'></a>";
4659
4773
 
4660
4774
  let buttonEl = this.addButton(null, buttonName, (value, event) => {
4661
4775
  if( instance )
4662
4776
  {
4663
4777
  element.querySelector(".lexcustomitems").toggleAttribute('hidden');
4778
+ element.dataset["opened"] = !element.querySelector(".lexcustomitems").hasAttribute("hidden");
4664
4779
  }
4665
4780
  else
4666
4781
  {
@@ -4669,6 +4784,7 @@ function ADD_CUSTOM_WIDGET( customWidgetName, options = {} )
4669
4784
  instance = {};
4670
4785
  refresh_widget();
4671
4786
  element.querySelector(".lexcustomitems").toggleAttribute('hidden', false);
4787
+ element.dataset["opened"] = !element.querySelector(".lexcustomitems").hasAttribute("hidden");
4672
4788
  });
4673
4789
  });
4674
4790
  }
@@ -4783,7 +4899,7 @@ class NodeTree {
4783
4899
  _createItem( parent, node, level = 0, selectedId ) {
4784
4900
 
4785
4901
  const that = this;
4786
- const nodeFilterInput = this.domEl.querySelector( "#lexnodetree_filter" );
4902
+ const nodeFilterInput = this.domEl.querySelector( ".lexnodetree_filter" );
4787
4903
 
4788
4904
  node.children = node.children ?? [];
4789
4905
  if( nodeFilterInput && nodeFilterInput.value != "" && !node.id.includes( nodeFilterInput.value ) )
@@ -5362,14 +5478,7 @@ class TextInput extends Widget {
5362
5478
 
5363
5479
  this._lastValueTriggered = value = newValue;
5364
5480
 
5365
- if( options.disabled )
5366
- {
5367
- wValue.innerText = newValue;
5368
- }
5369
- else
5370
- {
5371
- wValue.value = newValue;
5372
- }
5481
+ wValue.value = newValue;
5373
5482
 
5374
5483
  if( !skipCallback )
5375
5484
  {
@@ -5390,21 +5499,18 @@ class TextInput extends Widget {
5390
5499
  };
5391
5500
 
5392
5501
  let container = document.createElement( 'div' );
5393
- container.className = "lextext" + ( options.warning ? " lexwarning" : "" );
5502
+ container.className = ( options.warning ? " lexwarning" : "" );
5394
5503
  container.style.display = "flex";
5504
+ container.style.position = "relative";
5395
5505
  this.root.appendChild( container );
5396
5506
 
5397
- if( options.textClass )
5398
- {
5399
- container.classList.add( options.textClass );
5400
- }
5401
-
5402
5507
  this.disabled = ( options.disabled || options.warning ) ?? ( options.url ? true : false );
5403
5508
  let wValue = null;
5404
5509
 
5405
5510
  if( !this.disabled )
5406
5511
  {
5407
5512
  wValue = document.createElement( 'input' );
5513
+ wValue.className = "lextext " + ( options.inputClass ?? "" );
5408
5514
  wValue.type = options.type || "";
5409
5515
  wValue.value = wValue.iValue = value || "";
5410
5516
  wValue.style.width = "100%";
@@ -5451,27 +5557,36 @@ class TextInput extends Widget {
5451
5557
 
5452
5558
  if( options.icon )
5453
5559
  {
5560
+ wValue.style.paddingLeft = "1.75rem";
5454
5561
  let icon = document.createElement( 'a' );
5455
5562
  icon.className = "inputicon " + options.icon;
5456
5563
  container.appendChild( icon );
5457
5564
  }
5458
5565
 
5459
5566
  }
5460
- else
5567
+ else if( options.url )
5461
5568
  {
5462
- wValue = document.createElement( options.url ? 'a' : 'div' );
5463
-
5464
- if( options.url )
5465
- {
5466
- wValue.href = options.url;
5467
- wValue.target = "_blank";
5468
- }
5569
+ wValue = document.createElement( 'a' );
5570
+ wValue.href = options.url;
5571
+ wValue.target = "_blank";
5469
5572
 
5470
5573
  const icon = options.warning ? '<i class="fa-solid fa-triangle-exclamation"></i>' : '';
5471
5574
  wValue.innerHTML = ( icon + value ) || "";
5472
5575
  wValue.style.width = "100%";
5473
5576
  wValue.style.textAlign = options.float ?? "";
5474
- wValue.className = "ellipsis-overflow";
5577
+ wValue.className = "lextext ellipsis-overflow";
5578
+ }
5579
+ else
5580
+ {
5581
+ wValue = document.createElement( 'input' );
5582
+
5583
+ const icon = options.warning ? '<i class="fa-solid fa-triangle-exclamation"></i>' : '';
5584
+ wValue.disabled = true;
5585
+ wValue.innerHTML = icon;
5586
+ wValue.value = value;
5587
+ wValue.style.width = "100%";
5588
+ wValue.style.textAlign = options.float ?? "";
5589
+ wValue.className = "lextext ellipsis-overflow " + ( options.inputClass ?? "" );
5475
5590
  }
5476
5591
 
5477
5592
  Object.assign( wValue.style, options.style ?? {} );
@@ -5481,7 +5596,7 @@ class TextInput extends Widget {
5481
5596
  }
5482
5597
  }
5483
5598
 
5484
- LX.Text = Text;
5599
+ LX.TextInput = TextInput;
5485
5600
 
5486
5601
  /**
5487
5602
  * @class TextArea
@@ -5519,6 +5634,13 @@ class TextArea extends Widget {
5519
5634
  this.root.appendChild( container );
5520
5635
 
5521
5636
  let wValue = document.createElement( "textarea" );
5637
+
5638
+ if( !( options.resize ?? true ) )
5639
+ {
5640
+ wValue.style.resize = "none";
5641
+ }
5642
+
5643
+ wValue.className = ( options.inputClass ?? "" );
5522
5644
  wValue.value = wValue.iValue = value || "";
5523
5645
  wValue.style.width = "100%";
5524
5646
  wValue.style.textAlign = options.float ?? "";
@@ -5589,9 +5711,36 @@ class Button extends Widget {
5589
5711
  };
5590
5712
 
5591
5713
  this.onSetValue = ( newValue, skipCallback, event ) => {
5592
- wValue.innerHTML =
5593
- ( options.icon ? "<a class='" + options.icon + "'></a>" :
5594
- ( options.img ? "<img src='" + options.img + "'>" : "<span>" + ( newValue || "" ) + "</span>" ) );
5714
+
5715
+ wValue.innerHTML = `<span></span>`;
5716
+
5717
+ if( options.icon )
5718
+ {
5719
+ let icon = null;
5720
+
5721
+ // @legacy
5722
+ if( options.icon.includes( "fa-" ) )
5723
+ {
5724
+ icon = document.createElement( 'a' );
5725
+ icon.className = options.icon;
5726
+ }
5727
+ else
5728
+ {
5729
+ icon = LX.makeIcon( options.icon );
5730
+ }
5731
+
5732
+ wValue.prepend( icon );
5733
+ }
5734
+ else if( options.img )
5735
+ {
5736
+ let img = document.createElement( 'img' );
5737
+ img.src = options.img;
5738
+ wValue.prepend( img );
5739
+ }
5740
+ else
5741
+ {
5742
+ wValue.innerHTML = `<span>${ ( newValue || "" ) }</span>`;
5743
+ }
5595
5744
  };
5596
5745
 
5597
5746
  this.onResize = ( rect ) => {
@@ -5600,8 +5749,14 @@ class Button extends Widget {
5600
5749
  };
5601
5750
 
5602
5751
  var wValue = document.createElement( 'button' );
5603
- wValue.title = options.title ?? "";
5752
+ wValue.title = options.tooltip ? "" : ( options.title ?? "" );
5604
5753
  wValue.className = "lexbutton " + ( options.buttonClass ?? "" );
5754
+
5755
+ if( options.icon )
5756
+ {
5757
+ wValue.classList.add( "justify-center" );
5758
+ }
5759
+
5605
5760
  this.root.appendChild( wValue );
5606
5761
 
5607
5762
  if( options.selected )
@@ -5609,9 +5764,7 @@ class Button extends Widget {
5609
5764
  wValue.classList.add( "selected" );
5610
5765
  }
5611
5766
 
5612
- wValue.innerHTML =
5613
- ( options.icon ? "<a class='" + options.icon + "'></a>" :
5614
- ( options.img ? "<img src='" + options.img + "'>" : "<span>" + ( value || "" ) + "</span>" ) );
5767
+ this.onSetValue( value, true );
5615
5768
 
5616
5769
  if( options.disabled )
5617
5770
  {
@@ -5632,6 +5785,11 @@ class Button extends Widget {
5632
5785
  this._trigger( new IEvent( name, value, e ), callback );
5633
5786
  });
5634
5787
 
5788
+ if( options.tooltip )
5789
+ {
5790
+ LX.asTooltip( wValue, options.title ?? name );
5791
+ }
5792
+
5635
5793
  doAsync( this.onResize.bind( this ) );
5636
5794
  }
5637
5795
  }
@@ -5908,7 +6066,7 @@ class Form extends Widget {
5908
6066
  }
5909
6067
 
5910
6068
  entryData.placeholder = entryData.placeholder ?? entry;
5911
- entryData.width = "calc(100% - 10px)";
6069
+ entryData.width = "100%";
5912
6070
 
5913
6071
  // this.addLabel( entry, { textClass: "formlabel" } );
5914
6072
 
@@ -5938,7 +6096,7 @@ class Form extends Widget {
5938
6096
  {
5939
6097
  callback( container.formData, event );
5940
6098
  }
5941
- }, { buttonClass: "primary", width: "calc(100% - 10px)" } );
6099
+ }, { buttonClass: "primary" } );
5942
6100
 
5943
6101
  container.appendChild( submitButton.root );
5944
6102
  }
@@ -5981,7 +6139,7 @@ class Select extends Widget {
5981
6139
  // Reset filter
5982
6140
  if( filter )
5983
6141
  {
5984
- filter.querySelector( "input" ).value = "";
6142
+ filter.root.querySelector( "input" ).value = "";
5985
6143
  const filteredOptions = this._filterOptions( values, "" );
5986
6144
  list.refresh( filteredOptions );
5987
6145
  }
@@ -6008,7 +6166,7 @@ class Select extends Widget {
6008
6166
 
6009
6167
  // Add select widget button
6010
6168
  let buttonName = value;
6011
- buttonName += "<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>";
6169
+ buttonName += "<a class='fa-solid fa-angle-down'></a>";
6012
6170
 
6013
6171
  const _placeOptions = ( parent ) => {
6014
6172
 
@@ -6034,6 +6192,7 @@ class Select extends Widget {
6034
6192
  {
6035
6193
  const rect = nestedDialog.getBoundingClientRect();
6036
6194
  topPosition -= rect.y;
6195
+ maxY -= rect.y;
6037
6196
  }
6038
6197
 
6039
6198
  parent.style.top = ( topPosition + selectRoot.offsetHeight ) + 'px';
@@ -6099,7 +6258,7 @@ class Select extends Widget {
6099
6258
 
6100
6259
  if( filter )
6101
6260
  {
6102
- filter.querySelector( "input" ).focus();
6261
+ filter.root.querySelector( "input" ).focus();
6103
6262
  }
6104
6263
 
6105
6264
  }, { buttonClass: "array", skipInlineCount: true, disabled: options.disabled } );
@@ -6138,7 +6297,7 @@ class Select extends Widget {
6138
6297
  this.unfocus_event = true;
6139
6298
  setTimeout( () => delete this.unfocus_event, 200 );
6140
6299
  }
6141
- else if ( e.relatedTarget && e.relatedTarget.tagName == "INPUT" )
6300
+ else if ( e.relatedTarget && ( e.relatedTarget.tagName == "INPUT" || e.relatedTarget.classList.contains("lexoptions") ) )
6142
6301
  {
6143
6302
  return;
6144
6303
  }
@@ -6159,12 +6318,13 @@ class Select extends Widget {
6159
6318
  filterOptions.trigger = "input";
6160
6319
  filterOptions.icon = "fa-solid fa-magnifying-glass";
6161
6320
  filterOptions.className = "lexfilter";
6321
+ filterOptions.inputClass = "outline";
6162
6322
 
6163
- let filter = new TextInput(null, options.filterValue ?? "", ( v ) => {
6323
+ filter = new TextInput(null, options.filterValue ?? "", ( v ) => {
6164
6324
  const filteredOptions = this._filterOptions( values, v );
6165
6325
  list.refresh( filteredOptions );
6166
6326
  }, filterOptions );
6167
- filter.root.querySelector( ".lextext" ).classList.remove( "lextext" );
6327
+ filter.root.querySelector( ".lextext" ).style.border = "1px solid transparent";
6168
6328
 
6169
6329
  const input = filter.root.querySelector( "input" );
6170
6330
 
@@ -6185,12 +6345,12 @@ class Select extends Widget {
6185
6345
  list.appendChild( listOptions );
6186
6346
 
6187
6347
  // Add select options list
6188
- list.refresh = ( options ) => {
6348
+ list.refresh = ( currentOptions ) => {
6189
6349
 
6190
6350
  // Empty list
6191
6351
  listOptions.innerHTML = "";
6192
6352
 
6193
- if( !options.length )
6353
+ if( !currentOptions.length )
6194
6354
  {
6195
6355
  let iValue = options.emptyMsg ?? "No options found.";
6196
6356
 
@@ -6206,9 +6366,9 @@ class Select extends Widget {
6206
6366
  return;
6207
6367
  }
6208
6368
 
6209
- for( let i = 0; i < options.length; i++ )
6369
+ for( let i = 0; i < currentOptions.length; i++ )
6210
6370
  {
6211
- let iValue = options[ i ];
6371
+ let iValue = currentOptions[ i ];
6212
6372
  let li = document.createElement( "li" );
6213
6373
  let option = document.createElement( "div" );
6214
6374
  option.className = "option";
@@ -6533,13 +6693,15 @@ class ItemArray extends Widget {
6533
6693
  container.className = "lexarray";
6534
6694
  container.style.width = "100%";
6535
6695
  this.root.appendChild( container );
6696
+ this.root.dataset["opened"] = false;
6536
6697
 
6537
- const angleDown = `<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>`;
6698
+ const angleDown = `<a class='fa-solid fa-angle-down'></a>`;
6538
6699
 
6539
6700
  let buttonName = "Array (size " + values.length + ")";
6540
6701
  buttonName += angleDown;
6541
6702
 
6542
6703
  const toggleButton = new Button(null, buttonName, () => {
6704
+ this.root.dataset["opened"] = this.root.dataset["opened"] == "true" ? false : true;
6543
6705
  this.root.querySelector(".lexarrayitems").toggleAttribute('hidden');
6544
6706
  }, { buttonClass: 'array' });
6545
6707
  container.appendChild( toggleButton.root );
@@ -6603,7 +6765,7 @@ class ItemArray extends Widget {
6603
6765
  }
6604
6766
 
6605
6767
  buttonName = "Add item";
6606
- buttonName += "<a class='fa-solid fa-plus' style='float:right; margin-right: 3px; margin-top: 2px;'></a>";
6768
+ buttonName += "<a class='fa-solid fa-plus'></a>";
6607
6769
 
6608
6770
  const addButton = new Button(null, buttonName, (v, event) => {
6609
6771
  values.push( options.innerValues ? options.innerValues[ 0 ] : "" );
@@ -6853,7 +7015,7 @@ class Checkbox extends Widget {
6853
7015
 
6854
7016
  let checkbox = document.createElement( "input" );
6855
7017
  checkbox.type = "checkbox";
6856
- checkbox.className = "lexcheckbox " + ( options.className ?? "" );
7018
+ checkbox.className = "lexcheckbox " + ( options.className ?? "primary" );
6857
7019
  checkbox.checked = value;
6858
7020
  checkbox.disabled = options.disabled ?? false;
6859
7021
  container.appendChild( checkbox );
@@ -7074,8 +7236,7 @@ class ColorInput extends Widget {
7074
7236
  newValue = hexToRgb( newValue );
7075
7237
  }
7076
7238
 
7077
- // Means it was called from the color input listener, not the text
7078
- if( event )
7239
+ if( !this._skipTextUpdate )
7079
7240
  {
7080
7241
  textWidget.set( newValue, true, event );
7081
7242
  }
@@ -7101,9 +7262,8 @@ class ColorInput extends Widget {
7101
7262
  color.style.width = "32px";
7102
7263
  color.type = 'color';
7103
7264
  color.className = "colorinput";
7104
- color.id = "color" + simple_guidGenerator();
7105
7265
  color.useRGB = options.useRGB ?? false;
7106
- color.value = color.iValue = value;
7266
+ color.value = value;
7107
7267
  container.appendChild( color );
7108
7268
 
7109
7269
  if( options.disabled )
@@ -7116,8 +7276,10 @@ class ColorInput extends Widget {
7116
7276
  }, false );
7117
7277
 
7118
7278
  const textWidget = new TextInput( null, color.value, v => {
7279
+ this._skipTextUpdate = true;
7119
7280
  this.set( v );
7120
- }, { width: "calc( 100% - 32px )"});
7281
+ delete this._skipTextUpdate;
7282
+ }, { width: "calc( 100% - 32px )", disabled: options.disabled });
7121
7283
 
7122
7284
  textWidget.root.style.marginLeft = "4px";
7123
7285
  container.appendChild( textWidget.root );
@@ -7169,12 +7331,23 @@ class RangeInput extends Widget {
7169
7331
 
7170
7332
  let slider = document.createElement( 'input' );
7171
7333
  slider.className = "lexrangeslider " + ( options.className ?? "" );
7172
- slider.value = slider.iValue = value;
7173
7334
  slider.min = options.min ?? 0;
7174
7335
  slider.max = options.max ?? 100;
7175
7336
  slider.step = options.step ?? 1;
7176
7337
  slider.type = "range";
7177
7338
  slider.disabled = options.disabled ?? false;
7339
+
7340
+ if( value.constructor == Number )
7341
+ {
7342
+ value = clamp( value, +slider.min, +slider.max );
7343
+ }
7344
+
7345
+ if( options.left )
7346
+ {
7347
+ value = ( ( +slider.max ) - value + ( +slider.min ) );
7348
+ }
7349
+
7350
+ slider.value = value;
7178
7351
  container.appendChild( slider );
7179
7352
 
7180
7353
  if( options.left ?? false )
@@ -7213,11 +7386,6 @@ class RangeInput extends Widget {
7213
7386
  Widget._dispatchEvent( slider, "input", true );
7214
7387
  };
7215
7388
 
7216
- if( value.constructor == Number )
7217
- {
7218
- value = clamp( value, +slider.min, +slider.max );
7219
- }
7220
-
7221
7389
  doAsync( this.onResize.bind( this ) );
7222
7390
  }
7223
7391
  }
@@ -8139,7 +8307,7 @@ class FileInput extends Widget {
8139
8307
  {
8140
8308
  let settingsDialog = null;
8141
8309
 
8142
- const settingButton = new Button(null, "<a style='margin-top: 0px;' class='fa-solid fa-gear'></a>", () => {
8310
+ const settingButton = new Button(null, "", () => {
8143
8311
 
8144
8312
  if( settingsDialog )
8145
8313
  {
@@ -8151,7 +8319,7 @@ class FileInput extends Widget {
8151
8319
  p.addButton( null, "Reload", v => { input.dispatchEvent( new Event( 'change' ) ) } );
8152
8320
  }, { onclose: ( root ) => { root.remove(); settingsDialog = null; } } );
8153
8321
 
8154
- }, { className: "micro", skipInlineCount: true, title: "Settings" });
8322
+ }, { skipInlineCount: true, title: "Settings", disabled: options.disabled, icon: "fa-solid fa-gear" });
8155
8323
 
8156
8324
  this.root.appendChild( settingButton.root );
8157
8325
  }
@@ -8214,9 +8382,9 @@ class Tree extends Widget {
8214
8382
  if( options.filter )
8215
8383
  {
8216
8384
  nodeFilterInput = document.createElement('input');
8217
- nodeFilterInput.id = "lexnodetree_filter";
8385
+ nodeFilterInput.className = "lexnodetree_filter";
8218
8386
  nodeFilterInput.setAttribute("placeholder", "Filter..");
8219
- nodeFilterInput.style.width = "calc( 100% - 17px )";
8387
+ nodeFilterInput.style.width = "100%";
8220
8388
  nodeFilterInput.addEventListener('input', () => {
8221
8389
  this.innerTree.refresh();
8222
8390
  });
@@ -8366,11 +8534,11 @@ class Counter extends Widget {
8366
8534
  container.className = "lexcounter";
8367
8535
  this.root.appendChild( container );
8368
8536
 
8369
- const substrButton = new Button(null, "<a style='margin-top: 0px;' class='fa-solid fa-minus'></a>", ( value, e ) => {
8537
+ const substrButton = new Button(null, "", ( value, e ) => {
8370
8538
  let mult = step ?? 1;
8371
8539
  if( e.shiftKey ) mult *= 10;
8372
8540
  this.set( counterText.count - mult, false, e );
8373
- }, { className: "micro", skipInlineCount: true, title: "Minus" });
8541
+ }, { skipInlineCount: true, title: "Minus", icon: "fa-solid fa-minus" });
8374
8542
 
8375
8543
  container.appendChild( substrButton.root );
8376
8544
 
@@ -8392,11 +8560,11 @@ class Counter extends Widget {
8392
8560
  containerBox.appendChild( counterLabel );
8393
8561
  }
8394
8562
 
8395
- const addButton = new Button(null, "<a style='margin-top: 0px;' class='fa-solid fa-plus'></a>", ( value, e ) => {
8563
+ const addButton = new Button(null, "", ( value, e ) => {
8396
8564
  let mult = step ?? 1;
8397
8565
  if( e.shiftKey ) mult *= 10;
8398
8566
  this.set( counterText.count + mult, false, e );
8399
- }, { className: "micro", skipInlineCount: true, title: "Plus" });
8567
+ }, { skipInlineCount: true, title: "Plus", icon: "fa-solid fa-plus" });
8400
8568
  container.appendChild( addButton.root );
8401
8569
  }
8402
8570
  }
@@ -8459,7 +8627,7 @@ class Table extends Widget {
8459
8627
  // Append header
8460
8628
  if( this.filter || this.customFilters || this.toggleColumns )
8461
8629
  {
8462
- const headerContainer = LX.makeContainer( [ "100%", "auto" ] );
8630
+ const headerContainer = LX.makeContainer( [ "100%", "auto" ], "flex flex-row" );
8463
8631
 
8464
8632
  if( this.filter )
8465
8633
  {
@@ -8467,7 +8635,7 @@ class Table extends Widget {
8467
8635
  filterOptions.placeholder = `Filter ${ this.filter }...`;
8468
8636
  filterOptions.skipWidget = true;
8469
8637
  filterOptions.trigger = "input";
8470
- filterOptions.textClass = "outline";
8638
+ filterOptions.inputClass = "outline";
8471
8639
 
8472
8640
  let filter = new TextInput(null, "", ( v ) => {
8473
8641
  this._currentFilter = v;
@@ -8500,7 +8668,7 @@ class Table extends Widget {
8500
8668
  return item;
8501
8669
  } );
8502
8670
  new DropdownMenu( customFilterBtn.root, menuOptions, { side: "bottom", align: "start" });
8503
- }, { buttonClass: "dashed" } );
8671
+ }, { buttonClass: " primary dashed" } );
8504
8672
  headerContainer.appendChild( customFilterBtn.root );
8505
8673
  }
8506
8674
 
@@ -8575,7 +8743,7 @@ class Table extends Widget {
8575
8743
  th.style.width = "0px";
8576
8744
  const input = document.createElement( 'input' );
8577
8745
  input.type = "checkbox";
8578
- input.className = "lexcheckbox";
8746
+ input.className = "lexcheckbox accent";
8579
8747
  input.checked = data.checkMap[ ":root" ] ?? false;
8580
8748
  th.appendChild( input );
8581
8749
 
@@ -8742,7 +8910,7 @@ class Table extends Widget {
8742
8910
 
8743
8911
  const row = document.createElement( 'tr' );
8744
8912
  const rowId = LX.getSupportedDOMName( bodyData.join( '-' ) );
8745
- row.setAttribute( "rowId", rowId.substr(0, 16) );
8913
+ row.setAttribute( "rowId", rowId.substr(0, 32) );
8746
8914
 
8747
8915
  if( options.sortable )
8748
8916
  {
@@ -8793,7 +8961,7 @@ class Table extends Widget {
8793
8961
  const td = document.createElement( 'td' );
8794
8962
  const input = document.createElement( 'input' );
8795
8963
  input.type = "checkbox";
8796
- input.className = "lexcheckbox";
8964
+ input.className = "lexcheckbox accent";
8797
8965
  input.checked = data.checkMap[ rowId ];
8798
8966
  td.appendChild( input );
8799
8967
 
@@ -8940,7 +9108,7 @@ class Panel {
8940
9108
  root.className += " " + options.className;
8941
9109
  }
8942
9110
 
8943
- root.style.width = options.width || "calc( 100% - 6px )";
9111
+ root.style.width = options.width || "100%";
8944
9112
  root.style.height = options.height || "100%";
8945
9113
  Object.assign( root.style, options.style ?? {} );
8946
9114
 
@@ -9055,10 +9223,11 @@ class Panel {
9055
9223
 
9056
9224
  /**
9057
9225
  * @method endLine
9226
+ * @param {String} className Extra class to customize inline widgets parent container
9058
9227
  * @description Stop inlining widgets. Use it only if the number of widgets to be inlined is NOT specified.
9059
9228
  */
9060
9229
 
9061
- endLine( justifyContent ) {
9230
+ endLine( className ) {
9062
9231
 
9063
9232
  if( this._inlineWidgetsLeft == -1 )
9064
9233
  {
@@ -9073,9 +9242,9 @@ class Panel {
9073
9242
  this._inlineContainer = document.createElement('div');
9074
9243
  this._inlineContainer.className = "lexinlinewidgets";
9075
9244
 
9076
- if( justifyContent )
9245
+ if( className )
9077
9246
  {
9078
- this._inlineContainer.style.justifyContent = justifyContent;
9247
+ this._inlineContainer.className += ` ${ className }`;
9079
9248
  }
9080
9249
  }
9081
9250
 
@@ -9218,7 +9387,7 @@ class Panel {
9218
9387
  }
9219
9388
  else
9220
9389
  {
9221
- el.classList.add("nobranch");
9390
+ el.className += " nobranch w-full";
9222
9391
  this.root.appendChild( el );
9223
9392
  }
9224
9393
  }
@@ -9282,7 +9451,7 @@ class Panel {
9282
9451
  let input = document.createElement('input');
9283
9452
  input.className = 'lexinput-filter';
9284
9453
  input.setAttribute( "placeholder", options.placeholder );
9285
- input.style.width = "calc( 100% - 17px )";
9454
+ input.style.width = "100%";
9286
9455
  input.value = options.filterValue || "";
9287
9456
 
9288
9457
  let searchIcon = document.createElement('a');
@@ -9457,9 +9626,11 @@ class Panel {
9457
9626
  * disabled: Make the widget disabled [false]
9458
9627
  * required: Make the input required
9459
9628
  * placeholder: Add input placeholder
9629
+ * icon: Icon (if any) to append at the input start
9460
9630
  * pattern: Regular expression that value must match
9461
9631
  * trigger: Choose onchange trigger (default, input) [default]
9462
9632
  * inputWidth: Width of the text input
9633
+ * inputClass: Class to add to the native input element
9463
9634
  * skipReset: Don't add the reset value button when value changes
9464
9635
  * float: Justify input text content
9465
9636
  * justifyName: Justify name content
@@ -9479,6 +9650,7 @@ class Panel {
9479
9650
  * hideName: Don't use name as label [false]
9480
9651
  * disabled: Make the widget disabled [false]
9481
9652
  * placeholder: Add input placeholder
9653
+ * resize: Allow resize [true]
9482
9654
  * trigger: Choose onchange trigger (default, input) [default]
9483
9655
  * inputWidth: Width of the text input
9484
9656
  * float: Justify input text content
@@ -9499,6 +9671,7 @@ class Panel {
9499
9671
 
9500
9672
  addLabel( value, options = {} ) {
9501
9673
  options.disabled = true;
9674
+ options.inputClass = ( options.inputClass ?? "" ) + " nobg";
9502
9675
  const widget = this.addText( null, value, null, options );
9503
9676
  widget.type = Widget.LABEL;
9504
9677
  return widget;
@@ -9515,6 +9688,7 @@ class Panel {
9515
9688
  * icon: Icon class to show as button value
9516
9689
  * img: Path to image to show as button value
9517
9690
  * title: Text to show in native Element title
9691
+ * buttonClass: Class to add to the native button element
9518
9692
  */
9519
9693
 
9520
9694
  addButton( name, value, callback, options = {} ) {
@@ -10054,7 +10228,6 @@ class Branch {
10054
10228
  root.className += " " + options.className;
10055
10229
  }
10056
10230
 
10057
- root.style.width = "calc(100% - 7px)";
10058
10231
  root.style.margin = "0 auto";
10059
10232
 
10060
10233
  var that = this;
@@ -10092,7 +10265,7 @@ class Branch {
10092
10265
  this.grabber.setAttribute( "hidden", true );
10093
10266
  doAsync( () => {
10094
10267
  this.content.setAttribute( "hidden", true );
10095
- }, 15 );
10268
+ }, 10 );
10096
10269
  }
10097
10270
 
10098
10271
  this.onclick = function( e ) {
@@ -10242,6 +10415,7 @@ class Branch {
10242
10415
  let value = element.children[ 1 ];
10243
10416
 
10244
10417
  name.style.width = size;
10418
+ name.style.minWidth = size;
10245
10419
 
10246
10420
  switch( widget.type )
10247
10421
  {
@@ -10276,9 +10450,13 @@ class Footer {
10276
10450
  root.className = "lexfooter";
10277
10451
 
10278
10452
  const wrapper = document.createElement( "div" );
10279
- wrapper.className = "wrapper";
10453
+ wrapper.style.minHeight = "48px";
10454
+ wrapper.className = "w-full";
10280
10455
  root.appendChild( wrapper );
10281
10456
 
10457
+ // const hr = document.createElement( "hr" );
10458
+ // wrapper.appendChild( hr );
10459
+
10282
10460
  if( options.columns && options.columns.constructor == Array )
10283
10461
  {
10284
10462
  const cols = document.createElement( "div" );
@@ -10315,9 +10493,6 @@ class Footer {
10315
10493
 
10316
10494
  if( options.credits || options.socials )
10317
10495
  {
10318
- const hr = document.createElement( "hr" );
10319
- wrapper.appendChild( hr );
10320
-
10321
10496
  const creditsSocials = document.createElement( "div" );
10322
10497
  creditsSocials.className = "credits-and-socials";
10323
10498
  wrapper.appendChild( creditsSocials );
@@ -10351,6 +10526,10 @@ class Footer {
10351
10526
  // Append directly to body
10352
10527
  const parent = options.parent ?? document.body;
10353
10528
  parent.appendChild( root );
10529
+
10530
+ // Set always at bottom
10531
+ root.previousElementSibling.style.height = "unset";
10532
+ root.previousElementSibling.style.flexGrow = "1";
10354
10533
  }
10355
10534
 
10356
10535
  }
@@ -10549,7 +10728,6 @@ class Dialog {
10549
10728
  root.style.left = position[ 0 ] ?? "50%";
10550
10729
  root.style.top = position[ 1 ] ?? "50%";
10551
10730
 
10552
- panel.root.style.width = "calc( 100% - 30px )";
10553
10731
  panel.root.style.height = title ? "calc( 100% - " + ( titleDiv.offsetHeight + 30 ) + "px )" : "calc( 100% - 51px )";
10554
10732
  }
10555
10733
 
@@ -10621,8 +10799,8 @@ class PocketDialog extends Dialog {
10621
10799
  this.root.style.top = dragMargin + "px";
10622
10800
  }
10623
10801
 
10624
- this.panel.root.style.width = "calc( 100% - 12px )";
10625
- this.panel.root.style.height = "calc( 100% - 40px )";
10802
+ this.panel.root.style.width = "100%";
10803
+ this.panel.root.style.height = "100%";
10626
10804
  this.dock_pos = PocketDialog.TOP;
10627
10805
 
10628
10806
  this.minimized = false;
@@ -11023,8 +11201,8 @@ class CanvasCurve {
11023
11201
  element.style.minHeight = "20px";
11024
11202
 
11025
11203
  element.bgcolor = options.bgColor || LX.getThemeColor( "global-intense-background" );
11026
- element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected" );
11027
- element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-selected-light" );
11204
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-color-accent" );
11205
+ element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-color-accent-light" );
11028
11206
  element.linecolor = options.lineColor || "#555";
11029
11207
  element.value = value || [];
11030
11208
  element.xrange = options.xrange || [ 0, 1 ]; // min, max
@@ -11040,8 +11218,8 @@ class CanvasCurve {
11040
11218
 
11041
11219
  LX.addSignal( "@on_new_color_scheme", (el, value) => {
11042
11220
  element.bgcolor = options.bgColor || LX.getThemeColor( "global-intense-background" );
11043
- element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected" );
11044
- element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-selected-light" );
11221
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-color-accent" );
11222
+ element.activepointscolor = options.activePointsColor || LX.getThemeColor( "global-color-accent-light" );
11045
11223
  this.redraw();
11046
11224
  } );
11047
11225
 
@@ -11370,7 +11548,7 @@ class CanvasDial {
11370
11548
  element.style.minWidth = element.style.minHeight = "50px";
11371
11549
 
11372
11550
  element.bgcolor = options.bgColor || LX.getThemeColor( "global-dark-background" );
11373
- element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected-light" );
11551
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-color-accent-light" );
11374
11552
  element.linecolor = options.lineColor || "#555";
11375
11553
  element.value = value || [];
11376
11554
  element.xrange = options.xrange || [ 0, 1 ]; // min, max
@@ -12028,11 +12206,15 @@ class AssetView {
12028
12206
  this.rightPanel.sameLine();
12029
12207
  this.rightPanel.addSelect( "Filter", this.allowedTypes, this.allowedTypes[ 0 ], v => this._refreshContent.call(this, null, v), { width: "30%", minWidth: "128px" } );
12030
12208
  this.rightPanel.addText( null, this.searchValue ?? "", v => this._refreshContent.call(this, v, null), { placeholder: "Search assets.." } );
12031
- this.rightPanel.addButton( null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { className: "micro", title: "Sort" } );
12032
- this.rightPanel.addButton( null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { className: "micro", title: "View" } );
12209
+ this.rightPanel.addButton( null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { title: "Sort" } );
12210
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { title: "View" } );
12033
12211
  // Content Pages
12034
- this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-left'></a>", on_change_page.bind(this, -1), { className: "micro", title: "Previous Page" } );
12035
- this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-right'></a>", on_change_page.bind(this, 1), { className: "micro", title: "Next Page" } );
12212
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-left'></a>", on_change_page.bind(this, -1), { title: "Previous Page", className: "ml-auto" } );
12213
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-right'></a>", on_change_page.bind(this, 1), { title: "Next Page" } );
12214
+ const textString = "Page " + this.contentPage + " / " + ((((this.currentData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1);
12215
+ this.rightPanel.addText(null, textString, null, {
12216
+ inputClass: "nobg", disabled: true, signal: "@on_page_change", maxWidth: "16ch" }
12217
+ );
12036
12218
  this.rightPanel.endLine();
12037
12219
 
12038
12220
  if( !this.skipBrowser )
@@ -12066,9 +12248,13 @@ class AssetView {
12066
12248
  icon: "fa-solid fa-arrows-rotate",
12067
12249
  callback: domEl => { this._refreshContent(); }
12068
12250
  }
12069
- ], { width: "20%", minWidth: "164px", noSelection: true } );
12070
- this.rightPanel.addText(null, this.path.join('/'), null, { width: "70%", maxWidth: "calc(70% - 64px)", minWidth: "164px", disabled: true, signal: "@on_folder_change", style: { fontWeight: "bolder", fontSize: "16px", color: "#aaa" } });
12071
- this.rightPanel.addText(null, "Page " + this.contentPage + " / " + ((((this.currentData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1), null, {disabled: true, signal: "@on_page_change", width: "fit-content"})
12251
+ ], { noSelection: true } );
12252
+
12253
+ this.rightPanel.addText(null, this.path.join('/'), null, {
12254
+ inputClass: "nobg", disabled: true, signal: "@on_folder_change",
12255
+ style: { fontWeight: "600", fontSize: "15px" }
12256
+ });
12257
+
12072
12258
  this.rightPanel.endLine();
12073
12259
  }
12074
12260
 
@@ -12346,7 +12532,9 @@ class AssetView {
12346
12532
  }
12347
12533
 
12348
12534
  this.allowNextPage = filteredData.length - 1 > AssetView.MAX_PAGE_ELEMENTS;
12349
- LX.emit("@on_page_change", "Page " + this.contentPage + " / " + ((((filteredData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1));
12535
+
12536
+ const textString = "Page " + this.contentPage + " / " + ((((filteredData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1);
12537
+ LX.emit( "@on_page_change", textString );
12350
12538
 
12351
12539
  if( this.onRefreshContent )
12352
12540
  {
@@ -12640,44 +12828,44 @@ Object.assign(LX, {
12640
12828
  * Request file from url
12641
12829
  * @method requestText
12642
12830
  * @param {String} url
12643
- * @param {Function} on_complete
12644
- * @param {Function} on_error
12831
+ * @param {Function} onComplete
12832
+ * @param {Function} onError
12645
12833
  **/
12646
- requestText(url, on_complete, on_error ) {
12647
- return this.request({ url: url, dataType:"text", success: on_complete, error: on_error });
12834
+ requestText( url, onComplete, onError ) {
12835
+ return this.request({ url: url, dataType:"text", success: onComplete, error: onError });
12648
12836
  },
12649
12837
 
12650
12838
  /**
12651
12839
  * Request file from url
12652
12840
  * @method requestJSON
12653
12841
  * @param {String} url
12654
- * @param {Function} on_complete
12655
- * @param {Function} on_error
12842
+ * @param {Function} onComplete
12843
+ * @param {Function} onError
12656
12844
  **/
12657
- requestJSON(url, on_complete, on_error ) {
12658
- return this.request({ url: url, dataType:"json", success: on_complete, error: on_error });
12845
+ requestJSON( url, onComplete, onError ) {
12846
+ return this.request({ url: url, dataType:"json", success: onComplete, error: onError });
12659
12847
  },
12660
12848
 
12661
12849
  /**
12662
12850
  * Request binary file from url
12663
12851
  * @method requestBinary
12664
12852
  * @param {String} url
12665
- * @param {Function} on_complete
12666
- * @param {Function} on_error
12853
+ * @param {Function} onComplete
12854
+ * @param {Function} onError
12667
12855
  **/
12668
- requestBinary(url, on_complete, on_error ) {
12669
- return this.request({ url: url, dataType:"binary", success: on_complete, error: on_error });
12856
+ requestBinary( url, onComplete, onError ) {
12857
+ return this.request({ url: url, dataType:"binary", success: onComplete, error: onError });
12670
12858
  },
12671
12859
 
12672
12860
  /**
12673
12861
  * Request script and inserts it in the DOM
12674
12862
  * @method requireScript
12675
12863
  * @param {String|Array} url the url of the script or an array containing several urls
12676
- * @param {Function} on_complete
12677
- * @param {Function} on_error
12678
- * @param {Function} on_progress (if several files are required, on_progress is called after every file is added to the DOM)
12864
+ * @param {Function} onComplete
12865
+ * @param {Function} onError
12866
+ * @param {Function} onProgress (if several files are required, onProgress is called after every file is added to the DOM)
12679
12867
  **/
12680
- requireScript(url, on_complete, on_error, on_progress, version ) {
12868
+ requireScript( url, onComplete, onError, onProgress, version ) {
12681
12869
 
12682
12870
  if(!url)
12683
12871
  throw("invalid URL");
@@ -12702,15 +12890,17 @@ Object.assign(LX, {
12702
12890
  loaded_scripts.push(this);
12703
12891
  if(total)
12704
12892
  {
12705
- if(on_progress)
12706
- on_progress(this.original_src, this.num);
12893
+ if( onProgress )
12894
+ {
12895
+ onProgress( this.original_src, this.num );
12896
+ }
12707
12897
  }
12708
- else if(on_complete)
12709
- on_complete( loaded_scripts );
12898
+ else if(onComplete)
12899
+ onComplete( loaded_scripts );
12710
12900
  };
12711
- if(on_error)
12901
+ if(onError)
12712
12902
  script.onerror = function(err) {
12713
- on_error(err, this.original_src, this.num );
12903
+ onError(err, this.original_src, this.num );
12714
12904
  }
12715
12905
  document.getElementsByTagName('head')[0].appendChild(script);
12716
12906
  }
@@ -12799,10 +12989,11 @@ Element.prototype.addClass = function( className ) {
12799
12989
  }
12800
12990
 
12801
12991
  Element.prototype.getComputedSize = function() {
12802
- const cs = getComputedStyle( this );
12992
+ // Since we use "box-sizing: border-box" now,
12993
+ // it's all included in offsetWidth/offsetHeight
12803
12994
  return {
12804
- width: this.offsetWidth + cs.getPropertyValue('marginLeft') + cs.getPropertyValue('marginRight'),
12805
- height: this.offsetHeight + cs.getPropertyValue('marginTop') + cs.getPropertyValue('marginBottom')
12995
+ width: this.offsetWidth,
12996
+ height: this.offsetHeight
12806
12997
  }
12807
12998
  }
12808
12999
 
@@ -12814,6 +13005,18 @@ Element.prototype.getParentArea = function() {
12814
13005
  }
12815
13006
  }
12816
13007
 
13008
+ Element.prototype.listen = function( eventName, callback, callbackName ) {
13009
+ callbackName = callbackName ?? ( "_on" + eventName );
13010
+ this[ callbackName ] = callback;
13011
+ this.addEventListener( eventName, callback );
13012
+ }
13013
+
13014
+ Element.prototype.ignore = function( eventName, callbackName ) {
13015
+ callbackName = callbackName ?? ( "_on" + eventName );
13016
+ const callback = this[ callbackName ];
13017
+ this.removeEventListener( eventName, callback );
13018
+ }
13019
+
12817
13020
  LX.UTILS = {
12818
13021
  getTime() { return new Date().getTime() },
12819
13022
  compareThreshold( v, p, n, t ) { return Math.abs(v - p) >= t || Math.abs(v - n) >= t },
@@ -12914,6 +13117,7 @@ LX.ICONS = {
12914
13117
  "edit": [512, 512, [], "regular", "M441 58.9L453.1 71c9.4 9.4 9.4 24.6 0 33.9L424 134.1 377.9 88 407 58.9c9.4-9.4 24.6-9.4 33.9 0zM209.8 256.2L344 121.9 390.1 168 255.8 302.2c-2.9 2.9-6.5 5-10.4 6.1l-58.5 16.7 16.7-58.5c1.1-3.9 3.2-7.5 6.1-10.4zM373.1 25L175.8 222.2c-8.7 8.7-15 19.4-18.3 31.1l-28.6 100c-2.4 8.4-.1 17.4 6.1 23.6s15.2 8.5 23.6 6.1l100-28.6c11.8-3.4 22.5-9.7 31.1-18.3L487 138.9c28.1-28.1 28.1-73.7 0-101.8L474.9 25C446.8-3.1 401.2-3.1 373.1 25zM88 64C39.4 64 0 103.4 0 152L0 424c0 48.6 39.4 88 88 88l272 0c48.6 0 88-39.4 88-88l0-112c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 112c0 22.1-17.9 40-40 40L88 464c-22.1 0-40-17.9-40-40l0-272c0-22.1 17.9-40 40-40l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24L88 64z"],
12915
13118
  "envelope": [512, 512, [], "regular", "M64 112c-8.8 0-16 7.2-16 16l0 22.1L220.5 291.7c20.7 17 50.4 17 71.1 0L464 150.1l0-22.1c0-8.8-7.2-16-16-16L64 112zM48 212.2L48 384c0 8.8 7.2 16 16 16l384 0c8.8 0 16-7.2 16-16l0-171.8L322 328.8c-38.4 31.5-93.7 31.5-132 0L48 212.2zM0 128C0 92.7 28.7 64 64 64l384 0c35.3 0 64 28.7 64 64l0 256c0 35.3-28.7 64-64 64L64 448c-35.3 0-64-28.7-64-64L0 128z"],
12916
13119
  "envelope-open": [512, 512, [], "regular", "M255.4 48.2c.2-.1 .4-.2 .6-.2s.4 .1 .6 .2L460.6 194c2.1 1.5 3.4 3.9 3.4 6.5l0 13.6L291.5 355.7c-20.7 17-50.4 17-71.1 0L48 214.1l0-13.6c0-2.6 1.2-5 3.4-6.5L255.4 48.2zM48 276.2L190 392.8c38.4 31.5 93.7 31.5 132 0L464 276.2 464 456c0 4.4-3.6 8-8 8L56 464c-4.4 0-8-3.6-8-8l0-179.8zM256 0c-10.2 0-20.2 3.2-28.5 9.1L23.5 154.9C8.7 165.4 0 182.4 0 200.5L0 456c0 30.9 25.1 56 56 56l400 0c30.9 0 56-25.1 56-56l0-255.5c0-18.1-8.7-35.1-23.4-45.6L284.5 9.1C276.2 3.2 266.2 0 256 0z"],
13120
+ "inbox": [24, 24, [], "regular", "M22 12H16l-2 3h-4l-2-3H2M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11Z", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
12917
13121
  "map": [576, 512, [], "regular", "M565.6 36.2C572.1 40.7 576 48.1 576 56l0 336c0 10-6.2 18.9-15.5 22.4l-168 64c-5.2 2-10.9 2.1-16.1 .3L192.5 417.5l-160 61c-7.4 2.8-15.7 1.8-22.2-2.7S0 463.9 0 456L0 120c0-10 6.1-18.9 15.5-22.4l168-64c5.2-2 10.9-2.1 16.1-.3L383.5 94.5l160-61c7.4-2.8 15.7-1.8 22.2 2.7zM48 136.5l0 284.6 120-45.7 0-284.6L48 136.5zM360 422.7l0-285.4-144-48 0 285.4 144 48zm48-1.5l120-45.7 0-284.6L408 136.5l0 284.6z"],
12918
13122
  "note-sticky": [448, 512, ["sticky-note"], "regular", "M64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l224 0 0-80c0-17.7 14.3-32 32-32l80 0 0-224c0-8.8-7.2-16-16-16L64 80zM288 480L64 480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 224 0 5.5c0 17-6.7 33.3-18.7 45.3l-90.5 90.5c-12 12-28.3 18.7-45.3 18.7l-5.5 0z"],
12919
13123
  "file": [384, 512, [], "regular", "M320 464c8.8 0 16-7.2 16-16l0-288-80 0c-17.7 0-32-14.3-32-32l0-80L64 48c-8.8 0-16 7.2-16 16l0 384c0 8.8 7.2 16 16 16l256 0zM0 64C0 28.7 28.7 0 64 0L229.5 0c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3L384 448c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 64z"],
@@ -12921,7 +13125,10 @@ LX.ICONS = {
12921
13125
  "file-code": [384, 512, [], "regular", "M64 464c-8.8 0-16-7.2-16-16L48 64c0-8.8 7.2-16 16-16l160 0 0 80c0 17.7 14.3 32 32 32l80 0 0 288c0 8.8-7.2 16-16 16L64 464zM64 0C28.7 0 0 28.7 0 64L0 448c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-293.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0L64 0zm97 289c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L79 303c-9.4 9.4-9.4 24.6 0 33.9l48 48c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-31-31 31-31zM257 255c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l31 31-31 31c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l48-48c9.4-9.4 9.4-24.6 0-33.9l-48-48z"],
12922
13126
  "file-zip": [384, 512, [], "regular", "M64 464c-8.8 0-16-7.2-16-16L48 64c0-8.8 7.2-16 16-16l48 0c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l48 0 0 80c0 17.7 14.3 32 32 32l80 0 0 288c0 8.8-7.2 16-16 16L64 464zM64 0C28.7 0 0 28.7 0 64L0 448c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-293.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0L64 0zm48 112c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm0 64c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm-6.3 71.8L82.1 335.9c-1.4 5.4-2.1 10.9-2.1 16.4c0 35.2 28.8 63.7 64 63.7s64-28.5 64-63.7c0-5.5-.7-11.1-2.1-16.4l-23.5-88.2c-3.7-14-16.4-23.8-30.9-23.8l-14.8 0c-14.5 0-27.2 9.7-30.9 23.8zM128 336l32 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-32 0c-8.8 0-16-7.2-16-16s7.2-16 16-16z"],
12923
13127
  "file-pdf": [512, 512, [], "regular", "M64 464l48 0 0 48-48 0c-35.3 0-64-28.7-64-64L0 64C0 28.7 28.7 0 64 0L229.5 0c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3L384 304l-48 0 0-144-80 0c-17.7 0-32-14.3-32-32l0-80L64 48c-8.8 0-16 7.2-16 16l0 384c0 8.8 7.2 16 16 16zM176 352l32 0c30.9 0 56 25.1 56 56s-25.1 56-56 56l-16 0 0 32c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-48 0-80c0-8.8 7.2-16 16-16zm32 80c13.3 0 24-10.7 24-24s-10.7-24-24-24l-16 0 0 48 16 0zm96-80l32 0c26.5 0 48 21.5 48 48l0 64c0 26.5-21.5 48-48 48l-32 0c-8.8 0-16-7.2-16-16l0-128c0-8.8 7.2-16 16-16zm32 128c8.8 0 16-7.2 16-16l0-64c0-8.8-7.2-16-16-16l-16 0 0 96 16 0zm80-112c0-8.8 7.2-16 16-16l48 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-32 0 0 32 32 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-32 0 0 48c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-64 0-64z"],
13128
+ "box-archive": [24, 24, [], "regular", "M2 3a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H2V3Zm2 5h16v11a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8Zm6 4h4", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
13129
+ "box-archive-x": [24, 24, [], "regular", "M3 3h18a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1ZM4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8M9.5 17l5-5m-5-0l5 5", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
12924
13130
  "scroll": [576, 512, ["script"], "solid", "M0 80l0 48c0 17.7 14.3 32 32 32l16 0 48 0 0-80c0-26.5-21.5-48-48-48S0 53.5 0 80zM112 32c10 13.4 16 30 16 48l0 304c0 35.3 28.7 64 64 64s64-28.7 64-64l0-5.3c0-32.4 26.3-58.7 58.7-58.7L480 320l0-192c0-53-43-96-96-96L112 32zM464 480c61.9 0 112-50.1 112-112c0-8.8-7.2-16-16-16l-245.3 0c-14.7 0-26.7 11.9-26.7 26.7l0 5.3c0 53-43 96-96 96l176 0 96 0z"],
13131
+ "paper-plane": [512, 512, [], "", "M16.1 260.2c-22.6 12.9-20.5 47.3 3.6 57.3L160 376l0 103.3c0 18.1 14.6 32.7 32.7 32.7c9.7 0 18.9-4.3 25.1-11.8l62-74.3 123.9 51.6c18.9 7.9 40.8-4.5 43.9-24.7l64-416c1.9-12.1-3.4-24.3-13.5-31.2s-23.3-7.5-34-1.4l-448 256zm52.1 25.5L409.7 90.6 190.1 336l1.2 1L68.2 285.7zM403.3 425.4L236.7 355.9 450.8 116.6 403.3 425.4z"],
12925
13132
  "floppy-disk": [448, 512, ["save"], "regular", "M48 96l0 320c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 16-16l0-245.5c0-4.2-1.7-8.3-4.7-11.3l33.9-33.9c12 12 18.7 28.3 18.7 45.3L448 416c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l245.5 0c17 0 33.3 6.7 45.3 18.7l74.5 74.5-33.9 33.9L320.8 84.7c-.3-.3-.5-.5-.8-.8L320 184c0 13.3-10.7 24-24 24l-192 0c-13.3 0-24-10.7-24-24L80 80 64 80c-8.8 0-16 7.2-16 16zm80-16l0 80 144 0 0-80L128 80zm32 240a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z"],
12926
13133
  "download": [512, 512, [], "solid", "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 242.7-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7 288 32zM64 352c-35.3 0-64 28.7-64 64l0 32c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-32c0-35.3-28.7-64-64-64l-101.5 0-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352 64 352zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"],
12927
13134
  "upload": [512, 512, [], "solid", "M288 109.3L288 352c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-242.7-73.4 73.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l128-128c12.5-12.5 32.8-12.5 45.3 0l128 128c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L288 109.3zM64 352l128 0c0 35.3 28.7 64 64 64s64-28.7 64-64l128 0c35.3 0 64 28.7 64 64l0 32c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64l0-32c0-35.3 28.7-64 64-64zM432 456a24 24 0 1 0 0-48 24 24 0 1 0 0 48z"],
@@ -12931,6 +13138,7 @@ LX.ICONS = {
12931
13138
  "eye": [576, 512, [], "regular", "M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256c13.6 30 40.2 72.5 78.6 108.3C169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6zM288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80c-.7 0-1.3 0-2 0c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2c0 .7 0 1.3 0 2c0 44.2 35.8 80 80 80zm0-208a128 128 0 1 1 0 256 128 128 0 1 1 0-256z"],
12932
13139
  "eye-slash": [640, 512, [], "regular", "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zm151 118.3C226 97.7 269.5 80 320 80c65.2 0 118.8 29.6 159.9 67.7C518.4 183.5 545 226 558.6 256c-12.6 28-36.6 66.8-70.9 100.9l-53.8-42.2c9.1-17.6 14.2-37.5 14.2-58.7c0-70.7-57.3-128-128-128c-32.2 0-61.7 11.9-84.2 31.5l-46.1-36.1zM394.9 284.2l-81.5-63.9c4.2-8.5 6.6-18.2 6.6-28.3c0-5.5-.7-10.9-2-16c.7 0 1.3 0 2 0c44.2 0 80 35.8 80 80c0 9.9-1.8 19.4-5.1 28.2zm9.4 130.3C378.8 425.4 350.7 432 320 432c-65.2 0-118.8-29.6-159.9-67.7C121.6 328.5 95 286 81.4 256c8.3-18.4 21.5-41.5 39.4-64.8L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5l-41.9-33zM192 256c0 70.7 57.3 128 128 128c13.3 0 26.1-2 38.2-5.8L302 334c-23.5-5.4-43.1-21.2-53.7-42.3l-56.1-44.2c-.2 2.8-.3 5.6-.3 8.5z"],
12933
13140
  "comment": [512, 512, [], "regular", "M123.6 391.3c12.9-9.4 29.6-11.8 44.6-6.4c26.5 9.6 56.2 15.1 87.8 15.1c124.7 0 208-80.5 208-160s-83.3-160-208-160S48 160.5 48 240c0 32 12.4 62.8 35.7 89.2c8.6 9.7 12.8 22.5 11.8 35.5c-1.4 18.1-5.7 34.7-11.3 49.4c17-7.9 31.1-16.7 39.4-22.7zM21.2 431.9c1.8-2.7 3.5-5.4 5.1-8.1c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208s-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6c-15.1 6.6-32.3 12.6-50.1 16.1c-.8 .2-1.6 .3-2.4 .5c-4.4 .8-8.7 1.5-13.2 1.9c-.2 0-.5 .1-.7 .1c-5.1 .5-10.2 .8-15.3 .8c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c4.1-4.2 7.8-8.7 11.3-13.5c1.7-2.3 3.3-4.6 4.8-6.9l.3-.5z"],
13141
+ "comments": [640, 512, [], "regular", "M88.2 309.1c9.8-18.3 6.8-40.8-7.5-55.8C59.4 230.9 48 204 48 176c0-63.5 63.8-128 160-128s160 64.5 160 128s-63.8 128-160 128c-13.1 0-25.8-1.3-37.8-3.6c-10.4-2-21.2-.6-30.7 4.2c-4.1 2.1-8.3 4.1-12.6 6c-16 7.2-32.9 13.5-49.9 18c2.8-4.6 5.4-9.1 7.9-13.6c1.1-1.9 2.2-3.9 3.2-5.9zM208 352c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176c0 41.8 17.2 80.1 45.9 110.3c-.9 1.7-1.9 3.5-2.8 5.1c-10.3 18.4-22.3 36.5-36.6 52.1c-6.6 7-8.3 17.2-4.6 25.9C5.8 378.3 14.4 384 24 384c43 0 86.5-13.3 122.7-29.7c4.8-2.2 9.6-4.5 14.2-6.8c15.1 3 30.9 4.5 47.1 4.5zM432 480c16.2 0 31.9-1.6 47.1-4.5c4.6 2.3 9.4 4.6 14.2 6.8C529.5 498.7 573 512 616 512c9.6 0 18.2-5.7 22-14.5c3.8-8.8 2-19-4.6-25.9c-14.2-15.6-26.2-33.7-36.6-52.1c-.9-1.7-1.9-3.4-2.8-5.1C622.8 384.1 640 345.8 640 304c0-94.4-87.9-171.5-198.2-175.8c4.1 15.2 6.2 31.2 6.2 47.8l0 .6c87.2 6.7 144 67.5 144 127.4c0 28-11.4 54.9-32.7 77.2c-14.3 15-17.3 37.6-7.5 55.8c1.1 2 2.2 4 3.2 5.9c2.5 4.5 5.2 9 7.9 13.6c-17-4.5-33.9-10.7-49.9-18c-4.3-1.9-8.5-3.9-12.6-6c-9.5-4.8-20.3-6.2-30.7-4.2c-12.1 2.4-24.8 3.6-37.8 3.6c-61.7 0-110-26.5-136.8-62.3c-16 5.4-32.8 9.4-50 11.8C279 439.8 350 480 432 480z"],
12934
13142
  "message": [512, 512, [], "regular", "M160 368c26.5 0 48 21.5 48 48l0 16 72.5-54.4c8.3-6.2 18.4-9.6 28.8-9.6L448 368c8.8 0 16-7.2 16-16l0-288c0-8.8-7.2-16-16-16L64 48c-8.8 0-16 7.2-16 16l0 288c0 8.8 7.2 16 16 16l96 0zm48 124l-.2 .2-5.1 3.8-17.1 12.8c-4.8 3.6-11.3 4.2-16.8 1.5s-8.8-8.2-8.8-14.3l0-21.3 0-6.4 0-.3 0-4 0-48-48 0-48 0c-35.3 0-64-28.7-64-64L0 64C0 28.7 28.7 0 64 0L448 0c35.3 0 64 28.7 64 64l0 288c0 35.3-28.7 64-64 64l-138.7 0L208 492z"],
12935
13143
  "folder": [512, 512, [], "regular", "M0 96C0 60.7 28.7 32 64 32l132.1 0c19.1 0 37.4 7.6 50.9 21.1L289.9 96 448 96c35.3 0 64 28.7 64 64l0 256c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zM64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l384 0c8.8 0 16-7.2 16-16l0-256c0-8.8-7.2-16-16-16l-161.4 0c-10.6 0-20.8-4.2-28.3-11.7L213.1 87c-4.5-4.5-10.6-7-17-7L64 80z"],
12936
13144
  "folder-closed": [512, 512, [], "regular", "M251.7 127.6s0 0 0 0c10.5 10.5 24.7 16.4 39.6 16.4L448 144c8.8 0 16 7.2 16 16l0 32L48 192l0-96c0-8.8 7.2-16 16-16l133.5 0c4.2 0 8.3 1.7 11.3 4.7l33.9-33.9L208.8 84.7l42.9 42.9zM48 240l416 0 0 176c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-176zM285.7 93.7L242.7 50.7c-12-12-28.3-18.7-45.3-18.7L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64L291.3 96c-2.1 0-4.2-.8-5.7-2.3z"],
@@ -12944,27 +13152,33 @@ LX.ICONS = {
12944
13152
  "up": [448, 512, [], "solid", "M201.4 137.4c12.5-12.5 32.8-12.5 45.3 0l160 160c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L224 205.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l160-160z"],
12945
13153
  "down": [448, 512, [], "solid", "M201.4 374.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 306.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z"],
12946
13154
  "arrows": [512, 512, ["arrows-up-down-left-right"], "solid", "M278.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l9.4-9.4L224 224l-114.7 0 9.4-9.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4L224 288l0 114.7-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-9.4 9.4L288 288l114.7 0-9.4 9.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l9.4 9.4L288 224l0-114.7 9.4 9.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-64-64z"],
13155
+ "arrow-pointer": [320, 512, [], "solid", "M0 55.2L0 426c0 12.2 9.9 22 22 22c6.3 0 12.4-2.7 16.6-7.5L121.2 346l58.1 116.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9L179.8 320l118.1 0c12.2 0 22.1-9.9 22.1-22.1c0-6.3-2.7-12.3-7.4-16.5L38.6 37.9C34.3 34.1 28.9 32 23.2 32C10.4 32 0 42.4 0 55.2z"],
13156
+ "reply": [24, 24, [], "regular", "M9 17L4 12L9 7M4 12H16A4 4 0 0 1 20 16V18", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
13157
+ "reply-all": [24, 24, [], "regular", "M7 17L2 12L7 7M12 17L7 12L12 7M7 12H18A4 4 0 0 1 22 16V18", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
13158
+ "forward": [24, 24, [], "regular", "M15 17L20 12L15 7M4 18V16A4 4 0 0 1 8 12H20", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
12947
13159
  "rotate": [512, 512, [], "solid", "M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z"],
12948
13160
  "rotate-right": [512, 512, ["rotate-forward"], "solid", "M463.5 224l8.5 0c13.3 0 24-10.7 24-24l0-128c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8l119.5 0z"],
12949
13161
  "rotate-left": [512, 512, ["rotate-back"], "solid", "M48.5 224L40 224c-13.3 0-24-10.7-24-24L16 72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8L48.5 224z"],
12950
- "arrow-pointer": [320, 512, [], "solid", "M0 55.2L0 426c0 12.2 9.9 22 22 22c6.3 0 12.4-2.7 16.6-7.5L121.2 346l58.1 116.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9L179.8 320l118.1 0c12.2 0 22.1-9.9 22.1-22.1c0-6.3-2.7-12.3-7.4-16.5L38.6 37.9C34.3 34.1 28.9 32 23.2 32C10.4 32 0 42.4 0 55.2z"],
12951
13162
  "hand-pointer": [448, 512, [], "regular", "M160 64c0-8.8 7.2-16 16-16s16 7.2 16 16l0 136c0 10.3 6.6 19.5 16.4 22.8s20.6-.1 26.8-8.3c3-3.9 7.6-6.4 12.8-6.4c8.8 0 16 7.2 16 16c0 10.3 6.6 19.5 16.4 22.8s20.6-.1 26.8-8.3c3-3.9 7.6-6.4 12.8-6.4c7.8 0 14.3 5.6 15.7 13c1.6 8.2 7.3 15.1 15.1 18s16.7 1.6 23.3-3.6c2.7-2.1 6.1-3.4 9.9-3.4c8.8 0 16 7.2 16 16l0 16 0 104c0 39.8-32.2 72-72 72l-56 0-59.8 0-.9 0c-37.4 0-72.4-18.7-93.2-49.9L50.7 312.9c-4.9-7.4-2.9-17.3 4.4-22.2s17.3-2.9 22.2 4.4L116 353.2c5.9 8.8 16.8 12.7 26.9 9.7s17-12.4 17-23l0-19.9 0-256zM176 0c-35.3 0-64 28.7-64 64l0 197.7C91.2 238 55.5 232.8 28.5 250.7C-.9 270.4-8.9 310.1 10.8 339.5L78.3 440.8c29.7 44.5 79.6 71.2 133.1 71.2l.9 0 59.8 0 56 0c66.3 0 120-53.7 120-120l0-104 0-16c0-35.3-28.7-64-64-64c-4.5 0-8.8 .5-13 1.3c-11.7-15.4-30.2-25.3-51-25.3c-6.9 0-13.5 1.1-19.7 3.1C288.7 170.7 269.6 160 248 160c-2.7 0-5.4 .2-8 .5L240 64c0-35.3-28.7-64-64-64zm48 304c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 96c0 8.8 7.2 16 16 16s16-7.2 16-16l0-96zm48-16c-8.8 0-16 7.2-16 16l0 96c0 8.8 7.2 16 16 16s16-7.2 16-16l0-96c0-8.8-7.2-16-16-16zm80 16c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 96c0 8.8 7.2 16 16 16s16-7.2 16-16l0-96z"],
12952
13163
  "log-in": [512, 512, [], "solid", "M352 96l64 0c17.7 0 32 14.3 32 32l0 256c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0c53 0 96-43 96-96l0-256c0-53-43-96-96-96l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32zm-9.4 182.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L242.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z"],
12953
13164
  "log-out": [512, 512, [], "solid", "M502.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224 192 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128zM160 96c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 32C43 32 0 75 0 128L0 384c0 53 43 96 96 96l64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l64 0z"],
12954
- "menu-arrows": [512, 512, [], "solid", "M352 144l96 112-96 112M160 144L64 256l96 112", "transform=rotate(90)", "fill=none stroke=currentColor stroke-width=60 stroke-linejoin=round stroke-linecap=round"],
13165
+ "menu-arrows": [512, 512, [], "solid", "M352 144l96 112-96 112M160 144L64 256l96 112", "transform=rotate(90)", "fill=none stroke-width=60 stroke-linejoin=round stroke-linecap=round"],
12955
13166
  "more": [128, 512, [], "solid", "M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z"],
12956
13167
  "minus": [448, 512, [], "solid", "M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z"],
12957
13168
  "more-horizontal": [448, 512, [], "solid", "M8 256a56 56 0 1 1 112 0A56 56 0 1 1 8 256zm160 0a56 56 0 1 1 112 0 56 56 0 1 1 -112 0zm216-56a56 56 0 1 1 0 112 56 56 0 1 1 0-112z"],
12958
13169
  "plus": [448, 512, [], "solid", "M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 144L48 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l144 0 0 144c0 17.7 14.3 32 32 32s32-14.3 32-32l0-144 144 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-144 0 0-144z"],
12959
13170
  "circle-plus": [24, 24, [], "regular", "M12 8V16M8 12H16M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
13171
+ "circle-info": [24, 24, [], "regular", "M12 2a10 10 0 1 1 0 20 10 10 0 0 1 0-20ZM12 8v4M12 16h.01", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
12960
13172
  "search": [512, 512, [], "solid", "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z"],
12961
13173
  "compass": [512, 512, [], "regular", "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm306.7 69.1L162.4 380.6c-19.4 7.5-38.5-11.6-31-31l55.5-144.3c3.3-8.5 9.9-15.1 18.4-18.4l144.3-55.5c19.4-7.5 38.5 11.6 31 31L325.1 306.7c-3.2 8.5-9.9 15.1-18.4 18.4zM288 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"],
12962
- "sidebar": [512, 512, [], "regular", "M64 64h384a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H64a32 32 0 0 1-32-32V96a32 32 0 0 1 32-32zm128 0v384", null, "fill=none stroke=currentColor stroke-width=50 stroke-linejoin=round stroke-linecap=round"],
13174
+ "clock": [512, 512, [], "regular", "M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM232 120l0 136c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2 280 120c0-13.3-10.7-24-24-24s-24 10.7-24 24z"],
13175
+ "sidebar": [512, 512, [], "regular", "M64 64h384a32 32 0 0 1 32 32v320a32 32 0 0 1-32 32H64a32 32 0 0 1-32-32V96a32 32 0 0 1 32-32zm128 0v384", null, "fill=none stroke-width=50 stroke-linejoin=round stroke-linecap=round"],
12963
13176
  "table-cells": [512, 512, [], "solid", "M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm88 64l0 64-88 0 0-64 88 0zm56 0l88 0 0 64-88 0 0-64zm240 0l0 64-88 0 0-64 88 0zM64 224l88 0 0 64-88 0 0-64zm232 0l0 64-88 0 0-64 88 0zm64 0l88 0 0 64-88 0 0-64zM152 352l0 64-88 0 0-64 88 0zm56 0l88 0 0 64-88 0 0-64zm240 0l0 64-88 0 0-64 88 0z"],
12964
13177
  "table-cells-large": [512, 512, [], "solid", "M448 96l0 128-160 0 0-128 160 0zm0 192l0 128-160 0 0-128 160 0zM224 224L64 224 64 96l160 0 0 128zM64 288l160 0 0 128L64 416l0-128zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32z"],
12965
13178
  "lightbulb": [384, 512, [], "regular", "M297.2 248.9C311.6 228.3 320 203.2 320 176c0-70.7-57.3-128-128-128S64 105.3 64 176c0 27.2 8.4 52.3 22.8 72.9c3.7 5.3 8.1 11.3 12.8 17.7c0 0 0 0 0 0c12.9 17.7 28.3 38.9 39.8 59.8c10.4 19 15.7 38.8 18.3 57.5L109 384c-2.2-12-5.9-23.7-11.8-34.5c-9.9-18-22.2-34.9-34.5-51.8c0 0 0 0 0 0s0 0 0 0c-5.2-7.1-10.4-14.2-15.4-21.4C27.6 247.9 16 213.3 16 176C16 78.8 94.8 0 192 0s176 78.8 176 176c0 37.3-11.6 71.9-31.4 100.3c-5 7.2-10.2 14.3-15.4 21.4c0 0 0 0 0 0s0 0 0 0c-12.3 16.8-24.6 33.7-34.5 51.8c-5.9 10.8-9.6 22.5-11.8 34.5l-48.6 0c2.6-18.7 7.9-38.6 18.3-57.5c11.5-20.9 26.9-42.1 39.8-59.8c0 0 0 0 0 0s0 0 0 0s0 0 0 0c4.7-6.4 9-12.4 12.7-17.7zM192 128c-26.5 0-48 21.5-48 48c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16s-7.2 16-16 16zm0 384c-44.2 0-80-35.8-80-80l0-16 160 0 0 16c0 44.2-35.8 80-80 80z"],
12966
13179
  "flag": [448, 512, [], "regular", "M48 24C48 10.7 37.3 0 24 0S0 10.7 0 24L0 64 0 350.5 0 400l0 88c0 13.3 10.7 24 24 24s24-10.7 24-24l0-100 80.3-20.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30l0-279.7c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L48 52l0-28zm0 77.5l96.6-24.2c27-6.7 55.5-3.6 80.4 8.8c54.9 27.4 118.7 29.7 175 6.8l0 241.8-24.4 9.1c-33.7 12.6-71.2 10.7-103.4-5.4c-48.2-24.1-103.3-30.1-155.6-17.1L48 338.5l0-237z"],
12967
13180
  "shuffle": [512, 512, [], "solid", "M403.8 34.4c12-5 25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6l0-32-32 0c-10.1 0-19.6 4.7-25.6 12.8L284 229.3 244 176l31.2-41.6C293.3 110.2 321.8 96 352 96l32 0 0-32c0-12.9 7.8-24.6 19.8-29.6zM164 282.7L204 336l-31.2 41.6C154.7 401.8 126.2 416 96 416l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0c10.1 0 19.6-4.7 25.6-12.8L164 282.7zm274.6 188c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6l0-32-32 0c-30.2 0-58.7-14.2-76.8-38.4L121.6 172.8c-6-8.1-15.5-12.8-25.6-12.8l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0c30.2 0 58.7 14.2 76.8 38.4L326.4 339.2c6 8.1 15.5 12.8 25.6 12.8l32 0 0-32c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64z"],
13181
+ "shopping-cart": [24, 24, [], "regular", "M8 20a1 1 0 1 0 0 2 1 1 0 0 0 0-2ZM19 20a1 1 0 1 0 0 2 1 1 0 0 0 0-2ZM2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12", null, "fill=none stroke-width=2 stroke-linecap=round stroke-linejoin=round"],
12968
13182
  "credit-card": [576, 512, [], "regular", "M512 80c8.8 0 16 7.2 16 16l0 32L48 128l0-32c0-8.8 7.2-16 16-16l448 0zm16 144l0 192c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-192 480 0zM64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l448 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm56 304c-13.3 0-24 10.7-24 24s10.7 24 24 24l48 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0zm128 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-112 0z"],
12969
13183
  "lock": [448, 512, [], "solid", "M144 144l0 48 160 0 0-48c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192l0-48C80 64.5 144.5 0 224 0s144 64.5 144 144l0 48 16 0c35.3 0 64 28.7 64 64l0 192c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 256c0-35.3 28.7-64 64-64l16 0z"],
12970
13184
  "lock-open": [576, 512, [], "solid", "M352 144c0-44.2 35.8-80 80-80s80 35.8 80 80l0 48c0 17.7 14.3 32 32 32s32-14.3 32-32l0-48C576 64.5 511.5 0 432 0S288 64.5 288 144l0 48L64 192c-35.3 0-64 28.7-64 64L0 448c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-192c0-35.3-28.7-64-64-64l-32 0 0-48z"],