|  | @ -134,7 +134,33 @@ class DirectionUnitDependentAttribute { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const SideDirections = Object.freeze({ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     LEFT: 1, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     TOP: 2, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     RIGHT: 3, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     BOTTOM: 4 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const SideTransitionDirection = Object.freeze({ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     HORIZONTAL: 0, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     VERTICAL: 1 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const Corners = Object.freeze({ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     TOP_LEFT: 0, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     TOP_RIGHT: 1, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     BOTTOM_LEFT: 2, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     BOTTOM_RIGHT: 3 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | }); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | const CornerTransitionDirection = Object.freeze({ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     TOP_LEFT_BOTTOM_RIGHT: 0, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     TOP_RIGHT_BOTTOM_LEFT: 1 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | }); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					|  |  | class Sides extends DirectionUnitDependentAttribute { |  |  | class Sides extends DirectionUnitDependentAttribute { | 
			
		
	
		
		
			
				
					|  |  |     /** |  |  |     /** | 
			
		
	
		
		
			
				
					|  |  |      *  |  |  |      *  | 
			
		
	
	
		
		
			
				
					|  | @ -201,6 +227,21 @@ class Sides extends DirectionUnitDependentAttribute { | 
			
		
	
		
		
			
				
					|  |  |         return this.top(amount).bottom(amount); |  |  |         return this.top(amount).bottom(amount); | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      *  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      * @returns {Object} | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     getValues() { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         return { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             "left": this._fFirst, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             "top": this._fSecond, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             "right": this._fThird, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             "bottom": this._fForth, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             "horizontal": this._fFirst + this._fThird, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             "vertical": this._fSecond + this._fForth | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |     toModifications() { |  |  |     toModifications() { | 
			
		
	
		
		
			
				
					|  |  |         return [ |  |  |         return [ | 
			
		
	
		
		
			
				
					|  |  |             { key: "left", value: this._fFirst + this._unit }, |  |  |             { key: "left", value: this._fFirst + this._unit }, | 
			
		
	
	
		
		
			
				
					|  | @ -271,3 +312,98 @@ class PaddingChain extends Sides { | 
			
		
	
		
		
			
				
					|  |  |     } |  |  |     } | 
			
		
	
		
		
			
				
					|  |  | } |  |  | } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | class TwoDimPoint { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      *  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      * @param {number} x  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      * @param {number} y  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |      */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     constructor(x, y) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         this.x = x; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         this.y = y; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} start  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} end  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} value  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} tolerance  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {boolean} usePercentage  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @returns {boolean} | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  | function isValueInBounds(start, end, value, tolerance = 0, usePercentage = false) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     if (tolerance !== 0) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         if (usePercentage) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             start = start * (1 - tolerance / 100); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             end = end * (1 + tolerance / 100); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } else { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             start = start - tolerance; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             end = end + tolerance; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return value >= start && value <= end; | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} x  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} y  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {Map<SideDirections,number>} area  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} tolerance  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {boolean} usePercentage if tolerance is given and this is set to true,  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *                  the tolerance will be calculated by percentage,  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *                  otherwise it will be subtracted/added | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @returns {boolean} | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  | function areXYInArea(x, y, area, tolerance = 0, usePercentage = false) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return isValueInBounds( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         area.get(SideDirections.LEFT), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         area.get(SideDirections.RIGHT), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         x, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         tolerance, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         usePercentage | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     ) && isValueInBounds( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         area.get(SideDirections.TOP), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         area.get(SideDirections.BOTTOM), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         y, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         tolerance, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         usePercentage | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     ); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {TwoDimPoint} point  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {Map<SideDirections,number>} area  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {number} tolerance  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {boolean} usePercentage if tolerance is given and this is set to true,  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *                  the tolerance will be calculated by percentage,  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *                  otherwise it will be subtracted/added | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  | function isPointInArea(point, area, tolerance = 0, usePercentage = false) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return areXYInArea( | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         point.x, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         point.y, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         area, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         tolerance, | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         usePercentage | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     ); | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  | /** | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  *  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  * @param {HTMLElement} element  | 
			
		
	
		
		
			
				
					|  |  |  |  |  |  */ | 
			
		
	
		
		
			
				
					|  |  |  |  |  | function getEnclosingBounds(element) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     let area = element.getBoundingClientRect(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     let parentArea = element.parentElement.getBoundingClientRect(); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     return { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         [SideDirections.LEFT]: Math.min(area.left, parentArea.left), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         [SideDirections.RIGHT]: Math.max(area.right, parentArea.right), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         [SideDirections.TOP]: Math.min(area.top, parentArea.top), | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         [SideDirections.BOTTOM]: Math.max(area.bottom, parentArea.bottom) | 
			
		
	
		
		
			
				
					|  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | } |