lexgui 0.5.8 → 0.5.9
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.css +558 -99
- package/build/lexgui.js +531 -148
- package/build/lexgui.min.css +2 -6
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +531 -148
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +12 -1
- package/demo.js +2 -2
- package/examples/all_widgets.html +12 -2
- package/package.json +1 -1
- package/build/utilities.css +0 -421
package/build/lexgui.module.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
var LX = {
|
|
9
|
-
version: "0.5.
|
|
9
|
+
version: "0.5.9",
|
|
10
10
|
ready: false,
|
|
11
11
|
components: [], // Specific pre-build components
|
|
12
12
|
signals: {}, // Events and triggers
|
|
@@ -773,7 +773,7 @@ LX.makeKbd = makeKbd;
|
|
|
773
773
|
* @description Gets an SVG element using one of LX.ICONS
|
|
774
774
|
* @param {String} iconName
|
|
775
775
|
* @param {Object} options
|
|
776
|
-
*
|
|
776
|
+
* title
|
|
777
777
|
* extraClass
|
|
778
778
|
* svgClass
|
|
779
779
|
*/
|
|
@@ -782,7 +782,7 @@ function makeIcon( iconName, options = { } )
|
|
|
782
782
|
let data = LX.ICONS[ iconName ];
|
|
783
783
|
console.assert( data, `No icon named _${ iconName }_` );
|
|
784
784
|
|
|
785
|
-
const iconTitle = options.
|
|
785
|
+
const iconTitle = options.title;
|
|
786
786
|
const iconClass = options.iconClass;
|
|
787
787
|
const svgClass = options.svgClass;
|
|
788
788
|
|
|
@@ -1641,7 +1641,7 @@ function toast( title, description, options = {} )
|
|
|
1641
1641
|
if( options.action )
|
|
1642
1642
|
{
|
|
1643
1643
|
const panel = new Panel();
|
|
1644
|
-
panel.addButton(null, options.action.name ?? "Accept", options.action.callback.bind( this, toast ), { width: "auto", maxWidth: "150px", className: "right", buttonClass: "
|
|
1644
|
+
panel.addButton(null, options.action.name ?? "Accept", options.action.callback.bind( this, toast ), { width: "auto", maxWidth: "150px", className: "right", buttonClass: "border" });
|
|
1645
1645
|
toast.appendChild( panel.root.childNodes[ 0 ] );
|
|
1646
1646
|
}
|
|
1647
1647
|
|
|
@@ -1941,6 +1941,158 @@ LX.addSignal = addSignal;
|
|
|
1941
1941
|
* DOM Elements
|
|
1942
1942
|
*/
|
|
1943
1943
|
|
|
1944
|
+
/**
|
|
1945
|
+
* @class Popover
|
|
1946
|
+
*/
|
|
1947
|
+
|
|
1948
|
+
class Popover {
|
|
1949
|
+
|
|
1950
|
+
static activeElement = false;
|
|
1951
|
+
|
|
1952
|
+
constructor( trigger, content, options = {} ) {
|
|
1953
|
+
|
|
1954
|
+
console.assert( trigger, "Popover needs a DOM element as trigger!" );
|
|
1955
|
+
|
|
1956
|
+
if( Popover.activeElement )
|
|
1957
|
+
{
|
|
1958
|
+
Popover.activeElement.destroy();
|
|
1959
|
+
return;
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
this._trigger = trigger;
|
|
1963
|
+
trigger.classList.add( "triggered" );
|
|
1964
|
+
trigger.active = this;
|
|
1965
|
+
|
|
1966
|
+
this._windowPadding = 4;
|
|
1967
|
+
this.side = options.side ?? "bottom";
|
|
1968
|
+
this.align = options.align ?? "center";
|
|
1969
|
+
this.avoidCollisions = options.avoidCollisions ?? true;
|
|
1970
|
+
|
|
1971
|
+
this.root = document.createElement( "div" );
|
|
1972
|
+
this.root.dataset["side"] = this.side;
|
|
1973
|
+
this.root.tabIndex = "1";
|
|
1974
|
+
this.root.className = "lexpopover";
|
|
1975
|
+
LX.root.appendChild( this.root );
|
|
1976
|
+
|
|
1977
|
+
this.root.addEventListener( "keydown", (e) => {
|
|
1978
|
+
if( e.key == "Escape" )
|
|
1979
|
+
{
|
|
1980
|
+
e.preventDefault();
|
|
1981
|
+
e.stopPropagation();
|
|
1982
|
+
this.destroy();
|
|
1983
|
+
}
|
|
1984
|
+
} )
|
|
1985
|
+
|
|
1986
|
+
if( content )
|
|
1987
|
+
{
|
|
1988
|
+
content = [].concat( content );
|
|
1989
|
+
content.forEach( e => {
|
|
1990
|
+
const domNode = e.root ?? e;
|
|
1991
|
+
this.root.appendChild( domNode );
|
|
1992
|
+
if( e.onPopover )
|
|
1993
|
+
{
|
|
1994
|
+
e.onPopover();
|
|
1995
|
+
}
|
|
1996
|
+
} );
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1999
|
+
Popover.activeElement = this;
|
|
2000
|
+
|
|
2001
|
+
doAsync( () => {
|
|
2002
|
+
this._adjustPosition();
|
|
2003
|
+
|
|
2004
|
+
this.root.focus();
|
|
2005
|
+
|
|
2006
|
+
this._onClick = e => {
|
|
2007
|
+
if( e.target && ( this.root.contains( e.target ) || e.target == this._trigger ) )
|
|
2008
|
+
{
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
this.destroy();
|
|
2012
|
+
};
|
|
2013
|
+
|
|
2014
|
+
document.body.addEventListener( "mousedown", this._onClick, true );
|
|
2015
|
+
document.body.addEventListener( "focusin", this._onClick, true );
|
|
2016
|
+
}, 10 );
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
destroy() {
|
|
2020
|
+
|
|
2021
|
+
this._trigger.classList.remove( "triggered" );
|
|
2022
|
+
|
|
2023
|
+
delete this._trigger.active;
|
|
2024
|
+
|
|
2025
|
+
document.body.removeEventListener( "click", this._onClick );
|
|
2026
|
+
|
|
2027
|
+
this.root.remove();
|
|
2028
|
+
|
|
2029
|
+
Popover.activeElement = null;
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
_adjustPosition() {
|
|
2033
|
+
|
|
2034
|
+
const position = [ 0, 0 ];
|
|
2035
|
+
|
|
2036
|
+
// Place menu using trigger position and user options
|
|
2037
|
+
{
|
|
2038
|
+
const rect = this._trigger.getBoundingClientRect();
|
|
2039
|
+
|
|
2040
|
+
let alignWidth = true;
|
|
2041
|
+
|
|
2042
|
+
switch( this.side )
|
|
2043
|
+
{
|
|
2044
|
+
case "left":
|
|
2045
|
+
position[ 0 ] += ( rect.x - this.root.offsetWidth );
|
|
2046
|
+
alignWidth = false;
|
|
2047
|
+
break;
|
|
2048
|
+
case "right":
|
|
2049
|
+
position[ 0 ] += ( rect.x + rect.width );
|
|
2050
|
+
alignWidth = false;
|
|
2051
|
+
break;
|
|
2052
|
+
case "top":
|
|
2053
|
+
position[ 1 ] += ( rect.y - this.root.offsetHeight );
|
|
2054
|
+
alignWidth = true;
|
|
2055
|
+
break;
|
|
2056
|
+
case "bottom":
|
|
2057
|
+
position[ 1 ] += ( rect.y + rect.height );
|
|
2058
|
+
alignWidth = true;
|
|
2059
|
+
break;
|
|
2060
|
+
default:
|
|
2061
|
+
break;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
switch( this.align )
|
|
2065
|
+
{
|
|
2066
|
+
case "start":
|
|
2067
|
+
if( alignWidth ) { position[ 0 ] += rect.x; }
|
|
2068
|
+
else { position[ 1 ] += rect.y; }
|
|
2069
|
+
break;
|
|
2070
|
+
case "center":
|
|
2071
|
+
if( alignWidth ) { position[ 0 ] += ( rect.x + rect.width * 0.5 ) - this.root.offsetWidth * 0.5; }
|
|
2072
|
+
else { position[ 1 ] += ( rect.y + rect.height * 0.5 ) - this.root.offsetHeight * 0.5; }
|
|
2073
|
+
break;
|
|
2074
|
+
case "end":
|
|
2075
|
+
if( alignWidth ) { position[ 0 ] += rect.x - this.root.offsetWidth + rect.width; }
|
|
2076
|
+
else { position[ 1 ] += rect.y - this.root.offsetHeight + rect.height; }
|
|
2077
|
+
break;
|
|
2078
|
+
default:
|
|
2079
|
+
break;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
if( this.avoidCollisions )
|
|
2084
|
+
{
|
|
2085
|
+
position[ 0 ] = LX.clamp( position[ 0 ], 0, window.innerWidth - this.root.offsetWidth - this._windowPadding );
|
|
2086
|
+
position[ 1 ] = LX.clamp( position[ 1 ], 0, window.innerHeight - this.root.offsetHeight - this._windowPadding );
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
this.root.style.left = `${ position[ 0 ] }px`;
|
|
2090
|
+
this.root.style.top = `${ position[ 1 ] }px`;
|
|
2091
|
+
}
|
|
2092
|
+
};
|
|
2093
|
+
|
|
2094
|
+
LX.Popover = Popover;
|
|
2095
|
+
|
|
1944
2096
|
/**
|
|
1945
2097
|
* @class DropdownMenu
|
|
1946
2098
|
*/
|
|
@@ -2238,14 +2390,8 @@ class ColorPicker {
|
|
|
2238
2390
|
|
|
2239
2391
|
static currentPicker = false;
|
|
2240
2392
|
|
|
2241
|
-
constructor( hexValue,
|
|
2242
|
-
|
|
2243
|
-
console.assert( trigger, "ColorPicker needs a DOM element as trigger!" );
|
|
2393
|
+
constructor( hexValue, options = {} ) {
|
|
2244
2394
|
|
|
2245
|
-
this._windowPadding = 4;
|
|
2246
|
-
this.side = options.side ?? "bottom";
|
|
2247
|
-
this.align = options.align ?? "center";
|
|
2248
|
-
this.avoidCollisions = options.avoidCollisions ?? true;
|
|
2249
2395
|
this.colorModel = options.colorModel ?? "Hex";
|
|
2250
2396
|
this.useAlpha = options.useAlpha ?? false;
|
|
2251
2397
|
this.callback = options.onChange;
|
|
@@ -2255,32 +2401,8 @@ class ColorPicker {
|
|
|
2255
2401
|
console.warn( "Define a callback in _options.onChange_ to allow getting new Color values!" );
|
|
2256
2402
|
}
|
|
2257
2403
|
|
|
2258
|
-
if( ColorPicker.currentPicker )
|
|
2259
|
-
{
|
|
2260
|
-
ColorPicker.currentPicker.destroy();
|
|
2261
|
-
return;
|
|
2262
|
-
}
|
|
2263
|
-
|
|
2264
|
-
this._trigger = trigger;
|
|
2265
|
-
trigger.classList.add( "triggered" );
|
|
2266
|
-
trigger.picker = this;
|
|
2267
|
-
|
|
2268
2404
|
this.root = document.createElement( "div" );
|
|
2269
|
-
this.root.tabIndex = "1";
|
|
2270
2405
|
this.root.className = "lexcolorpicker";
|
|
2271
|
-
this.root.dataset["side"] = this.side;
|
|
2272
|
-
LX.root.appendChild( this.root );
|
|
2273
|
-
|
|
2274
|
-
this.root.addEventListener( "keydown", (e) => {
|
|
2275
|
-
if( e.key == "Escape" )
|
|
2276
|
-
{
|
|
2277
|
-
e.preventDefault();
|
|
2278
|
-
e.stopPropagation();
|
|
2279
|
-
this.destroy();
|
|
2280
|
-
}
|
|
2281
|
-
} )
|
|
2282
|
-
|
|
2283
|
-
ColorPicker.currentPicker = this;
|
|
2284
2406
|
|
|
2285
2407
|
this.markerHalfSize = 8;
|
|
2286
2408
|
this.markerSize = this.markerHalfSize * 2;
|
|
@@ -2299,8 +2421,6 @@ class ColorPicker {
|
|
|
2299
2421
|
this.intSatMarker.style.backgroundColor = this.currentColor.hex;
|
|
2300
2422
|
this.colorPickerBackground.appendChild( this.intSatMarker );
|
|
2301
2423
|
|
|
2302
|
-
doAsync( this._svToPosition.bind( this, this.currentColor.hsv.s, this.currentColor.hsv.v ) );
|
|
2303
|
-
|
|
2304
2424
|
let pickerRect = null;
|
|
2305
2425
|
|
|
2306
2426
|
let innerMouseDown = e => {
|
|
@@ -2380,11 +2500,6 @@ class ColorPicker {
|
|
|
2380
2500
|
this.hueMarker.style.backgroundColor = `rgb(${ hueColor.css.r }, ${ hueColor.css.g }, ${ hueColor.css.b })`;
|
|
2381
2501
|
this.colorPickerTracker.appendChild( this.hueMarker );
|
|
2382
2502
|
|
|
2383
|
-
doAsync( () => {
|
|
2384
|
-
const hueLeft = LX.remapRange( this.currentColor.hsv.h, 0, 360, 0, this.colorPickerTracker.offsetWidth - this.markerSize );
|
|
2385
|
-
this.hueMarker.style.left = hueLeft + "px";
|
|
2386
|
-
} );
|
|
2387
|
-
|
|
2388
2503
|
const _fromHueX = ( hueX ) => {
|
|
2389
2504
|
this.hueMarker.style.left = hueX + "px";
|
|
2390
2505
|
this.currentColor.hsv.h = LX.remapRange( hueX, 0, this.colorPickerTracker.offsetWidth - this.markerSize, 0, 360 );
|
|
@@ -2447,11 +2562,6 @@ class ColorPicker {
|
|
|
2447
2562
|
this.alphaMarker.style.backgroundColor = `rgb(${ this.currentColor.css.r }, ${ this.currentColor.css.g }, ${ this.currentColor.css.b },${ this.currentColor.css.a })`;
|
|
2448
2563
|
this.alphaTracker.appendChild( this.alphaMarker );
|
|
2449
2564
|
|
|
2450
|
-
doAsync( () => {
|
|
2451
|
-
const alphaLeft = LX.remapRange( this.currentColor.hsv.a, 0, 1, 0, this.alphaTracker.offsetWidth - this.markerSize );
|
|
2452
|
-
this.alphaMarker.style.left = alphaLeft + "px";
|
|
2453
|
-
} );
|
|
2454
|
-
|
|
2455
2565
|
const _fromAlphaX = ( alphaX ) => {
|
|
2456
2566
|
this.alphaMarker.style.left = alphaX + "px";
|
|
2457
2567
|
this.currentColor.hsv.a = LX.remapRange( alphaX, 0, this.alphaTracker.offsetWidth - this.markerSize, 0, 1 );
|
|
@@ -2529,62 +2639,34 @@ class ColorPicker {
|
|
|
2529
2639
|
|
|
2530
2640
|
this._updateColorValue( hexValue, true );
|
|
2531
2641
|
|
|
2532
|
-
doAsync( ()
|
|
2533
|
-
this._adjustPosition();
|
|
2534
|
-
|
|
2535
|
-
this.root.focus();
|
|
2536
|
-
|
|
2537
|
-
this._onClick = e => {
|
|
2538
|
-
if( e.target && ( this.root.contains( e.target ) || e.target == this._trigger ) )
|
|
2539
|
-
{
|
|
2540
|
-
return;
|
|
2541
|
-
}
|
|
2542
|
-
this.destroy();
|
|
2543
|
-
};
|
|
2642
|
+
doAsync( this._placeMarkers.bind( this ) );
|
|
2544
2643
|
|
|
2545
|
-
|
|
2546
|
-
document.body.addEventListener( "focusin", this._onClick, true );
|
|
2547
|
-
}, 10 );
|
|
2644
|
+
this.onPopover = this._placeMarkers.bind( this );
|
|
2548
2645
|
}
|
|
2549
2646
|
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
this.currentColor.setHex( hexColor );
|
|
2553
|
-
|
|
2554
|
-
// Decompose into HSV
|
|
2555
|
-
const { h, s, v } = this.currentColor.hsv;
|
|
2556
|
-
this._svToPosition( s, v );
|
|
2647
|
+
_placeMarkers() {
|
|
2557
2648
|
|
|
2558
|
-
|
|
2559
|
-
this.hueMarker.style.backgroundColor = this.colorPickerBackground.style.backgroundColor = `rgb(${ hueColor.css.r }, ${ hueColor.css.g }, ${ hueColor.css.b })`;
|
|
2560
|
-
this.hueMarker.style.left = LX.remapRange( h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize ) + "px";
|
|
2649
|
+
this._svToPosition( this.currentColor.hsv.s, this.currentColor.hsv.v );
|
|
2561
2650
|
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
destroy() {
|
|
2651
|
+
const hueLeft = LX.remapRange( this.currentColor.hsv.h, 0, 360, 0, this.colorPickerTracker.offsetWidth - this.markerSize );
|
|
2652
|
+
this.hueMarker.style.left = hueLeft + "px";
|
|
2566
2653
|
|
|
2567
|
-
this.
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
document.body.removeEventListener( "focusin", this._onClick, true );
|
|
2573
|
-
|
|
2574
|
-
LX.root.querySelectorAll( ".lexcolorpicker" ).forEach( m => { m.remove(); } );
|
|
2575
|
-
|
|
2576
|
-
ColorPicker.currentPicker = null;
|
|
2654
|
+
if( this.useAlpha )
|
|
2655
|
+
{
|
|
2656
|
+
const alphaLeft = LX.remapRange( this.currentColor.hsv.a, 0, 1, 0, this.alphaTracker.offsetWidth - this.markerSize );
|
|
2657
|
+
this.alphaMarker.style.left = alphaLeft + "px";
|
|
2658
|
+
}
|
|
2577
2659
|
}
|
|
2578
2660
|
|
|
2579
2661
|
_svToPosition( s, v ) {
|
|
2580
2662
|
this.intSatMarker.style.left = `${ LX.remapRange( s, 0, 1, -this.markerHalfSize, this.colorPickerBackground.offsetWidth - this.markerHalfSize ) }px`;
|
|
2581
2663
|
this.intSatMarker.style.top = `${ LX.remapRange( 1 - v, 0, 1, -this.markerHalfSize, this.colorPickerBackground.offsetHeight - this.markerHalfSize ) }px`
|
|
2582
|
-
}
|
|
2664
|
+
}
|
|
2583
2665
|
|
|
2584
2666
|
_positionToSv( left, top ) {
|
|
2585
2667
|
this.currentColor.hsv.s = LX.remapRange( left, -this.markerHalfSize, this.colorPickerBackground.offsetWidth - this.markerHalfSize, 0, 1 );
|
|
2586
2668
|
this.currentColor.hsv.v = 1 - LX.remapRange( top, -this.markerHalfSize, this.colorPickerBackground.offsetHeight - this.markerHalfSize, 0, 1 );
|
|
2587
|
-
}
|
|
2669
|
+
}
|
|
2588
2670
|
|
|
2589
2671
|
_updateColorValue( newHexValue, skipCallback = false ) {
|
|
2590
2672
|
|
|
@@ -2627,71 +2709,274 @@ class ColorPicker {
|
|
|
2627
2709
|
if( this.useAlpha ) components.push( toFixed( a ) );
|
|
2628
2710
|
this.labelWidget.set( components.join( ' ' ) );
|
|
2629
2711
|
}
|
|
2630
|
-
}
|
|
2712
|
+
}
|
|
2631
2713
|
|
|
2632
|
-
|
|
2714
|
+
fromHexColor( hexColor ) {
|
|
2633
2715
|
|
|
2634
|
-
|
|
2716
|
+
this.currentColor.setHex( hexColor );
|
|
2635
2717
|
|
|
2636
|
-
//
|
|
2718
|
+
// Decompose into HSV
|
|
2719
|
+
const { h, s, v } = this.currentColor.hsv;
|
|
2720
|
+
this._svToPosition( s, v );
|
|
2721
|
+
|
|
2722
|
+
const hueColor = new Color( { h, s: 1, v: 1 } );
|
|
2723
|
+
this.hueMarker.style.backgroundColor = this.colorPickerBackground.style.backgroundColor = `rgb(${ hueColor.css.r }, ${ hueColor.css.g }, ${ hueColor.css.b })`;
|
|
2724
|
+
this.hueMarker.style.left = LX.remapRange( h, 0, 360, -this.markerHalfSize, this.colorPickerTracker.offsetWidth - this.markerHalfSize ) + "px";
|
|
2725
|
+
|
|
2726
|
+
this._updateColorValue( hexColor );
|
|
2727
|
+
}
|
|
2728
|
+
};
|
|
2729
|
+
|
|
2730
|
+
LX.ColorPicker = ColorPicker;
|
|
2731
|
+
|
|
2732
|
+
class Calendar {
|
|
2733
|
+
|
|
2734
|
+
/**
|
|
2735
|
+
* @constructor Calendar
|
|
2736
|
+
* @param {String} dateString D/M/Y
|
|
2737
|
+
* @param {Object} options
|
|
2738
|
+
* onChange: Function to call on date changes
|
|
2739
|
+
*/
|
|
2740
|
+
|
|
2741
|
+
constructor( dateString, options = {} ) {
|
|
2742
|
+
|
|
2743
|
+
this.root = LX.makeContainer( ["256px", "auto"], "border p-3 bg-primary rounded-lg text-md" );
|
|
2744
|
+
|
|
2745
|
+
this.onChange = options.onChange;
|
|
2746
|
+
this.untilToday = options.untilToday;
|
|
2747
|
+
this.fromToday = options.fromToday;
|
|
2748
|
+
|
|
2749
|
+
if( dateString )
|
|
2637
2750
|
{
|
|
2638
|
-
|
|
2751
|
+
this.fromDateString( dateString );
|
|
2752
|
+
}
|
|
2753
|
+
else
|
|
2754
|
+
{
|
|
2755
|
+
const date = new Date();
|
|
2756
|
+
this.month = date.getMonth() + 1;
|
|
2757
|
+
this.year = date.getFullYear();
|
|
2758
|
+
this.fromMonthYear( this.month, this.year );
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2639
2761
|
|
|
2640
|
-
|
|
2762
|
+
_getCurrentDate() {
|
|
2763
|
+
return {
|
|
2764
|
+
day: this.day,
|
|
2765
|
+
month: this.month,
|
|
2766
|
+
year: this.year,
|
|
2767
|
+
fullDate: this.getFullDate()
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2641
2770
|
|
|
2642
|
-
|
|
2771
|
+
_previousMonth() {
|
|
2772
|
+
|
|
2773
|
+
this.month = Math.max( 0, this.month - 1 );
|
|
2774
|
+
|
|
2775
|
+
if( this.month == 0 )
|
|
2776
|
+
{
|
|
2777
|
+
this.month = 12;
|
|
2778
|
+
this.year--;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
this.fromMonthYear( this.month, this.year );
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
_nextMonth() {
|
|
2785
|
+
|
|
2786
|
+
this.month = Math.min( this.month + 1, 12 );
|
|
2787
|
+
|
|
2788
|
+
if( this.month == 12 )
|
|
2789
|
+
{
|
|
2790
|
+
this.month = 0;
|
|
2791
|
+
this.year++;
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
this.fromMonthYear( this.month, this.year );
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
refresh() {
|
|
2798
|
+
|
|
2799
|
+
this.root.innerHTML = "";
|
|
2800
|
+
|
|
2801
|
+
// Header
|
|
2802
|
+
{
|
|
2803
|
+
const header = LX.makeContainer( ["100%", "auto"], "flex flex-row p-1", "", this.root );
|
|
2804
|
+
|
|
2805
|
+
const prevMonthIcon = LX.makeIcon( "left", { title: "Previous Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
|
|
2806
|
+
header.appendChild( prevMonthIcon );
|
|
2807
|
+
prevMonthIcon.addEventListener( "click", () => {
|
|
2808
|
+
this._previousMonth();
|
|
2809
|
+
} );
|
|
2810
|
+
|
|
2811
|
+
const monthYearLabel = LX.makeContainer( ["100%", "auto"], "text-center font-medium select-none", `${ this.monthName } ${ this.year }`, header );
|
|
2812
|
+
|
|
2813
|
+
const nextMonthIcon = LX.makeIcon( "right", { title: "Next Month", iconClass: "border p-1 rounded hover:bg-secondary", svgClass: "sm" } );
|
|
2814
|
+
header.appendChild( nextMonthIcon );
|
|
2815
|
+
nextMonthIcon.addEventListener( "click", () => {
|
|
2816
|
+
this._nextMonth();
|
|
2817
|
+
} );
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
// Body
|
|
2821
|
+
{
|
|
2822
|
+
const daysTable = document.createElement( "table" );
|
|
2823
|
+
daysTable.className = "w-full";
|
|
2824
|
+
this.root.appendChild( daysTable );
|
|
2825
|
+
|
|
2826
|
+
// Table Head
|
|
2643
2827
|
{
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
alignWidth = true;
|
|
2659
|
-
break;
|
|
2660
|
-
default:
|
|
2661
|
-
break;
|
|
2828
|
+
const head = document.createElement( 'thead' );
|
|
2829
|
+
daysTable.appendChild( head );
|
|
2830
|
+
|
|
2831
|
+
const hrow = document.createElement( 'tr' );
|
|
2832
|
+
|
|
2833
|
+
for( const headData of [ "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su" ] )
|
|
2834
|
+
{
|
|
2835
|
+
const th = document.createElement( 'th' );
|
|
2836
|
+
th.className = "fg-tertiary text-sm font-normal select-none";
|
|
2837
|
+
th.innerHTML = `<span>${ headData }</span>`;
|
|
2838
|
+
hrow.appendChild( th );
|
|
2839
|
+
}
|
|
2840
|
+
|
|
2841
|
+
head.appendChild( hrow );
|
|
2662
2842
|
}
|
|
2663
2843
|
|
|
2664
|
-
|
|
2844
|
+
// Table Body
|
|
2665
2845
|
{
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2846
|
+
const body = document.createElement( 'tbody' );
|
|
2847
|
+
daysTable.appendChild( body );
|
|
2848
|
+
|
|
2849
|
+
for( let week = 0; week < 6; week++ )
|
|
2850
|
+
{
|
|
2851
|
+
const hrow = document.createElement( 'tr' );
|
|
2852
|
+
const weekDays = this.calendarDays.slice( week * 7, week * 7 + 7 );
|
|
2853
|
+
|
|
2854
|
+
for( const dayData of weekDays )
|
|
2855
|
+
{
|
|
2856
|
+
const th = document.createElement( 'th' );
|
|
2857
|
+
th.className = "leading-loose font-normal rounded select-none cursor-pointer";
|
|
2858
|
+
|
|
2859
|
+
const dayDate = new Date( `${ this.month }/${ dayData.day }/${ this.year }` );
|
|
2860
|
+
const date = new Date();
|
|
2861
|
+
const beforeToday = this.untilToday ? ( dayDate.getTime() < date.getTime() ) : true;
|
|
2862
|
+
const afterToday = this.fromToday ? ( dayDate.getTime() > date.getTime() ) : true;
|
|
2863
|
+
const selectable = dayData.currentMonth && beforeToday && afterToday;
|
|
2864
|
+
|
|
2865
|
+
if( this.currentDate && ( dayData.day == this.currentDate.day ) && ( this.month == this.currentDate.month )
|
|
2866
|
+
&& ( this.year == this.currentDate.year ) && dayData.currentMonth )
|
|
2867
|
+
{
|
|
2868
|
+
th.className += ` bg-contrast fg-contrast`;
|
|
2869
|
+
}
|
|
2870
|
+
else
|
|
2871
|
+
{
|
|
2872
|
+
th.className += ` ${ selectable ? "fg-primary" : "fg-tertiary" } hover:bg-secondary`;
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2875
|
+
th.innerHTML = `<span>${ dayData.day }</span>`;
|
|
2876
|
+
hrow.appendChild( th );
|
|
2877
|
+
|
|
2878
|
+
if( selectable )
|
|
2879
|
+
{
|
|
2880
|
+
th.addEventListener( "click", () => {
|
|
2881
|
+
this.day = dayData.day;
|
|
2882
|
+
this.currentDate = this._getCurrentDate();
|
|
2883
|
+
if( this.onChange )
|
|
2884
|
+
{
|
|
2885
|
+
this.onChange( this.currentDate );
|
|
2886
|
+
}
|
|
2887
|
+
} );
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
body.appendChild( hrow );
|
|
2892
|
+
}
|
|
2680
2893
|
}
|
|
2681
2894
|
}
|
|
2895
|
+
}
|
|
2682
2896
|
|
|
2683
|
-
|
|
2897
|
+
fromDateString( dateString ) {
|
|
2898
|
+
|
|
2899
|
+
const tokens = dateString.split( '/' );
|
|
2900
|
+
|
|
2901
|
+
this.day = parseInt( tokens[ 0 ] );
|
|
2902
|
+
this.month = parseInt( tokens[ 1 ] );
|
|
2903
|
+
this.year = parseInt( tokens[ 2 ] );
|
|
2904
|
+
|
|
2905
|
+
this.currentDate = this._getCurrentDate();
|
|
2906
|
+
|
|
2907
|
+
this.fromMonthYear( this.month, this.year );
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
fromMonthYear( month, year ) {
|
|
2911
|
+
|
|
2912
|
+
// Month is 0-based (0 = January, ... 11 = December)
|
|
2913
|
+
month--;
|
|
2914
|
+
|
|
2915
|
+
year = year ?? new Date().getFullYear();
|
|
2916
|
+
|
|
2917
|
+
const weekDay = new Date( year, month, 1 ).getDay();
|
|
2918
|
+
const firstDay = weekDay === 0 ? 6 : weekDay - 1; // 0 = Monday, 1 = Tuesday...
|
|
2919
|
+
const daysInMonth = new Date( year, month + 1, 0 ).getDate();
|
|
2920
|
+
|
|
2921
|
+
// Previous month
|
|
2922
|
+
const prevMonth = month === 0 ? 11 : month - 1;
|
|
2923
|
+
const prevYear = month === 0 ? year - 1 : year;
|
|
2924
|
+
const daysInPrevMonth = new Date( prevYear, prevMonth + 1, 0 ).getDate();
|
|
2925
|
+
|
|
2926
|
+
// Prepare full grid (up to 6 weeks = 42 days)
|
|
2927
|
+
const calendarDays = [];
|
|
2928
|
+
|
|
2929
|
+
// Fill in days from previous month
|
|
2930
|
+
for( let i = firstDay - 1; i >= 0; i--)
|
|
2684
2931
|
{
|
|
2685
|
-
|
|
2686
|
-
position[ 1 ] = LX.clamp( position[ 1 ], 0, window.innerHeight - this.root.offsetHeight - this._windowPadding );
|
|
2932
|
+
calendarDays.push( { day: daysInPrevMonth - i, currentMonth: false } );
|
|
2687
2933
|
}
|
|
2688
2934
|
|
|
2689
|
-
|
|
2690
|
-
|
|
2935
|
+
// Fill in current month days
|
|
2936
|
+
for ( let i = 1; i <= daysInMonth; i++ )
|
|
2937
|
+
{
|
|
2938
|
+
calendarDays.push( { day: i, currentMonth: true } );
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
// Fill in next month days to complete the grid (if needed)
|
|
2942
|
+
const remaining = 42 - calendarDays.length;
|
|
2943
|
+
for( let i = 1; i <= remaining; i++ )
|
|
2944
|
+
{
|
|
2945
|
+
calendarDays.push( { day: i, currentMonth: false } );
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
this.monthName = this.getMonthName( month );
|
|
2949
|
+
this.firstDay = firstDay;
|
|
2950
|
+
this.daysInMonth = daysInMonth;
|
|
2951
|
+
this.calendarDays = calendarDays;
|
|
2952
|
+
|
|
2953
|
+
this.refresh();
|
|
2691
2954
|
}
|
|
2692
|
-
};
|
|
2693
2955
|
|
|
2694
|
-
|
|
2956
|
+
getMonthName( monthIndex, locale = "en-US" ) {
|
|
2957
|
+
const formatter = new Intl.DateTimeFormat( locale, { month: "long" } );
|
|
2958
|
+
return formatter.format( new Date( 2000, monthIndex, 1 ) );
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
getFullDate() {
|
|
2962
|
+
return `${ this.monthName } ${ this.day }${ this._getOrdinalSuffix( this.day ) }, ${ this.year }`;
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2965
|
+
_getOrdinalSuffix( day ) {
|
|
2966
|
+
if ( day > 3 && day < 21 ) return "th";
|
|
2967
|
+
switch ( day % 10 )
|
|
2968
|
+
{
|
|
2969
|
+
case 1: return "st";
|
|
2970
|
+
case 2: return "nd";
|
|
2971
|
+
case 3: return "rd";
|
|
2972
|
+
default: return "th";
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
LX.Calendar = Calendar;
|
|
2978
|
+
|
|
2979
|
+
/* Layout Classes */
|
|
2695
2980
|
|
|
2696
2981
|
class Area {
|
|
2697
2982
|
|
|
@@ -5297,8 +5582,9 @@ class Widget {
|
|
|
5297
5582
|
static COUNTER = 33;
|
|
5298
5583
|
static TABLE = 34;
|
|
5299
5584
|
static TABS = 35;
|
|
5300
|
-
static
|
|
5301
|
-
static
|
|
5585
|
+
static DATE = 36;
|
|
5586
|
+
static LABEL = 37;
|
|
5587
|
+
static BLANK = 38;
|
|
5302
5588
|
|
|
5303
5589
|
static NO_CONTEXT_TYPES = [
|
|
5304
5590
|
Widget.BUTTON,
|
|
@@ -5536,6 +5822,7 @@ class Widget {
|
|
|
5536
5822
|
case Widget.COUNTER: return "Counter";
|
|
5537
5823
|
case Widget.TABLE: return "Table";
|
|
5538
5824
|
case Widget.TABS: return "Tabs";
|
|
5825
|
+
case Widget.DATE: return "Date";
|
|
5539
5826
|
case Widget.LABEL: return "Label";
|
|
5540
5827
|
case Widget.BLANK: return "Blank";
|
|
5541
5828
|
case Widget.CUSTOM: return this.customName;
|
|
@@ -6136,8 +6423,11 @@ class NodeTree {
|
|
|
6136
6423
|
actionEl.className = "lexicon " + a.icon;
|
|
6137
6424
|
actionEl.title = a.name;
|
|
6138
6425
|
actionEl.addEventListener("click", function( e ) {
|
|
6139
|
-
a.callback
|
|
6140
|
-
|
|
6426
|
+
if( a.callback )
|
|
6427
|
+
{
|
|
6428
|
+
a.callback( node, actionEl );
|
|
6429
|
+
e.stopPropagation();
|
|
6430
|
+
}
|
|
6141
6431
|
});
|
|
6142
6432
|
|
|
6143
6433
|
inputContainer.appendChild( actionEl );
|
|
@@ -6238,6 +6528,8 @@ class NodeTree {
|
|
|
6238
6528
|
}
|
|
6239
6529
|
}
|
|
6240
6530
|
|
|
6531
|
+
LX.NodeTree = NodeTree;
|
|
6532
|
+
|
|
6241
6533
|
/**
|
|
6242
6534
|
* @class Blank
|
|
6243
6535
|
* @description Blank Widget
|
|
@@ -6628,6 +6920,7 @@ class Button extends Widget {
|
|
|
6628
6920
|
wValue.querySelector( "a" ).classList.add( "swap-off" );
|
|
6629
6921
|
|
|
6630
6922
|
const input = document.createElement( "input" );
|
|
6923
|
+
input.className = "p-0 border-0";
|
|
6631
6924
|
input.type = "checkbox";
|
|
6632
6925
|
wValue.prepend( input );
|
|
6633
6926
|
|
|
@@ -8188,6 +8481,16 @@ class ColorInput extends Widget {
|
|
|
8188
8481
|
container.className = "lexcolor";
|
|
8189
8482
|
this.root.appendChild( container );
|
|
8190
8483
|
|
|
8484
|
+
this.picker = new ColorPicker( value, {
|
|
8485
|
+
colorModel: options.useRGB ? "RGB" : "Hex",
|
|
8486
|
+
useAlpha,
|
|
8487
|
+
onChange: ( color ) => {
|
|
8488
|
+
this._fromColorPicker = true;
|
|
8489
|
+
this.set( color.hex );
|
|
8490
|
+
delete this._fromColorPicker;
|
|
8491
|
+
}
|
|
8492
|
+
} );
|
|
8493
|
+
|
|
8191
8494
|
let sampleContainer = LX.makeContainer( ["18px", "18px"], "flex flex-row bg-contrast rounded overflow-hidden", "", container );
|
|
8192
8495
|
sampleContainer.tabIndex = "1";
|
|
8193
8496
|
sampleContainer.addEventListener( "click", e => {
|
|
@@ -8195,15 +8498,8 @@ class ColorInput extends Widget {
|
|
|
8195
8498
|
{
|
|
8196
8499
|
return;
|
|
8197
8500
|
}
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
useAlpha,
|
|
8201
|
-
onChange: ( color ) => {
|
|
8202
|
-
this._fromColorPicker = true;
|
|
8203
|
-
this.set( color.hex );
|
|
8204
|
-
delete this._fromColorPicker;
|
|
8205
|
-
}
|
|
8206
|
-
} );
|
|
8501
|
+
|
|
8502
|
+
this._popover = new Popover( sampleContainer, [ this.picker ] );
|
|
8207
8503
|
} );
|
|
8208
8504
|
|
|
8209
8505
|
let colorSampleRGB = document.createElement( 'div' );
|
|
@@ -10196,6 +10492,75 @@ class Table extends Widget {
|
|
|
10196
10492
|
|
|
10197
10493
|
LX.Table = Table;
|
|
10198
10494
|
|
|
10495
|
+
/**
|
|
10496
|
+
* @class DatePicker
|
|
10497
|
+
* @description DatePicker Widget
|
|
10498
|
+
*/
|
|
10499
|
+
|
|
10500
|
+
class DatePicker extends Widget {
|
|
10501
|
+
|
|
10502
|
+
constructor( name, dateString, callback, options = { } ) {
|
|
10503
|
+
|
|
10504
|
+
super( Widget.DATE, name, null, options );
|
|
10505
|
+
|
|
10506
|
+
if( options.today )
|
|
10507
|
+
{
|
|
10508
|
+
const date = new Date();
|
|
10509
|
+
dateString = `${ date.getDate() }/${ date.getMonth() + 1 }/${ date.getFullYear() }`;
|
|
10510
|
+
}
|
|
10511
|
+
|
|
10512
|
+
this.onGetValue = () => {
|
|
10513
|
+
return dateString;
|
|
10514
|
+
}
|
|
10515
|
+
|
|
10516
|
+
this.onSetValue = ( newValue, skipCallback, event ) => {
|
|
10517
|
+
|
|
10518
|
+
dateString = newValue;
|
|
10519
|
+
|
|
10520
|
+
this.calendar.fromDateString( newValue );
|
|
10521
|
+
|
|
10522
|
+
refresh( this.calendar.getFullDate() );
|
|
10523
|
+
|
|
10524
|
+
if( !skipCallback )
|
|
10525
|
+
{
|
|
10526
|
+
this._trigger( new IEvent( name, newValue, event ), callback );
|
|
10527
|
+
}
|
|
10528
|
+
}
|
|
10529
|
+
|
|
10530
|
+
this.onResize = ( rect ) => {
|
|
10531
|
+
const realNameWidth = ( this.root.domName?.style.width ?? "0px" );
|
|
10532
|
+
container.style.width = `calc( 100% - ${ realNameWidth })`;
|
|
10533
|
+
};
|
|
10534
|
+
|
|
10535
|
+
const container = document.createElement('div');
|
|
10536
|
+
container.className = "lexdate";
|
|
10537
|
+
this.root.appendChild( container );
|
|
10538
|
+
|
|
10539
|
+
this.calendar = new Calendar( dateString, { onChange: ( date ) => {
|
|
10540
|
+
this.set( `${ date.day }/${ date.month }/${ date.year }` )
|
|
10541
|
+
}, ...options });
|
|
10542
|
+
|
|
10543
|
+
const refresh = ( currentDate ) => {
|
|
10544
|
+
container.innerHTML = "";
|
|
10545
|
+
const calendarIcon = LX.makeIcon( "calendar" );
|
|
10546
|
+
const calendarButton = new Button( null, currentDate ?? "Pick a date", () => {
|
|
10547
|
+
this._popover = new Popover( calendarButton.root, ( popoverRoot ) => {
|
|
10548
|
+
popoverRoot.appendChild( this.calendar.root );
|
|
10549
|
+
} );
|
|
10550
|
+
}, { buttonClass: `flex flex-row px-3 ${ currentDate ? "" : "fg-tertiary" } justify-between` } );
|
|
10551
|
+
|
|
10552
|
+
calendarButton.root.querySelector( "button" ).appendChild( calendarIcon );
|
|
10553
|
+
container.appendChild( calendarButton.root );
|
|
10554
|
+
};
|
|
10555
|
+
|
|
10556
|
+
refresh( dateString ? this.calendar.getFullDate(): null );
|
|
10557
|
+
|
|
10558
|
+
doAsync( this.onResize.bind( this ) );
|
|
10559
|
+
}
|
|
10560
|
+
}
|
|
10561
|
+
|
|
10562
|
+
LX.DatePicker = DatePicker;
|
|
10563
|
+
|
|
10199
10564
|
/**
|
|
10200
10565
|
* @class Panel
|
|
10201
10566
|
*/
|
|
@@ -11342,6 +11707,23 @@ class Panel {
|
|
|
11342
11707
|
const widget = new Table( name, data, options );
|
|
11343
11708
|
return this._attachWidget( widget );
|
|
11344
11709
|
}
|
|
11710
|
+
|
|
11711
|
+
/**
|
|
11712
|
+
* @method addDate
|
|
11713
|
+
* @param {String} name Widget name
|
|
11714
|
+
* @param {String} dateString
|
|
11715
|
+
* @param {Function} callback
|
|
11716
|
+
* @param {Object} options:
|
|
11717
|
+
* hideName: Don't use name as label [false]
|
|
11718
|
+
* today: Set current day as selected by default
|
|
11719
|
+
* untilToday: Allow dates only until current day
|
|
11720
|
+
* fromToday: Allow dates only from current day
|
|
11721
|
+
*/
|
|
11722
|
+
|
|
11723
|
+
addDate( name, dateString, callback, options = { } ) {
|
|
11724
|
+
const widget = new DatePicker( name, dateString, callback, options );
|
|
11725
|
+
return this._attachWidget( widget );
|
|
11726
|
+
}
|
|
11345
11727
|
}
|
|
11346
11728
|
|
|
11347
11729
|
LX.Panel = Panel;
|
|
@@ -14374,6 +14756,7 @@ LX.ICONS = {
|
|
|
14374
14756
|
"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"],
|
|
14375
14757
|
"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"],
|
|
14376
14758
|
"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"],
|
|
14759
|
+
"frame": [24, 24, [], "solid", "M2 6h20M2 18h20M6 2v20M18 2v20", null, "fill=none stroke-width=2 stroke-linejoin=round stroke-linecap=round"],
|
|
14377
14760
|
"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"],
|
|
14378
14761
|
"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"],
|
|
14379
14762
|
"newspaper": [512, 512, [], "regular", "M168 80c-13.3 0-24 10.7-24 24l0 304c0 8.4-1.4 16.5-4.1 24L440 432c13.3 0 24-10.7 24-24l0-304c0-13.3-10.7-24-24-24L168 80zM72 480c-39.8 0-72-32.2-72-72L0 112C0 98.7 10.7 88 24 88s24 10.7 24 24l0 296c0 13.3 10.7 24 24 24s24-10.7 24-24l0-304c0-39.8 32.2-72 72-72l272 0c39.8 0 72 32.2 72 72l0 304c0 39.8-32.2 72-72 72L72 480zM176 136c0-13.3 10.7-24 24-24l96 0c13.3 0 24 10.7 24 24l0 80c0 13.3-10.7 24-24 24l-96 0c-13.3 0-24-10.7-24-24l0-80zm200-24l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l32 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-32 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z"],
|