text: /*!
   * OpenUI5
   * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company.
   * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
   */
  
  sap.ui.define([
  	"sap/ui/layout/cssgrid/GridLayoutBase",
  	"sap/ui/layout/cssgrid/GridSettings",
  	"sap/ui/layout/cssgrid/GridBoxLayoutStyleHelper",
  	"sap/ui/Device",
  	"sap/ui/thirdparty/jquery"
  ], function (GridLayoutBase, GridSettings, GridBoxLayoutStyleHelper, Device, jQuery) {
  	"use strict";
  
  	var SPAN_PATTERN = /^([X][L](?:[1-9]|1[0-2]))? ?([L](?:[1-9]|1[0-2]))? ?([M](?:[1-9]|1[0-2]))? ?([S](?:[1-9]|1[0-2]))?$/i;
  
  	var DEFAULT_SPAN_PATTERN = SPAN_PATTERN.exec("XL7 L6 M4 S2");
  
  	// Maps StdExt sizes to BoxContainer size classes
  	var mSizeClasses = {
  		"Phone": "sapUiLayoutCSSGridBoxLayoutSizeS",
  		"Tablet": "sapUiLayoutCSSGridBoxLayoutSizeM",
  		"Desktop": "sapUiLayoutCSSGridBoxLayoutSizeL",
  		"LargeDesktop": "sapUiLayoutCSSGridBoxLayoutSizeXL"
  	};
  
  	var DEFAULT_SPAN_CLASSES = {
  		"XL": "sapUiLayoutCSSGridBoxLayoutSpanXL7",
  		"L": "sapUiLayoutCSSGridBoxLayoutSpanL6",
  		"M": "sapUiLayoutCSSGridBoxLayoutSpanM4",
  		"S": "sapUiLayoutCSSGridBoxLayoutSpanS2"
  	};
  
  	/**
  	 * Constructor for a new GridBoxLayout.
  	 *
  	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
  	 * @param {object} [mSettings] Initial settings for the new control
  	 *
  	 * @class
  	 * Applies a sap.ui.layout.cssgrid.GridSettings to a provided DOM element or Control.
  	 *
  	 * @author SAP SE
  	 * @version 1.73.1
  	 *
  	 * @extends sap.ui.layout.cssgrid.GridLayoutBase
  	 *
  	 * @since 1.60
  	 * @constructor
  	 * @public
  	 * @alias sap.ui.layout.cssgrid.GridBoxLayout
  	 * @ui5-metamodel This simple type will also be described in the UI5 (legacy) designtime metamodel
  	 */
  	var GridBoxLayout = GridLayoutBase.extend("sap.ui.layout.cssgrid.GridBoxLayout", {
  		metadata: {
  			library: "sap.ui.layout",
  			properties: {
  
  				/**
  				 * Defines the minimum width of the Boxes
  				 */
  				boxMinWidth: {type: "sap.ui.core.CSSSize", defaultValue: ""},
  
  				/**
  				 * Defines the width of the Boxes
  				 */
  				boxWidth: {type: "sap.ui.core.CSSSize", defaultValue: ""},
  
  				/**
  				 * A string type that defines number of Boxes per row for extra large, large, medium and small screens
  				 */
  				boxesPerRowConfig: {type: "sap.ui.layout.BoxesPerRowConfig", group: "Behavior", defaultValue: "XL7 L6 M4 S2"}
  			}
  		}
  	});
  
  	/**
  	 * @override
  	 * @protected
  	 * @returns {sap.ui.layout.cssgrid.GridSettings} The active GridSettings
  	 */
  	GridBoxLayout.prototype.getActiveGridSettings = function () {
  		return new GridSettings({
  			gridTemplateColumns: this._getTemplateColumns(),
  			gridGap: "0.5rem 0.5rem"
  		});
  	};
  
  	/**
  	 * Apply display:grid styles to the provided HTML element or control based on the currently active GridSettings
  	 *
  	 * @protected
  	 * @param {sap.ui.core.Control|HTMLElement} oElement The element or control on which to apply the display:grid styles
  	 */
  	GridBoxLayout.prototype._applySingleGridLayout = function (oElement) {
  		if (this.isGridSupportedByBrowser()) {
  			GridLayoutBase.prototype._applySingleGridLayout.call(this, oElement);
  		}
  	};
  
  	/**
  	 * Render display:grid styles. Used for non-responsive grid layouts.
  	 *
  	 * @param {sap.ui.core.RenderManager} rm The render manager of the Control which wants to render display:grid styles
  	 */
  	GridBoxLayout.prototype.renderSingleGridLayout = function (rm) {
  		this._addSpanClasses(rm);
  
  		if (this.isGridSupportedByBrowser()) {
  			rm.addClass("sapUiLayoutCSSGridBoxLayoutContainer");
  		} else {
  			rm.addClass("sapUiLayoutCSSGridBoxLayoutPolyfill");
  		}
  	};
  
  	/**
  	 * Hook function for the Grid's onAfterRendering
  	 * @param {sap.ui.layout.cssgrid.IGridConfigurable} oGrid The grid
  	 */
  	GridBoxLayout.prototype.onGridAfterRendering = function (oGrid) {
  		// Add a specific class to each grid item
  		GridLayoutBase.prototype.onGridAfterRendering.call(this, oGrid);
  
  		if (!this._hasBoxWidth()) {
  			this._applySizeClass(oGrid);
  		}
  
  		if (!this.isGridSupportedByBrowser()) {
  			this._calcWidth(oGrid);
  			this._flattenHeight(oGrid);
  
  			if (!this._hasBoxWidth()) {
  				this._applyClassForLastItem(oGrid);
  			}
  		}
  
  		if (oGrid.isA("sap.f.GridList") && oGrid.getGrowing()) { // if there is growing of the list new GridListItems are loaded and there could be changes in all GridListItems dimensions
  			var fnCopyOfOnAfterPageLoaded = oGrid._oGrowingDelegate._onAfterPageLoaded;
  
  			oGrid._oGrowingDelegate._onAfterPageLoaded = function () {
  				fnCopyOfOnAfterPageLoaded.call(oGrid._oGrowingDelegate);
  
  				if (!this.isGridSupportedByBrowser()) {
  					this._flattenHeight(oGrid);
  					this._calcWidth(oGrid);
  					this._loopOverGridItems(oGrid, function (oGridItem) {
  						if (!oGridItem.classList.contains("sapMGHLI") && !oGridItem.classList.contains("sapUiBlockLayerTabbable")) { // the item is not group header or a block layer tabbable
  							oGridItem.classList.add("sapUiLayoutCSSGridItem"); // newly loaded items don't have this class
  						}
  					});
  
  					if (!this._hasBoxWidth()) {
  						this._applyClassForLastItem(oGrid);
  					}
  
  				} else if (oGrid.isA("sap.f.GridList") && oGrid.isGrouped()) {
  					this._flattenHeight(oGrid);
  				}
  			}.bind(this);
  		}
  
  		if (!this.isGridSupportedByBrowser() && !this._dndPolyfillAttached) {
  			oGrid.attachEvent("_gridPolyfillAfterDragOver", oGrid, this._polyfillAfterDragOver, this);
  			oGrid.attachEvent("_gridPolyfillAfterDragEnd", oGrid, this._polyfillAfterDragEnd, this);
  			this._dndPolyfillAttached = true;
  			// todo: detach
  		}
  	};
  
  	/**
  	 * Sets all display:grid styles to the provided HTML element
  	 *
  	 * @protected
  	 * @param {HTMLElement} oElement The element to which to apply the grid styles
  	 * @param {sap.ui.layout.cssgrid.GridSettings} oGridSettings The grid settings to apply
  	 */
  	GridBoxLayout.prototype._setGridLayout = function (oElement, oGridSettings) {
  		var oGridList = sap.ui.getCore().byId(oElement.parentElement.id);
  
  		// we need to overwrite this function since after it the GridListItems are with final dimensions and further calculation cold be done.
  		GridLayoutBase.prototype._setGridLayout.call(this, oElement, oGridSettings);
  
  		if (this.isGridSupportedByBrowser() && (oGridList && oGridList.isA("sap.f.GridList") && oGridList.isGrouped())) {
  			this._flattenHeight(oGridList);
  		}
  	};
  
  	/**
  	 * @public
  	 * @returns {boolean} If the Grid Layout is responsive.
  	 */
  	GridBoxLayout.prototype.isResponsive = function () {
  		return true;
  	};
  
  	/**
  	 * Resize handler for the GridBoxLayout.
  	 * - Changes the size class if needed.
  	 * - Manually flatten the height of the boxes.
  	 *
  	 * @param {object} oEvent - The event from a resize
  	 * @private
  	 */
  	GridBoxLayout.prototype.onGridResize = function (oEvent) {
  		if (!this.isGridSupportedByBrowser() || (oEvent.control && oEvent.control.isA("sap.f.GridList") && oEvent.control.isGrouped())) {
  			this._flattenHeight(oEvent.control);
  		}
  
  		if (!this.isGridSupportedByBrowser() && !this._hasBoxWidth()){
  			this._applyClassForLastItem(oEvent.control);
  		}
  
  		if (oEvent) {
  			// Size class is used when no boxWidth or boxMinWidth is being set.
  			if (!this._hasBoxWidth()) {
  				this._applySizeClass(oEvent.control);
  			}
  		}
  	};
  
  	/**
  	 * Make all Elements inside the GridBoxLayout with equal widths specified by one of
  	 * boxMinWidth or boxWidth properties.
  	 * Note: Only needed for IE11.
  	 *
  	 * @param {sap.ui.layout.cssgrid.IGridConfigurable} oControl The grid
  	 * @private
  	 */
  	GridBoxLayout.prototype._calcWidth = function (oControl) {
  		var sWidth;
  		if (this._hasBoxWidth()) {
  			sWidth = this.getBoxWidth() || this.getBoxMinWidth();
  		}
  		this._loopOverGridItems(oControl, function (oGridItem) {
  			if (!oGridItem.classList.contains("sapMGHLI")) { // the item is not group header
  				oGridItem.style.width = sWidth;
  			}
  		});
  	};
  
  	/**
  	 * Make all Elements inside the GridBoxLayout with equal heights
  	 *
  	 * @param {sap.ui.layout.cssgrid.IGridConfigurable} oControl The grid
  	 * @private
  	 */
  	GridBoxLayout.prototype._flattenHeight = function (oControl) {
  		var iMaxHeight = 0;
  
  		oControl.$().removeClass('sapUiLayoutCSSGridBoxLayoutFlattenHeight');
  
  		this._loopOverGridItems(oControl, function (oGridItem) {
  			iMaxHeight = Math.max(jQuery(oGridItem).outerHeight(), iMaxHeight);
  		});
  
  		GridBoxLayoutStyleHelper.setItemHeight(oControl.getId(), iMaxHeight);
  
  		oControl.$().addClass('sapUiLayoutCSSGridBoxLayoutFlattenHeight');
  	};
  
  	GridBoxLayout.prototype._applyClassForLastItem = function (oControl) {
  		var iCurrentNumberPerRow = 0;
  		var aBoxesPerRowConfig = this.getBoxesPerRowConfig().split(" ");
  		var oRange = Device.media.getCurrentRange("StdExt", oControl.$().width());
  		var sSizeClassCode = mSizeClasses[oRange.name].substring("sapUiLayoutCSSGridBoxLayoutSize".length);
  		var iMaxNumberPerRow;
  
  		aBoxesPerRowConfig.forEach(function (element) {
  			// Check if SizeClassCode (for example "XL") is contained inside the element
  			if (element.indexOf(sSizeClassCode) != -1){
  				// This splits the layout size and the maximum number of columns from the string: Example: "XL7" -> 7
  				iMaxNumberPerRow = parseInt(element.substring(sSizeClassCode.length));
  			}
  		});
  
  		this._loopOverGridItems(oControl, function (oGridItem) {
  			if (oGridItem.classList.contains("sapUiLayoutCSSGridItem")) { // the item is not group header or a block layer tabbable, it is an item
  				iCurrentNumberPerRow++;
  				if (iCurrentNumberPerRow == iMaxNumberPerRow) {
  					oGridItem.classList.add("sapUiLayoutCSSGridItemLastOnRow");
  					iCurrentNumberPerRow = 0;
  				} else {
  					oGridItem.classList.remove("sapUiLayoutCSSGridItemLastOnRow");
  				}
  			} else if (oGridItem.classList.contains("sapMGHLI")) { // the item is group header, new row is following
  				iCurrentNumberPerRow = 0;
  			}
  		});
  	};
  
  	/**
  	 * Applies a size class on the list. The class is used for breakpoints.
  	 * Note: The class is needed only when no fixed width is set on the boxes.
  	 *
  	 * @param {object} oControl - The grid that contains items.
  	 * @private
  	 */
  	GridBoxLayout.prototype._applySizeClass = function (oControl) {
  
  		var oRange = Device.media.getCurrentRange("StdExt", oControl.$().width()),
  			sSizeClass = mSizeClasses[oRange.name];
  
  		oControl.getGridDomRefs().forEach(function (oDomRef) {
  			//Check if the class is already applied
  			if (!oDomRef.classList.contains(sSizeClass)) {
  
  				//Clear all size classes on the current DOMRef
  				Object.keys(mSizeClasses).map(function (sSize) {
  					oDomRef.classList.remove(mSizeClasses[sSize]);
  				});
  				oDomRef.classList.add(sSizeClass);
  			}
  		});
  	};
  
  	/**
  	 * Returns a gridTemplateColumns value based on boxWidth and boxMinWidth properties
  	 *
  	 * @protected
  	 * @returns {string} A value for gridTemplateColumns property
  	 */
  	GridBoxLayout.prototype._getTemplateColumns = function () {
  		var sTemplateColumns = "";
  
  		if (this.getBoxWidth()) {
  			sTemplateColumns = "repeat(auto-fit, " + this.getBoxWidth() + ")";
  		} else if (this.getBoxMinWidth()) {
  			sTemplateColumns = "repeat(auto-fit, minmax(" + this.getBoxMinWidth() + ", 1fr))";
  		}
  
  		return sTemplateColumns;
  	};
  
  	/**
  	 * Checks if boxWidth or boxMinWidth is set
  	 * @returns {boolean} True if there is boxWidth or boxMinWidth set
  	 * @private
  	 */
  	GridBoxLayout.prototype._hasBoxWidth = function () {
  		if (this.getBoxWidth() || this.getBoxMinWidth()) {
  			return true;
  		} else {
  			return false;
  		}
  	};
  
  	/**
  	 * Adds the breakpoint classes depending on boxesPerRowConfig property
  	 *
  	 * @param {sap.ui.core.RenderManager} rm - RenderManager of the layout which will be rendered
  	 * @private
  	 */
  	GridBoxLayout.prototype._addSpanClasses = function (rm) {
  		var aSpan,
  			sSpan,
  			sSpanPattern = this.getBoxesPerRowConfig(),
  			sSpanXLargeClass,
  			sSpanLargeClass,
  			sSpanMediumClass,
  			sSpanSmallClass;
  
  		// Span classes are used only when no boxWidth or boxMinWidth is being set.
  		if (this._hasBoxWidth()) {
  			return;
  		}
  
  		if (!sSpanPattern || !sSpanPattern.length === 0) {
  			aSpan = DEFAULT_SPAN_PATTERN;
  		} else {
  			aSpan = SPAN_PATTERN.exec(sSpanPattern);
  		}
  
  		if (aSpan) {
  			for (var i = 1; i < aSpan.length; i++) {
  				sSpan = aSpan[i];
  
  				if (sSpan) {
  					sSpan = sSpan.toUpperCase();
  
  					switch (sSpan.substr(0, 1)) {
  						case "X":
  							if (sSpan.substr(1, 1) === "L") {
  								sSpanXLargeClass = this._getBoxesPerRowClass(sSpan, 2);
  							}
  							break;
  						case "L":
  							sSpanLargeClass = this._getBoxesPerRowClass(sSpan, 1);
  							break;
  						case "M":
  							sSpanMediumClass = this._getBoxesPerRowClass(sSpan, 1);
  							break;
  						case "S":
  							sSpanSmallClass = this._getBoxesPerRowClass(sSpan, 1);
  							break;
  						default:
  							break;
  					}
  				}
  			}
  		}
  
  		sSpanXLargeClass = sSpanXLargeClass || DEFAULT_SPAN_CLASSES.XL;
  		sSpanLargeClass = sSpanLargeClass || DEFAULT_SPAN_CLASSES.L;
  		sSpanMediumClass = sSpanMediumClass || DEFAULT_SPAN_CLASSES.M;
  		sSpanSmallClass = sSpanSmallClass || DEFAULT_SPAN_CLASSES.S;
  
  		rm.addClass([
  			sSpanXLargeClass,
  			sSpanLargeClass,
  			sSpanMediumClass,
  			sSpanSmallClass
  		].join(" "));
  	};
  
  	/**
  	 * Constructs the class name which should be used for that span and that index.
  	 *
  	 * @param {string} sSpan A string that represents the span - like XL12 or S4
  	 * @param {number} iIndex How long is the text part of sSpan - 2 for XL, 1 for S and etc...
  	 * @returns {string|undefined} The class which should be used
  	 */
  	GridBoxLayout.prototype._getBoxesPerRowClass = function (sSpan, iIndex) {
  		var iSpan = parseInt(sSpan.substr(iIndex, sSpan.length));
  		if (iSpan && iSpan > 0 && iSpan < 13) {
  			return "sapUiLayoutCSSGridBoxLayoutSpan" + sSpan;
  		}
  	};
  
  	/**
  	 * Loops over each grid item and call passed function on each iteration.
  	 *
  	 * @param {sap.ui.layout.cssgrid.IGridConfigurable} oControl The grid
  	 * @param {function} fn - Function that will be called on every child element. As parameter the DOM node of the child is passed.
  	 */
  	GridBoxLayout.prototype._loopOverGridItems = function (oControl, fn) {
  		oControl.getGridDomRefs().forEach(function (oDomRef) {
  			if (oDomRef && oDomRef.children) {
  				for (var i = 0; i < oDomRef.children.length; i++) {
  
  					// process only visible items
  					// avoid using jQuery for performance reasons
  					if (oDomRef.children[i].style.display !== "none" && oDomRef.children[i].style.visibility !== "hidden") {
  						fn(oDomRef.children[i]);
  					}
  				}
  			}
  		});
  	};
  
  	/**
  	 * Implements polyfill for IE after drag over.
  	 * @param {Object} oEvent After drag over event
  	 * @protected
  	 */
  	GridBoxLayout.prototype._polyfillAfterDragOver = function (oEvent, oGrid) {
  		oEvent.getParameter("indicator").addClass("sapUiLayoutCSSGridItem");
  
  		this._calcWidth(oGrid);
  		this._flattenHeight(oGrid);
  		this._applyClassForLastItem(oGrid);
  	};
  
  	/**
  	 * Implements polyfill for IE after drag end.
  	 * @param {Object} oEvent After drag end event
  	 * @protected
  	 */
  	GridBoxLayout.prototype._polyfillAfterDragEnd = function (oEvent, oGrid) {
  		oEvent.getParameter("indicator").removeClass("sapUiLayoutCSSGridItem");
  
  		this._applyClassForLastItem(oGrid);
  	};
  
  	return GridBoxLayout;
  });