File: //home/arjun/projects/buyercall/node_modules/@ckeditor/ckeditor5-table/build/table.js.map
{"version":3,"sources":["webpack://CKEditor5.table/./theme/colorinput.css","webpack://CKEditor5.table/./theme/form.css","webpack://CKEditor5.table/./theme/formrow.css","webpack://CKEditor5.table/./theme/inserttable.css","webpack://CKEditor5.table/./theme/table.css","webpack://CKEditor5.table/./theme/tablecaption.css","webpack://CKEditor5.table/./theme/tablecellproperties.css","webpack://CKEditor5.table/./theme/tableediting.css","webpack://CKEditor5.table/./theme/tableform.css","webpack://CKEditor5.table/./theme/tableproperties.css","webpack://CKEditor5.table/./theme/tableselection.css","webpack://CKEditor5.table/../node_modules/css-loader/dist/runtime/api.js","webpack://CKEditor5.table/../node_modules/css-loader/dist/runtime/cssWithMappingToString.js","webpack://CKEditor5.table/./theme/icons/table-cell-properties.svg","webpack://CKEditor5.table/./theme/icons/table-column.svg","webpack://CKEditor5.table/./theme/icons/table-merge-cell.svg","webpack://CKEditor5.table/./theme/icons/table-properties.svg","webpack://CKEditor5.table/./theme/icons/table-row.svg","webpack://CKEditor5.table/./theme/icons/table.svg","webpack://CKEditor5.table/./theme/colorinput.css?6671","webpack://CKEditor5.table/./theme/form.css?4090","webpack://CKEditor5.table/./theme/formrow.css?93db","webpack://CKEditor5.table/./theme/inserttable.css?778c","webpack://CKEditor5.table/./theme/table.css?dfa0","webpack://CKEditor5.table/./theme/tablecaption.css?c60a","webpack://CKEditor5.table/./theme/tablecellproperties.css?4c9a","webpack://CKEditor5.table/./theme/tableediting.css?31d0","webpack://CKEditor5.table/./theme/tableform.css?f298","webpack://CKEditor5.table/./theme/tableproperties.css?8755","webpack://CKEditor5.table/./theme/tableselection.css?fb5c","webpack://CKEditor5.table/../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack://CKEditor5.table/./src/commands/insertcolumncommand.js","webpack://CKEditor5.table/./src/commands/insertrowcommand.js","webpack://CKEditor5.table/./src/commands/inserttablecommand.js","webpack://CKEditor5.table/./src/commands/mergecellcommand.js","webpack://CKEditor5.table/./src/commands/mergecellscommand.js","webpack://CKEditor5.table/./src/commands/removecolumncommand.js","webpack://CKEditor5.table/./src/commands/removerowcommand.js","webpack://CKEditor5.table/./src/commands/selectcolumncommand.js","webpack://CKEditor5.table/./src/commands/selectrowcommand.js","webpack://CKEditor5.table/./src/commands/setheadercolumncommand.js","webpack://CKEditor5.table/./src/commands/setheaderrowcommand.js","webpack://CKEditor5.table/./src/commands/splitcellcommand.js","webpack://CKEditor5.table/./src/converters/downcast.js","webpack://CKEditor5.table/./src/converters/table-caption-post-fixer.js","webpack://CKEditor5.table/./src/converters/table-cell-paragraph-post-fixer.js","webpack://CKEditor5.table/./src/converters/table-cell-refresh-post-fixer.js","webpack://CKEditor5.table/./src/converters/table-heading-rows-refresh-post-fixer.js","webpack://CKEditor5.table/./src/converters/table-layout-post-fixer.js","webpack://CKEditor5.table/./src/converters/tableproperties.js","webpack://CKEditor5.table/./src/converters/upcasttable.js","webpack://CKEditor5.table/./src/table.js","webpack://CKEditor5.table/./src/tablecaption.js","webpack://CKEditor5.table/./src/tablecaption/tablecaptionediting.js","webpack://CKEditor5.table/./src/tablecaption/tablecaptionui.js","webpack://CKEditor5.table/./src/tablecaption/toggletablecaptioncommand.js","webpack://CKEditor5.table/./src/tablecaption/utils.js","webpack://CKEditor5.table/./src/tablecellproperties.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellbackgroundcolorcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellbordercolorcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellborderstylecommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellborderwidthcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellheightcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellhorizontalalignmentcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellpaddingcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellpropertycommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellverticalalignmentcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/commands/tablecellwidthcommand.js","webpack://CKEditor5.table/./src/tablecellproperties/tablecellpropertiesediting.js","webpack://CKEditor5.table/./src/tablecellproperties/tablecellpropertiesui.js","webpack://CKEditor5.table/./src/tablecellproperties/ui/tablecellpropertiesview.js","webpack://CKEditor5.table/./src/tableclipboard.js","webpack://CKEditor5.table/./src/tableediting.js","webpack://CKEditor5.table/./src/tablekeyboard.js","webpack://CKEditor5.table/./src/tablemouse.js","webpack://CKEditor5.table/./src/tablemouse/mouseeventsobserver.js","webpack://CKEditor5.table/./src/tableproperties.js","webpack://CKEditor5.table/./src/tableproperties/commands/tablealignmentcommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tablebackgroundcolorcommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tablebordercolorcommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tableborderstylecommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tableborderwidthcommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tableheightcommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tablepropertycommand.js","webpack://CKEditor5.table/./src/tableproperties/commands/tablewidthcommand.js","webpack://CKEditor5.table/./src/tableproperties/tablepropertiesediting.js","webpack://CKEditor5.table/./src/tableproperties/tablepropertiesui.js","webpack://CKEditor5.table/./src/tableproperties/ui/tablepropertiesview.js","webpack://CKEditor5.table/./src/tableselection.js","webpack://CKEditor5.table/./src/tabletoolbar.js","webpack://CKEditor5.table/./src/tableui.js","webpack://CKEditor5.table/./src/tableutils.js","webpack://CKEditor5.table/./src/tablewalker.js","webpack://CKEditor5.table/./src/ui/colorinputview.js","webpack://CKEditor5.table/./src/ui/formrowview.js","webpack://CKEditor5.table/./src/ui/inserttableview.js","webpack://CKEditor5.table/./src/utils/common.js","webpack://CKEditor5.table/./src/utils/selection.js","webpack://CKEditor5.table/./src/utils/structure.js","webpack://CKEditor5.table/./src/utils/table-properties.js","webpack://CKEditor5.table/./src/utils/ui/contextualballoon.js","webpack://CKEditor5.table/./src/utils/ui/table-properties.js","webpack://CKEditor5.table/./src/utils/ui/widget.js","webpack://CKEditor5.table/delegated \"./src/core.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.table/delegated \"./src/engine.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.table/delegated \"./src/ui.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.table/delegated \"./src/utils.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.table/delegated \"./src/widget.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.table/external var \"CKEditor5.dll\"","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_Symbol.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_baseGetTag.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_baseTrim.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_freeGlobal.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_getRawTag.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_objectToString.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_root.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/_trimmedEndIndex.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/debounce.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/isObject.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/isObjectLike.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/isSymbol.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/now.js","webpack://CKEditor5.table/javascript/node_modules/lodash-es/toNumber.js","webpack://CKEditor5.table/webpack/bootstrap","webpack://CKEditor5.table/webpack/runtime/compat get default export","webpack://CKEditor5.table/webpack/runtime/define property getters","webpack://CKEditor5.table/webpack/runtime/hasOwnProperty shorthand","webpack://CKEditor5.table/webpack/runtime/make namespace object","webpack://CKEditor5.table/./src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,6DAA6D,WAAW,aAAa,2BAA2B,0CAA0C,eAAe,YAAY,sCAAsC,eAAe,kFAAkF,aAAa,8CAA8C,aAAa,kFAAkF,kBAAkB,gBAAgB,0IAA0I,kBAAkB,cAAc,+CAA+C,0BAA0B,6BAA6B,+CAA+C,yBAAyB,4BAA4B,wEAAwE,UAAU,kFAAkF,oBAAoB,yBAAyB,4BAA4B,kFAAkF,qBAAqB,0BAA0B,6BAA6B,oFAAoF,qDAAqD,4GAA4G,gBAAgB,+PAA+P,sCAAsC,4GAA4G,WAAW,YAAY,8CAA8C,oKAAoK,SAAS,SAAS,YAAY,SAAS,eAAe,kBAAkB,wBAAwB,qBAAqB,oDAAoD,WAAW,qDAAqD,sEAAsE,4BAA4B,6BAA6B,8DAA8D,0BAA0B,8DAA8D,yBAAyB,gEAAgE,wCAAwC,0EAA0E,eAAe,uCAAuC,OAAO,slCAAslC,gBAAgB,kBAAkB,gCAAgC,kCAAkC,sBAAsB,mBAAmB,KAAK,8BAA8B,sBAAsB,4HAA4H,sBAAsB,OAAO,KAAK,oCAAoC,8FAA8F,+CAA+C,2BAA2B,yBAAyB,uEAAuE,6BAA6B,yBAAyB,SAAS,OAAO,KAAK,GAAG,4OAA4O,qCAAqC,wBAAwB,2BAA2B,yBAAyB,mCAAmC,sCAAsC,OAAO,2BAA2B,kCAAkC,qCAAqC,OAAO,KAAK,2BAA2B,gDAAgD,mBAAmB,6BAA6B,+BAA+B,oCAAoC,uCAAuC,SAAS,6BAA6B,gCAAgC,qCAAqC,wCAAwC,SAAS,yBAAyB,gEAAgE,SAAS,mDAAmD,oCAAoC,wBAAwB,uBAAuB,yDAAyD,yEAAyE,sBAAsB,sBAAsB,yBAAyB,sBAAsB,0CAA0C,+BAA+B,qCAAqC,kCAAkC,WAAW,SAAS,OAAO,KAAK,0CAA0C,kBAAkB,4DAA4D,+EAA+E,qCAAqC,oCAAoC,2BAA2B,mCAAmC,OAAO,2BAA2B,kCAAkC,OAAO,uBAAuB,iDAAiD,6BAA6B,0BAA0B,kDAAkD,SAAS,OAAO,KAAK,GAAG,qUAAqU,qBAAqB,4DAA4D,6CAA6C,qBAAqB,KAAK,GAAG,qBAAqB;AACxxO;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,sDAAsD,oCAAoC,kBAAkB,aAAa,8BAA8B,eAAe,QAAQ,4BAA4B,eAAe,6DAA6D,6CAA6C,mEAAmE,WAAW,OAAO,gbAAgb,yCAAyC,eAAe,sFAAsF,KAAK,2BAA2B,sBAAsB,eAAe,KAAK,yBAAyB,sBAAsB,gCAAgC,uBAAuB,wDAAwD,SAAS,+BAA+B,sBAAsB,SAAS,OAAO,KAAK,GAAG,qBAAqB;AACzyC;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,2DAA2D,aAAa,mBAAmB,iBAAiB,8BAA8B,iCAAiC,YAAY,wHAAwH,uBAAuB,iBAAiB,6DAA6D,6CAA6C,oCAAoC,6CAA6C,qCAAqC,2BAA2B,WAAW,eAAe,2CAA2C,mCAAmC,wEAAwE,2BAA2B,OAAO,kjBAAkjB,kBAAkB,wBAAwB,sBAAsB,mCAAmC,iFAAiF,mBAAmB,KAAK,mCAAmC,mDAAmD,gCAAgC,OAAO,KAAK,GAAG,4OAA4O,sBAAsB,kEAAkE,iFAAiF,aAAa,2BAA2B,+CAA+C,SAAS,6BAA6B,gDAAgD,SAAS,OAAO,KAAK,qBAAqB,kBAAkB,sBAAsB,KAAK,mCAAmC,0CAA0C,wCAAwC,oCAAoC,OAAO,KAAK,GAAG,qBAAqB;AAC7/E;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,8EAA8E,aAAa,mBAAmB,eAAe,MAAM,wCAAwC,2CAA2C,0CAA0C,0CAA0C,oCAAoC,qJAAqJ,0FAA0F,qCAAqC,kBAAkB,uCAAuC,gDAAgD,kDAAkD,kDAAkD,6CAA6C,kBAAkB,6CAA6C,0CAA0C,8CAA8C,OAAO,snBAAsnB,kBAAkB,wBAAwB,oBAAoB,GAAG,0LAA0L,6CAA6C,gDAAgD,+CAA+C,+CAA+C,GAAG,yCAAyC,gQAAgQ,+FAA+F,GAAG,0CAA0C,uBAAuB,GAAG,4CAA4C,qDAAqD,uDAAuD,uDAAuD,kDAAkD,uBAAuB,eAAe,iDAAiD,qDAAqD,KAAK,GAAG,uBAAuB;AACp6F;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,6DAA6D,iBAAiB,cAAc,yBAAyB,yBAAyB,iBAAiB,WAAW,YAAY,0BAA0B,wDAAwD,cAAc,aAAa,yBAAyB,4BAA4B,gBAAgB,4BAA4B,+BAA+B,iBAAiB,+BAA+B,gBAAgB,+CAA+C,qBAAqB,WAAW,OAAO,kgBAAkgB,yRAAyR,mBAAmB,eAAe,sFAAsF,wBAAwB,6NAA6N,mBAAmB,yMAAyM,yBAAyB,uBAAuB,sBAAsB,uWAAuW,OAAO,cAAc,0BAA0B,wCAAwC,OAAO,KAAK,GAAG,kQAAkQ,sBAAsB,GAAG,wCAAwC,qBAAqB,GAAG,oDAAoD,mMAAmM,4MAA4M,GAAG,qBAAqB;AACtuG;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gDAAgD,4CAA4C,mCAAmC,qDAAqD,8BAA8B,sBAAsB,iBAAiB,sBAAsB,kBAAkB,yCAAyC,0DAA0D,aAAa,gBAAgB,oBAAoB,qEAAqE,kDAAkD,gEAAgE,qBAAqB,sBAAsB,mBAAmB,gBAAgB,uBAAuB,sCAAsC,GAAG,sEAAsE,GAAG,2DAA2D,OAAO,4jBAA4jB,yDAAyD,mDAAmD,yEAAyE,GAAG,2DAA2D,2BAA2B,sBAAsB,2BAA2B,uBAAuB,8CAA8C,+DAA+D,kBAAkB,qBAAqB,yBAAyB,GAAG,uEAAuE,kCAAkC,yDAAyD,KAAK,gCAAgC,4BAA4B,6BAA6B,mMAAmM,uBAAuB,8BAA8B,KAAK,GAAG,2CAA2C,QAAQ,6EAA6E,KAAK,YAAY,iEAAiE,KAAK,GAAG,qBAAqB;AACtrF;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,uIAAuI,eAAe,0HAA0H,eAAe,yHAAyH,eAAe,uHAAuH,YAAY,kCAAkC,YAAY,2FAA2F,oBAAoB,UAAU,UAAU,4GAA4G,gBAAgB,sCAAsC,OAAO,2iBAA2iB,qBAAqB,sDAAsD,wBAAwB,4BAA4B,2BAA2B,mGAAmG,WAAW,4BAA4B,mGAAmG,WAAW,0BAA0B,yBAAyB,WAAW,SAAS,OAAO,KAAK,GAAG,sNAAsN,iBAAiB,uBAAuB,oDAAoD,6BAA6B,mBAAmB,mBAAmB,OAAO,wDAAwD,0BAA0B,2BAA2B,yJAAyJ,SAAS,OAAO,KAAK,GAAG,qBAAqB;AACtkF;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gDAAgD,+DAA+D,8QAA8Q,yDAAyD,kBAAkB,+CAA+C,oBAAoB,OAAO,6YAA6Y,sEAAsE,GAAG,sBAAsB,mBAAmB,gHAAgH,sIAAsI,gQAAgQ,wDAAwD,8BAA8B,oDAAoD,KAAK,GAAG,qBAAqB;AAC9qD;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,kKAAkK,eAAe,8DAA8D,eAAe,mBAAmB,qFAAqF,aAAa,8BAA8B,mBAAmB,sMAAsM,YAAY,4CAA4C,kBAAkB,8EAA8E,kBAAkB,SAAS,4DAA4D,+BAA+B,UAAU,oFAAoF,aAAa,kBAAkB,yDAAyD,SAAS,2BAA2B,MAAM,2CAA2C,4CAA4C,2FAA2F,mCAAmC,kBAAkB,8KAA8K,WAAW,eAAe,eAAe,8DAA8D,UAAU,yMAAyM,SAAS,iGAAiG,oBAAoB,qBAAqB,yCAAyC,8CAA8C,iCAAiC,4CAA4C,uCAAuC,8EAA8E,gBAAgB,mMAAmM,sCAAsC,8EAA8E,sCAAsC,sCAAsC,yDAAyD,qDAAqD,kBAAkB,oFAAoF,0EAA0E,2FAA2F,2EAA2E,+BAA+B,8EAA8E,kEAAkE,6GAA6G,aAAa,oDAAoD,GAAG,UAAU,GAAG,WAAW,OAAO,6mCAA6mC,qBAAqB,mCAAmC,wBAAwB,OAAO,yCAAyC,wBAAwB,OAAO,yCAAyC,wBAAwB,4BAA4B,oCAAoC,wBAAwB,yCAAyC,8BAA8B,+BAA+B,yBAAyB,WAAW,SAAS,gDAAgD,uBAAuB,SAAS,OAAO,KAAK,mCAAmC,+FAA+F,6CAA6C,2BAA2B,kBAAkB,yEAAyE,wCAAwC,oGAAoG,uEAAuE,wBAAwB,6BAA6B,wEAAwE,oBAAoB,wCAAwC,SAAS,OAAO,KAAK,GAAG,sNAAsN,WAAW,gDAAgD,iDAAiD,GAAG,uBAAuB,qBAAqB,mCAAmC,kCAAkC,yBAAyB,gDAAgD,+BAA+B,WAAW,SAAS,iFAAiF,sBAAsB,0BAA0B,0BAA0B,SAAS,OAAO,yCAAyC,mBAAmB,oGAAoG,4BAA4B,gDAAgD,+BAA+B,gCAAgC,oDAAoD,yDAAyD,4CAA4C,SAAS,OAAO,KAAK,mCAAmC,8CAA8C,6CAA6C,kCAAkC,iDAAiD,+CAA+C,kEAAkE,8DAA8D,2BAA2B,uEAAuE,uFAAuF,8JAA8J,8BAA8B,SAAS,6EAA6E,OAAO,iLAAiL,sBAAsB,OAAO,KAAK,GAAG,yDAAyD,QAAQ,iBAAiB,KAAK,YAAY,iBAAiB,KAAK,GAAG,qUAAqU,qBAAqB,4DAA4D,6CAA6C,qBAAqB,KAAK,GAAG,qBAAqB;AACrlR;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,6HAA6H,eAAe,aAAa,uBAAuB,qHAAqH,iBAAiB,6BAA6B,YAAY,mFAAmF,oBAAoB,UAAU,kGAAkG,gBAAgB,sCAAsC,uHAAuH,WAAW,OAAO,yhBAAyhB,qBAAqB,iDAAiD,wBAAwB,sBAAsB,gCAAgC,+CAA+C,4BAA4B,SAAS,OAAO,KAAK,GAAG,iNAAiN,iBAAiB,uBAAuB,iDAAiD,6BAA6B,mBAAmB,4BAA4B,2BAA2B,yJAAyJ,sCAAsC,wBAAwB,WAAW,SAAS,OAAO,KAAK,GAAG,qBAAqB;AACjqE;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gDAAgD,0DAA0D,0IAA0I,kBAAkB,wBAAwB,cAAc,iBAAiB,sJAAsJ,aAAa,oBAAoB,0DAA0D,kBAAkB,MAAM,OAAO,QAAQ,SAAS,wTAAwT,6BAA6B,gKAAgK,cAAc,0NAA0N,aAAa,OAAO,8hBAA8hB,iEAAiE,GAAG,0CAA0C,6EAA6E,yBAAyB,+BAA+B,qBAAqB,wBAAwB,8EAA8E,oBAAoB,6BAA6B,mEAAmE,2BAA2B,eAAe,gBAAgB,iBAAiB,kBAAkB,OAAO,qCAAqC,sCAAsC,OAAO,yNAAyN,uBAAuB,4CAA4C,wBAAwB,SAAS,OAAO,KAAK,GAAG,qBAAqB;AACt2F;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;ACP1B;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;;AAEjB;AACA;AACA;;AAEA;AACA,4CAA4C,qBAAqB;AACjE;;AAEA;AACA,KAAK;AACL,KAAK;AACL;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,sBAAsB,iBAAiB;AACvC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,qBAAqB,qBAAqB;AAC1C;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;ACjEa;;AAEb,kCAAkC;;AAElC,8BAA8B;;AAE9B,kDAAkD,gBAAgB,gEAAgE,wDAAwD,6DAA6D,sDAAsD;;AAE7S,uCAAuC,uDAAuD,uCAAuC,SAAS,OAAO,oBAAoB;;AAEzK,yCAAyC,8FAA8F,wBAAwB,eAAe,eAAe,gBAAgB,YAAY,MAAM,wBAAwB,+BAA+B,aAAa,qBAAqB,uCAAuC,cAAc,WAAW,YAAY,UAAU,MAAM,mDAAmD,UAAU,sBAAsB;;AAEve,gCAAgC;;AAEhC;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,uDAAuD,cAAc;AACrE;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;;;;;;;;;;;;;;;ACnCA,iEAAe,4pBAA4pB;;;;;;;;;;;;;;;ACA3qB,iEAAe,sZAAsZ;;;;;;;;;;;;;;;ACAra,iEAAe,sZAAsZ;;;;;;;;;;;;;;;ACAra,iEAAe,ufAAuf;;;;;;;;;;;;;;;ACAtgB,iEAAe,mZAAmZ;;;;;;;;;;;;;;;ACAla,iEAAe,mUAAmU;;;;;;;;;;;;;;;;;;ACAnP;AAC/F,YAA+K;;AAE/K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,2JAAO;;;;AAIxB,iEAAe,kKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAyK;;AAEzK,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,qJAAO;;;;AAIxB,iEAAe,4JAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA4K;;AAE5K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,wJAAO;;;;AAIxB,iEAAe,+JAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAgL;;AAEhL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,4JAAO;;;;AAIxB,iEAAe,mKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA0K;;AAE1K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,sJAAO;;;;AAIxB,iEAAe,6JAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAiL;;AAEjL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,6JAAO;;;;AAIxB,iEAAe,oKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAwL;;AAExL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,oKAAO;;;;AAIxB,iEAAe,2KAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAiL;;AAEjL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,6JAAO;;;;AAIxB,iEAAe,oKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA8K;;AAE9K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,0JAAO;;;;AAIxB,iEAAe,iKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAoL;;AAEpL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,gKAAO;;;;AAIxB,iEAAe,uKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAmL;;AAEnL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,+JAAO;;;;AAIxB,iEAAe,sKAAc,MAAM;;;;;;;;;;;ACZtB;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA,wDAAwD;;AAExD;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;;AAEA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,kBAAkB,iBAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,gBAAgB,KAAwC,GAAG,sBAAiB,GAAG,CAAI;;AAEnF;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA,qEAAqE,qBAAqB,cAAc;;AAExG;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA,yDAAyD;AACzD,IAAI;;AAEJ;;;AAGA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA;AACA;AACA;;AAEA;AACA,2BAA2B;AAC3B;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAoB,4BAA4B;AAChD;AACA;AACA;AACA;;AAEA;;AAEA,qBAAqB,6BAA6B;AAClD;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;AC5QA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACyC;;AAEtF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA,mCAAmC;AACnC;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gFAA8B;;AAE5D;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6BAA6B,gFAA8B;AAC3D,wBAAwB,kEAAgB;;AAExC;AACA;;AAEA,qCAAqC,qDAAqD;AAC1F;AACA;;;;;;;;;;;;;;;;;;ACjFA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACsC;;AAEnF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA,mCAAmC;AACnC;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gFAA8B;;AAE5D;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6BAA6B,gFAA8B;AAC3D,qBAAqB,+DAAa;;AAElC;AACA;;AAEA,kCAAkC,wEAAwE;AAC1G;AACA;;;;;;;;;;;;;;;;;;AChFA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACoB;;AAEjE;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA,qCAAqC,uBAAuB;AAC5D;AACA;AACA;AACe,iCAAiC,uDAAO;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,wCAAwC;AACxC;AACA,YAAY,QAAQ;AACpB,wCAAwC;AACxC;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;;AAEA,yBAAyB,+EAAyB;;AAElD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA,WAAW,iGAAiG;AAC5G,WAAW,mCAAmC;AAC9C,aAAa;AACb;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;AC1FA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACJ;AAC6B;AAChB;AACM;;AAE5D;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,kBAAkB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kFAAgC;;AAEpD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,GAAG,wEAAsB;AACzB,IAAI;AACJ;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,oBAAoB,kFAAgC;;AAEpD;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;;AAEnC;;AAEA,qCAAqC,kEAAmB;AACxD,sCAAsC,kEAAmB;;AAEzD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,2BAA2B,oDAAW,WAAW,2BAA2B;;AAE5E;AACA;;AAEA,4CAA4C,0BAA0B;AACtE;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACjRA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACN;AAC4C;AAC1B;AACG;;AAE5D;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACe,gCAAgC,uDAAO;AACtD;AACA;AACA;AACA;AACA,6BAA6B,uEAAqB;AAClD,mBAAmB,wEAAsB,+CAA+C,mDAAU;AAClG;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,mDAAU;;AAExD;AACA,8BAA8B,uEAAqB;;AAEnD;AACA;;AAEA;AACA,WAAW,0BAA0B;AACrC,GAAG,qEAAsB;AACzB,GAAG,qEAAsB;;AAEzB;AACA;AACA;;AAEA;;AAEA;AACA,GAAG,wEAAsB;;AAEzB;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,UAAU,cAAc;;AAExB;AACA;AACA;;AAEA;AACA,SAAS,6CAA6C;;AAEtD;AACA;;AAEA,UAAU;AACV;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACzHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAEJ;AAC6C;;AAEtF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;AACtD;;AAEA;AACA;AACA;;AAEA,WAAW,cAAc,EAAE,kEAAgB;;AAE3C;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,4BAA4B,oDAAW;;AAEvC;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,SAAS;AAChD;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,uCAAuC,SAAS;AAChD;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA,wBAAwB,gFAA8B;AACtD;AACA;;AAEA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACzHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAEsC;;AAEnF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;AACtD;;AAEA;AACA;AACA;AACA;;AAEA,8BAA8B,+DAAa;;AAE3C;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,yBAAyB,gFAA8B;AACvD,4BAA4B,+DAAa;;AAEzC;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACnGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAEJ;AAC2B;;AAEpE;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;;AAEtD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gFAA8B;AACvD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,8BAA8B,oDAAW,WAAW,yBAAyB;AAC7E;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;ACxEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAEsC;;AAEnF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;;AAEtD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gFAA8B;AACvD,qBAAqB,+DAAa;;AAElC;AACA;;AAEA,yCAAyC,6BAA6B;AACtE;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;;;ACjEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAKpB;AAC6D;AACA;;AAEtF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,qCAAqC,uDAAO;AAC3D;AACA;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;AACtD;AACA;;AAEA;;AAEA;AACA;AACA,MAAM,+CAA+C;AACrD;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA,yDAAyD,kEAAmB;AAC5E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA,uBAAuB;AACvB;AACA;AACA;;AAEA;AACA,wBAAwB,gFAA8B;AACtD;;AAEA,UAAU,cAAc,EAAE,kEAAgB;AAC1C;;AAEA;AACA;AACA;AACA;AACA,6BAA6B,iFAA+B;;AAE5D,kBAAkB,eAAe;AACjC,KAAK,iEAAe;AACpB;AACA;;AAEA,GAAG,qEAAsB;AACzB,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;;;AC9FA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAEY;AAC0B;AACG;;AAEtF;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;AACtD;;AAEA;;AAEA;AACA;AACA,MAAM,+CAA+C;AACrD;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;AACtD;;AAEA,UAAU,cAAc,EAAE,+DAAa;AACvC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,6BAA6B,+EAA6B;;AAE1D,kBAAkB,OAAO;AACzB,KAAK,mEAAiB;AACtB;AACA;;AAEA,GAAG,qEAAsB;AACzB,IAAI;AACJ;;AAEA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,qCAAqC;AACjD,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;ACxGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACuB;;AAEpE;AACA;AACA;AACA,iCAAiC,8CAA8C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,mCAAmC;AACnC;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,wBAAwB,gFAA8B;;AAEtD;AACA;;AAEA;AACA;AACA;AACA;AACA,oBAAoB,gFAA8B;AAClD;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACnEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE2C;AACuB;;AAElE;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa,UAAU;AACvB;AACO,2CAA2C;AAClD;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,iFAAiF,iBAAiB;AAClG;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,0BAA0B,oDAAW;;AAErC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,WAAW,YAAY;;AAEvB;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA,0BAA0B,oDAAW,WAAW,MAAM;;AAEtD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,4FAA4F,iBAAiB;AAC7G;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,0BAA0B,oDAAW,WAAW,gBAAgB;;AAEhE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,6FAA6F,iBAAiB;;AAE9G;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,+BAA+B,oDAAW,WAAW,+BAA+B;AACpF;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAE,IAAI,qBAAqB;AAC3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mEAAmE;AAC9E,aAAa;AACb;AACO;AACP,SAAS,SAAS;;AAElB;AACA;AACA;;AAEA;AACA,kDAAkD,oCAAoC;AACtF,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP;;AAEA;;AAEA;AACA;;AAEA,qBAAqB,0CAA0C;AAC/D,aAAa,6EAA6E;AAC1F,gBAAgB,oCAAoC;AACpD;AACA,WAAW,oCAAoC;AAC/C,WAAW,kDAAkD;AAC7D,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;;AAEA,QAAQ,8DAAQ,yBAAyB,2BAA2B;AACpE;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACA;AACA;;AAEA;AACA,qBAAqB,sEAAgB;;AAErC;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,YAAY,8BAA8B;AAC1C,WAAW,mEAAmE;AAC9E;AACA,SAAS,OAAO;;AAEhB;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,sCAAsC;AACjD,WAAW,mEAAmE;AAC9E;AACA;AACA;;AAEA;AACA,EAAE,sEAAgB;AAClB;;AAEA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,YAAY,8BAA8B;AAC1C,WAAW,mEAAmE;AAC9E,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,YAAY,8BAA8B;AAC1C,aAAa;AACb;AACA,SAAS,cAAc;AACvB,SAAS,8BAA8B;;AAEvC;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,YAAY,8BAA8B;AAC1C,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,oCAAoC;AAC/C,WAAW,mEAAmE;AAC9E,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,oCAAoC;AAC/C,WAAW,mEAAmE;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,oCAAoC;AAC/C,WAAW,mEAAmE;AAC9E,aAAa;AACb;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,oCAAoC;AAC/C,WAAW,mEAAmE;AAC9E;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW;AACX,aAAa;AACb;AACA;AACA;;;;;;;;;;;;;;;;ACzfA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,yDAAyD;AACrE;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C;AACe;AACf;AACA;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,iCAAiC;AAC5C;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;ACpEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C;AACe;AACf;AACA;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,iCAAiC;AAC5C;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;ACzIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEgE;;AAEhE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,wCAAwC;AACnD;AACe;AACf;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,8FAA8F,mBAAmB;AACjH;;AAEA;AACA;AACA,mGAAmG,sBAAsB;AACzH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,wCAAwC;AACnD,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,QAAQ,6EAAkC;AAC1C;;;;;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C;AACe;AACf;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wFAAwF,sBAAsB;;AAE9G;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACvEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE2C;AACoC;;AAE/E;AACA;AACA;AACA;AACA,YAAY,yDAAyD;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C;AACe;AACf;AACA;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,iCAAiC;AAC5C;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACA;;AAEA;;AAEA;AACA,yFAAyF,oBAAoB;;AAE7G;;AAEA;AACA,GAAG,qEAAsB;AACzB;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kFAAkF,qBAAqB;;AAEvG;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,qBAAqB,qBAAqB;AAC1C,KAAK,mEAAoB;AACzB;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa,SAAS,eAAe;AACrC;AACA;AACA;AACA;;AAEA;;AAEA,eAAe,wBAAwB,OAAO,oDAAW;AACzD;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,uBAAuB,4BAA4B;AACnD;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACA;AACA;;AAEA,eAAe,WAAW,OAAO,oDAAW,WAAW,wBAAwB;AAC/E;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACnZA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACO;AACP,SAAS,+EAA+E;;AAExF;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,wDAAwD,gBAAgB;;AAExE;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACO,iDAAiD,0CAA0C;AAClG;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACO,+CAA+C,4BAA4B;AAClF,8EAA8E,gBAAgB;AAC9F,UAAU,0BAA0B;AACpC,UAAU,iBAAiB;;AAE3B;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;ACzLA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEuD;AACX;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA;AACA;AACA,yDAAyD,+BAA+B;AACxF;AACA;;AAEA;AACA;;AAEA;AACA,mEAAmE,aAAa;AAChF;AACA;;AAEA;AACA,sDAAsD,+BAA+B;;AAErF;AACA;;AAEA;AACA,sBAAsB,0DAAK;;AAE3B;AACA;AACA;AACA,sDAAsD,+BAA+B;;AAErF;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACe;AACf;AACA;AACA;;AAEA;AACA,qDAAqD,aAAa;AAClE;AACA;;AAEA,WAAW,oCAAoC;;AAE/C;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,kDAAkD,aAAa;;AAE/D;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,IAAI,mEAAoB;AACxB;;AAEA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA,kEAAkE,4CAA4C;AAC9G;AACA;AACA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;AACA;AACA,GAAG,IAAI,mBAAmB;AAC1B;AACA;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB;AACO;AACP;AACA,6BAA6B,aAAa;AAC1C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG,IAAI,kBAAkB;AACzB;AACA;;AAEA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;ACvRA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACE;;AAEJ;AACV;AACc;AACA;AACF;AACN;;AAEV;;AAE5B;AACA;AACA;AACA,uCAAuC,kDAAkD;AACzF;AACA;AACA;AACA,MAAM,6DAA6D;AACnE,MAAM,mEAAmE;AACzE,MAAM,2EAA2E;AACjF,MAAM,iEAAiE;AACvE,MAAM,mEAAmE;AACzE,MAAM,8CAA8C;AACpD;AACA;AACA;AACe,oBAAoB,sDAAM;AACzC;AACA;AACA;AACA;AACA,WAAW,qDAAY,EAAE,gDAAO,EAAE,uDAAc,EAAE,mDAAU,EAAE,sDAAa,EAAE,uDAAc,EAAE,wDAAM;AACnG;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,QAAQ,sEAAsE;AAC9E;AACA;AACA;;AAEA;AACA,6BAA6B,gCAAgC;AAC7D;AACA,iBAAiB,qCAAqC;AACtD;AACA,YAAY,gCAAgC;AAC5C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,IAAI;AACJ,OAAO,4FAA4F;AACnG;AACA,aAAa,uBAAuB;AACpC;;;;;;;;;;;;;;;;;;;;ACvHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACyB;AACV;;AAExB;;AAEnC;AACA;AACA;AACA;AACA;AACe,2BAA2B,sDAAM;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,yEAAmB,EAAE,oEAAc;AAC9C;AACA;;;;;;;;;;;;;;;;;;;;;;AClCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACsB;AACV;;AAEyB;AACb;AACJ;;AAEhE;AACA;AACA;AACA;AACA;AACe,kCAAkC,sDAAM;AACvD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,2CAA2C,oBAAoB;AAC/D;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;AACJ;AACA;AACA,KAAK;AACL;;AAEA,iDAAiD,kEAAyB;;AAE1E;AACA;AACA,SAAS,gEAA4B;AACrC;AACA,IAAI;;AAEJ;AACA;AACA;AACA,2BAA2B,SAAS;AACpC,UAAU,+CAAO;AACjB;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,2BAA2B,SAAS;AACpC,UAAU,+CAAO;AACjB;AACA;;AAEA;AACA;;AAEA,IAAI,uEAAiB;AACrB;AACA;AACA;AACA;AACA,MAAM;;AAEN,WAAW,sEAAgB;AAC3B;AACA,IAAI;;AAEJ,EAAE,gFAA2B;AAC7B;;AAEA;AACA,uBAAuB,4DAA4D;AACnF;AACA;AACA,SAAS,oBAAoB;AAC7B;AACA;AACA,YAAY,qCAAqC;AACjD;AACA,cAAc,0CAA0C;AACxD;AACA;AACA;;AAEA,sBAAsB,kEAAgB;AACtC;;AAEA;AACA,aAAa,4DAA4D;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,wBAAwB;AACjC;AACA;AACA,YAAY,qCAAqC;AACjD;AACA,YAAY,qCAAqC;AACjD;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACxJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEmD;AACL;;AAES;;AAEvD;AACA;AACA;AACA;AACA;AACe,6BAA6B,sDAAM;AAClD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,oBAAoB,wDAAU;;AAE9B;AACA,UAAU,6DAAa;AACvB;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA,4CAA4C,2BAA2B;;AAEvE;AACA;AACA,iCAAiC,oEAA4B;AAC7D;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA,KAAK;;AAEL;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;ACtEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAEwC;;AAErF;AACA;AACA;AACA,kCAAkC,yEAAyE;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,2BAA2B;AACvE;AACA;AACA;AACe,wCAAwC,uDAAO;AAC9D;AACA;AACA;AACA;AACA;AACA,uBAAuB,iEAAyB;;AAEhD;;AAEA;AACA;AACA,IAAI;AACJ,kBAAkB,uEAA+B;AACjD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA,uBAAuB;AACvB,UAAU,qBAAqB;;AAE/B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB,iEAAyB;AAChD;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C;AACA;AACA;AACA,uBAAuB,iEAAyB;AAChD;AACA,yBAAyB,uEAA+B;;AAExD;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACvHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,iGAAiG;AAC5G;AACA,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI,0CAA0C;AAC9C;AACA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa,aAAa,gCAAgC,0CAA0C;AACpG;AACA;AACO;AACP;;AAEA;AACA,WAAW;AACX;;AAEA;AACA,WAAW;AACX;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;AC5FA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACoC;AACU;;AAE1F;AACA;AACA;AACA,qBAAqB,iFAAiF;AACtG,iBAAiB,oDAAoD;AACrE;AACA;AACA,IAAI,oIAAoI;AACxI,QAAQ,oHAAoH;AAC5H;AACA;AACA;AACe,kCAAkC,sDAAM;AACvD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uFAA0B,EAAE,kFAAqB;AAC5D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,mFAAmF;AACxF;AACA;AACA,IAAI,2EAA2E;AAC/E;AACA,qDAAqD,qCAAqC;AAC1F;AACA,YAAY,QAAQ;AACpB;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;;;;;;;;;;;;;;;;;;ACtHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;;AAElE;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,8CAA8C,iEAAwB;AACrF;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;AACJ;;AAE9D;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,0CAA0C,iEAAwB;AACjF;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;ACrDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;AACJ;;AAE9D;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,0CAA0C,iEAAwB;AACjF;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;ACrDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;AAC0B;;AAE5F;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,0CAA0C,iEAAwB;AACjF;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;AACU;;AAE5E;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,qCAAqC,iEAAwB;AAC5E;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;;AAElE;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,kDAAkD,iEAAwB;AACzF;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;AAC0B;;AAE5F;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,sCAAsC,iEAAwB;AAC7E;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAC0B;;AAEvE;AACA;AACA;AACA;AACA;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,6BAA6B,gFAA8B;;AAE3D;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,GAAG;AACf;AACA,YAAY,iCAAiC;AAC7C;AACA;AACA,uBAAuB;AACvB,UAAU,eAAe;AACzB;AACA,qBAAqB,gFAA8B;AACnD;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,GAAG;AACf,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;ACvIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;;AAElE;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,gDAAgD,iEAAwB;AACvF;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC3CA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkE;AACU;;AAE5E;AACA;AACA;AACA,qCAAqC,8FAA8F;AACnI;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,oCAAoC,iEAAwB;AAC3E;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC+C;;AAE4B;AAC1E;AAC4B;AACJ;AACE;AACkB;AACI;AACI;AAChB;AACA;AACA;AACN;;AAE3E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,yCAAyC,sDAAM;AAC9D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qDAAY;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,0EAA0E;;AAE1E,qCAAqC,wFAA8B;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,sCAAsC,gEAAc;AACpD;AACA;AACA;AACA;AACA,IAAI;AACJ,mDAAmD,8EAA2B;AAC9E,mDAAmD,8EAA2B;AAC9E,mDAAmD,8EAA2B;;AAE9E;AACA;AACA;AACA;AACA,IAAI;AACJ,6CAA6C,uEAAqB;;AAElE;AACA;AACA;AACA;AACA,IAAI;AACJ,8CAA8C,wEAAsB;;AAEpE,sCAAsC,iEAAe;AACrD;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ,+CAA+C,yEAAuB;;AAEtE,sCAAsC,oEAAkB;AACxD;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,OAAO,iFAA+B;AACtC;;AAEA;AACA;AACA;AACA,OAAO,qFAAmC;AAC1C;;AAEA;AACA;AACA;AACA,OAAO,mFAAiC;AACxC;AACA;AACA;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH,CAAC,+EAAkB;AACnB,CAAC,+EAAkB;AACnB,CAAC,qFAAwB,gBAAgB,8FAA8F;AACvI,CAAC,qFAAwB,gBAAgB,8FAA8F;AACvI,CAAC,qFAAwB,gBAAgB,8FAA8F;AACvI;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,4BAA4B,YAAY,+CAA+C;AAClG,WAAW,QAAQ;AACnB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,SAAS,iBAAiB;;AAE1B;AACA;AACA,GAAG;;AAEH,CAAC,mFAAsB,gBAAgB,uCAAuC;AAC9E,CAAC,qFAAwB,gBAAgB,wCAAwC;AACjF;;;;;;;;;;;;;;;;;;;;;;;;;ACrTA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC2F;;AAEpE;AAQ7B;AACD;AACuB;AAC4C;;AAExB;AACL;;AAE3E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,4FAA4F;AAChG;AACA;AACA;AACe,oCAAoC,sDAAM;AACzD;AACA;AACA;AACA;AACA,WAAW,+DAAiB;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,qEAAa;AAC9B,qBAAqB,qEAAa;AAClC,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,qCAAqC,uFAA8B;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,sCAAsC,+DAAiB;;AAEvD;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,oBAAoB,wDAAU;;AAE9B;AACA;AACA,UAAU,8EAAmB;AAC7B;AACA,KAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,2FAA2F;AAC5G;AACA;AACA,cAAc,qFAAqF;AACnG;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,uEAAqB;AAClD,gCAAgC,0EAAwB;AACxD,iCAAiC,uEAAqB;AACtD,oCAAoC,0EAAwB;AAC5D,mBAAmB,mEAAuB;AAC1C;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,SAAS,wEAAsB;AAC/B;AACA,KAAK;AACL,IAAI,wFAA2B;AAC/B;AACA,IAAI;;AAEJ;AACA,EAAE,qEAAmB;AACrB;AACA;AACA;AACA;AACA,IAAI;;AAEJ,yBAAyB,sFAA0B;AACnD,0BAA0B,uFAA2B;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,2EAAmB;AACjC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,+EAAuB;AACrC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,4EAAoB;AAClC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,4EAAoB;AAClC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,4EAAoB;AAClC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,2EAAmB;AACjC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,4BAA4B,YAAY;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;;AAEA;AACA,eAAe,aAAa,QAAQ,gBAAgB;AACpD;AACA,gDAAgD,uBAAuB;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,aAAa,uFAA0B;AACvC,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iBAAiB,aAAa,UAAU,gBAAgB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,aAAa,mBAAmB,gBAAgB;AAC7E;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,aAAa,WAAW,gBAAgB;AACrE;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA,oDAAoD,oBAAoB;AACxE;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA,oDAAoD,oBAAoB;AACxE;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,qBAAqB;AACjC,YAAY,UAAU;AACtB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA,UAAU,6DAA6D;AACvE,gCAAgC,qDAAQ;AACxC;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;AC5cA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAe0B;AAC2C;AAC1B;;AAOF;AACM;;AAEd;AACK;AACU;;AAEhD;AACA,OAAO,+DAAe;AACtB,SAAS,iEAAiB;AAC1B,QAAQ,gEAAgB;AACxB,UAAU,kEAAkB;AAC5B,MAAM,8DAAc;AACpB,SAAS,iEAAiB;AAC1B,SAAS,iEAAiB;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACe,sCAAsC,kDAAI;AACzD;AACA,YAAY,4BAA4B,YAAY,+CAA+C;AACnG,YAAY,QAAQ;AACpB,YAAY,qCAAqC;AACjD;AACA,KAAK,2GAA2G;AAChH,YAAY,qCAAqC;AACjD;AACA,KAAK,0GAA0G;AAC/G,YAAY,6DAA6D;AACzE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,sCAAsC,oBAAoB;AAC1D;AACA,cAAc;AACd;AACA;;AAEA,UAAU,0EAA0E;AACpF,UAAU,sCAAsC;AAChD,UAAU,0DAA0D;AACpE,UAAU,uEAAuE;;AAEjF;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,0BAA0B,6DAAY;;AAEtC;AACA,yBAAyB,qDAAqD;AAC9E;AACA;AACA,cAAc;AACd;AACA,wBAAwB,iEAAgB;;AAExC;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,UAAU,mCAAmC;;AAE7C;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,yBAAyB,4DAAc;;AAEvC;AACA,yBAAyB,oBAAoB;AAC7C;AACA;AACA;AACA,cAAc;AACd;AACA,0BAA0B,yDAAW;AACrC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,yBAAyB,4DAAc;AACvC;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA,QAAQ,uDAAW;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,QAAQ,uDAAW;AACnB;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAE,+DAAa;AACf;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,2BAA2B;AAClC,OAAO,wBAAwB;AAC/B,OAAO,wBAAwB;AAC/B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,uFAA2B;AACvD;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;;AAEA,6BAA6B,uDAAS;AACtC;;AAEA;;AAEA,sBAAsB,gFAAoB;AAC1C,kCAAkC,8DAAgB,UAAU,mEAAqB;AACjF;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;;AAEA,EAAE,mEAAiB,iCAAiC,qFAAyB;;AAE7E;;AAEA,+BAA+B,8DAAgB,UAAU,oEAAsB;;AAE/E;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA,+BAA+B,8DAAgB;;AAE/C;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,uBAAuB;AAC9B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA,iCAAiC,uDAAS;AAC1C;;AAEA;;AAEA,4BAA4B,uFAA2B;AACvD;AACA;AACA;AACA,IAAI;;AAEJ,8BAA8B,8DAAgB;;AAE9C;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,kBAAkB;AACzB,OAAO,mBAAmB;AAC1B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA,8BAA8B,uDAAS;AACvC;;AAEA;;AAEA,yBAAyB,8DAAgB,UAAU,oEAAsB;;AAEzE;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA,4BAA4B,kDAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,MAAM;AACN;AACA,IAAI;;AAEJ;;AAEA,0BAA0B,8DAAgB,UAAU,oEAAsB;;AAE1E;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,oBAAoB;AAC3B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA,2BAA2B,8DAAgB,UAAU,oEAAsB;;AAE3E;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA,OAAO,kCAAkC;AACzC,OAAO,gCAAgC;AACvC;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA,6BAA6B,uDAAS;;AAEtC;;AAEA;;AAEA,yCAAyC,yDAAW;AACpD;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ,EAAE,uEAAW;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;;AAEA;AACA,IAAI;AACJ;AACA,IAAI;;AAEJ;;AAEA,uCAAuC,yDAAW;;AAElD;AACA;AACA;AACA,IAAI;;AAEJ,EAAE,uEAAW;AACb;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,sBAAsB;AAC7B,OAAO,wBAAwB;AAC/B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC,+BAA+B,wDAAU;AACzC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS,2DAAW;AACpB;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,SAAS,4DAAY;AACrB;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mCAAmC,mCAAmC;AACtE;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAY;AACZ,IAAI;AACJ,YAAY;AACZ;AACA;;AAEA;AACA,mCAAmC,iCAAiC;AACpE;AACA;AACA,WAAW;AACX;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;AC/1BA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAEE;AACN;AACF;AACkG;AAW7G;;AAE3B;AACA;AACA,sCAAsC,gCAAgC;AACtE;AACA;AACA;AACe,6BAA6B,sDAAM;AAClD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uDAAc,EAAE,mDAAU;AACrC;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0GAA0G,mBAAmB;;AAE7H;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA,kDAAkD,uDAAc;;AAEhE;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,uBAAuB,6EAA6E;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qFAAqF;AACjG,YAAY,0CAA0C;AACtD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8CAA8C,mDAAU;;AAExD;AACA;;AAEA;AACA;AACA;;AAEA,6BAA6B,gFAA8B;;AAE3D;AACA,GAAG,wEAAsB;;AAEzB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAiB,uEAAqB;;AAEtC;AACA;;AAEA;;AAEA;AACA;AACA;AACA,4BAA4B,4DAAU;;AAEtC;AACA,KAAK;AACL;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,mCAAmC;AAC/C,cAAc;AACd;AACA;AACA,UAAU,2CAA2C;;AAErD;AACA;;AAEA,oCAAoC,oDAAW;AAC/C;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,cAAc;;AAEzB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,GAAG,uEAAqB;;AAExB;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,0BAA0B;AAC1B;;AAEA;AACA;;AAEA;AACA,uBAAuB;AACvB;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,oCAAoC;AAChD,YAAY,qCAAqC;AACjD,YAAY,uCAAuC;AACnD,YAAY,mCAAmC;AAC/C,cAAc,0CAA0C;AACxD;AACA;AACA,UAAU,iBAAiB;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qFAAqF;AAChG,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA,yCAAyC,0BAA0B;AACnE;AACA;;AAEA;AACA;;AAEA,wCAAwC,0BAA0B;AAClE;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,6CAA6C;AACxD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,mCAAmC;AAC9C,WAAW,oCAAoC;AAC/C,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;;AAEA,uBAAuB,kEAAgB;AACvC,oBAAoB,+DAAa;;AAEjC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gCAAgC,wEAAsB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,oEAAkB;AACxC,yBAAyB,uEAAqB;AAC9C;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,eAAe,oBAAoB,OAAO,oDAAW;AACrD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,6CAA6C;;AAEtD,sBAAsB;AACtB,yBAAyB;;AAEzB;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,0BAA0B,+EAA6B;;AAEvD;AACA,mDAAmD,oBAAoB;;AAEvE,8BAA8B,OAAO,KAAK,mEAAiB;AAC3D;;AAEA;AACA;AACA;AACA;AACA;;AAEA,0BAA0B,iFAA+B;;AAEzD;AACA,mDAAmD,kBAAkB;;AAErE,8BAA8B,eAAe,KAAK,iEAAe;AACjE;;AAEA;AACA;AACA;AACA;AACA;AACA,SAAS,cAAc;;AAEvB;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzkBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAE6E;AAQ1F;;AAEgC;AACJ;AACM;AACN;AACA;AACA;AACM;AACA;AACM;AACV;AACF;AACM;AACtB;;AAEmC;AACe;AACJ;AACe;;AAErE;;AAEnC;AACA;AACA;AACA;AACA;AACe,2BAA2B,sDAAM;AAChD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,kCAAkC,0EAAiB;;AAEnD;AACA,kCAAkC,mEAAW;;AAE7C,2CAA2C,yEAAmB,IAAI,iBAAiB;AACnF,wCAAwC,yEAAmB;;AAE3D;AACA,iDAAiD,gCAAgC;AACjF,kCAAkC,0EAAiB;;AAEnD,2CAA2C,uEAAiB;AAC5D,2CAA2C,uEAAiB;;AAE5D;AACA,iDAAiD,iCAAiC;AAClF,iDAAiD,iCAAiC;AAClF,kCAAkC,mFAA0B;AAC5D,kCAAkC,mFAA0B;;AAE5D,2CAA2C,wEAAkB;;AAE7D;AACA;AACA;AACA,SAAS,6EAA2B;AACpC;AACA,IAAI;;AAEJ;AACA,uDAAuD,oCAAoC;AAC3F;AACA,YAAY,oDAAoD;AAChE;AACA,IAAI;;AAEJ,uDAAuD,oCAAoC;AAC3F;AACA,YAAY,oDAAoD;AAChE;AACA,IAAI;;AAEJ;AACA,2CAA2C,uFAAiC;;AAE5E;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,0CAA0C,oEAAkB;AAC5D,kDAAkD,kEAAgB,YAAY,iBAAiB;AAC/F,kDAAkD,kEAAgB,YAAY,iBAAiB;AAC/F,oDAAoD,qEAAmB,YAAY,gBAAgB;AACnG,qDAAqD,qEAAmB,YAAY,iBAAiB;;AAErG,6CAA6C,kEAAgB;AAC7D,gDAAgD,qEAAmB;;AAEnE,uDAAuD,kEAAgB,YAAY,0BAA0B;AAC7G,yDAAyD,kEAAgB,YAAY,4BAA4B;;AAEjH,8CAA8C,oEAAiB;;AAE/D,kDAAkD,kEAAgB,YAAY,qBAAqB;AACnG,iDAAiD,kEAAgB,YAAY,oBAAoB;AACjG,iDAAiD,kEAAgB,YAAY,oBAAoB;AACjG,+CAA+C,kEAAgB,YAAY,kBAAkB;;AAE7F,mDAAmD,yEAAsB;AACzE,gDAAgD,sEAAmB;;AAEnE,6CAA6C,mEAAgB;AAC7D,gDAAgD,sEAAmB;;AAEnE,EAAE,8FAAsC;AACxC,EAAE,gFAA0B;AAC5B,EAAE,sFAA+B;AACjC,EAAE,wFAAiC;AACnC;;AAEA;AACA;AACA;AACA;AACA,WAAW,wDAAU;AACrB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,UAAU;AACvB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACrOA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE8C;AACN;;AAEI;AAC4B;AACoB;;AAE5F;AACA;AACA,sCAAsC,gCAAgC;AACtE;AACA;AACA;AACe,4BAA4B,sDAAM;AACjD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uDAAc;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iGAAiG,kBAAkB;AACnH,oEAAoE,kBAAkB;AACtF,2EAA2E,kBAAkB;;AAE7F,yFAAyF,mBAAmB;AAC5G;;AAEA;AACA,aAAa,kEAAkE;AAC/E;AACA;AACA;AACA,YAAY,sDAAsD;AAClE,YAAY,UAAU;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,2BAA2B,kEAAkE;AAC7F;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;;AAEA;AACA;AACA,mBAAmB,kFAAgC;;AAEnD;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;;AAEP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA,aAAa,kEAAkE;AAC/E;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,uDAAuD;AACnE;AACA;AACA;AACA;;AAEA,oBAAoB,sFAAiC;AACrD;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,4BAA4B;AACxC,YAAY,SAAS;AACrB,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB,uEAAqB;;AAE7C;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,yCAAyC;AACrD,YAAY,qCAAqC;AACjD,YAAY,SAAS;AACrB,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA,kCAAkC,gDAAgD;;AAElF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,4BAA4B;AACxC,YAAY,SAAS;AACrB;AACA;AACA;;AAEA;AACA,4BAA4B,oDAAW,WAAW,wBAAwB;AAC1E,UAAU,mCAAmC;;AAE7C,6CAA6C,OAAO;AACpD,QAAQ,cAAc;;AAEtB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;;AAEL;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA;;;;;;;;;;;;;;;;;;;;;ACrWA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAEE;AACqB;;AAEE;;AAErE;AACA;AACA,sCAAsC,gCAAgC;AACtE;AACA;AACA;AACe,yBAAyB,sDAAM;AAC9C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uDAAc;AACzB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,mCAAmC,uEAAmB;;AAEtD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6CAA6C,uDAAc;;AAE3D;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,wDAAwD,kFAAgC;;AAExF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG,IAAI,sBAAsB;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6CAA6C,uDAAc;;AAE3D;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG,IAAI,sBAAsB;AAC7B;;AAEA;AACA;AACA;AACA;AACA,YAAY,uDAAuD;AACnE,cAAc,+CAA+C;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,mDAAmD,oBAAoB;AACvE;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;ACzNA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwD;;AAExD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,oCAAoC,WAAW,gDAAgD;AACnG;AACA,sCAAsC,kDAAkD;AACxF;AACA;AACA;AACe,kCAAkC,kEAAgB;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,0EAA0E;AAC5F;AACA;AACA,IAAI,2EAA2E;AAC/E,OAAO,oCAAoC,WAAW,gDAAgD;AACtG;AACA;AACA;AACA,WAAW,uDAAuD;AAClE;;AAEA;AACA;AACA;AACA,kBAAkB,0EAA0E;AAC5F;AACA;AACA,IAAI,2EAA2E;AAC/E,OAAO,oCAAoC,WAAW,gDAAgD;AACtG;AACA;AACA;AACA,WAAW,uDAAuD;AAClE;;;;;;;;;;;;;;;;;;;ACvEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAEkC;AACV;;AAEpE;AACA;AACA;AACA,qBAAqB,iFAAiF;AACtG,iBAAiB,4DAA4D;AAC7E;AACA;AACA,IAAI,mHAAmH;AACvH,QAAQ,mGAAmG;AAC3G;AACA;AACA;AACe,8BAA8B,sDAAM;AACnD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+EAAsB,EAAE,0EAAiB;AACpD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,mFAAmF;AACxF;AACA;AACA,IAAI,2EAA2E;AAC/E;AACA,qDAAqD,qCAAqC;AAC1F;AACA,YAAY,QAAQ;AACpB;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;AACA,cAAc,QAAQ;AACtB;;;;;;;;;;;;;;;;;ACpHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;;AAE1D;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,oCAAoC,6DAAoB;AACvE;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;;AAE1D;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,0CAA0C,6DAAoB;AAC7E;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;AACI;;AAE9D;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,sCAAsC,6DAAoB;AACzE;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;ACrDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;AACI;;AAE9D;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACe,sCAAsC,6DAAoB;AACzE;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;ACrDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;AACkC;;AAE5F;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,sCAAsC,6DAAoB;AACzE;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,uEAAc;;AAE9B;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;AACkB;;AAE5E;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,iCAAiC,6DAAoB;AACpE;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAE7C;AACA;AACA;AACA;AACA;AACA;AACA;AACe,mCAAmC,uDAAO;AACzD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,GAAG;AACf;AACA,YAAY,iCAAiC;AAC7C;AACA;AACA,uBAAuB;AACvB;AACA;;AAEA,UAAU,eAAe;;AAEzB;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,GAAG;AACf,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC3HA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE0D;AACkB;;AAE5E;AACA;AACA;AACA,qCAAqC,kFAAkF;AACvH;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACe,gCAAgC,6DAAoB;AACnE;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,qFAA4B;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC8B;;AAE/B;AAMJ;AAC0C;AACR;AACA;AACA;AACZ;AACE;AACM;AACM;;AAE3E;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,qCAAqC,sDAAM;AAC1D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qDAAY;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,sEAAsE;;AAEtE,iCAAiC,wFAA8B;AAC/D;AACA,IAAI;;AAEJ,sCAAsC,gEAAc;AACpD;AACA;AACA;AACA;AACA,IAAI;AACJ,+CAA+C,yEAAuB;AACtE,+CAA+C,yEAAuB;AACtE,+CAA+C,yEAAuB;;AAEtE;AACA,6CAA6C,wEAAqB;;AAElE;AACA;AACA;AACA;AACA,IAAI;AACJ,yCAAyC,mEAAiB;;AAE1D;AACA;AACA;AACA;AACA,IAAI;AACJ,0CAA0C,oEAAkB;;AAE5D,sCAAsC,oEAAkB;AACxD;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,OAAO,6EAA2B;AAClC;AACA;AACA;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH,CAAC,+EAAkB;;AAEnB,CAAC,mFAAsB,gBAAgB,mEAAmE;AAC1G,CAAC,mFAAsB,gBAAgB,mEAAmE;AAC1G,CAAC,mFAAsB,gBAAgB,mEAAmE;AAC1G;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,IAAI;;AAEJ;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,SAAS,iBAAiB;;AAE1B;AACA;AACA,GAAG;AACH,CAAC,mFAAsB,gBAAgB,mCAAmC;AAC1E,CAAC,mFAAsB;AACvB;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,gDAAgD;AAC3D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,SAAS,iBAAiB;;AAE1B;AACA;AACA,GAAG;AACH,CAAC,mFAAsB,gBAAgB,8CAA8C;AACrF,CAAC,qFAAwB,gBAAgB,oCAAoC;AAC7E;;;;;;;;;;;;;;;;;;;;;;;;;ACtPA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC2F;;AAElG;;AAEsB;AACY;AAQjC;AACsB;AAC6C;AAC9B;;AAE3E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,4FAA4F;AAChG;AACA;AACA;AACe,gCAAgC,sDAAM;AACrD;AACA;AACA;AACA;AACA,WAAW,+DAAiB;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,qEAAa;AAC9B,qBAAqB,qEAAa;AAClC,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,iCAAiC,uFAA8B;AAC/D;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,sCAAsC,+DAAiB;;AAEvD;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,oBAAoB,wDAAU;;AAE9B;AACA;AACA,UAAU,yEAAe;AACzB;AACA,KAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,+EAA+E;AAChG;AACA;AACA,cAAc,yEAAyE;AACvF;AACA;AACA;AACA;AACA;AACA,6BAA6B,uEAAqB;AAClD,gCAAgC,0EAAwB;AACxD,iCAAiC,uEAAqB;AACtD,oCAAoC,0EAAwB;;AAE5D,mBAAmB,+DAAmB;AACtC;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,EAAE,qEAAmB;AACrB;AACA;AACA;AACA;AACA,IAAI;;AAEJ,yBAAyB,sFAA0B;AACnD,0BAA0B,uFAA2B;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,2EAAmB;AACjC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,+EAAuB;AACrC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,2EAAmB;AACjC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,4EAAoB;AAClC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,cAAc,4EAAoB;AAClC;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,4BAA4B,YAAY;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;;AAEA;AACA,eAAe,aAAa,QAAQ,gBAAgB;AACpD;AACA,kDAAkD,uBAAuB;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA,aAAa,wFAA2B;AACxC,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA,iBAAiB,aAAa,UAAU,gBAAgB;AACxD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,iBAAiB,cAAc,aAAa;AACjE;AACA;AACA;AACA;AACA;AACA;;AAEA,QAAQ,wEAAsB;AAC9B;AACA,IAAI;AACJ,GAAG,wFAA2B;AAC9B;AACA;;AAEA;AACA,6BAA6B,aAAa,uBAAuB,gBAAgB;AACjF;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,aAAa,WAAW,gBAAgB;AACrE;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA,gDAAgD,oBAAoB;AACpE;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA,gDAAgD,oBAAoB;AACpE;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,qBAAqB;AACjC,YAAY,UAAU;AACtB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA,UAAU,6DAA6D;AACvE,gCAAgC,qDAAQ;AACxC;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;ACjcA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAe0B;AAC2C;AAC1B;;AAOF;AACM;;AAEd;AACK;AACM;;AAE5C;AACA,OAAO,gEAAgB;AACvB,SAAS,kEAAkB;AAC3B,QAAQ,iEAAiB;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACe,kCAAkC,kDAAI;AACrD;AACA,YAAY,4BAA4B,YAAY,+CAA+C;AACnG,YAAY,QAAQ;AACpB,YAAY,qCAAqC;AACjD;AACA,KAAK,+FAA+F;AACpG,YAAY,qCAAqC;AACjD;AACA,KAAK,8FAA8F;AACnG,YAAY,qDAAqD;AACjE;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,sCAAsC,oBAAoB;AAC1D;AACA;AACA,cAAc;AACd;AACA;;AAEA,UAAU,0EAA0E;AACpF,UAAU,sCAAsC;AAChD,UAAU,0DAA0D;AACpE,UAAU,mCAAmC;;AAE7C;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,0BAA0B,6DAAY;;AAEtC;AACA,yBAAyB,qDAAqD;AAC9E;AACA;AACA,cAAc;AACd;AACA,wBAAwB,iEAAgB;;AAExC;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,UAAU,mCAAmC;;AAE7C;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,yBAAyB,4DAAc;;AAEvC;AACA,yBAAyB,oBAAoB;AAC7C;AACA;AACA;AACA,cAAc;AACd;AACA,0BAA0B,yDAAW;AACrC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,yBAAyB,4DAAc;AACvC;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ,yBAAyB,uDAAW;AACpC;AACA;AACA,QAAQ,uDAAW;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,QAAQ,uDAAW;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,IAAI;;AAEJ;AACA,yBAAyB,uDAAW;AACpC;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,EAAE,+DAAa;AACf;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,2BAA2B;AAClC,OAAO,wBAAwB;AAC/B,OAAO,wBAAwB;AAC/B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,4BAA4B,uFAA2B;AACvD;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;;AAEA,6BAA6B,uDAAS;AACtC;;AAEA;;AAEA,sBAAsB,gFAAoB;AAC1C,kCAAkC,8DAAgB,UAAU,mEAAqB;AACjF;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;;AAEA,EAAE,mEAAiB,iCAAiC,qFAAyB;;AAE7E;;AAEA,+BAA+B,8DAAgB,UAAU,oEAAsB;;AAE/E;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA,+BAA+B,8DAAgB;;AAE/C;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,uBAAuB;AAC9B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA,iCAAiC,uDAAS;AAC1C;;AAEA;;AAEA,iCAAiC,uFAA2B;AAC5D;AACA;AACA;AACA,IAAI;;AAEJ,8BAA8B,8DAAgB;;AAE9C;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,kBAAkB;AACzB,OAAO,mBAAmB;AAC1B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA,8BAA8B,uDAAS;AACvC;;AAEA;;AAEA,yBAAyB,8DAAgB,UAAU,oEAAsB;;AAEzE;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA,4BAA4B,kDAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,MAAM;AACN;AACA,IAAI;;AAEJ;;AAEA,0BAA0B,8DAAgB,UAAU,oEAAsB;;AAE1E;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,wBAAwB;AAC/B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;;AAEA,6BAA6B,uDAAS;AACtC;;AAEA;;AAEA,+BAA+B,yDAAW;AAC1C;AACA;AACA;AACA,IAAI;;AAEJ,EAAE,uEAAW;AACb;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,OAAO,sBAAsB;AAC7B,OAAO,wBAAwB;AAC/B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA,6BAA6B,wDAAU;AACvC,+BAA+B,wDAAU;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,SAAS,2DAAW;AACpB;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,SAAS,4DAAY;AACrB;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mCAAmC,yBAAyB;AAC5D;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,YAAY;AACZ,IAAI;AACJ,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;ACjuBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACA;;AAEJ;AACF;;AAE+D;AACc;;AAE9E;;AAErC;AACA;AACA,sCAAsC,gCAAgC;AACtE;AACA;AACA;AACe,6BAA6B,sDAAM;AAClD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,mDAAU;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,oGAAoG,mBAAmB;;AAEvH;AACA,iCAAiC;AACjC;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA,wBAAwB,uEAAqB;;AAE7C;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,WAAW,uCAAuC,EAAE,kEAAgB;AACpE,WAAW,iCAAiC,EAAE,+DAAa;;AAE3D;;AAEA;AACA;;AAEA;AACA;AACA,QAAQ,wEAAsB;AAC9B;AACA;AACA;AACA;AACA;AACA;;AAEA,sBAAsB,oEAAkB;AACxC,yBAAyB,uEAAqB;AAC9C;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,iBAAiB,uEAAqB;;AAEtC;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,qCAAqC;AACjD;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,cAAc,qCAAqC;AACnD;AACA;AACA;AACA,0BAA0B,0DAAK;AAC/B;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,GAAG,IAAI,qBAAqB;;AAE5B;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,kDAAkD,kBAAkB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAM;AACN;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,WAAW;AACvB;AACA;AACA;AACA;AACA;AACA,6BAA6B,uEAAqB;;AAElD;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,qCAAqC;AACjD,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,gBAAgB,YAAY,OAAO,oDAAW;AAC9C;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACpWA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACmB;AACoB;;AAEnF;AACA;AACA;AACA;AACA,IAAI,4FAA4F;AAChG;AACA;AACA,IAAI,gGAAgG;AACpG;AACA;AACA;AACe,2BAA2B,sDAAM;AAChD;AACA;AACA;AACA;AACA,WAAW,yEAAuB;AAClC;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,yEAAuB;;AAE7E;;AAEA;;AAEA;AACA;AACA;AACA;AACA,uBAAuB,oEAAsB;AAC7C,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,uBAAuB,oEAAsB;AAC7C,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA,QAAQ,8CAA8C;AACtD;AACA,8BAA8B,oCAAoC;AAClE,OAAO,kDAAkD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,+EAA+E;AACnF;AACA,+CAA+C,2DAA2D;AAC1G;AACA,YAAY,gBAAgB;AAC5B;;AAEA;AACA;AACA,QAAQ,8CAA8C;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,+EAA+E;AACnF;AACA,+CAA+C,2DAA2D;AAC1G;AACA,YAAY,gBAAgB;AAC5B;;;;;;;;;;;;;;;;;;;;;;;;AC9GA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACiD;AAC5C;;AAEE;;AAEA;AACa;AACN;AACa;;AAEvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uFAAuF,6CAA6C;AACpI;AACA;AACA;AACe,sBAAsB,sDAAM;AAC3C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB,gEAAc;;AAEtC;;AAEA;AACA;AACA,UAAU,8DAAS;AACnB;AACA;AACA,KAAK;;AAEL;;AAEA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,2DAAe;AACzC;;AAEA;;AAEA;AACA;AACA;AACA;AACA,MAAM;;AAEN;AACA,sCAAsC,+DAA+D;AACrG;AACA,MAAM;AACN,KAAK;;AAEL;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,MAAM,mBAAmB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,gDAAgD,qEAAe;AAC/D,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,MAAM,mBAAmB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,6CAA6C,kEAAY;AACzD,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,MAAM,mBAAmB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qEAAqE,yEAAkB;AACvF,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,6DAA6D;AACzE,YAAY,4BAA4B;AACxC,cAAc;AACd;AACA;AACA;AACA,uBAAuB,gEAAc;AACrC;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA,oCAAoC,iEAAiE;AACrG;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,6DAA6D;AACzE,YAAY,4BAA4B;AACxC,cAAc;AACd;AACA;AACA;AACA,uBAAuB,gEAAc,UAAU,6DAAe;AAC9D;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA,eAAe,wCAAwC;AACvD;AACA;AACA;AACA,YAAY,8CAA8C;AAC1D,YAAY,6DAA6D;AACzE,cAAc,qCAAqC;AACnD;AACA;AACA;AACA;AACA,8BAA8B,2DAAU;;AAExC;AACA;AACA;;AAEA,EAAE,mEAAiB;;AAEnB;AACA;AACA;;AAEA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,kCAAkC;AAC7C,WAAW,qCAAqC;AAChD,WAAW,gEAAgE;AAC3E;AACA;AACA,kCAAkC,mDAAK;AACvC,SAAS,wBAAwB;;AAEjC;AACA;;AAEA;;AAEA,eAAe,cAAc;;AAE7B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;;;;;;;;;;;;;;;;;;;;AC/WA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEoD;AACR;;AAEJ;AACsC;AACN;;AAExE;AACA;AACA;AACA;AACA;AACe,yBAAyB,sDAAM;AAC9C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,sBAAsB;AACtB;AACA,YAAY,qCAAqC;AACjD,cAAc,QAAQ,YAAY,YAAY;AAC9C;AACA;AACA;AACA;;AAEA;;AAEA,0BAA0B,oDAAW,WAAW,gBAAgB;;AAEhE,gBAAgB,oBAAoB;AACpC;AACA,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA,+BAA+B,qDAAqD;AACpF;AACA;AACA;AACA,sDAAsD,sBAAsB;AAC5E;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc,qCAAqC;AACnD;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,GAAG,qEAAsB;AACzB;;AAEA;AACA,GAAG,qEAAsB;AACzB;;AAEA;AACA;;AAEA;AACA;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,mBAAmB;AAC/B;AACA;AACA,iCAAiC;AACjC;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,8DAAa;AAC1B;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;;AAEA;AACA;AACA,IAAI,qEAAsB;AAC1B;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,6BAA6B,oDAAW,WAAW,uBAAuB;;AAE1E;AACA;;AAEA,iBAAiB,2CAA2C;AAC5D;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,2BAA2B,yBAAyB;AACpD;;AAEA;;AAEA,6BAA6B,mCAAmC;AAChE;AACA;;AAEA;AACA;AACA,MAAM,mEAAoB,0CAA0C,UAAU;AAC9E;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA,gEAAgE,oBAAoB;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,oCAAoC;AACpC;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA,2BAA2B,oDAAW,WAAW,0CAA0C;;AAE3F;AACA,YAAY,oEAAoE;;AAEhF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,wBAAwB,kBAAkB;AAC1C;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,iBAAiB;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,8DAAa;AAC1B;AACA;AACA,MAAM;AACN;AACA;;AAEA;AACA;AACA;;AAEA;AACA,WAAW,2BAA2B;;AAEtC;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,uBAAuB,YAAY;AACnC;AACA;;AAEA;AACA,iBAAiB,gBAAgB;AACjC,IAAI,qEAAsB;AAC1B;;AAEA;AACA;;AAEA;AACA,SAAS,oEAAkB;AAC3B;AACA;AACA,IAAI,iEAAe;AACnB;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,oBAAoB;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC,aAAa;;AAE/C,wCAAwC,6BAA6B;AACrE,kBAAkB,0BAA0B,YAAY,oDAAW;AACnE;AACA;AACA,MAAM,qEAAsB;AAC5B,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA,SAAS,iEAAe;AACxB;AACA;AACA,IAAI,oEAAkB;AACtB;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,4BAA4B;;AAExC,IAAI,qEAAsB;;AAE1B;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,8BAA8B,oDAAW;;AAEzC;AACA,YAAY,0BAA0B,qBAAqB,OAAO;;AAElE;AACA,+CAA+C,0BAA0B;AACzE;AACA;;AAEA;AACA,MAAM;;AAEN;AACA,kBAAkB,kBAAkB;AACpC;AACA;;AAEA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,KAAK,qEAAsB;AAC3B;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,8BAA8B,oDAAW;AACzC;AACA;AACA;AACA,MAAM;;AAEN;AACA,YAAY,4BAA4B;;AAExC,IAAI,qEAAsB;;AAE1B,YAAY,qBAAqB,qBAAqB,OAAO;;AAE7D;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,aAAa,cAAc;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,8BAA8B,oDAAW,WAAW,oCAAoC;;AAExF;AACA,kBAAkB,wBAAwB;AAC1C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA,KAAK,qEAAsB;AAC3B;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,4FAA4F;AAC5F,kBAAkB,UAAU;AAC5B;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,mCAAmC;AAC9C,WAAW,uCAAuC;AAClD,qEAAqE;AACrE,kBAAkB,WAAW;AAC7B,EAAE,mEAAoB;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,cAAc;AACd;AACA;AACA,WAAW;AACX;;AAEA;AACA;;AAEA,UAAU;AACV;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,EAAE,qEAAsB;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,eAAe,gCAAgC,OAAO,oDAAW,WAAW,eAAe;AAC3F;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,UAAU;AACV;;AAEA;AACA,yBAAyB,oDAAW;AACpC;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;;AAEA,eAAe,yBAAyB;AACxC;AACA,WAAW,4BAA4B;;AAEvC;AACA;AACA;;AAEA;AACA,GAAG,qEAAsB;;AAEzB;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACh7BA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,4BAA4B,gBAAgB;;AAE5C;AACA;AACA,IAAI,0CAA0C;AAC9C;AACe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,0CAA0C;AACnD;AACA;AACA;AACA,mDAAmD,yBAAyB;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,gCAAgC;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ,WAAW;AAC/B,YAAY,QAAQ;AACpB;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA,6DAA6D,yBAAyB;AACtF;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,cAAc,oCAAoC;AAClD;AACA;AACA;;AAEA;AACA;AACA,YAAY;AACZ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,uCAAuC,eAAe;AACtD;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA,wCAAwC;AACxC;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,eAAe,uBAAuB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,qCAAqC,mCAAmC;AACxE,4CAA4C,yCAAyC;AACrF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,0BAA0B,4CAA4C;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sCAAsC;AAClD,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,6CAA6C;AAC9D;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;;AAEA,sCAAsC;AACtC,oCAAoC;AACpC,oCAAoC;AACpC,sCAAsC;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;;AAEA;AACA;AACA;AACA,sBAAsB;AACtB;;;;;;;;;;;;;;;;;;;AC5jBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkG;AACvD;;AAEP;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;AACe,6BAA6B,kDAAI;AAChD;AACA;AACA;AACA,YAAY,4BAA4B;AACxC,YAAY,QAAQ;AACpB,YAAY,uDAAuD;AACnE;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;AACA,MAAM,yEAAyE;AAC/E;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA,0DAA0D,kBAAkB;AAC5E;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAAgC,qBAAqB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAc;AACjC,2BAA2B,kDAAI;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,2CAA2C,sDAAsD;AACjG;AACA;AACA,cAAc,iDAAiD,oCAAoC,kBAAkB;AACrH;AACA;AACA;AACA,wBAAwB,2DAAa;;AAErC;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wDAAU;AAC1C;AACA;;AAEA;AACA;AACA,2BAA2B,4DAAY;AACvC;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA,sDAAsD,qBAAqB;AAC3E;AACA;AACA;AACA;AACA,wBAAwB,2DAAa;AACrC;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA,UAAU,kBAAkB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;AC1VA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwC;;AAEP;;AAEjC;AACA;AACA,YAAY,0FAA0F;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACe,0BAA0B,kDAAI;AAC7C;AACA;AACA;AACA,YAAY,4BAA4B;AACxC,YAAY,QAAQ;AACpB,YAAY,6BAA6B;AACzC,YAAY,QAAQ;AACpB,YAAY,qBAAqB;AACjC;AACA;AACA,mCAAmC;AACnC;;AAEA;;AAEA;AACA,2CAA2C,eAAe;AAC1D;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;;AAEA;AACA,qEAAqE,eAAe;AACpF;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA,gFAAgF,eAAe;AAC/F;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;ACtGA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwC;;AAED;;AAEvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,8BAA8B,kDAAI;AACjD;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA,gEAAgE,OAAO,KAAK,SAAS;;AAErF;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,MAAM;;AAEN;AACA;AACA,MAAM;AACN;AACA,IAAI;;AAEJ;AACA,WAAW,cAAc;;AAEzB;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA,cAAc,yCAAyC;AACvD;AACA;AACA;;AAEA;AACA,uBAAuB,aAAa;AACpC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,gDAAgD,8BAA8B;AAC9E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,kEAAkE,sDAAsD;AACxH;AACA;AACA;AACA,mCAAmC,kDAAI;AACvC;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;AC7NA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,GAAG;AACd,WAAW,+BAA+B;AAC1C,WAAW,mCAAmC;AAC9C,WAAW,GAAG;AACd;AACO;AACP;AACA;AACA,GAAG;AACH;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,mCAAmC;AAC9C,WAAW,uCAAuC;AAClD,WAAW,QAAQ;AACnB,aAAa,qCAAqC;AAClD;AACO,uEAAuE;AAC9E;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP;AACA;AACA,SAAS,SAAS;;AAElB;AACA;;;;;;;;;;;;;;;;;;;;;;;ACxDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyC;;AAEzC;AACA;AACA;AACA;AACA;AACA,IAAI,oEAAoE;AACxE;AACA,WAAW,yCAAyC;AACpD,aAAa;AACb;AACO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,IAAI,6CAA6C;AACjD;AACA;AACA,IAAI,yDAAyD;AAC7D;AACA,WAAW,yCAAyC;AACpD,aAAa;AACb;AACO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAI,6DAA6D;AACjE;AACA,aAAa,qEAAqE;AAClF,IAAI,yDAAyD;AAC7D;AACA,WAAW,yCAAyC;AACpD,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,cAAc;AAC1B;AACA,oCAAoC,QAAQ,MAAM,MAAM;AACxD;AACA,WAAW,6CAA6C;AACxD,aAAa,QAAQ;AACrB;AACO;AACP;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,cAAc;AAC1B;AACA,uCAAuC,QAAQ,MAAM,MAAM;AAC3D;AACA,WAAW,6CAA6C;AACxD,aAAa,QAAQ;AACrB;AACO;AACP;AACA,2BAA2B,oDAAW;;AAEtC;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,6CAA6C;AACxD,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,UAAU,cAAc;AACxB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,4CAA4C;AACvD,YAAY;AACZ;AACO;AACP;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA,UAAU;AACV;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,gBAAgB;AAC3B,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,oCAAoC,aAAa;AACjD;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnRA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyC;AAC+B;;AAExE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,mCAAmC;AAC9C,aAAa;AACb;AACO;AACP,SAAS,2CAA2C;;AAEpD;AACA;AACA;;AAEA,kBAAkB,gBAAgB;AAClC;AACA;;AAEA,2BAA2B,oDAAW,iBAAiB,kEAAkE;;AAEzH;AACA,eAAe,mGAAmG;AAClH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,6DAAoB;AACxB;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;;AAEA,yBAAyB,oDAAW,WAAW,mCAAmC;;AAElF;AACA,UAAU,kBAAkB;AAC5B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,mCAAmC;AAC9C,aAAa,qCAAqC;AAClD;AACO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,2BAA2B,oDAAW,WAAW,0CAA0C;;AAE3F;AACA;;AAEA;AACA,UAAU,oBAAoB;;AAE9B;AACA;AACA;;AAEA;AACA,aAAa,6DAAoB;AACjC;AACA;;AAEA;AACA,CAAC,+DAAsB;;AAEvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;;AAEA,yBAAyB,oDAAW;;AAEpC;AACA,UAAU,oBAAoB;AAC9B;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,mCAAmC;AAC9C,aAAa,qCAAqC;AAClD;AACO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,iBAAiB,6DAAoB;;AAErC;AACA,CAAC,+DAAsB;;AAEvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,mCAAmC;AAC9C;AACO;AACP;AACA;;AAEA;;AAEA;AACA;;AAEA,EAAE,+DAAsB;AACxB;;AAEA;;AAEA;AACA;;AAEA,EAAE,+DAAsB;AACxB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,EAAE,+DAAsB;AACxB;;AAEA;;AAEA;AACA;AACA,EAAE,+DAAsB;AACxB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,oFAAoF;AAC5H;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,oCAAoC;AAC/C,aAAa,SAAS;AACtB;AACO;AACP;AACA;;AAEA,eAAe,SAAS,OAAO,oDAAW;AAC1C;AACA;;AAEA;AACA;AACA,EAAE;;AAEF;AACA;AACA;;AAEA,mEAAmE,aAAa;AAChF,qCAAqC,kBAAkB;;AAEvD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,8EAA8E;AACnH;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,oCAAoC;AAC/C,aAAa,SAAS;AACtB;AACO;AACP;AACA;;AAEA,yBAAyB,0BAA0B;AACnD;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,gEAAgE,UAAU;AAC1E,kCAAkC,eAAe;;AAEjD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,+EAA+E;AACrH,IAAI,qFAAqF;AACzF;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,oCAAoC;AAC/C;AACO;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP,oCAAoC,oDAAW;AAC/C;AACA;AACA;AACA,GAAG;;AAEH,yDAAyD,aAAa;;AAEtE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACO;AACP,uCAAuC,oDAAW;AAClD;AACA;AACA;AACA,GAAG;;AAEH,4DAA4D,YAAY;;AAExE;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC/hBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEqC;;AAErC;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,uDAAuD;AAC7E;AACA;AACA;AACA,sBAAsB,uDAAuD;AAC7E,sBAAsB,2BAA2B;AACjD;AACA;AACA,aAAa;AACb;AACO;AACP,0BAA0B,qDAAQ;AAClC;AACA;;AAEA,SAAS,2BAA2B;;AAEpC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC,iCAAiC;AACjC,oCAAoC;AACpC,mCAAmC;AACnC;AACA,WAAW,GAAG;AACd,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,YAAY,cAAc,GAAG,aAAa;AAC1C;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ,WAAW;AAC9B,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa;AACb;AACO,8DAA8D;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;;AAEF;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;AC1GA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE2C;AACS;;AAEF;;AAElD,kCAAkC,+EAAiC;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,sFAAsF;AAC1F;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB;AACA;AACO;AACP;;AAEA,MAAM,+DAAsB;AAC5B;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAI,sFAAsF;AAC1F;AACA;AACA,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,sFAAsF;AAC1F;AACA;AACA,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,WAAW,uCAAuC;AAClD,aAAa;AACb;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,4CAA4C;AACvD,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,qDAAI;AACjB,GAAG;;AAEH,QAAQ,qEAAoB;AAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5HA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEqD;AACJ;AACsB;;AAElB;;AAErD;;AAEA;AACA;AACA,oBAAoB;AACpB,QAAQ,8EAA8E;AACtF;AACA,WAAW,8BAA8B;AACzC;AACA,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC;AACA,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC;AACA,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ,8CAA8C;AACtD;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;;AAEA,4BAA4B,6DAAO;AACnC;;AAEA;AACA;AACA;AACA;AACA,QAAQ,+CAA+C;AACvD,QAAQ,mDAAmD;AAC3D;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;;AAEA,uDAAuD,8DAAQ,aAAa,kEAAY;AACxF;;AAEA;AACA;AACA;AACA;AACA,QAAQ,+CAA+C;AACvD;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;;AAEA,uDAAuD,8DAAQ;AAC/D;;AAEA;AACA;AACA;AACA,WAAW;AACX,4EAA4E;AAC5E,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP,6BAA6B,2DAAU;AACvC;;AAEA;AACA;AACA;AACA,cAAc,mDAAK;AACnB;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL,IAAI;AACJ;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW;AACX,4EAA4E;AAC5E,WAAW,gBAAgB;AAC3B,WAAW,2CAA2C;AACtD,WAAW,wBAAwB;AACnC,WAAW,QAAQ;AACnB,WAAW,UAAU;AACrB;AACO;AACP,SAAS,wEAAwE;AACjF;AACA,qBAAqB,wDAAU;;AAE/B;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA,OAAO,oFAAoF;AAC3F,IAAI,uEAAuE;AAC3E;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI,iEAAiE;AACrE,MAAM,6EAA6E;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA,WAAW,qCAAqC;AAChD;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA,aAAa;AACb;AACO;AACP;AACA,wBAAwB,0DAAc;AACtC;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,WAAW,gBAAgB;AAC3B,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;;;;;;;;;;;;;;;;;AClaA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEgD;;AAEhD;AACA;AACA;AACA,WAAW,+FAA+F;AAC1G,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,WAAW,+FAA+F;AAC1G,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACA,sDAAsD,8DAAQ;AAC9D;;;;;;;;;;;ACrDA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;;;;;;;;;;;ACA8B;;AAE9B;AACA,aAAa,uDAAW;;AAExB,iEAAe,MAAM,EAAC;;;;;;;;;;;;;;;;;;;ACLY;AACM;AACU;;AAElD;AACA;AACA;;AAEA;AACA,qBAAqB,kDAAM,GAAG,8DAAkB;;AAEhD;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,yDAAS;AACf,MAAM,8DAAc;AACpB;;AAEA,iEAAe,UAAU,EAAC;;;;;;;;;;;;;;;;;AC3B0B;;AAEpD;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA;AACA;AACA,sBAAsB,+DAAe;AACrC;AACA;;AAEA,iEAAe,QAAQ,EAAC;;;;;;;;;;;;;;;;AClBxB;AACA;;AAEA,iEAAe,UAAU,EAAC;;;;;;;;;;;;;;;;;ACHQ;;AAElC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,kDAAM,GAAG,8DAAkB;;AAEhD;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA,iEAAe,SAAS,EAAC;;;;;;;;;;;;;;;;AC7CzB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA,iEAAe,cAAc,EAAC;;;;;;;;;;;;;;;;;ACrBY;;AAE1C;AACA;;AAEA;AACA,WAAW,sDAAU;;AAErB,iEAAe,IAAI,EAAC;;;;;;;;;;;;;;;;ACRpB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;;AAEA,iEAAe,eAAe,EAAC;;;;;;;;;;;;;;;;;;;AClBM;AACV;AACU;;AAErC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,QAAQ;AACnB,WAAW,QAAQ,WAAW;AAC9B,WAAW,SAAS;AACpB;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,SAAS;AACpB;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,+CAA+C,iBAAiB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAS,wDAAQ;AACjB,MAAM,wDAAQ;AACd;AACA;AACA,iCAAiC,wDAAQ;AACzC;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,eAAe,mDAAG;AAClB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yDAAyD,mDAAG;AAC5D;;AAEA;AACA,eAAe,mDAAG;AAClB;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iEAAe,QAAQ,EAAC;;;;;;;;;;;;;;;;AC9LxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,SAAS;AACtB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iEAAe,QAAQ,EAAC;;;;;;;;;;;;;;;;AC9BxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,SAAS;AACtB;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,iEAAe,YAAY,EAAC;;;;;;;;;;;;;;;;;;AC5Bc;AACG;;AAE7C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,4DAAY,WAAW,0DAAU;AACtC;;AAEA,iEAAe,QAAQ,EAAC;;;;;;;;;;;;;;;;;AC5BM;;AAE9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,SAAS,yDAAa;AACtB;;AAEA,iEAAe,GAAG,EAAC;;;;;;;;;;;;;;;;;;;ACtBmB;AACD;AACA;;AAErC;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,GAAG;AACd,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,wDAAQ;AACd;AACA;AACA,MAAM,wDAAQ;AACd;AACA,YAAY,wDAAQ;AACpB;AACA;AACA;AACA;AACA,UAAU,wDAAQ;AAClB;AACA;AACA;AACA;AACA;;AAEA,iEAAe,QAAQ,EAAC;;;;;;;UC/DxB;UACA;;UAEA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;;UAEA;UACA;;UAEA;UACA;UACA;;;;;WCtBA;WACA;WACA;WACA;WACA;WACA,iCAAiC,WAAW;WAC5C;WACA;;;;;WCPA;WACA;WACA;WACA;WACA,yCAAyC,wCAAwC;WACjF;WACA;WACA;;;;;WCPA;;;;;WCAA;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACNA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE2C;AACc;AACV;AACU;AACc;AACkC;AACV;AAChC;AAC8B;AACV;AAC1B;AAC2B;AACV;AACb;AACR;AACM;AACE;AACR","file":"table.js","sourcesContent":["// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck.ck-input-color{width:100%;display:flex;flex-direction:row-reverse}.ck.ck-input-color>input.ck.ck-input-text{min-width:auto;flex-grow:1}.ck.ck-input-color>div.ck.ck-dropdown{min-width:auto}.ck.ck-input-color>div.ck.ck-dropdown>.ck-input-color__button .ck-dropdown__arrow{display:none}.ck.ck-input-color .ck.ck-input-color__button{display:flex}.ck.ck-input-color .ck.ck-input-color__button .ck.ck-input-color__button__preview{position:relative;overflow:hidden}.ck.ck-input-color .ck.ck-input-color__button .ck.ck-input-color__button__preview>.ck.ck-input-color__button__preview__no-color-indicator{position:absolute;display:block}[dir=ltr] .ck.ck-input-color>.ck.ck-input-text{border-top-right-radius:0;border-bottom-right-radius:0}[dir=rtl] .ck.ck-input-color>.ck.ck-input-text{border-top-left-radius:0;border-bottom-left-radius:0}.ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button{padding:0}[dir=ltr] .ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button{border-left-width:0;border-top-left-radius:0;border-bottom-left-radius:0}[dir=rtl] .ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button{border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button.ck-disabled{background:var(--ck-color-input-disabled-background)}.ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button>.ck.ck-input-color__button__preview{border-radius:0}.ck-rounded-corners .ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button>.ck.ck-input-color__button__preview,.ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button>.ck.ck-input-color__button__preview.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button>.ck.ck-input-color__button__preview{width:20px;height:20px;border:1px solid var(--ck-color-input-border)}.ck.ck-input-color>.ck.ck-dropdown>.ck.ck-button.ck-input-color__button>.ck.ck-input-color__button__preview>.ck.ck-input-color__button__preview__no-color-indicator{top:-30%;left:50%;height:150%;width:8%;background:red;border-radius:2px;transform:rotate(45deg);transform-origin:50%}.ck.ck-input-color .ck.ck-input-color__remove-color{width:100%;border-bottom:1px solid var(--ck-color-input-border);padding:calc(var(--ck-spacing-standard)/2) var(--ck-spacing-standard);border-bottom-left-radius:0;border-bottom-right-radius:0}[dir=ltr] .ck.ck-input-color .ck.ck-input-color__remove-color{border-top-right-radius:0}[dir=rtl] .ck.ck-input-color .ck.ck-input-color__remove-color{border-top-left-radius:0}.ck.ck-input-color .ck.ck-input-color__remove-color .ck.ck-icon{margin-right:var(--ck-spacing-standard)}[dir=rtl] .ck.ck-input-color .ck.ck-input-color__remove-color .ck.ck-icon{margin-right:0;margin-left:var(--ck-spacing-standard)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/colorinput.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/colorinput.css\",\"webpack://./../ckeditor5-theme-lark/theme/mixins/_rounded.css\"],\"names\":[],\"mappings\":\"AAKA,mBACC,UAAW,CACX,YAAa,CACb,0BA8BD,CA5BC,0CACC,cAAe,CACf,WACD,CAEA,sCACC,cAMD,CAHC,kFACC,YACD,CAGD,8CAEC,YAWD,CATC,kFACC,iBAAkB,CAClB,eAMD,CAJC,0IACC,iBAAkB,CAClB,aACD,CC1BF,+CAEE,yBAA0B,CAC1B,4BAOF,CAVA,+CAOE,wBAAyB,CACzB,2BAEF,CAGC,wEACC,SAoCD,CArCA,kFAIE,mBAAoB,CACpB,wBAAyB,CACzB,2BA+BF,CArCA,kFAUE,oBAAqB,CACrB,yBAA0B,CAC1B,4BAyBF,CAtBC,oFACC,oDACD,CAEA,4GC9BF,eD+CE,CAjBA,+PC1BD,qCD2CC,CAjBA,4GAGC,UAAW,CACX,WAAY,CACZ,6CAYD,CAVC,oKACC,QAAS,CACT,QAAS,CACT,WAAY,CACZ,QAAS,CACT,cAA6B,CAC7B,iBAAkB,CAClB,uBAAwB,CACxB,oBACD,CAKH,oDACC,UAAW,CACX,oDAAqD,CACrD,qEAAwE,CAExE,2BAA4B,CAC5B,4BAkBD,CAxBA,8DASE,yBAeF,CAxBA,8DAaE,wBAWF,CARC,gEACC,uCAMD,CAPA,0EAIE,cAAe,CACf,sCAEF\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-input-color {\\n\\twidth: 100%;\\n\\tdisplay: flex;\\n\\tflex-direction: row-reverse;\\n\\n\\t& > input.ck.ck-input-text {\\n\\t\\tmin-width: auto;\\n\\t\\tflex-grow: 1;\\n\\t}\\n\\n\\t& > div.ck.ck-dropdown {\\n\\t\\tmin-width: auto;\\n\\n\\t\\t/* This dropdown has no arrow but a color preview instead. */\\n\\t\\t& > .ck-input-color__button .ck-dropdown__arrow {\\n\\t\\t\\tdisplay: none;\\n\\t\\t}\\n\\t}\\n\\n\\t& .ck.ck-input-color__button {\\n\\t\\t/* Resolving issue with misaligned buttons on Safari (see #10589) */\\n\\t\\tdisplay: flex;\\n\\n\\t\\t& .ck.ck-input-color__button__preview {\\n\\t\\t\\tposition: relative;\\n\\t\\t\\toverflow: hidden;\\n\\n\\t\\t\\t& > .ck.ck-input-color__button__preview__no-color-indicator {\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tdisplay: block;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n@import \\\"@ckeditor/ckeditor5-ui/theme/mixins/_dir.css\\\";\\n@import \\\"../mixins/_rounded.css\\\";\\n\\n.ck.ck-input-color {\\n\\t& > .ck.ck-input-text {\\n\\t\\t@mixin ck-dir ltr {\\n\\t\\t\\tborder-top-right-radius: 0;\\n\\t\\t\\tborder-bottom-right-radius: 0;\\n\\t\\t}\\n\\n\\t\\t@mixin ck-dir rtl {\\n\\t\\t\\tborder-top-left-radius: 0;\\n\\t\\t\\tborder-bottom-left-radius: 0;\\n\\t\\t}\\n\\t}\\n\\n\\t& > .ck.ck-dropdown {\\n\\t\\t& > .ck.ck-button.ck-input-color__button {\\n\\t\\t\\tpadding: 0;\\n\\n\\t\\t\\t@mixin ck-dir ltr {\\n\\t\\t\\t\\tborder-left-width: 0;\\n\\t\\t\\t\\tborder-top-left-radius: 0;\\n\\t\\t\\t\\tborder-bottom-left-radius: 0;\\n\\t\\t\\t}\\n\\n\\t\\t\\t@mixin ck-dir rtl {\\n\\t\\t\\t\\tborder-right-width: 0;\\n\\t\\t\\t\\tborder-top-right-radius: 0;\\n\\t\\t\\t\\tborder-bottom-right-radius: 0;\\n\\t\\t\\t}\\n\\n\\t\\t\\t&.ck-disabled {\\n\\t\\t\\t\\tbackground: var(--ck-color-input-disabled-background);\\n\\t\\t\\t}\\n\\n\\t\\t\\t& > .ck.ck-input-color__button__preview {\\n\\t\\t\\t\\t@mixin ck-rounded-corners;\\n\\n\\t\\t\\t\\twidth: 20px;\\n\\t\\t\\t\\theight: 20px;\\n\\t\\t\\t\\tborder: 1px solid var(--ck-color-input-border);\\n\\n\\t\\t\\t\\t& > .ck.ck-input-color__button__preview__no-color-indicator {\\n\\t\\t\\t\\t\\ttop: -30%;\\n\\t\\t\\t\\t\\tleft: 50%;\\n\\t\\t\\t\\t\\theight: 150%;\\n\\t\\t\\t\\t\\twidth: 8%;\\n\\t\\t\\t\\t\\tbackground: hsl(0, 100%, 50%);\\n\\t\\t\\t\\t\\tborder-radius: 2px;\\n\\t\\t\\t\\t\\ttransform: rotate(45deg);\\n\\t\\t\\t\\t\\ttransform-origin: 50%;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t& .ck.ck-input-color__remove-color {\\n\\t\\twidth: 100%;\\n\\t\\tborder-bottom: 1px solid var(--ck-color-input-border);\\n\\t\\tpadding: calc(var(--ck-spacing-standard) / 2) var(--ck-spacing-standard);\\n\\n\\t\\tborder-bottom-left-radius: 0;\\n\\t\\tborder-bottom-right-radius: 0;\\n\\n\\t\\t@mixin ck-dir ltr {\\n\\t\\t\\tborder-top-right-radius: 0;\\n\\t\\t}\\n\\n\\t\\t@mixin ck-dir rtl {\\n\\t\\t\\tborder-top-left-radius: 0;\\n\\t\\t}\\n\\n\\t\\t& .ck.ck-icon {\\n\\t\\t\\tmargin-right: var(--ck-spacing-standard);\\n\\n\\t\\t\\t@mixin ck-dir rtl {\\n\\t\\t\\t\\tmargin-right: 0;\\n\\t\\t\\t\\tmargin-left: var(--ck-spacing-standard);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n/**\\n * Implements rounded corner interface for .ck-rounded-corners class.\\n *\\n * @see $ck-border-radius\\n */\\n@define-mixin ck-rounded-corners {\\n\\tborder-radius: 0;\\n\\n\\t@nest .ck-rounded-corners &,\\n\\t&.ck-rounded-corners {\\n\\t\\tborder-radius: var(--ck-border-radius);\\n\\t\\t@mixin-content;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck.ck-form{padding:0 0 var(--ck-spacing-large)}.ck.ck-form:focus{outline:none}.ck.ck-form .ck.ck-input-text{min-width:100%;width:0}.ck.ck-form .ck.ck-dropdown{min-width:100%}.ck.ck-form .ck.ck-dropdown .ck-dropdown__button:not(:focus){border:1px solid var(--ck-color-base-border)}.ck.ck-form .ck.ck-dropdown .ck-dropdown__button .ck-button__label{width:100%}\", \"\",{\"version\":3,\"sources\":[\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/form.css\"],\"names\":[],\"mappings\":\"AAKA,YACC,mCAyBD,CAvBC,kBAEC,YACD,CAEA,8BACC,cAAe,CACf,OACD,CAEA,4BACC,cAWD,CARE,6DACC,4CACD,CAEA,mEACC,UACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-form {\\n\\tpadding: 0 0 var(--ck-spacing-large);\\n\\n\\t&:focus {\\n\\t\\t/* See: https://github.com/ckeditor/ckeditor5/issues/4773 */\\n\\t\\toutline: none;\\n\\t}\\n\\n\\t& .ck.ck-input-text {\\n\\t\\tmin-width: 100%;\\n\\t\\twidth: 0;\\n\\t}\\n\\n\\t& .ck.ck-dropdown {\\n\\t\\tmin-width: 100%;\\n\\n\\t\\t& .ck-dropdown__button {\\n\\t\\t\\t&:not(:focus) {\\n\\t\\t\\t\\tborder: 1px solid var(--ck-color-base-border);\\n\\t\\t\\t}\\n\\n\\t\\t\\t& .ck-button__label {\\n\\t\\t\\t\\twidth: 100%;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck.ck-form__row{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.ck.ck-form__row>:not(.ck-label){flex-grow:1}.ck.ck-form__row.ck-table-form__action-row .ck-button-cancel,.ck.ck-form__row.ck-table-form__action-row .ck-button-save{justify-content:center}.ck.ck-form__row{padding:var(--ck-spacing-standard) var(--ck-spacing-large) 0}[dir=ltr] .ck.ck-form__row>:not(.ck-label)+*{margin-left:var(--ck-spacing-large)}[dir=rtl] .ck.ck-form__row>:not(.ck-label)+*{margin-right:var(--ck-spacing-large)}.ck.ck-form__row>.ck-label{width:100%;min-width:100%}.ck.ck-form__row.ck-table-form__action-row{margin-top:var(--ck-spacing-large)}.ck.ck-form__row.ck-table-form__action-row .ck-button .ck-button__label{color:var(--ck-color-text)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/formrow.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/formrow.css\"],\"names\":[],\"mappings\":\"AAKA,iBACC,YAAa,CACb,kBAAmB,CACnB,gBAAiB,CACjB,6BAaD,CAVC,iCACC,WACD,CAGC,wHAEC,sBACD,CCbF,iBACC,4DA2BD,CAvBE,6CAEE,mCAMF,CARA,6CAME,oCAEF,CAGD,2BACC,UAAW,CACX,cACD,CAEA,2CACC,kCAKD,CAHC,wEACC,0BACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-form__row {\\n\\tdisplay: flex;\\n\\tflex-direction: row;\\n\\tflex-wrap: nowrap;\\n\\tjustify-content: space-between;\\n\\n\\t/* Ignore labels that work as fieldset legends */\\n\\t& > *:not(.ck-label) {\\n\\t\\tflex-grow: 1;\\n\\t}\\n\\n\\t&.ck-table-form__action-row {\\n\\t\\t& .ck-button-save,\\n\\t\\t& .ck-button-cancel {\\n\\t\\t\\tjustify-content: center;\\n\\t\\t}\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n@import \\\"@ckeditor/ckeditor5-ui/theme/mixins/_dir.css\\\";\\n\\n.ck.ck-form__row {\\n\\tpadding: var(--ck-spacing-standard) var(--ck-spacing-large) 0;\\n\\n\\t/* Ignore labels that work as fieldset legends */\\n\\t& > *:not(.ck-label) {\\n\\t\\t& + * {\\n\\t\\t\\t@mixin ck-dir ltr {\\n\\t\\t\\t\\tmargin-left: var(--ck-spacing-large);\\n\\t\\t\\t}\\n\\n\\t\\t\\t@mixin ck-dir rtl {\\n\\t\\t\\t\\tmargin-right: var(--ck-spacing-large);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t& > .ck-label {\\n\\t\\twidth: 100%;\\n\\t\\tmin-width: 100%;\\n\\t}\\n\\n\\t&.ck-table-form__action-row {\\n\\t\\tmargin-top: var(--ck-spacing-large);\\n\\n\\t\\t& .ck-button .ck-button__label {\\n\\t\\t\\tcolor: var(--ck-color-text);\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck .ck-insert-table-dropdown__grid{display:flex;flex-direction:row;flex-wrap:wrap}:root{--ck-insert-table-dropdown-padding:10px;--ck-insert-table-dropdown-box-height:11px;--ck-insert-table-dropdown-box-width:12px;--ck-insert-table-dropdown-box-margin:1px}.ck .ck-insert-table-dropdown__grid{width:calc(var(--ck-insert-table-dropdown-box-width)*10 + var(--ck-insert-table-dropdown-box-margin)*20 + var(--ck-insert-table-dropdown-padding)*2);padding:var(--ck-insert-table-dropdown-padding) var(--ck-insert-table-dropdown-padding) 0}.ck .ck-insert-table-dropdown__label{text-align:center}.ck .ck-insert-table-dropdown-grid-box{width:var(--ck-insert-table-dropdown-box-width);height:var(--ck-insert-table-dropdown-box-height);margin:var(--ck-insert-table-dropdown-box-margin);border:1px solid var(--ck-color-base-border);border-radius:1px}.ck .ck-insert-table-dropdown-grid-box.ck-on{border-color:var(--ck-color-focus-border);background:var(--ck-color-focus-outer-shadow)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/inserttable.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/inserttable.css\"],\"names\":[],\"mappings\":\"AAKA,oCACC,YAAa,CACb,kBAAmB,CACnB,cACD,CCJA,MACC,uCAAwC,CACxC,0CAA2C,CAC3C,yCAA0C,CAC1C,yCACD,CAEA,oCAEC,oJAA2J,CAC3J,yFACD,CAEA,qCACC,iBACD,CAEA,uCACC,+CAAgD,CAChD,iDAAkD,CAClD,iDAAkD,CAClD,4CAA6C,CAC7C,iBAMD,CAJC,6CACC,yCAA0C,CAC1C,6CACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck .ck-insert-table-dropdown__grid {\\n\\tdisplay: flex;\\n\\tflex-direction: row;\\n\\tflex-wrap: wrap;\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n:root {\\n\\t--ck-insert-table-dropdown-padding: 10px;\\n\\t--ck-insert-table-dropdown-box-height: 11px;\\n\\t--ck-insert-table-dropdown-box-width: 12px;\\n\\t--ck-insert-table-dropdown-box-margin: 1px;\\n}\\n\\n.ck .ck-insert-table-dropdown__grid {\\n\\t/* The width of a container should match 10 items in a row so there will be a 10x10 grid. */\\n\\twidth: calc(var(--ck-insert-table-dropdown-box-width) * 10 + var(--ck-insert-table-dropdown-box-margin) * 20 + var(--ck-insert-table-dropdown-padding) * 2);\\n\\tpadding: var(--ck-insert-table-dropdown-padding) var(--ck-insert-table-dropdown-padding) 0;\\n}\\n\\n.ck .ck-insert-table-dropdown__label {\\n\\ttext-align: center;\\n}\\n\\n.ck .ck-insert-table-dropdown-grid-box {\\n\\twidth: var(--ck-insert-table-dropdown-box-width);\\n\\theight: var(--ck-insert-table-dropdown-box-height);\\n\\tmargin: var(--ck-insert-table-dropdown-box-margin);\\n\\tborder: 1px solid var(--ck-color-base-border);\\n\\tborder-radius: 1px;\\n\\n\\t&.ck-on {\\n\\t\\tborder-color: var(--ck-color-focus-border);\\n\\t\\tbackground: var(--ck-color-focus-outer-shadow);\\n\\t}\\n}\\n\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck-content .table{margin:.9em auto;display:table}.ck-content .table table{border-collapse:collapse;border-spacing:0;width:100%;height:100%;border:1px double #b3b3b3}.ck-content .table table td,.ck-content .table table th{min-width:2em;padding:.4em;border:1px solid #bfbfbf}.ck-content .table table th{font-weight:700;background:hsla(0,0%,0%,5%)}.ck-content[dir=rtl] .table th{text-align:right}.ck-content[dir=ltr] .table th{text-align:left}.ck-editor__editable .ck-table-bogus-paragraph{display:inline-block;width:100%}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/table.css\"],\"names\":[],\"mappings\":\"AAKA,mBAIC,gBAAkB,CAClB,aAgCD,CA9BC,yBAEC,wBAAyB,CACzB,gBAAiB,CAIjB,UAAW,CACX,WAAY,CAIZ,yBAiBD,CAfC,wDAEC,aAAc,CACd,YAAa,CAKb,wBACD,CAEA,4BACC,eAAiB,CACjB,2BACD,CAMF,+BACC,gBACD,CAEA,+BACC,eACD,CAEA,+CAKC,oBAAqB,CAMrB,UACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck-content .table {\\n\\t/* Give the table widget some air and center it horizontally */\\n\\t/* The first value should be equal to --ck-spacing-large variable if used in the editor context\\n\\tto avoid the content jumping (See https://github.com/ckeditor/ckeditor5/issues/9825). */\\n\\tmargin: 0.9em auto;\\n\\tdisplay: table;\\n\\n\\t& table {\\n\\t\\t/* The table cells should have slight borders */\\n\\t\\tborder-collapse: collapse;\\n\\t\\tborder-spacing: 0;\\n\\n\\t\\t/* Table width and height are set on the parent <figure>. Make sure the table inside stretches\\n\\t\\tto the full dimensions of the container (https://github.com/ckeditor/ckeditor5/issues/6186). */\\n\\t\\twidth: 100%;\\n\\t\\theight: 100%;\\n\\n\\t\\t/* The outer border of the table should be slightly darker than the inner lines.\\n\\t\\tAlso see https://github.com/ckeditor/ckeditor5-table/issues/50. */\\n\\t\\tborder: 1px double hsl(0, 0%, 70%);\\n\\n\\t\\t& td,\\n\\t\\t& th {\\n\\t\\t\\tmin-width: 2em;\\n\\t\\t\\tpadding: .4em;\\n\\n\\t\\t\\t/* The border is inherited from .ck-editor__nested-editable styles, so theoretically it's not necessary here.\\n\\t\\t\\tHowever, the border is a content style, so it should use .ck-content (so it works outside the editor).\\n\\t\\t\\tHence, the duplication. See https://github.com/ckeditor/ckeditor5/issues/6314 */\\n\\t\\t\\tborder: 1px solid hsl(0, 0%, 75%);\\n\\t\\t}\\n\\n\\t\\t& th {\\n\\t\\t\\tfont-weight: bold;\\n\\t\\t\\tbackground: hsla(0, 0%, 0%, 5%);\\n\\t\\t}\\n\\t}\\n}\\n\\n/* Text alignment of the table header should match the editor settings and override the native browser styling,\\nwhen content is available outside the ediitor. See https://github.com/ckeditor/ckeditor5/issues/6638 */\\n.ck-content[dir=\\\"rtl\\\"] .table th {\\n\\ttext-align: right;\\n}\\n\\n.ck-content[dir=\\\"ltr\\\"] .table th {\\n\\ttext-align: left;\\n}\\n\\n.ck-editor__editable .ck-table-bogus-paragraph {\\n\\t/*\\n\\t * Use display:inline-block to force Chrome/Safari to limit text mutations to this element.\\n\\t * See https://github.com/ckeditor/ckeditor5/issues/6062.\\n\\t */\\n\\tdisplay: inline-block;\\n\\n\\t/*\\n\\t * Inline HTML elements nested in the span should always be dimensioned in relation to the whole cell width.\\n\\t * See https://github.com/ckeditor/ckeditor5/issues/9117.\\n\\t */\\n\\twidth: 100%;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":root{--ck-color-table-caption-background:#f7f7f7;--ck-color-table-caption-text:#333;--ck-color-table-caption-highlighted-background:#fd0}.ck-content .table>figcaption{display:table-caption;caption-side:top;word-break:break-word;text-align:center;color:var(--ck-color-table-caption-text);background-color:var(--ck-color-table-caption-background);padding:.6em;font-size:.75em;outline-offset:-1px}.ck.ck-editor__editable .table>figcaption.table__caption_highlighted{animation:ck-table-caption-highlight .6s ease-out}.ck.ck-editor__editable .table>figcaption.ck-placeholder:before{padding-left:inherit;padding-right:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@keyframes ck-table-caption-highlight{0%{background-color:var(--ck-color-table-caption-highlighted-background)}to{background-color:var(--ck-color-table-caption-background)}}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/tablecaption.css\"],\"names\":[],\"mappings\":\"AAKA,MACC,2CAAoD,CACpD,kCAA8C,CAC9C,oDACD,CAGA,8BACC,qBAAsB,CACtB,gBAAiB,CACjB,qBAAsB,CACtB,iBAAkB,CAClB,wCAAyC,CACzC,yDAA0D,CAC1D,YAAa,CACb,eAAgB,CAChB,mBACD,CAIC,qEACC,iDACD,CAEA,gEACC,oBAAqB,CACrB,qBAAsB,CAMtB,kBAAmB,CACnB,eAAgB,CAChB,sBACD,CAGD,sCACC,GACC,qEACD,CAEA,GACC,yDACD,CACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n:root {\\n\\t--ck-color-table-caption-background: hsl(0, 0%, 97%);\\n\\t--ck-color-table-caption-text: hsl(0, 0%, 20%);\\n\\t--ck-color-table-caption-highlighted-background: hsl(52deg 100% 50%);\\n}\\n\\n/* Content styles */\\n.ck-content .table > figcaption {\\n\\tdisplay: table-caption;\\n\\tcaption-side: top;\\n\\tword-break: break-word;\\n\\ttext-align: center;\\n\\tcolor: var(--ck-color-table-caption-text);\\n\\tbackground-color: var(--ck-color-table-caption-background);\\n\\tpadding: .6em;\\n\\tfont-size: .75em;\\n\\toutline-offset: -1px;\\n}\\n\\n/* Editing styles */\\n.ck.ck-editor__editable .table > figcaption {\\n\\t&.table__caption_highlighted {\\n\\t\\tanimation: ck-table-caption-highlight .6s ease-out;\\n\\t}\\n\\n\\t&.ck-placeholder::before {\\n\\t\\tpadding-left: inherit;\\n\\t\\tpadding-right: inherit;\\n\\n\\t\\t/*\\n\\t\\t * Make sure the table caption placeholder doesn't overflow the placeholder area.\\n\\t\\t * See https://github.com/ckeditor/ckeditor5/issues/9162.\\n\\t\\t */\\n\\t\\twhite-space: nowrap;\\n\\t\\toverflow: hidden;\\n\\t\\ttext-overflow: ellipsis;\\n\\t}\\n}\\n\\n@keyframes ck-table-caption-highlight {\\n\\t0% {\\n\\t\\tbackground-color: var(--ck-color-table-caption-highlighted-background);\\n\\t}\\n\\n\\t100% {\\n\\t\\tbackground-color: var(--ck-color-table-caption-background);\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row{flex-wrap:wrap}.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar:first-of-type{flex-grow:0.57}.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar:last-of-type{flex-grow:0.43}.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar .ck-button{flex-grow:1}.ck.ck-table-cell-properties-form{width:320px}.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__padding-row{align-self:flex-end;padding:0;width:25%}.ck.ck-table-cell-properties-form .ck-form__row.ck-table-cell-properties-form__alignment-row .ck.ck-toolbar{background:none;margin-top:var(--ck-spacing-standard)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/tablecellproperties.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/tablecellproperties.css\"],\"names\":[],\"mappings\":\"AAOE,6FACC,cAiBD,CAdE,0HAEC,cACD,CAEA,yHAEC,cACD,CAEA,uHACC,WACD,CClBJ,kCACC,WAkBD,CAfE,2FACC,mBAAoB,CACpB,SAAU,CACV,SACD,CAGC,4GACC,eAAgB,CAGhB,qCACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-table-cell-properties-form {\\n\\t& .ck-form__row {\\n\\t\\t&.ck-table-cell-properties-form__alignment-row {\\n\\t\\t\\tflex-wrap: wrap;\\n\\n\\t\\t\\t& .ck.ck-toolbar {\\n\\t\\t\\t\\t&:first-of-type {\\n\\t\\t\\t\\t\\t/* 4 buttons out of 7 (h-alignment + v-alignment) = 0.57 */\\n\\t\\t\\t\\t\\tflex-grow: 0.57;\\n\\t\\t\\t\\t}\\n\\n\\t\\t\\t\\t&:last-of-type {\\n\\t\\t\\t\\t\\t/* 3 buttons out of 7 (h-alignment + v-alignment) = 0.43 */\\n\\t\\t\\t\\t\\tflex-grow: 0.43;\\n\\t\\t\\t\\t}\\n\\n\\t\\t\\t\\t& .ck-button {\\n\\t\\t\\t\\t\\tflex-grow: 1;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-table-cell-properties-form {\\n\\twidth: 320px;\\n\\n\\t& .ck-form__row {\\n\\t\\t&.ck-table-cell-properties-form__padding-row {\\n\\t\\t\\talign-self: flex-end;\\n\\t\\t\\tpadding: 0;\\n\\t\\t\\twidth: 25%;\\n\\t\\t}\\n\\n\\t\\t&.ck-table-cell-properties-form__alignment-row {\\n\\t\\t\\t& .ck.ck-toolbar {\\n\\t\\t\\t\\tbackground: none;\\n\\n\\t\\t\\t\\t/* Compensate for missing input label that would push the margin (toolbar has no inputs). */\\n\\t\\t\\t\\tmargin-top: var(--ck-spacing-standard);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":root{--ck-color-table-focused-cell-background:rgba(158,207,250,0.3)}.ck-widget.table td.ck-editor__nested-editable.ck-editor__nested-editable_focused,.ck-widget.table td.ck-editor__nested-editable:focus,.ck-widget.table th.ck-editor__nested-editable.ck-editor__nested-editable_focused,.ck-widget.table th.ck-editor__nested-editable:focus{background:var(--ck-color-table-focused-cell-background);border-style:none;outline:1px solid var(--ck-color-focus-border);outline-offset:-1px}\", \"\",{\"version\":3,\"sources\":[\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/tableediting.css\"],\"names\":[],\"mappings\":\"AAKA,MACC,8DACD,CAKE,8QAGC,wDAAyD,CAKzD,iBAAkB,CAClB,8CAA+C,CAC/C,mBACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n:root {\\n\\t--ck-color-table-focused-cell-background: hsla(208, 90%, 80%, .3);\\n}\\n\\n.ck-widget.table {\\n\\t& td,\\n\\t& th {\\n\\t\\t&.ck-editor__nested-editable.ck-editor__nested-editable_focused,\\n\\t\\t&.ck-editor__nested-editable:focus {\\n\\t\\t\\t/* A very slight background to highlight the focused cell */\\n\\t\\t\\tbackground: var(--ck-color-table-focused-cell-background);\\n\\n\\t\\t\\t/* Fixes the problem where surrounding cells cover the focused cell's border.\\n\\t\\t\\tIt does not fix the problem in all places but the UX is improved.\\n\\t\\t\\tSee https://github.com/ckeditor/ckeditor5-table/issues/29. */\\n\\t\\t\\tborder-style: none;\\n\\t\\t\\toutline: 1px solid var(--ck-color-focus-border);\\n\\t\\t\\toutline-offset: -1px; /* progressive enhancement - no IE support */\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck.ck-table-form .ck-form__row.ck-table-form__background-row,.ck.ck-table-form .ck-form__row.ck-table-form__border-row{flex-wrap:wrap}.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row{flex-wrap:wrap;align-items:center}.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-labeled-field-view{display:flex;flex-direction:column-reverse;align-items:center}.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-labeled-field-view .ck.ck-dropdown,.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimension-operator{flex-grow:0}.ck.ck-table-form .ck.ck-labeled-field-view{position:relative}.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status{position:absolute;left:50%;bottom:calc(var(--ck-table-properties-error-arrow-size)*-1);transform:translate(-50%,100%);z-index:1}.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status:after{content:\\\"\\\";position:absolute;top:calc(var(--ck-table-properties-error-arrow-size)*-1);left:50%;transform:translateX(-50%)}:root{--ck-table-properties-error-arrow-size:6px;--ck-table-properties-min-error-width:150px}.ck.ck-table-form .ck-form__row.ck-table-form__border-row .ck-labeled-field-view>.ck-label{font-size:var(--ck-font-size-tiny);text-align:center}.ck.ck-table-form .ck-form__row.ck-table-form__border-row .ck-table-form__border-style,.ck.ck-table-form .ck-form__row.ck-table-form__border-row .ck-table-form__border-width{width:80px;min-width:80px;max-width:80px}.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row{padding:0}.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimensions-row__height,.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimensions-row__width{margin:0}.ck.ck-table-form .ck-form__row.ck-table-form__dimensions-row .ck-table-form__dimension-operator{align-self:flex-end;display:inline-block;height:var(--ck-ui-component-min-height);line-height:var(--ck-ui-component-min-height);margin:0 var(--ck-spacing-small)}.ck.ck-table-form .ck.ck-labeled-field-view{padding-top:var(--ck-spacing-standard)}.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status{border-radius:0}.ck-rounded-corners .ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status,.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status.ck-rounded-corners{border-radius:var(--ck-border-radius)}.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status{background:var(--ck-color-base-error);color:var(--ck-color-base-background);padding:var(--ck-spacing-small) var(--ck-spacing-medium);min-width:var(--ck-table-properties-min-error-width);text-align:center}.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status:after{border-left:var(--ck-table-properties-error-arrow-size) solid transparent;border-bottom:var(--ck-table-properties-error-arrow-size) solid var(--ck-color-base-error);border-right:var(--ck-table-properties-error-arrow-size) solid transparent;border-top:0 solid transparent}.ck.ck-table-form .ck.ck-labeled-field-view .ck.ck-labeled-field-view__status{animation:ck-table-form-labeled-view-status-appear .15s ease both}.ck.ck-table-form .ck.ck-labeled-field-view .ck-input.ck-error:not(:focus)+.ck.ck-labeled-field-view__status{display:none}@keyframes ck-table-form-labeled-view-status-appear{0%{opacity:0}to{opacity:1}}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/tableform.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/tableform.css\",\"webpack://./../ckeditor5-theme-lark/theme/mixins/_rounded.css\"],\"names\":[],\"mappings\":\"AAWE,wHACC,cACD,CAEA,8DACC,cAAe,CACf,kBAeD,CAbC,qFACC,YAAa,CACb,6BAA8B,CAC9B,kBAKD,CAEA,sMACC,WACD,CAIF,4CAEC,iBAoBD,CAlBC,8EACC,iBAAkB,CAClB,QAAS,CACT,2DAAgE,CAChE,8BAA+B,CAG/B,SAUD,CAPC,oFACC,UAAW,CACX,iBAAkB,CAClB,wDAA6D,CAC7D,QAAS,CACT,0BACD,CChDH,MACC,0CAA2C,CAC3C,2CACD,CAMI,2FACC,kCAAmC,CACnC,iBACD,CAGD,8KAEC,UAAW,CACX,cAAe,CACf,cACD,CAGD,8DACC,SAcD,CAZC,yMAEC,QACD,CAEA,iGACC,mBAAoB,CACpB,oBAAqB,CACrB,wCAAyC,CACzC,6CAA8C,CAC9C,gCACD,CAIF,4CACC,sCAyBD,CAvBC,8ECxCD,eDyDC,CAjBA,mMCpCA,qCDqDA,CAjBA,8EAGC,qCAAsC,CACtC,qCAAsC,CACtC,wDAAyD,CACzD,oDAAqD,CACrD,iBAUD,CAPC,oFAGC,yEAAmB,CAAnB,0FAAmB,CAAnB,0EAAmB,CAAnB,8BACD,CAdD,8EAgBC,iEACD,CAGA,6GACC,YACD,CAIF,oDACC,GACC,SACD,CAEA,GACC,SACD,CACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-table-form {\\n\\t& .ck-form__row {\\n\\t\\t&.ck-table-form__border-row {\\n\\t\\t\\tflex-wrap: wrap;\\n\\t\\t}\\n\\n\\t\\t&.ck-table-form__background-row {\\n\\t\\t\\tflex-wrap: wrap;\\n\\t\\t}\\n\\n\\t\\t&.ck-table-form__dimensions-row {\\n\\t\\t\\tflex-wrap: wrap;\\n\\t\\t\\talign-items: center;\\n\\n\\t\\t\\t& .ck-labeled-field-view {\\n\\t\\t\\t\\tdisplay: flex;\\n\\t\\t\\t\\tflex-direction: column-reverse;\\n\\t\\t\\t\\talign-items: center;\\n\\n\\t\\t\\t\\t& .ck.ck-dropdown {\\n\\t\\t\\t\\t\\tflex-grow: 0;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\n\\t\\t\\t& .ck-table-form__dimension-operator {\\n\\t\\t\\t\\tflex-grow: 0;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t& .ck.ck-labeled-field-view {\\n\\t\\t/* Allow absolute positioning of the status (error) balloons. */\\n\\t\\tposition: relative;\\n\\n\\t\\t& .ck.ck-labeled-field-view__status {\\n\\t\\t\\tposition: absolute;\\n\\t\\t\\tleft: 50%;\\n\\t\\t\\tbottom: calc( -1 * var(--ck-table-properties-error-arrow-size) );\\n\\t\\t\\ttransform: translate(-50%,100%);\\n\\n\\t\\t\\t/* Make sure the balloon status stays on top of other form elements. */\\n\\t\\t\\tz-index: 1;\\n\\n\\t\\t\\t/* The arrow pointing towards the field. */\\n\\t\\t\\t&::after {\\n\\t\\t\\t\\tcontent: \\\"\\\";\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\ttop: calc( -1 * var(--ck-table-properties-error-arrow-size) );\\n\\t\\t\\t\\tleft: 50%;\\n\\t\\t\\t\\ttransform: translateX( -50% );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n@import \\\"../mixins/_rounded.css\\\";\\n\\n:root {\\n\\t--ck-table-properties-error-arrow-size: 6px;\\n\\t--ck-table-properties-min-error-width: 150px;\\n}\\n\\n.ck.ck-table-form {\\n\\t& .ck-form__row {\\n\\t\\t&.ck-table-form__border-row {\\n\\t\\t\\t& .ck-labeled-field-view {\\n\\t\\t\\t\\t& > .ck-label {\\n\\t\\t\\t\\t\\tfont-size: var(--ck-font-size-tiny);\\n\\t\\t\\t\\t\\ttext-align: center;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\n\\t\\t\\t& .ck-table-form__border-style,\\n\\t\\t\\t& .ck-table-form__border-width {\\n\\t\\t\\t\\twidth: 80px;\\n\\t\\t\\t\\tmin-width: 80px;\\n\\t\\t\\t\\tmax-width: 80px;\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\t&.ck-table-form__dimensions-row {\\n\\t\\t\\tpadding: 0;\\n\\n\\t\\t\\t& .ck-table-form__dimensions-row__width,\\n\\t\\t\\t& .ck-table-form__dimensions-row__height {\\n\\t\\t\\t\\tmargin: 0\\n\\t\\t\\t}\\n\\n\\t\\t\\t& .ck-table-form__dimension-operator {\\n\\t\\t\\t\\talign-self: flex-end;\\n\\t\\t\\t\\tdisplay: inline-block;\\n\\t\\t\\t\\theight: var(--ck-ui-component-min-height);\\n\\t\\t\\t\\tline-height: var(--ck-ui-component-min-height);\\n\\t\\t\\t\\tmargin: 0 var(--ck-spacing-small);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t& .ck.ck-labeled-field-view {\\n\\t\\tpadding-top: var(--ck-spacing-standard);\\n\\n\\t\\t& .ck.ck-labeled-field-view__status {\\n\\t\\t\\t@mixin ck-rounded-corners;\\n\\n\\t\\t\\tbackground: var(--ck-color-base-error);\\n\\t\\t\\tcolor: var(--ck-color-base-background);\\n\\t\\t\\tpadding: var(--ck-spacing-small) var(--ck-spacing-medium);\\n\\t\\t\\tmin-width: var(--ck-table-properties-min-error-width);\\n\\t\\t\\ttext-align: center;\\n\\n\\t\\t\\t/* The arrow pointing towards the field. */\\n\\t\\t\\t&::after {\\n\\t\\t\\t\\tborder-color: transparent transparent var(--ck-color-base-error) transparent;\\n\\t\\t\\t\\tborder-width: 0 var(--ck-table-properties-error-arrow-size) var(--ck-table-properties-error-arrow-size) var(--ck-table-properties-error-arrow-size);\\n\\t\\t\\t\\tborder-style: solid;\\n\\t\\t\\t}\\n\\n\\t\\t\\tanimation: ck-table-form-labeled-view-status-appear .15s ease both;\\n\\t\\t}\\n\\n\\t\\t/* Hide the error balloon when the field is blurred. Makes the experience much more clear. */\\n\\t\\t& .ck-input.ck-error:not(:focus) + .ck.ck-labeled-field-view__status {\\n\\t\\t\\tdisplay: none;\\n\\t\\t}\\n\\t}\\n}\\n\\n@keyframes ck-table-form-labeled-view-status-appear {\\n\\t0% {\\n\\t\\topacity: 0;\\n\\t}\\n\\n\\t100% {\\n\\t\\topacity: 1;\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n/**\\n * Implements rounded corner interface for .ck-rounded-corners class.\\n *\\n * @see $ck-border-radius\\n */\\n@define-mixin ck-rounded-corners {\\n\\tborder-radius: 0;\\n\\n\\t@nest .ck-rounded-corners &,\\n\\t&.ck-rounded-corners {\\n\\t\\tborder-radius: var(--ck-border-radius);\\n\\t\\t@mixin-content;\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row{flex-wrap:wrap;flex-basis:0;align-content:baseline}.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row .ck.ck-toolbar .ck-toolbar__items{flex-wrap:nowrap}.ck.ck-table-properties-form{width:320px}.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row{align-self:flex-end;padding:0}.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row .ck.ck-toolbar{background:none;margin-top:var(--ck-spacing-standard)}.ck.ck-table-properties-form .ck-form__row.ck-table-properties-form__alignment-row .ck.ck-toolbar .ck-toolbar__items>*{width:40px}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/tableproperties.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/tableproperties.css\"],\"names\":[],\"mappings\":\"AAOE,mFACC,cAAe,CACf,YAAa,CACb,sBAKD,CAHC,qHACC,gBACD,CCTH,6BACC,WAmBD,CAhBE,mFACC,mBAAoB,CACpB,SAYD,CAVC,kGACC,eAAgB,CAGhB,qCAKD,CAHC,uHACC,UACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-table-properties-form {\\n\\t& .ck-form__row {\\n\\t\\t&.ck-table-properties-form__alignment-row {\\n\\t\\t\\tflex-wrap: wrap;\\n\\t\\t\\tflex-basis: 0;\\n\\t\\t\\talign-content: baseline;\\n\\n\\t\\t\\t& .ck.ck-toolbar .ck-toolbar__items {\\n\\t\\t\\t\\tflex-wrap: nowrap;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\",\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n.ck.ck-table-properties-form {\\n\\twidth: 320px;\\n\\n\\t& .ck-form__row {\\n\\t\\t&.ck-table-properties-form__alignment-row {\\n\\t\\t\\talign-self: flex-end;\\n\\t\\t\\tpadding: 0;\\n\\n\\t\\t\\t& .ck.ck-toolbar {\\n\\t\\t\\t\\tbackground: none;\\n\\n\\t\\t\\t\\t/* Compensate for missing input label that would push the margin (toolbar has no inputs). */\\n\\t\\t\\t\\tmargin-top: var(--ck-spacing-standard);\\n\\n\\t\\t\\t\\t& .ck-toolbar__items > * {\\n\\t\\t\\t\\t\\twidth: 40px;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/cssWithMappingToString.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \":root{--ck-table-selected-cell-background:rgba(158,207,250,0.3)}.ck.ck-editor__editable .table table td.ck-editor__editable_selected,.ck.ck-editor__editable .table table th.ck-editor__editable_selected{position:relative;caret-color:transparent;outline:unset;box-shadow:unset}.ck.ck-editor__editable .table table td.ck-editor__editable_selected:after,.ck.ck-editor__editable .table table th.ck-editor__editable_selected:after{content:\\\"\\\";pointer-events:none;background-color:var(--ck-table-selected-cell-background);position:absolute;top:0;left:0;right:0;bottom:0}.ck.ck-editor__editable .table table td.ck-editor__editable_selected ::selection,.ck.ck-editor__editable .table table td.ck-editor__editable_selected:focus,.ck.ck-editor__editable .table table th.ck-editor__editable_selected ::selection,.ck.ck-editor__editable .table table th.ck-editor__editable_selected:focus{background-color:transparent}.ck.ck-editor__editable .table table td.ck-editor__editable_selected .ck-widget,.ck.ck-editor__editable .table table th.ck-editor__editable_selected .ck-widget{outline:unset}.ck.ck-editor__editable .table table td.ck-editor__editable_selected .ck-widget>.ck-widget__selection-handle,.ck.ck-editor__editable .table table th.ck-editor__editable_selected .ck-widget>.ck-widget__selection-handle{display:none}\", \"\",{\"version\":3,\"sources\":[\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-table/tableselection.css\"],\"names\":[],\"mappings\":\"AAKA,MACC,yDACD,CAGC,0IAEC,iBAAkB,CAClB,uBAAwB,CACxB,aAAc,CACd,gBA8BD,CA3BC,sJACC,UAAW,CACX,mBAAoB,CACpB,yDAA0D,CAC1D,iBAAkB,CAClB,KAAM,CACN,MAAO,CACP,OAAQ,CACR,QACD,CAEA,wTAEC,4BACD,CAMA,gKACC,aAKD,CAHC,0NACC,YACD\",\"sourcesContent\":[\"/*\\n * Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\\n */\\n\\n:root {\\n\\t--ck-table-selected-cell-background: hsla(208, 90%, 80%, .3);\\n}\\n\\n.ck.ck-editor__editable .table table {\\n\\t& td.ck-editor__editable_selected,\\n\\t& th.ck-editor__editable_selected {\\n\\t\\tposition: relative;\\n\\t\\tcaret-color: transparent;\\n\\t\\toutline: unset;\\n\\t\\tbox-shadow: unset;\\n\\n\\t\\t/* https://github.com/ckeditor/ckeditor5/issues/6446 */\\n\\t\\t&:after {\\n\\t\\t\\tcontent: '';\\n\\t\\t\\tpointer-events: none;\\n\\t\\t\\tbackground-color: var(--ck-table-selected-cell-background);\\n\\t\\t\\tposition: absolute;\\n\\t\\t\\ttop: 0;\\n\\t\\t\\tleft: 0;\\n\\t\\t\\tright: 0;\\n\\t\\t\\tbottom: 0;\\n\\t\\t}\\n\\n\\t\\t& ::selection,\\n\\t\\t&:focus {\\n\\t\\t\\tbackground-color: transparent;\\n\\t\\t}\\n\\n\\t\\t/*\\n\\t\\t * To reduce the amount of noise, all widgets in the table selection have no outline and no selection handle.\\n\\t\\t * See https://github.com/ckeditor/ckeditor5/issues/9491.\\n\\t\\t */\\n\\t\\t& .ck-widget {\\n\\t\\t\\toutline: unset;\\n\\n\\t\\t\\t& > .ck-widget__selection-handle {\\n\\t\\t\\t\\tdisplay: none;\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (cssWithMappingToString) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join(\"\");\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === \"string\") {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, \"\"]];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};","\"use strict\";\n\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr && (typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]); if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nmodule.exports = function cssWithMappingToString(item) {\n var _item = _slicedToArray(item, 4),\n content = _item[1],\n cssMapping = _item[3];\n\n if (!cssMapping) {\n return content;\n }\n\n if (typeof btoa === \"function\") {\n // eslint-disable-next-line no-undef\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n var sourceURLs = cssMapping.sources.map(function (source) {\n return \"/*# sourceURL=\".concat(cssMapping.sourceRoot || \"\").concat(source, \" */\");\n });\n return [content].concat(sourceURLs).concat([sourceMapping]).join(\"\\n\");\n }\n\n return [content].join(\"\\n\");\n};","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m11.105 18-.17 1H2.5A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1h15A1.5 1.5 0 0 1 19 2.5v9.975l-.85-.124-.15-.302V8h-5v4h.021l-.172.351-1.916.28-.151.027c-.287.063-.54.182-.755.341L8 13v5h3.105zM2 12h5V8H2v4zm10-4H8v4h4V8zM2 2v5h5V2H2zm0 16h5v-5H2v5zM13 7h5V2h-5v5zM8 2v5h4V2H8z\\\" opacity=\\\".6\\\"/><path d=\\\"m15.5 11.5 1.323 2.68 2.957.43-2.14 2.085.505 2.946L15.5 18.25l-2.645 1.39.505-2.945-2.14-2.086 2.957-.43L15.5 11.5zM13 6a1 1 0 0 1 1 1v3.172a2.047 2.047 0 0 0-.293.443l-.858 1.736-1.916.28-.151.027A1.976 1.976 0 0 0 9.315 14H7a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6zm-1 2H8v4h4V8z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M18 7v1H2V7h16zm0 5v1H2v-1h16z\\\" opacity=\\\".6\\\"/><path d=\\\"M14 1v18a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1zm-2 1H8v4h4V2zm0 6H8v4h4V8zm0 6H8v4h4v-4z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 2h1v16H7V2zm5 0h1v7h-1V2zm6 5v1H2V7h16zM8 12v1H2v-1h6z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 7h12a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1zm1 2v9h10V9H8z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M8 2v5h4V2h1v5h5v1h-5v4h.021l-.172.351-1.916.28-.151.027c-.287.063-.54.182-.755.341L8 13v5H7v-5H2v-1h5V8H2V7h5V2h1zm4 6H8v4h4V8z\\\" opacity=\\\".6\\\"/><path d=\\\"m15.5 11.5 1.323 2.68 2.957.43-2.14 2.085.505 2.946L15.5 18.25l-2.645 1.39.505-2.945-2.14-2.086 2.957-.43L15.5 11.5zM17 1a2 2 0 0 1 2 2v9.475l-.85-.124-.857-1.736a2.048 2.048 0 0 0-.292-.44L17 3H3v14h7.808l.402.392L10.935 19H3a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h14z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M2.5 1h15A1.5 1.5 0 0 1 19 2.5v15a1.5 1.5 0 0 1-1.5 1.5h-15A1.5 1.5 0 0 1 1 17.5v-15A1.5 1.5 0 0 1 2.5 1zM2 2v16h16V2H2z\\\" opacity=\\\".6\\\"/><path d=\\\"M7 2h1v16H7V2zm5 0h1v16h-1V2z\\\" opacity=\\\".6\\\"/><path d=\\\"M1 6h18a1 1 0 0 1 1 1v6a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm1 2v4h4V8H2zm6 0v4h4V8H8zm6 0v4h4V8h-4z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M3 6v3h4V6H3zm0 4v3h4v-3H3zm0 4v3h4v-3H3zm5 3h4v-3H8v3zm5 0h4v-3h-4v3zm4-4v-3h-4v3h4zm0-4V6h-4v3h4zm1.5 8a1.5 1.5 0 0 1-1.5 1.5H3A1.5 1.5 0 0 1 1.5 17V4c.222-.863 1.068-1.5 2-1.5h13c.932 0 1.778.637 2 1.5v13zM12 13v-3H8v3h4zm0-4V6H8v3h4z\\\"/></svg>\";","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./colorinput.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./form.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./formrow.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./inserttable.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./table.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./tablecaption.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./tablecellproperties.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./tableediting.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./tableform.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./tableproperties.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","import api from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import content from \"!!../../../node_modules/css-loader/dist/cjs.js!../../../node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[1].use[2]!./tableselection.css\";\n\nvar options = {\"injectType\":\"singletonStyleTag\",\"attributes\":{\"data-cke\":true}};\n\noptions.insert = \"head\";\noptions.singleton = true;\n\nvar update = api(content, options);\n\n\n\nexport default content.locals || {};","\"use strict\";\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && typeof btoa !== 'undefined') {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of <style>\n // tags it will allow on a page\n\n if (!options.singleton && typeof options.singleton !== 'boolean') {\n options.singleton = isOldIE();\n }\n\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n if (Object.prototype.toString.call(newList) !== '[object Array]') {\n return;\n }\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDom[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDom[_index].references === 0) {\n stylesInDom[_index].updater();\n\n stylesInDom.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/insertcolumncommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getColumnIndexes, getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The insert column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTableColumnLeft'` and\n * `'insertTableColumnRight'` editor commands.\n *\n * To insert a column to the left of the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableColumnLeft' );\n *\n * To insert a column to the right of the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableColumnRight' );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertColumnCommand extends Command {\n\t/**\n\t * Creates a new `InsertColumnCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} [options.order=\"right\"] The order of insertion relative to the column in which the caret is located.\n\t * Possible values: `\"left\"` and `\"right\"`.\n\t */\n\tconstructor( editor, options = {} ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The order of insertion relative to the column in which the caret is located.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:table/commands/insertcolumncommand~InsertColumnCommand#order\n\t\t */\n\t\tthis.order = options.order || 'right';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst isAnyCellSelected = !!getSelectionAffectedTableCells( selection ).length;\n\n\t\tthis.isEnabled = isAnyCellSelected;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a column to the `'left'` or `'right'` of the column\n\t * in which the selection is set.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils = editor.plugins.get( 'TableUtils' );\n\t\tconst insertBefore = this.order === 'left';\n\n\t\tconst affectedTableCells = getSelectionAffectedTableCells( selection );\n\t\tconst columnIndexes = getColumnIndexes( affectedTableCells );\n\n\t\tconst column = insertBefore ? columnIndexes.first : columnIndexes.last;\n\t\tconst table = affectedTableCells[ 0 ].findAncestor( 'table' );\n\n\t\ttableUtils.insertColumns( table, { columns: 1, at: insertBefore ? column : column + 1 } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/insertrowcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The insert row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTableRowBelow'` and\n * `'insertTableRowAbove'` editor commands.\n *\n * To insert a row below the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableRowBelow' );\n *\n * To insert a row above the selected cell, execute the following command:\n *\n *\t\teditor.execute( 'insertTableRowAbove' );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertRowCommand extends Command {\n\t/**\n\t * Creates a new `InsertRowCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} [options.order=\"below\"] The order of insertion relative to the row in which the caret is located.\n\t * Possible values: `\"above\"` and `\"below\"`.\n\t */\n\tconstructor( editor, options = {} ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The order of insertion relative to the row in which the caret is located.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} module:table/commands/insertrowcommand~InsertRowCommand#order\n\t\t */\n\t\tthis.order = options.order || 'below';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst isAnyCellSelected = !!getSelectionAffectedTableCells( selection ).length;\n\n\t\tthis.isEnabled = isAnyCellSelected;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #order} value, it inserts a row `'below'` or `'above'` the row in which selection is set.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst tableUtils = editor.plugins.get( 'TableUtils' );\n\t\tconst insertAbove = this.order === 'above';\n\n\t\tconst affectedTableCells = getSelectionAffectedTableCells( selection );\n\t\tconst rowIndexes = getRowIndexes( affectedTableCells );\n\n\t\tconst row = insertAbove ? rowIndexes.first : rowIndexes.last;\n\t\tconst table = affectedTableCells[ 0 ].findAncestor( 'table' );\n\n\t\ttableUtils.insertRows( table, { at: insertAbove ? row : row + 1, copyStructureFromAbove: !insertAbove } );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/inserttablecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { findOptimalInsertionRange } from 'ckeditor5/src/widget';\n\n/**\n * The insert table command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'insertTable'` editor command.\n *\n * To insert a table at the current selection, execute the command and specify the dimensions:\n *\n *\t\teditor.execute( 'insertTable', { rows: 20, columns: 5 } );\n *\n * @extends module:core/command~Command\n */\nexport default class InsertTableCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst schema = model.schema;\n\n\t\tthis.isEnabled = isAllowedInParent( selection, schema );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Inserts a table with the given number of rows and columns into the editor.\n\t *\n\t * @param {Object} options\n\t * @param {Number} [options.rows=2] The number of rows to create in the inserted table.\n\t * @param {Number} [options.columns=2] The number of columns to create in the inserted table.\n\t * @param {Number} [options.headingRows] The number of heading rows.\n\t * If not provided it will default to {@link module:table/table~TableConfig#defaultHeadings `config.table.defaultHeadings.rows`}\n\t * table config.\n\t * @param {Number} [options.headingColumns] The number of heading columns.\n\t * If not provided it will default to {@link module:table/table~TableConfig#defaultHeadings `config.table.defaultHeadings.columns`}\n\t * table config.\n\t * @fires execute\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst config = this.editor.config.get( 'table' );\n\n\t\tconst insertionRange = findOptimalInsertionRange( selection, model );\n\n\t\tconst defaultRows = config.defaultHeadings.rows;\n\t\tconst defaultColumns = config.defaultHeadings.columns;\n\n\t\tif ( options.headingRows === undefined && defaultRows ) {\n\t\t\toptions.headingRows = defaultRows;\n\t\t}\n\n\t\tif ( options.headingColumns === undefined && defaultColumns ) {\n\t\t\toptions.headingColumns = defaultColumns;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst table = tableUtils.createTable( writer, options );\n\n\t\t\tmodel.insertContent( table, insertionRange );\n\n\t\t\twriter.setSelection( writer.createPositionAt( table.getNodeByPath( [ 0, 0, 0 ] ), 0 ) );\n\t\t} );\n\t}\n}\n\n// Checks if the table is allowed in the parent.\n//\n// @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n// @param {module:engine/model/schema~Schema} schema\n// @returns {Boolean}\nfunction isAllowedInParent( selection, schema ) {\n\tconst positionParent = selection.getFirstPosition().parent;\n\tconst validParent = positionParent === positionParent.root ? positionParent : positionParent.parent;\n\n\treturn schema.checkChild( validParent, 'table' );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/mergecellcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport TableWalker from '../tablewalker';\nimport { getTableCellsContainingSelection } from '../utils/selection';\nimport { isHeadingColumnCell } from '../utils/common';\nimport { removeEmptyRowsColumns } from '../utils/structure';\n\n/**\n * The merge cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'mergeTableCellRight'`, `'mergeTableCellLeft'`,\n * `'mergeTableCellUp'` and `'mergeTableCellDown'` editor commands.\n *\n * To merge a table cell at the current selection with another cell, execute the command corresponding with the preferred direction.\n *\n * For example, to merge with a cell to the right:\n *\n *\t\teditor.execute( 'mergeTableCellRight' );\n *\n * **Note**: If a table cell has a different [`rowspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-rowspan)\n * (for `'mergeTableCellRight'` and `'mergeTableCellLeft'`) or [`colspan`](https://www.w3.org/TR/html50/tabular-data.html#attr-tdth-colspan)\n * (for `'mergeTableCellUp'` and `'mergeTableCellDown'`), the command will be disabled.\n *\n * @extends module:core/command~Command\n */\nexport default class MergeCellCommand extends Command {\n\t/**\n\t * Creates a new `MergeCellCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} options.direction Indicates which cell to merge with the currently selected one.\n\t * Possible values are: `'left'`, `'right'`, `'up'` and `'down'`.\n\t */\n\tconstructor( editor, options ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The direction that indicates which cell will be merged with the currently selected one.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #direction\n\t\t */\n\t\tthis.direction = options.direction;\n\n\t\t/**\n\t\t * Whether the merge is horizontal (left/right) or vertical (up/down).\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isHorizontal\n\t\t */\n\t\tthis.isHorizontal = this.direction == 'right' || this.direction == 'left';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst cellToMerge = this._getMergeableCell();\n\n\t\tthis.value = cellToMerge;\n\t\tthis.isEnabled = !!cellToMerge;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * Depending on the command's {@link #direction} value, it will merge the cell that is to the `'left'`, `'right'`, `'up'` or `'down'`.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst tableCell = getTableCellsContainingSelection( doc.selection )[ 0 ];\n\n\t\tconst cellToMerge = this.value;\n\t\tconst direction = this.direction;\n\n\t\tmodel.change( writer => {\n\t\t\tconst isMergeNext = direction == 'right' || direction == 'down';\n\n\t\t\t// The merge mechanism is always the same so sort cells to be merged.\n\t\t\tconst cellToExpand = isMergeNext ? tableCell : cellToMerge;\n\t\t\tconst cellToRemove = isMergeNext ? cellToMerge : tableCell;\n\n\t\t\t// Cache the parent of cell to remove for later check.\n\t\t\tconst removedTableCellRow = cellToRemove.parent;\n\n\t\t\tmergeTableCells( cellToRemove, cellToExpand, writer );\n\n\t\t\tconst spanAttribute = this.isHorizontal ? 'colspan' : 'rowspan';\n\t\t\tconst cellSpan = parseInt( tableCell.getAttribute( spanAttribute ) || 1 );\n\t\t\tconst cellToMergeSpan = parseInt( cellToMerge.getAttribute( spanAttribute ) || 1 );\n\n\t\t\t// Update table cell span attribute and merge set selection on merged contents.\n\t\t\twriter.setAttribute( spanAttribute, cellSpan + cellToMergeSpan, cellToExpand );\n\t\t\twriter.setSelection( writer.createRangeIn( cellToExpand ) );\n\n\t\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\t\tconst table = removedTableCellRow.findAncestor( 'table' );\n\n\t\t\t// Remove empty rows and columns after merging.\n\t\t\tremoveEmptyRowsColumns( table, tableUtils );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a cell that can be merged with the current cell depending on the command's direction.\n\t *\n\t * @returns {module:engine/model/element~Element|undefined}\n\t * @private\n\t */\n\t_getMergeableCell() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tconst tableCell = getTableCellsContainingSelection( doc.selection )[ 0 ];\n\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\t// First get the cell on proper direction.\n\t\tconst cellToMerge = this.isHorizontal ?\n\t\t\tgetHorizontalCell( tableCell, this.direction, tableUtils ) :\n\t\t\tgetVerticalCell( tableCell, this.direction, tableUtils );\n\n\t\tif ( !cellToMerge ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If found check if the span perpendicular to merge direction is equal on both cells.\n\t\tconst spanAttribute = this.isHorizontal ? 'rowspan' : 'colspan';\n\t\tconst span = parseInt( tableCell.getAttribute( spanAttribute ) || 1 );\n\n\t\tconst cellToMergeSpan = parseInt( cellToMerge.getAttribute( spanAttribute ) || 1 );\n\n\t\tif ( cellToMergeSpan === span ) {\n\t\t\treturn cellToMerge;\n\t\t}\n\t}\n}\n\n// Returns the cell that can be merged horizontally.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {String} direction\n// @param {module:table/tableutils~TableUtils} tableUtils\n// @returns {module:engine/model/node~Node|null}\nfunction getHorizontalCell( tableCell, direction, tableUtils ) {\n\tconst tableRow = tableCell.parent;\n\tconst table = tableRow.parent;\n\tconst horizontalCell = direction == 'right' ? tableCell.nextSibling : tableCell.previousSibling;\n\tconst hasHeadingColumns = ( table.getAttribute( 'headingColumns' ) || 0 ) > 0;\n\n\tif ( !horizontalCell ) {\n\t\treturn;\n\t}\n\n\t// Sort cells:\n\tconst cellOnLeft = direction == 'right' ? tableCell : horizontalCell;\n\tconst cellOnRight = direction == 'right' ? horizontalCell : tableCell;\n\n\t// Get their column indexes:\n\tconst { column: leftCellColumn } = tableUtils.getCellLocation( cellOnLeft );\n\tconst { column: rightCellColumn } = tableUtils.getCellLocation( cellOnRight );\n\n\tconst leftCellSpan = parseInt( cellOnLeft.getAttribute( 'colspan' ) || 1 );\n\n\tconst isCellOnLeftInHeadingColumn = isHeadingColumnCell( tableUtils, cellOnLeft, table );\n\tconst isCellOnRightInHeadingColumn = isHeadingColumnCell( tableUtils, cellOnRight, table );\n\n\t// We cannot merge heading columns cells with regular cells.\n\tif ( hasHeadingColumns && isCellOnLeftInHeadingColumn != isCellOnRightInHeadingColumn ) {\n\t\treturn;\n\t}\n\n\t// The cell on the right must have index that is distant to the cell on the left by the left cell's width (colspan).\n\tconst cellsAreTouching = leftCellColumn + leftCellSpan === rightCellColumn;\n\n\t// If the right cell's column index is different it means that there are rowspanned cells between them.\n\treturn cellsAreTouching ? horizontalCell : undefined;\n}\n\n// Returns the cell that can be merged vertically.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {String} direction\n// @param {module:table/tableutils~TableUtils} tableUtils\n// @returns {module:engine/model/node~Node|null}\nfunction getVerticalCell( tableCell, direction, tableUtils ) {\n\tconst tableRow = tableCell.parent;\n\tconst table = tableRow.parent;\n\n\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t// Don't search for mergeable cell if direction points out of the table.\n\tif ( ( direction == 'down' && rowIndex === tableUtils.getRows( table ) - 1 ) || ( direction == 'up' && rowIndex === 0 ) ) {\n\t\treturn;\n\t}\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\tconst isMergeWithBodyCell = direction == 'down' && ( rowIndex + rowspan ) === headingRows;\n\tconst isMergeWithHeadCell = direction == 'up' && rowIndex === headingRows;\n\n\t// Don't search for mergeable cell if direction points out of the current table section.\n\tif ( headingRows && ( isMergeWithBodyCell || isMergeWithHeadCell ) ) {\n\t\treturn;\n\t}\n\n\tconst currentCellRowSpan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\tconst rowOfCellToMerge = direction == 'down' ? rowIndex + currentCellRowSpan : rowIndex;\n\n\tconst tableMap = [ ...new TableWalker( table, { endRow: rowOfCellToMerge } ) ];\n\n\tconst currentCellData = tableMap.find( value => value.cell === tableCell );\n\tconst mergeColumn = currentCellData.column;\n\n\tconst cellToMergeData = tableMap.find( ( { row, cellHeight, column } ) => {\n\t\tif ( column !== mergeColumn ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( direction == 'down' ) {\n\t\t\t// If merging a cell below the mergeRow is already calculated.\n\t\t\treturn row === rowOfCellToMerge;\n\t\t} else {\n\t\t\t// If merging a cell above calculate if it spans to mergeRow.\n\t\t\treturn rowOfCellToMerge === row + cellHeight;\n\t\t}\n\t} );\n\n\treturn cellToMergeData && cellToMergeData.cell;\n}\n\n// Merges two table cells. It will ensure that after merging cells with an empty paragraph, the resulting table cell will only have one\n// paragraph. If one of the merged table cells is empty, the merged table cell will have the contents of the non-empty table cell.\n// If both are empty, the merged table cell will have only one empty paragraph.\n//\n// @param {module:engine/model/element~Element} cellToRemove\n// @param {module:engine/model/element~Element} cellToExpand\n// @param {module:engine/model/writer~Writer} writer\nfunction mergeTableCells( cellToRemove, cellToExpand, writer ) {\n\tif ( !isEmpty( cellToRemove ) ) {\n\t\tif ( isEmpty( cellToExpand ) ) {\n\t\t\twriter.remove( writer.createRangeIn( cellToExpand ) );\n\t\t}\n\n\t\twriter.move( writer.createRangeIn( cellToRemove ), writer.createPositionAt( cellToExpand, 'end' ) );\n\t}\n\n\t// Remove merged table cell.\n\twriter.remove( cellToRemove );\n}\n\n// Checks if the passed table cell contains an empty paragraph.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @returns {Boolean}\nfunction isEmpty( tableCell ) {\n\treturn tableCell.childCount == 1 && tableCell.getChild( 0 ).is( 'element', 'paragraph' ) && tableCell.getChild( 0 ).isEmpty;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/mergecellscommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport TableUtils from '../tableutils';\nimport { getSelectedTableCells, isSelectionRectangular } from '../utils/selection';\nimport { updateNumericAttribute } from '../utils/common';\nimport { removeEmptyRowsColumns } from '../utils/structure';\n\n/**\n * The merge cells command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'mergeTableCells'` editor command.\n *\n * For example, to merge selected table cells:\n *\n *\t\teditor.execute( 'mergeTableCells' );\n *\n * @extends module:core/command~Command\n */\nexport default class MergeCellsCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selectedTableCells = getSelectedTableCells( this.editor.model.document.selection );\n\t\tthis.isEnabled = isSelectionRectangular( selectedTableCells, this.editor.plugins.get( TableUtils ) );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\n\t\tmodel.change( writer => {\n\t\t\tconst selectedTableCells = getSelectedTableCells( model.document.selection );\n\n\t\t\t// All cells will be merged into the first one.\n\t\t\tconst firstTableCell = selectedTableCells.shift();\n\n\t\t\t// Update target cell dimensions.\n\t\t\tconst { mergeWidth, mergeHeight } = getMergeDimensions( firstTableCell, selectedTableCells, tableUtils );\n\t\t\tupdateNumericAttribute( 'colspan', mergeWidth, firstTableCell, writer );\n\t\t\tupdateNumericAttribute( 'rowspan', mergeHeight, firstTableCell, writer );\n\n\t\t\tfor ( const tableCell of selectedTableCells ) {\n\t\t\t\tmergeTableCells( tableCell, firstTableCell, writer );\n\t\t\t}\n\n\t\t\tconst table = firstTableCell.findAncestor( 'table' );\n\n\t\t\t// Remove rows and columns that become empty (have no anchored cells).\n\t\t\tremoveEmptyRowsColumns( table, tableUtils );\n\n\t\t\twriter.setSelection( firstTableCell, 'in' );\n\t\t} );\n\t}\n}\n\n// Merges two table cells. It will ensure that after merging cells with empty paragraphs the resulting table cell will only have one\n// paragraph. If one of the merged table cells is empty, the merged table cell will have contents of the non-empty table cell.\n// If both are empty, the merged table cell will have only one empty paragraph.\n//\n// @param {module:engine/model/element~Element} cellBeingMerged\n// @param {module:engine/model/element~Element} targetCell\n// @param {module:engine/model/writer~Writer} writer\nfunction mergeTableCells( cellBeingMerged, targetCell, writer ) {\n\tif ( !isEmpty( cellBeingMerged ) ) {\n\t\tif ( isEmpty( targetCell ) ) {\n\t\t\twriter.remove( writer.createRangeIn( targetCell ) );\n\t\t}\n\n\t\twriter.move( writer.createRangeIn( cellBeingMerged ), writer.createPositionAt( targetCell, 'end' ) );\n\t}\n\n\t// Remove merged table cell.\n\twriter.remove( cellBeingMerged );\n}\n\n// Checks if the passed table cell contains an empty paragraph.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @returns {Boolean}\nfunction isEmpty( tableCell ) {\n\treturn tableCell.childCount == 1 && tableCell.getChild( 0 ).is( 'element', 'paragraph' ) && tableCell.getChild( 0 ).isEmpty;\n}\n\nfunction getMergeDimensions( firstTableCell, selectedTableCells, tableUtils ) {\n\tlet maxWidthOffset = 0;\n\tlet maxHeightOffset = 0;\n\n\tfor ( const tableCell of selectedTableCells ) {\n\t\tconst { row, column } = tableUtils.getCellLocation( tableCell );\n\n\t\tmaxWidthOffset = getMaxOffset( tableCell, column, maxWidthOffset, 'colspan' );\n\t\tmaxHeightOffset = getMaxOffset( tableCell, row, maxHeightOffset, 'rowspan' );\n\t}\n\n\t// Update table cell span attribute and merge set selection on a merged contents.\n\tconst { row: firstCellRow, column: firstCellColumn } = tableUtils.getCellLocation( firstTableCell );\n\n\tconst mergeWidth = maxWidthOffset - firstCellColumn;\n\tconst mergeHeight = maxHeightOffset - firstCellRow;\n\n\treturn { mergeWidth, mergeHeight };\n}\n\nfunction getMaxOffset( tableCell, start, currentMaxOffset, which ) {\n\tconst dimensionValue = parseInt( tableCell.getAttribute( which ) || 1 );\n\n\treturn Math.max( currentMaxOffset, start + dimensionValue );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/removecolumncommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport TableWalker from '../tablewalker';\nimport { getColumnIndexes, getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The remove column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableColumn'` editor command.\n *\n * To remove the column containing the selected cell, execute the command:\n *\n *\t\teditor.execute( 'removeTableColumn' );\n *\n * @extends module:core/command~Command\n */\nexport default class RemoveColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );\n\t\tconst firstCell = selectedCells[ 0 ];\n\n\t\tif ( firstCell ) {\n\t\t\tconst table = firstCell.findAncestor( 'table' );\n\t\t\tconst tableColumnCount = this.editor.plugins.get( 'TableUtils' ).getColumns( table );\n\n\t\t\tconst { first, last } = getColumnIndexes( selectedCells );\n\n\t\t\tthis.isEnabled = last - first < ( tableColumnCount - 1 );\n\t\t} else {\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst [ firstCell, lastCell ] = getBoundaryCells( this.editor.model.document.selection );\n\t\tconst table = firstCell.parent.parent;\n\n\t\t// Cache the table before removing or updating colspans.\n\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t// Store column indexes of removed columns.\n\t\tconst removedColumnIndexes = {\n\t\t\tfirst: tableMap.find( value => value.cell === firstCell ).column,\n\t\t\tlast: tableMap.find( value => value.cell === lastCell ).column\n\t\t};\n\n\t\tconst cellToFocus = getCellToFocus( tableMap, firstCell, lastCell, removedColumnIndexes );\n\n\t\tthis.editor.model.change( writer => {\n\t\t\tconst columnsToRemove = removedColumnIndexes.last - removedColumnIndexes.first + 1;\n\n\t\t\tthis.editor.plugins.get( 'TableUtils' ).removeColumns( table, {\n\t\t\t\tat: removedColumnIndexes.first,\n\t\t\t\tcolumns: columnsToRemove\n\t\t\t} );\n\n\t\t\twriter.setSelection( writer.createPositionAt( cellToFocus, 0 ) );\n\t\t} );\n\t}\n}\n\n// Returns a proper table cell to focus after removing a column.\n// - selection is on last table cell it will return previous cell.\nfunction getCellToFocus( tableMap, firstCell, lastCell, removedColumnIndexes ) {\n\tconst colspan = parseInt( lastCell.getAttribute( 'colspan' ) || 1 );\n\n\t// If the table cell is spanned over 2+ columns - it will be truncated so the selection should\n\t// stay in that cell.\n\tif ( colspan > 1 ) {\n\t\treturn lastCell;\n\t}\n\t// Normally, look for the cell in the same row that precedes the first cell to put selection there (\"column on the left\").\n\t// If the deleted column is the first column of the table, there will be no predecessor: use the cell\n\t// from the column that follows then (also in the same row).\n\telse if ( firstCell.previousSibling || lastCell.nextSibling ) {\n\t\treturn lastCell.nextSibling || firstCell.previousSibling;\n\t}\n\t// It can happen that table cells have no siblings in a row, for instance, when there are row spans\n\t// in the table (in the previous row). Then just look for the closest cell that is in a column\n\t// that will not be removed to put the selection there.\n\telse {\n\t\t// Look for any cell in a column that precedes the first removed column.\n\t\tif ( removedColumnIndexes.first ) {\n\t\t\treturn tableMap.reverse().find( ( { column } ) => {\n\t\t\t\treturn column < removedColumnIndexes.first;\n\t\t\t} ).cell;\n\t\t}\n\t\t// If the first removed column is the first column of the table, then\n\t\t// look for any cell that is in a column that follows the last removed column.\n\t\telse {\n\t\t\treturn tableMap.reverse().find( ( { column } ) => {\n\t\t\t\treturn column > removedColumnIndexes.last;\n\t\t\t} ).cell;\n\t\t}\n\t}\n}\n\n// Returns helper object returning the first and the last cell contained in given selection, based on DOM order.\nfunction getBoundaryCells( selection ) {\n\tconst referenceCells = getSelectionAffectedTableCells( selection );\n\tconst firstCell = referenceCells[ 0 ];\n\tconst lastCell = referenceCells.pop();\n\n\tconst returnValue = [ firstCell, lastCell ];\n\n\treturn firstCell.isBefore( lastCell ) ? returnValue : returnValue.reverse();\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/removerowcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The remove row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'removeTableRow'` editor command.\n *\n * To remove the row containing the selected cell, execute the command:\n *\n *\t\teditor.execute( 'removeTableRow' );\n *\n * @extends module:core/command~Command\n */\nexport default class RemoveRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );\n\t\tconst firstCell = selectedCells[ 0 ];\n\n\t\tif ( firstCell ) {\n\t\t\tconst table = firstCell.findAncestor( 'table' );\n\t\t\tconst tableRowCount = this.editor.plugins.get( 'TableUtils' ).getRows( table );\n\t\t\tconst lastRowIndex = tableRowCount - 1;\n\n\t\t\tconst selectedRowIndexes = getRowIndexes( selectedCells );\n\n\t\t\tconst areAllRowsSelected = selectedRowIndexes.first === 0 && selectedRowIndexes.last === lastRowIndex;\n\n\t\t\t// Disallow selecting whole table -> delete whole table should be used instead.\n\t\t\tthis.isEnabled = !areAllRowsSelected;\n\t\t} else {\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tconst referenceCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst removedRowIndexes = getRowIndexes( referenceCells );\n\n\t\tconst firstCell = referenceCells[ 0 ];\n\t\tconst table = firstCell.findAncestor( 'table' );\n\n\t\tconst columnIndexToFocus = tableUtils.getCellLocation( firstCell ).column;\n\n\t\tmodel.change( writer => {\n\t\t\tconst rowsToRemove = removedRowIndexes.last - removedRowIndexes.first + 1;\n\n\t\t\ttableUtils.removeRows( table, {\n\t\t\t\tat: removedRowIndexes.first,\n\t\t\t\trows: rowsToRemove\n\t\t\t} );\n\n\t\t\tconst cellToFocus = getCellToFocus( table, removedRowIndexes.first, columnIndexToFocus, tableUtils.getRows( table ) );\n\n\t\t\twriter.setSelection( writer.createPositionAt( cellToFocus, 0 ) );\n\t\t} );\n\t}\n}\n\n// Returns a cell that should be focused before removing the row, belonging to the same column as the currently focused cell.\n// * If the row was not the last one, the cell to focus will be in the row that followed it (before removal).\n// * If the row was the last one, the cell to focus will be in the row that preceded it (before removal).\nfunction getCellToFocus( table, removedRowIndex, columnToFocus, tableRowCount ) {\n\t// Don't go beyond last row's index.\n\tconst row = table.getChild( Math.min( removedRowIndex, tableRowCount - 1 ) );\n\n\t// Default to first table cell.\n\tlet cellToFocus = row.getChild( 0 );\n\tlet column = 0;\n\n\tfor ( const tableCell of row.getChildren() ) {\n\t\tif ( column > columnToFocus ) {\n\t\t\treturn cellToFocus;\n\t\t}\n\n\t\tcellToFocus = tableCell;\n\t\tcolumn += parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\t}\n\n\treturn cellToFocus;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/selectcolumncommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport TableWalker from '../tablewalker';\nimport { getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The select column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableColumn'` editor command.\n *\n * To select the columns containing the selected cells, execute the command:\n *\n *\t\teditor.execute( 'selectTableColumn' );\n *\n * @extends module:core/command~Command\n */\nexport default class SelectColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t// It does not affect data so should be enabled in read-only mode.\n\t\tthis.affectsData = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );\n\n\t\tthis.isEnabled = selectedCells.length > 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst referenceCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst firstCell = referenceCells[ 0 ];\n\t\tconst lastCell = referenceCells.pop();\n\t\tconst table = firstCell.findAncestor( 'table' );\n\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst startLocation = tableUtils.getCellLocation( firstCell );\n\t\tconst endLocation = tableUtils.getCellLocation( lastCell );\n\n\t\tconst startColumn = Math.min( startLocation.column, endLocation.column );\n\t\tconst endColumn = Math.max( startLocation.column, endLocation.column );\n\n\t\tconst rangesToSelect = [];\n\n\t\tfor ( const cellInfo of new TableWalker( table, { startColumn, endColumn } ) ) {\n\t\t\trangesToSelect.push( model.createRangeOn( cellInfo.cell ) );\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( rangesToSelect );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/selectrowcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The select row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'selectTableRow'` editor command.\n *\n * To select the rows containing the selected cells, execute the command:\n *\n *\t\teditor.execute( 'selectTableRow' );\n *\n * @extends module:core/command~Command\n */\nexport default class SelectRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t// It does not affect data so should be enabled in read-only mode.\n\t\tthis.affectsData = false;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );\n\n\t\tthis.isEnabled = selectedCells.length > 0;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst referenceCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst rowIndexes = getRowIndexes( referenceCells );\n\n\t\tconst table = referenceCells[ 0 ].findAncestor( 'table' );\n\t\tconst rangesToSelect = [];\n\n\t\tfor ( let rowIndex = rowIndexes.first; rowIndex <= rowIndexes.last; rowIndex++ ) {\n\t\t\tfor ( const cell of table.getChild( rowIndex ).getChildren() ) {\n\t\t\t\trangesToSelect.push( model.createRangeOn( cell ) );\n\t\t\t}\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( rangesToSelect );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/setheadercolumncommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport {\n\tisHeadingColumnCell,\n\tupdateNumericAttribute\n} from '../utils/common';\nimport { getColumnIndexes, getSelectionAffectedTableCells } from '../utils/selection';\nimport { getHorizontallyOverlappingCells, splitVertically } from '../utils/structure';\n\n/**\n * The header column command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.\n *\n * You can make the column containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element)\n * by executing:\n *\n *\t\teditor.execute( 'setTableColumnHeader' );\n *\n * **Note:** All preceding columns will also become headers. If the current column is already a header, executing this command\n * will make it a regular column back again (including the following columns).\n *\n * @extends module:core/command~Command\n */\nexport default class SetHeaderColumnCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst selectedCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst isInTable = selectedCells.length > 0;\n\n\t\tthis.isEnabled = isInTable;\n\n\t\t/**\n\t\t * Flag indicating whether the command is active. The command is active when the\n\t\t * {@link module:engine/model/selection~Selection} is in a header column.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t\tthis.value = isInTable && selectedCells.every( cell => isHeadingColumnCell( tableUtils, cell ) );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header column, the command will set the `headingColumns` table attribute to cover that column.\n\t *\n\t * When the selection is already in a header column, it will set `headingColumns` so the heading section will end before that column.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.forceValue] If set, the command will set (`true`) or unset (`false`) the header columns according to\n\t * the `forceValue` parameter instead of the current model state.\n\t */\n\texecute( options = {} ) {\n\t\tif ( options.forceValue === this.value ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst model = this.editor.model;\n\t\tconst selectedCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst table = selectedCells[ 0 ].findAncestor( 'table' );\n\n\t\tconst { first, last } = getColumnIndexes( selectedCells );\n\t\tconst headingColumnsToSet = this.value ? first : last + 1;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( headingColumnsToSet ) {\n\t\t\t\t// Changing heading columns requires to check if any of a heading cell is overlapping horizontally the table head.\n\t\t\t\t// Any table cell that has a colspan attribute > 1 will not exceed the table head so we need to fix it in columns before.\n\t\t\t\tconst overlappingCells = getHorizontallyOverlappingCells( table, headingColumnsToSet );\n\n\t\t\t\tfor ( const { cell, column } of overlappingCells ) {\n\t\t\t\t\tsplitVertically( cell, column, headingColumnsToSet, writer );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdateNumericAttribute( 'headingColumns', headingColumnsToSet, table, writer, 0 );\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/setheaderrowcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport { updateNumericAttribute } from '../utils/common';\nimport { getRowIndexes, getSelectionAffectedTableCells } from '../utils/selection';\nimport { getVerticallyOverlappingCells, splitHorizontally } from '../utils/structure';\n\n/**\n * The header row command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'setTableColumnHeader'` editor command.\n *\n * You can make the row containing the selected cell a [header](https://www.w3.org/TR/html50/tabular-data.html#the-th-element) by executing:\n *\n *\t\teditor.execute( 'setTableRowHeader' );\n *\n * **Note:** All preceding rows will also become headers. If the current row is already a header, executing this command\n * will make it a regular row back again (including the following rows).\n *\n * @extends module:core/command~Command\n */\nexport default class SetHeaderRowCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst model = this.editor.model;\n\t\tconst selectedCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst isInTable = selectedCells.length > 0;\n\n\t\tthis.isEnabled = isInTable;\n\n\t\t/**\n\t\t * Flag indicating whether the command is active. The command is active when the\n\t\t * {@link module:engine/model/selection~Selection} is in a header row.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t\tthis.value = isInTable && selectedCells.every( cell => this._isInHeading( cell, cell.parent.parent ) );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * When the selection is in a non-header row, the command will set the `headingRows` table attribute to cover that row.\n\t *\n\t * When the selection is already in a header row, it will set `headingRows` so the heading section will end before that row.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {Boolean} [options.forceValue] If set, the command will set (`true`) or unset (`false`) the header rows according to\n\t * the `forceValue` parameter instead of the current model state.\n\t */\n\texecute( options = {} ) {\n\t\tif ( options.forceValue === this.value ) {\n\t\t\treturn;\n\t\t}\n\t\tconst model = this.editor.model;\n\t\tconst selectedCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst table = selectedCells[ 0 ].findAncestor( 'table' );\n\n\t\tconst { first, last } = getRowIndexes( selectedCells );\n\t\tconst headingRowsToSet = this.value ? first : last + 1;\n\t\tconst currentHeadingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( headingRowsToSet ) {\n\t\t\t\t// Changing heading rows requires to check if any of a heading cell is overlapping vertically the table head.\n\t\t\t\t// Any table cell that has a rowspan attribute > 1 will not exceed the table head so we need to fix it in rows below.\n\t\t\t\tconst startRow = headingRowsToSet > currentHeadingRows ? currentHeadingRows : 0;\n\t\t\t\tconst overlappingCells = getVerticallyOverlappingCells( table, headingRowsToSet, startRow );\n\n\t\t\t\tfor ( const { cell } of overlappingCells ) {\n\t\t\t\t\tsplitHorizontally( cell, headingRowsToSet, writer );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tupdateNumericAttribute( 'headingRows', headingRowsToSet, table, writer, 0 );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if a table cell is in the heading section.\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {module:engine/model/element~Element} table\n\t * @returns {Boolean}\n\t * @private\n\t */\n\t_isInHeading( tableCell, table ) {\n\t\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );\n\n\t\treturn !!headingRows && tableCell.parent.index < headingRows;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/commands/splitcellcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getSelectionAffectedTableCells } from '../utils/selection';\n\n/**\n * The split cell command.\n *\n * The command is registered by {@link module:table/tableediting~TableEditing} as the `'splitTableCellVertically'`\n * and `'splitTableCellHorizontally'` editor commands.\n *\n * You can split any cell vertically or horizontally by executing this command. For example, to split the selected table cell vertically:\n *\n *\t\teditor.execute( 'splitTableCellVertically' );\n *\n * @extends module:core/command~Command\n */\nexport default class SplitCellCommand extends Command {\n\t/**\n\t * Creates a new `SplitCellCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor on which this command will be used.\n\t * @param {Object} options\n\t * @param {String} options.direction Indicates whether the command should split cells `'horizontally'` or `'vertically'`.\n\t */\n\tconstructor( editor, options = {} ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The direction that indicates which cell will be split.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String} #direction\n\t\t */\n\t\tthis.direction = options.direction || 'horizontally';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst selectedCells = getSelectionAffectedTableCells( this.editor.model.document.selection );\n\n\t\tthis.isEnabled = selectedCells.length === 1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\texecute() {\n\t\tconst tableCell = getSelectionAffectedTableCells( this.editor.model.document.selection )[ 0 ];\n\t\tconst isHorizontal = this.direction === 'horizontally';\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\tif ( isHorizontal ) {\n\t\t\ttableUtils.splitCellHorizontally( tableCell, 2 );\n\t\t} else {\n\t\t\ttableUtils.splitCellVertically( tableCell, 2 );\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/downcast\n */\n\nimport TableWalker from './../tablewalker';\nimport { toWidget, toWidgetEditable } from 'ckeditor5/src/widget';\n\n/**\n * Model table element to view table element conversion helper.\n *\n * This conversion helper creates the whole table element with child elements.\n *\n * @param {Object} options\n * @param {Boolean} options.asWidget If set to `true`, the downcast conversion will produce a widget.\n * @returns {Function} Conversion helper.\n */\nexport function downcastInsertTable( options = {} ) {\n\treturn dispatcher => dispatcher.on( 'insert:table', ( evt, data, conversionApi ) => {\n\t\tconst table = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( table, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Consume attributes if present to not fire attribute change downcast\n\t\tconversionApi.consumable.consume( table, 'attribute:headingRows:table' );\n\t\tconversionApi.consumable.consume( table, 'attribute:headingColumns:table' );\n\n\t\tconst asWidget = options && options.asWidget;\n\n\t\tconst figureElement = conversionApi.writer.createContainerElement( 'figure', { class: 'table' } );\n\t\tconst tableElement = conversionApi.writer.createContainerElement( 'table' );\n\t\tconversionApi.writer.insert( conversionApi.writer.createPositionAt( figureElement, 0 ), tableElement );\n\n\t\tlet tableWidget;\n\n\t\tif ( asWidget ) {\n\t\t\ttableWidget = toTableWidget( figureElement, conversionApi.writer );\n\t\t}\n\n\t\tconst tableWalker = new TableWalker( table );\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\t// Cache for created table rows.\n\t\tconst viewRows = new Map();\n\n\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\tconst { row, cell } = tableSlot;\n\n\t\t\tconst tableRow = table.getChild( row );\n\t\t\tconst trElement = viewRows.get( row ) || createTr( tableElement, tableRow, row, tableAttributes, conversionApi );\n\t\t\tviewRows.set( row, trElement );\n\n\t\t\t// Consume table cell - it will be always consumed as we convert whole table at once.\n\t\t\tconversionApi.consumable.consume( cell, 'insert' );\n\n\t\t\tconst insertPosition = conversionApi.writer.createPositionAt( trElement, 'end' );\n\n\t\t\tcreateViewTableCellElement( tableSlot, tableAttributes, insertPosition, conversionApi, options );\n\t\t}\n\n\t\t// Insert empty TR elements if there are any rows without anchored cells. Since the model is always normalized\n\t\t// this can happen only in the document fragment that only part of the table is down-casted.\n\t\tfor ( const tableRow of table.getChildren() ) {\n\t\t\tconst rowIndex = tableRow.index;\n\n\t\t\t// Make sure that this is a table row and not some other element (i.e., caption).\n\t\t\tif ( tableRow.is( 'element', 'tableRow' ) && !viewRows.has( rowIndex ) ) {\n\t\t\t\tviewRows.set( rowIndex, createTr( tableElement, tableRow, rowIndex, tableAttributes, conversionApi ) );\n\t\t\t}\n\t\t}\n\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconversionApi.mapper.bindElements( table, asWidget ? tableWidget : figureElement );\n\t\tconversionApi.writer.insert( viewPosition, asWidget ? tableWidget : figureElement );\n\t} );\n}\n\n/**\n * Model row element to view `<tr>` element conversion helper.\n *\n * This conversion helper creates the whole `<tr>` element with child elements.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastInsertRow() {\n\treturn dispatcher => dispatcher.on( 'insert:tableRow', ( evt, data, conversionApi ) => {\n\t\tconst tableRow = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( tableRow, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst table = tableRow.parent;\n\n\t\tconst figureElement = conversionApi.mapper.toViewElement( table );\n\t\tconst tableElement = getViewTable( figureElement );\n\n\t\tconst row = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { row } );\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\t// Cache for created table rows.\n\t\tconst viewRows = new Map();\n\n\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\tconst trElement = viewRows.get( row ) || createTr( tableElement, tableRow, row, tableAttributes, conversionApi );\n\t\t\tviewRows.set( row, trElement );\n\n\t\t\t// Consume table cell - it will be always consumed as we convert whole row at once.\n\t\t\tconversionApi.consumable.consume( tableSlot.cell, 'insert' );\n\n\t\t\tconst insertPosition = conversionApi.writer.createPositionAt( trElement, 'end' );\n\n\t\t\tcreateViewTableCellElement( tableSlot, tableAttributes, insertPosition, conversionApi, { asWidget: true } );\n\t\t}\n\t} );\n}\n\n/**\n * Model table cell element to view `<td>` or `<th>` element conversion helper.\n *\n * This conversion helper will create proper `<th>` elements for table cells that are in the heading section (heading row or column)\n * and `<td>` otherwise.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastInsertCell() {\n\treturn dispatcher => dispatcher.on( 'insert:tableCell', ( evt, data, conversionApi ) => {\n\t\tconst tableCell = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( tableCell, 'insert' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\t\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { row: rowIndex } );\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\t// We need to iterate over a table in order to get proper row & column values from a walker\n\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\tif ( tableSlot.cell === tableCell ) {\n\t\t\t\tconst trElement = conversionApi.mapper.toViewElement( tableRow );\n\t\t\t\tconst insertPosition = conversionApi.writer.createPositionAt( trElement, tableRow.getChildIndex( tableCell ) );\n\n\t\t\t\tcreateViewTableCellElement( tableSlot, tableAttributes, insertPosition, conversionApi, { asWidget: true } );\n\n\t\t\t\t// No need to iterate further.\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t} );\n}\n\n/**\n * Conversion helper that acts on heading column table attribute change.\n *\n * Depending on changed attributes this converter will rename `<td` to `<th>` elements or vice versa depending on the cell column index.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastTableHeadingColumnsChange() {\n\treturn dispatcher => dispatcher.on( 'attribute:headingColumns:table', ( evt, data, conversionApi ) => {\n\t\tconst table = data.item;\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst tableAttributes = {\n\t\t\theadingRows: table.getAttribute( 'headingRows' ) || 0,\n\t\t\theadingColumns: table.getAttribute( 'headingColumns' ) || 0\n\t\t};\n\n\t\tconst oldColumns = data.attributeOldValue;\n\t\tconst newColumns = data.attributeNewValue;\n\n\t\tconst lastColumnToCheck = ( oldColumns > newColumns ? oldColumns : newColumns ) - 1;\n\n\t\tfor ( const tableSlot of new TableWalker( table, { endColumn: lastColumnToCheck } ) ) {\n\t\t\trenameViewTableCellIfRequired( tableSlot, tableAttributes, conversionApi );\n\t\t}\n\t} );\n}\n\n/**\n * Conversion helper that acts on a removed row.\n *\n * @returns {Function} Conversion helper.\n */\nexport function downcastRemoveRow() {\n\treturn dispatcher => dispatcher.on( 'remove:tableRow', ( evt, data, conversionApi ) => {\n\t\t// Prevent default remove converter.\n\t\tevt.stop();\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst mapper = conversionApi.mapper;\n\n\t\tconst viewStart = mapper.toViewPosition( data.position ).getLastMatchingPosition( value => !value.item.is( 'element', 'tr' ) );\n\t\tconst viewItem = viewStart.nodeAfter;\n\t\tconst tableSection = viewItem.parent;\n\t\tconst viewTable = tableSection.parent;\n\n\t\t// Remove associated <tr> from the view.\n\t\tconst removeRange = viewWriter.createRangeOn( viewItem );\n\t\tconst removed = viewWriter.remove( removeRange );\n\n\t\tfor ( const child of viewWriter.createRangeIn( removed ).getItems() ) {\n\t\t\tmapper.unbindViewElement( child );\n\t\t}\n\n\t\t// Cleanup: Ensure that thead & tbody sections are removed if left empty after removing rows. See #6437, #6391.\n\t\tremoveTableSectionIfEmpty( 'thead', viewTable, conversionApi );\n\t\tremoveTableSectionIfEmpty( 'tbody', viewTable, conversionApi );\n\t}, { priority: 'higher' } );\n}\n\n/**\n * Overrides paragraph inside table cell conversion.\n *\n * This converter:\n * * should be used to override default paragraph conversion in the editing view.\n * * It will only convert <paragraph> placed directly inside <tableCell>.\n * * For a single paragraph without attributes it returns `<span>` to simulate data table.\n * * For all other cases it returns `<p>` element.\n *\n * @param {module:engine/model/element~Element} modelElement\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n * @returns {module:engine/view/containerelement~ContainerElement|undefined}\n */\nexport function convertParagraphInTableCell( modelElement, conversionApi ) {\n\tconst { writer } = conversionApi;\n\n\tif ( !modelElement.parent.is( 'element', 'tableCell' ) ) {\n\t\treturn;\n\t}\n\n\tif ( isSingleParagraphWithoutAttributes( modelElement ) ) {\n\t\treturn writer.createContainerElement( 'span', { class: 'ck-table-bogus-paragraph' } );\n\t} else {\n\t\treturn writer.createContainerElement( 'p' );\n\t}\n}\n\n/**\n * Checks if given model `<paragraph>` is an only child of a parent (`<tableCell>`) and if it has any attribute set.\n *\n * The paragraph should be converted in the editing view to:\n *\n * * If returned `true` - to a `<span class=\"ck-table-bogus-paragraph\">`\n * * If returned `false` - to a `<p>`\n *\n * @param {module:engine/model/element~Element} modelElement\n * @returns {Boolean}\n */\nexport function isSingleParagraphWithoutAttributes( modelElement ) {\n\tconst tableCell = modelElement.parent;\n\n\tconst isSingleParagraph = tableCell.childCount === 1;\n\n\treturn isSingleParagraph && !hasAnyAttribute( modelElement );\n}\n\n// Converts a given {@link module:engine/view/element~Element} to a table widget:\n// * Adds a {@link module:engine/view/element~Element#_setCustomProperty custom property} allowing to recognize the table widget element.\n// * Calls the {@link module:widget/utils~toWidget} function with the proper element's label creator.\n//\n// @param {module:engine/view/element~Element} viewElement\n// @param {module:engine/view/downcastwriter~DowncastWriter} writer An instance of the view writer.\n// @param {String} label The element's label. It will be concatenated with the table `alt` attribute if one is present.\n// @returns {module:engine/view/element~Element}\nfunction toTableWidget( viewElement, writer ) {\n\twriter.setCustomProperty( 'table', true, viewElement );\n\n\treturn toWidget( viewElement, writer, { hasSelectionHandle: true } );\n}\n\n// Renames an existing table cell in the view to a given element name.\n//\n// **Note** This method will not do anything if a view table cell has not been converted yet.\n//\n// @param {module:engine/model/element~Element} tableCell\n// @param {String} desiredCellElementName\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction renameViewTableCell( tableCell, desiredCellElementName, conversionApi ) {\n\tconst viewWriter = conversionApi.writer;\n\tconst viewCell = conversionApi.mapper.toViewElement( tableCell );\n\n\tconst editable = viewWriter.createEditableElement( desiredCellElementName, viewCell.getAttributes() );\n\tconst renamedCell = toWidgetEditable( editable, viewWriter );\n\n\tviewWriter.insert( viewWriter.createPositionAfter( viewCell ), renamedCell );\n\tviewWriter.move( viewWriter.createRangeIn( viewCell ), viewWriter.createPositionAt( renamedCell, 0 ) );\n\tviewWriter.remove( viewWriter.createRangeOn( viewCell ) );\n\n\tconversionApi.mapper.unbindViewElement( viewCell );\n\tconversionApi.mapper.bindElements( tableCell, renamedCell );\n}\n\n// Renames a table cell element in the view according to its location in the table.\n//\n// @param {module:table/tablewalker~TableSlot} tableSlot\n// @param {{headingColumns, headingRows}} tableAttributes\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction renameViewTableCellIfRequired( tableSlot, tableAttributes, conversionApi ) {\n\tconst { cell } = tableSlot;\n\n\t// Check whether current columnIndex is overlapped by table cells from previous rows.\n\tconst desiredCellElementName = getCellElementName( tableSlot, tableAttributes );\n\n\tconst viewCell = conversionApi.mapper.toViewElement( cell );\n\n\t// If in single change we're converting attribute changes and inserting cell the table cell might not be inserted into view\n\t// because of child conversion is done after parent.\n\tif ( viewCell && viewCell.name !== desiredCellElementName ) {\n\t\trenameViewTableCell( cell, desiredCellElementName, conversionApi );\n\t}\n}\n\n// Creates a table cell element in the view.\n//\n// @param {module:table/tablewalker~TableSlot} tableSlot\n// @param {module:engine/view/position~Position} insertPosition\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction createViewTableCellElement( tableSlot, tableAttributes, insertPosition, conversionApi, options ) {\n\tconst asWidget = options && options.asWidget;\n\tconst cellElementName = getCellElementName( tableSlot, tableAttributes );\n\n\tconst cellElement = asWidget ?\n\t\ttoWidgetEditable( conversionApi.writer.createEditableElement( cellElementName ), conversionApi.writer ) :\n\t\tconversionApi.writer.createContainerElement( cellElementName );\n\n\tconst tableCell = tableSlot.cell;\n\n\tconst firstChild = tableCell.getChild( 0 );\n\tconst isSingleParagraph = tableCell.childCount === 1 && firstChild.name === 'paragraph';\n\n\tconversionApi.writer.insert( insertPosition, cellElement );\n\n\tconversionApi.mapper.bindElements( tableCell, cellElement );\n\n\t// Additional requirement for data pipeline to have backward compatible data tables.\n\tif ( !asWidget && isSingleParagraph && !hasAnyAttribute( firstChild ) ) {\n\t\tconst innerParagraph = tableCell.getChild( 0 );\n\n\t\tconversionApi.consumable.consume( innerParagraph, 'insert' );\n\n\t\tconversionApi.mapper.bindElements( innerParagraph, cellElement );\n\t}\n}\n\n// Creates a `<tr>` view element.\n//\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/model/element~Element} tableRow\n// @param {Number} rowIndex\n// @param {{headingColumns, headingRows}} tableAttributes\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @returns {module:engine/view/element~Element}\nfunction createTr( tableElement, tableRow, rowIndex, tableAttributes, conversionApi ) {\n\t// Will always consume since we're converting <tableRow> element from a parent <table>.\n\tconversionApi.consumable.consume( tableRow, 'insert' );\n\n\tconst trElement = tableRow.isEmpty ?\n\t\tconversionApi.writer.createEmptyElement( 'tr' ) :\n\t\tconversionApi.writer.createContainerElement( 'tr' );\n\n\tconversionApi.mapper.bindElements( tableRow, trElement );\n\n\tconst headingRows = tableAttributes.headingRows;\n\tconst tableSection = getOrCreateTableSection( getSectionName( rowIndex, tableAttributes ), tableElement, conversionApi );\n\n\tconst offset = headingRows > 0 && rowIndex >= headingRows ? rowIndex - headingRows : rowIndex;\n\tconst position = conversionApi.writer.createPositionAt( tableSection, offset );\n\n\tconversionApi.writer.insert( position, trElement );\n\n\treturn trElement;\n}\n\n// Returns `th` for heading cells and `td` for other cells for the current table walker value.\n//\n// @param {module:table/tablewalker~TableSlot} tableSlot\n// @param {{headingColumns, headingRows}} tableAttributes\n// @returns {String}\nfunction getCellElementName( tableSlot, tableAttributes ) {\n\tconst { row, column } = tableSlot;\n\tconst { headingColumns, headingRows } = tableAttributes;\n\n\t// Column heading are all tableCells in the first `columnHeading` rows.\n\tconst isColumnHeading = headingRows && headingRows > row;\n\n\t// So a whole row gets <th> element.\n\tif ( isColumnHeading ) {\n\t\treturn 'th';\n\t}\n\n\t// Row heading are tableCells which columnIndex is lower then headingColumns.\n\tconst isRowHeading = headingColumns && headingColumns > column;\n\n\treturn isRowHeading ? 'th' : 'td';\n}\n\n// Returns the table section name for the current table walker value.\n//\n// @param {Number} row\n// @param {{headingColumns, headingRows}} tableAttributes\n// @returns {String}\nfunction getSectionName( row, tableAttributes ) {\n\treturn row < tableAttributes.headingRows ? 'thead' : 'tbody';\n}\n\n// Creates or returns an existing `<tbody>` or `<thead>` element with caching.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} viewTable\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @param {Object} cachedTableSection An object that stores cached elements.\n// @returns {module:engine/view/containerelement~ContainerElement}\nfunction getOrCreateTableSection( sectionName, viewTable, conversionApi ) {\n\tconst viewTableSection = getExistingTableSectionElement( sectionName, viewTable );\n\n\treturn viewTableSection ? viewTableSection : createTableSection( sectionName, viewTable, conversionApi );\n}\n\n// Finds an existing `<tbody>` or `<thead>` element or returns undefined.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction getExistingTableSectionElement( sectionName, tableElement ) {\n\tfor ( const tableSection of tableElement.getChildren() ) {\n\t\tif ( tableSection.name == sectionName ) {\n\t\t\treturn tableSection;\n\t\t}\n\t}\n}\n\n// Creates a table section at the end of the table.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\n// @returns {module:engine/view/containerelement~ContainerElement}\nfunction createTableSection( sectionName, tableElement, conversionApi ) {\n\tconst tableChildElement = conversionApi.writer.createContainerElement( sectionName );\n\n\tconst insertPosition = conversionApi.writer.createPositionAt( tableElement, sectionName == 'tbody' ? 'end' : 0 );\n\n\tconversionApi.writer.insert( insertPosition, tableChildElement );\n\n\treturn tableChildElement;\n}\n\n// Removes an existing `<tbody>` or `<thead>` element if it is empty.\n//\n// @param {String} sectionName\n// @param {module:engine/view/element~Element} tableElement\n// @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi\nfunction removeTableSectionIfEmpty( sectionName, tableElement, conversionApi ) {\n\tconst tableSection = getExistingTableSectionElement( sectionName, tableElement );\n\n\tif ( tableSection && tableSection.childCount === 0 ) {\n\t\tconversionApi.writer.remove( conversionApi.writer.createRangeOn( tableSection ) );\n\t}\n}\n\n// Finds a '<table>' element inside the `<figure>` widget.\n//\n// @param {module:engine/view/element~Element} viewFigure\nfunction getViewTable( viewFigure ) {\n\tfor ( const child of viewFigure.getChildren() ) {\n\t\tif ( child.name === 'table' ) {\n\t\t\treturn child;\n\t\t}\n\t}\n}\n\n// Checks if an element has any attributes set.\n//\n// @param {module:engine/model/element~Element element\n// @returns {Boolean}\nfunction hasAnyAttribute( element ) {\n\treturn !![ ...element.getAttributeKeys() ].length;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-caption-post-fixer\n */\n\n/**\n * Injects a table caption post-fixer into the model.\n *\n * The role of the table caption post-fixer is to ensure that the table with caption have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * If there are many caption model element, they are merged into one model.\n * * A final, merged caption model is placed at the end of the table.\n *\n * @param {module:engine/model/model~Model} model\n */\nexport default function injectTableCaptionPostFixer( model ) {\n\tmodel.document.registerPostFixer( writer => tableCaptionPostFixer( writer, model ) );\n}\n\n// The table caption post-fixer.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\nfunction tableCaptionPostFixer( writer, model ) {\n\tconst changes = model.document.differ.getChanges();\n\tlet wasFixed = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type != 'insert' ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst positionParent = entry.position.parent;\n\n\t\tif ( positionParent.is( 'element', 'table' ) || entry.name == 'table' ) {\n\t\t\tconst table = entry.name == 'table' ? entry.position.nodeAfter : entry.position.parent;\n\t\t\tconst captionsToMerge = Array.from( table.getChildren() ).filter( child => child.is( 'element', 'caption' ) );\n\t\t\tconst firstCaption = captionsToMerge.shift();\n\n\t\t\tif ( !firstCaption ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Move all the contents of the captions to the first one.\n\t\t\tfor ( const caption of captionsToMerge ) {\n\t\t\t\twriter.move( writer.createRangeIn( caption ), firstCaption, 'end' );\n\t\t\t\twriter.remove( caption );\n\t\t\t}\n\n\t\t\t// Make sure the final caption is at the end of the table.\n\t\t\tif ( firstCaption.nextSibling ) {\n\t\t\t\twriter.move( writer.createRangeOn( firstCaption ), table, 'end' );\n\t\t\t\twasFixed = true;\n\t\t\t}\n\n\t\t\t// Do we merged captions and/or moved the single caption to the end of the table?\n\t\t\twasFixed = !!captionsToMerge.length || wasFixed;\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-cell-paragraph-post-fixer\n */\n\n/**\n * Injects a table cell post-fixer into the model which inserts a `paragraph` element into empty table cells.\n *\n * A table cell must contain at least one block element as a child. An empty table cell will have an empty `paragraph` as a child.\n *\n *\t\t<table>\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell></tableCell>\n *\t\t\t</tableRow>\n *\t\t</table>\n *\n * Will be fixed to:\n *\n *\t\t<table>\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell><paragraph></paragraph></tableCell>\n *\t\t\t</tableRow>\n *\t\t</table>\n *\n * @param {module:engine/model/model~Model} model\n */\nexport default function injectTableCellParagraphPostFixer( model ) {\n\tmodel.document.registerPostFixer( writer => tableCellContentsPostFixer( writer, model ) );\n}\n\n// The table cell contents post-fixer.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\nfunction tableCellContentsPostFixer( writer, model ) {\n\tconst changes = model.document.differ.getChanges();\n\n\tlet wasFixed = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name == 'table' ) {\n\t\t\twasFixed = fixTable( entry.position.nodeAfter, writer ) || wasFixed;\n\t\t}\n\n\t\tif ( entry.type == 'insert' && entry.name == 'tableRow' ) {\n\t\t\twasFixed = fixTableRow( entry.position.nodeAfter, writer ) || wasFixed;\n\t\t}\n\n\t\tif ( entry.type == 'insert' && entry.name == 'tableCell' ) {\n\t\t\twasFixed = fixTableCellContent( entry.position.nodeAfter, writer ) || wasFixed;\n\t\t}\n\n\t\tif ( checkTableCellChange( entry ) ) {\n\t\t\twasFixed = fixTableCellContent( entry.position.parent, writer ) || wasFixed;\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes all table cells in a table.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\nfunction fixTable( table, writer ) {\n\tlet wasFixed = false;\n\n\tfor ( const row of table.getChildren() ) {\n\t\tif ( row.is( 'element', 'tableRow' ) ) {\n\t\t\twasFixed = fixTableRow( row, writer ) || wasFixed;\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes all table cells in a table row.\n//\n// @param {module:engine/model/element~Element} tableRow\n// @param {module:engine/model/writer~Writer} writer\nfunction fixTableRow( tableRow, writer ) {\n\tlet wasFixed = false;\n\n\tfor ( const tableCell of tableRow.getChildren() ) {\n\t\twasFixed = fixTableCellContent( tableCell, writer ) || wasFixed;\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes all table cell content by:\n// - Adding a paragraph to a table cell without any child.\n// - Wrapping direct $text in a `<paragraph>`.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean}\nfunction fixTableCellContent( tableCell, writer ) {\n\t// Insert paragraph to an empty table cell.\n\tif ( tableCell.childCount == 0 ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( 'Post-fixing table: insert paragraph in empty cell.' );\n\n\t\twriter.insertElement( 'paragraph', tableCell );\n\n\t\treturn true;\n\t}\n\n\t// Check table cell children for directly placed text nodes.\n\t// Temporary solution. See https://github.com/ckeditor/ckeditor5/issues/1464.\n\tconst textNodes = Array.from( tableCell.getChildren() ).filter( child => child.is( '$text' ) );\n\n\t// @if CK_DEBUG_TABLE // textNodes.length && console.log( 'Post-fixing table: wrap cell content with paragraph.' );\n\n\tfor ( const child of textNodes ) {\n\t\twriter.wrap( writer.createRangeOn( child ), 'paragraph' );\n\t}\n\n\t// Return true when there were text nodes to fix.\n\treturn !!textNodes.length;\n}\n\n// Checks if a differ change should fix the table cell. This happens on:\n// - Removing content from the table cell (i.e. `tableCell` can be left empty).\n// - Adding a text node directly into a table cell.\n//\n// @param {Object} differ change entry\n// @returns {Boolean}\nfunction checkTableCellChange( entry ) {\n\tif ( !entry.position || !entry.position.parent.is( 'element', 'tableCell' ) ) {\n\t\treturn false;\n\t}\n\n\treturn entry.type == 'insert' && entry.name == '$text' || entry.type == 'remove';\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-cell-refresh-post-fixer\n */\n\nimport { isSingleParagraphWithoutAttributes } from './downcast';\n\n/**\n * Injects a table cell post-fixer into the model which marks the table cell in the differ to have it re-rendered.\n *\n * Model `paragraph` inside a table cell can be rendered as `<span>` or `<p>`. It is rendered as `<span>` if this is the only block\n * element in that table cell and it does not have any attributes. It is rendered as `<p>` otherwise.\n *\n * When table cell content changes, for example a second `paragraph` element is added, we need to ensure that the first `paragraph` is\n * re-rendered so it changes from `<span>` to `<p>`. The easiest way to do it is to re-render the entire table cell.\n *\n * @param {module:engine/model/model~Model} model\n * @param {module:engine/conversion/mapper~Mapper} mapper\n */\nexport default function injectTableCellRefreshPostFixer( model, mapper ) {\n\tmodel.document.registerPostFixer( () => tableCellRefreshPostFixer( model.document.differ, mapper ) );\n}\n\nfunction tableCellRefreshPostFixer( differ, mapper ) {\n\t// Stores cells to be refreshed, so the table cell will be refreshed once for multiple changes.\n\n\t// 1. Gather all changes inside table cell.\n\tconst cellsToCheck = new Set();\n\n\tfor ( const change of differ.getChanges() ) {\n\t\tconst parent = change.type == 'attribute' ? change.range.start.parent : change.position.parent;\n\n\t\tif ( parent.is( 'element', 'tableCell' ) ) {\n\t\t\tcellsToCheck.add( parent );\n\t\t}\n\t}\n\n\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: Checking table cell to refresh (${ cellsToCheck.size }).` );\n\t// @if CK_DEBUG_TABLE // let paragraphsRefreshed = 0;\n\n\tfor ( const tableCell of cellsToCheck.values() ) {\n\t\tfor ( const paragraph of [ ...tableCell.getChildren() ].filter( child => shouldRefresh( child, mapper ) ) ) {\n\t\t\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: refreshing paragraph in table cell (${++paragraphsRefreshed}).` );\n\t\t\tdiffer.refreshItem( paragraph );\n\t\t}\n\t}\n\n\t// Always return false to prevent the refresh post-fixer from re-running on the same set of changes and going into an infinite loop.\n\t// This \"post-fixer\" does not change the model structure so there shouldn't be need to run other post-fixers again.\n\t// See https://github.com/ckeditor/ckeditor5/issues/1936 & https://github.com/ckeditor/ckeditor5/issues/8200.\n\treturn false;\n}\n\n// Check if given model element needs refreshing.\n//\n// @param {module:engine/model/element~Element} modelElement\n// @param {module:engine/conversion/mapper~Mapper} mapper\n// @returns {Boolean}\nfunction shouldRefresh( child, mapper ) {\n\tif ( !child.is( 'element', 'paragraph' ) ) {\n\t\treturn false;\n\t}\n\n\tconst viewElement = mapper.toViewElement( child );\n\n\tif ( !viewElement ) {\n\t\treturn false;\n\t}\n\n\treturn isSingleParagraphWithoutAttributes( child ) !== viewElement.is( 'element', 'span' );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-heading-rows-refresh-post-fixer\n */\n\n/**\n * Injects a table post-fixer into the model which marks the table in the differ to have it re-rendered.\n *\n * Table heading rows are represented in the model by a `headingRows` attribute. However, in the view, it's represented as separate\n * sections of the table (`<thead>` or `<tbody>`) and changing `headingRows` attribute requires moving table rows between two sections.\n * This causes problems with structural changes in a table (like adding and removing rows) thus atomic converters cannot be used.\n *\n * When table `headingRows` attribute changes, the entire table is re-rendered.\n *\n * @param {module:engine/model/model~Model} model\n */\nexport default function injectTableHeadingRowsRefreshPostFixer( model ) {\n\tmodel.document.registerPostFixer( () => tableHeadingRowsRefreshPostFixer( model ) );\n}\n\nfunction tableHeadingRowsRefreshPostFixer( model ) {\n\tconst differ = model.document.differ;\n\n\t// Stores tables to be refreshed so the table will be refreshed once for multiple changes.\n\tconst tablesToRefresh = new Set();\n\n\tfor ( const change of differ.getChanges() ) {\n\t\tif ( change.type === 'attribute' ) {\n\t\t\tconst element = change.range.start.nodeAfter;\n\n\t\t\tif ( element && element.is( 'element', 'table' ) && change.attributeKey === 'headingRows' ) {\n\t\t\t\ttablesToRefresh.add( element );\n\t\t\t}\n\t\t} else {\n\t\t\t/* istanbul ignore else */\n\t\t\tif ( change.type === 'insert' || change.type === 'remove' ) {\n\t\t\t\tif ( change.name === 'tableRow' ) {\n\t\t\t\t\tconst table = change.position.findAncestor( 'table' );\n\t\t\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t\t\tif ( change.position.offset < headingRows ) {\n\t\t\t\t\t\ttablesToRefresh.add( table );\n\t\t\t\t\t}\n\t\t\t\t} else if ( change.name === 'tableCell' ) {\n\t\t\t\t\tconst table = change.position.findAncestor( 'table' );\n\t\t\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\n\t\t\t\t\tif ( change.position.offset < headingColumns ) {\n\t\t\t\t\t\ttablesToRefresh.add( table );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( tablesToRefresh.size ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: refreshing heading rows (${ tablesToRefresh.size }).` );\n\n\t\tfor ( const table of tablesToRefresh.values() ) {\n\t\t\t// Should be handled by a `triggerBy` configuration. See: https://github.com/ckeditor/ckeditor5/issues/8138.\n\t\t\tdiffer.refreshItem( table );\n\t\t}\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/table-layout-post-fixer\n */\n\nimport TableWalker from './../tablewalker';\nimport { createEmptyTableCell, updateNumericAttribute } from '../utils/common';\n\n/**\n * Injects a table layout post-fixer into the model.\n *\n * The role of the table layout post-fixer is to ensure that the table rows have the correct structure\n * after a {@link module:engine/model/model~Model#change `change()`} block was executed.\n *\n * The correct structure means that:\n *\n * * All table rows have the same size.\n * * None of the table cells extend vertically beyond their section (either header or body).\n * * A table cell has always at least one element as a child.\n *\n * If the table structure is not correct, the post-fixer will automatically correct it in two steps:\n *\n * 1. It will clip table cells that extend beyond their section.\n * 2. It will add empty table cells to the rows that are narrower than the widest table row.\n *\n * ## Clipping overlapping table cells\n *\n * Such situation may occur when pasting a table (or a part of a table) to the editor from external sources.\n *\n * For example, see the following table which has a cell (FOO) with the rowspan attribute (2):\n *\n *\t\t<table headingRows=\"1\">\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell rowspan=\"2\"><paragraph>FOO</paragraph></tableCell>\n *\t\t\t\t<tableCell colspan=\"2\"><paragraph>BAR</paragraph></tableCell>\n *\t\t\t</tableRow>\n *\t\t\t<tableRow>\n *\t\t\t\t<tableCell><paragraph>BAZ</paragraph></tableCell>\n *\t\t\t\t<tableCell><paragraph>XYZ</paragraph></tableCell>\n *\t\t\t</tableRow>\n *\t\t</table>\n *\n * It will be rendered in the view as:\n *\n *\t\t<table>\n *\t\t\t<thead>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td rowspan=\"2\">FOO</td>\n *\t\t\t\t\t<td colspan=\"2\">BAR</td>\n *\t\t\t\t</tr>\n *\t\t\t</thead>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>BAZ</td>\n *\t\t\t\t\t<td>XYZ</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * In the above example the table will be rendered as a table with two rows: one in the header and second one in the body.\n * The table cell (FOO) cannot span over multiple rows as it would extend from the header to the body section.\n * The `rowspan` attribute must be changed to (1). The value (1) is the default value of the `rowspan` attribute\n * so the `rowspan` attribute will be removed from the model.\n *\n * The table cell with BAZ in the content will be in the first column of the table.\n *\n * ## Adding missing table cells\n *\n * The table post-fixer will insert empty table cells to equalize table row sizes (the number of columns).\n * The size of a table row is calculated by counting column spans of table cells, both horizontal (from the same row) and\n * vertical (from the rows above).\n *\n * In the above example, the table row in the body section of the table is narrower then the row from the header: it has two cells\n * with the default colspan (1). The header row has one cell with colspan (1) and the second with colspan (2).\n * The table cell (FOO) does not extend beyond the head section (and as such will be fixed in the first step of this post-fixer).\n * The post-fixer will add a missing table cell to the row in the body section of the table.\n *\n * The table from the above example will be fixed and rendered to the view as below:\n *\n *\t\t<table>\n *\t\t\t<thead>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td rowspan=\"2\">FOO</td>\n *\t\t\t\t\t<td colspan=\"2\">BAR</td>\n *\t\t\t\t</tr>\n *\t\t\t</thead>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>BAZ</td>\n *\t\t\t\t\t<td>XYZ</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * ## Collaboration and undo - Expectations vs post-fixer results\n *\n * The table post-fixer only ensures proper structure without a deeper analysis of the nature of the change. As such, it might lead\n * to a structure which was not intended by the user. In particular, it will also fix undo steps (in conjunction with collaboration)\n * in which the editor content might not return to the original state.\n *\n * This will usually happen when one or more users change the size of the table.\n *\n * As an example see the table below:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * and the user actions:\n *\n * 1. Both users have a table with two rows and two columns.\n * 2. User A adds a column at the end of the table. This will insert empty table cells to two rows.\n * 3. User B adds a row at the end of the table. This will insert a row with two empty table cells.\n * 4. Both users will have a table as below:\n *\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * The last row is shorter then others so the table post-fixer will add an empty row to the last row:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t\t<td>(empty, inserted by A)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by the post-fixer)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * Unfortunately undo does not know the nature of the changes and depending on which user applies the post-fixer changes, undoing them\n * might lead to a broken table. If User B undoes inserting the column to the table, the undo engine will undo only the operations of\n * inserting empty cells to rows from the initial table state (row 1 and 2) but the cell in the post-fixed row will remain:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n *\n * After undo, the table post-fixer will detect that two rows are shorter than others and will fix the table to:\n *\n *\t\t<table>\n *\t\t\t<tbody>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>11</td>\n *\t\t\t\t\t<td>12</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer after undo)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>21</td>\n *\t\t\t\t\t<td>22</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer after undo)</td>\n *\t\t\t\t</tr>\n *\t\t\t\t<tr>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by B)</td>\n *\t\t\t\t\t<td>(empty, inserted by a post-fixer)</td>\n *\t\t\t\t</tr>\n *\t\t\t</tbody>\n *\t\t</table>\n * @param {module:engine/model/model~Model} model\n */\nexport default function injectTableLayoutPostFixer( model ) {\n\tmodel.document.registerPostFixer( writer => tableLayoutPostFixer( writer, model ) );\n}\n\n// The table layout post-fixer.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/model~Model} model\nfunction tableLayoutPostFixer( writer, model ) {\n\tconst changes = model.document.differ.getChanges();\n\n\tlet wasFixed = false;\n\n\t// Do not analyze the same table more then once - may happen for multiple changes in the same table.\n\tconst analyzedTables = new Set();\n\n\tfor ( const entry of changes ) {\n\t\tlet table;\n\n\t\tif ( entry.name == 'table' && entry.type == 'insert' ) {\n\t\t\ttable = entry.position.nodeAfter;\n\t\t}\n\n\t\t// Fix table on adding/removing table cells and rows.\n\t\tif ( entry.name == 'tableRow' || entry.name == 'tableCell' ) {\n\t\t\ttable = entry.position.findAncestor( 'table' );\n\t\t}\n\n\t\t// Fix table on any table's attribute change - including attributes of table cells.\n\t\tif ( isTableAttributeEntry( entry ) ) {\n\t\t\ttable = entry.range.start.findAncestor( 'table' );\n\t\t}\n\n\t\tif ( table && !analyzedTables.has( table ) ) {\n\t\t\t// Step 1: correct rowspans of table cells if necessary.\n\t\t\t// The wasFixed flag should be true if any of tables in batch was fixed - might be more then one.\n\t\t\twasFixed = fixTableCellsRowspan( table, writer ) || wasFixed;\n\t\t\t// Step 2: fix table rows sizes.\n\t\t\twasFixed = fixTableRowsSizes( table, writer ) || wasFixed;\n\n\t\t\tanalyzedTables.add( table );\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Fixes the invalid value of the `rowspan` attribute because a table cell cannot vertically extend beyond the table section it belongs to.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean} Returns `true` if the table was fixed.\nfunction fixTableCellsRowspan( table, writer ) {\n\tlet wasFixed = false;\n\n\tconst cellsToTrim = findCellsToTrim( table );\n\n\tif ( cellsToTrim.length ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: trimming cells row-spans (${ cellsToTrim.length }).` );\n\n\t\twasFixed = true;\n\n\t\tfor ( const data of cellsToTrim ) {\n\t\t\tupdateNumericAttribute( 'rowspan', data.rowspan, data.cell, writer, 1 );\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Makes all table rows in a table the same size.\n//\n// @param {module:engine/model/element~Element} table\n// @param {module:engine/model/writer~Writer} writer\n// @returns {Boolean} Returns `true` if the table was fixed.\nfunction fixTableRowsSizes( table, writer ) {\n\tlet wasFixed = false;\n\n\tconst childrenLengths = getChildrenLengths( table );\n\tconst rowsToRemove = [];\n\n\t// Find empty rows.\n\tfor ( const [ rowIndex, size ] of childrenLengths.entries() ) {\n\t\t// Ignore all non-row models.\n\t\tif ( !size && table.getChild( rowIndex ).is( 'element', 'tableRow' ) ) {\n\t\t\trowsToRemove.push( rowIndex );\n\t\t}\n\t}\n\n\t// Remove empty rows.\n\tif ( rowsToRemove.length ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( `Post-fixing table: remove empty rows (${ rowsToRemove.length }).` );\n\n\t\twasFixed = true;\n\n\t\tfor ( const rowIndex of rowsToRemove.reverse() ) {\n\t\t\twriter.remove( table.getChild( rowIndex ) );\n\t\t\tchildrenLengths.splice( rowIndex, 1 );\n\t\t}\n\t}\n\n\t// Filter out everything that's not a table row.\n\tconst rowsLengths = childrenLengths.filter( ( row, rowIndex ) => table.getChild( rowIndex ).is( 'element', 'tableRow' ) );\n\n\t// Verify if all the rows have the same number of columns.\n\tconst tableSize = rowsLengths[ 0 ];\n\tconst isValid = rowsLengths.every( length => length === tableSize );\n\n\tif ( !isValid ) {\n\t\t// @if CK_DEBUG_TABLE // console.log( 'Post-fixing table: adding missing cells.' );\n\n\t\t// Find the maximum number of columns.\n\t\tconst maxColumns = rowsLengths.reduce( ( prev, current ) => current > prev ? current : prev, 0 );\n\n\t\tfor ( const [ rowIndex, size ] of rowsLengths.entries() ) {\n\t\t\tconst columnsToInsert = maxColumns - size;\n\n\t\t\tif ( columnsToInsert ) {\n\t\t\t\tfor ( let i = 0; i < columnsToInsert; i++ ) {\n\t\t\t\t\tcreateEmptyTableCell( writer, writer.createPositionAt( table.getChild( rowIndex ), 'end' ) );\n\t\t\t\t}\n\n\t\t\t\twasFixed = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn wasFixed;\n}\n\n// Searches for table cells that extend beyond the table section to which they belong to. It will return an array of objects\n// that stores table cells to be trimmed and the correct value of the `rowspan` attribute to set.\n//\n// @param {module:engine/model/element~Element} table\n// @returns {Array.<{{cell, rowspan}}>}\nfunction findCellsToTrim( table ) {\n\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );\n\tconst maxRows = Array.from( table.getChildren() )\n\t\t.reduce( ( count, row ) => row.is( 'element', 'tableRow' ) ? count + 1 : count, 0 );\n\n\tconst cellsToTrim = [];\n\n\tfor ( const { row, cell, cellHeight } of new TableWalker( table ) ) {\n\t\t// Skip cells that do not expand over its row.\n\t\tif ( cellHeight < 2 ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst isInHeader = row < headingRows;\n\n\t\t// Row limit is either end of header section or whole table as table body is after the header.\n\t\tconst rowLimit = isInHeader ? headingRows : maxRows;\n\n\t\t// If table cell expands over its limit reduce it height to proper value.\n\t\tif ( row + cellHeight > rowLimit ) {\n\t\t\tconst newRowspan = rowLimit - row;\n\n\t\t\tcellsToTrim.push( { cell, rowspan: newRowspan } );\n\t\t}\n\t}\n\n\treturn cellsToTrim;\n}\n\n// Returns an array with lengths of rows assigned to the corresponding row index.\n//\n// @param {module:engine/model/element~Element} table\n// @returns {Array.<Number>}\nfunction getChildrenLengths( table ) {\n\t// TableWalker will not provide items for the empty rows, we need to pre-fill this array.\n\tconst lengths = new Array( table.childCount ).fill( 0 );\n\n\tfor ( const { rowIndex } of new TableWalker( table, { includeAllSlots: true } ) ) {\n\t\tlengths[ rowIndex ]++;\n\t}\n\n\treturn lengths;\n}\n\n// Checks if the differ entry for an attribute change is one of the table's attributes.\n//\n// @param entry\n// @returns {Boolean}\nfunction isTableAttributeEntry( entry ) {\n\tconst isAttributeType = entry.type === 'attribute';\n\tconst key = entry.attributeKey;\n\n\treturn isAttributeType && ( key === 'headingRows' || key === 'colspan' || key === 'rowspan' );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/tableproperites\n */\n\n/**\n * Conversion helper for upcasting attributes using normalized styles.\n *\n * @param {module:engine/conversion/conversion~Conversion} conversion\n * @param {Object} options\n * @param {String} options.modelAttribute The attribute to set.\n * @param {String} options.styleName The style name to convert.\n * @param {String} options.viewElement The view element name that should be converted.\n * @param {String} options.defaultValue The default value for the specified `modelAttribute`.\n * @param {Boolean} [options.reduceBoxSides=false]\n */\nexport function upcastStyleToAttribute( conversion, options ) {\n\tconst { viewElement, defaultValue, modelAttribute, styleName, reduceBoxSides = false } = options;\n\n\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\tview: {\n\t\t\tname: viewElement,\n\t\t\tstyles: {\n\t\t\t\t[ styleName ]: /[\\s\\S]+/\n\t\t\t}\n\t\t},\n\t\tmodel: {\n\t\t\tkey: modelAttribute,\n\t\t\tvalue: viewElement => {\n\t\t\t\tconst normalized = viewElement.getNormalizedStyle( styleName );\n\t\t\t\tconst value = reduceBoxSides ? reduceBoxSidesValue( normalized ) : normalized;\n\n\t\t\t\tif ( defaultValue !== value ) {\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n}\n\n/**\n * Conversion helper for upcasting border styles for view elements.\n *\n * @param {module:engine/conversion/conversion~Conversion} conversion\n * @param {String} viewElementName\n * @param {Object} modelAttributes\n * @param {Object} defaultBorder The default border values.\n * @param {String} defaultBorder.color The default `borderColor` value.\n * @param {String} defaultBorder.style The default `borderStyle` value.\n * @param {String} defaultBorder.width The default `borderWidth` value.\n */\nexport function upcastBorderStyles( conversion, viewElementName, modelAttributes, defaultBorder ) {\n\tconversion.for( 'upcast' ).add( dispatcher => dispatcher.on( 'element:' + viewElementName, ( evt, data, conversionApi ) => {\n\t\t// If the element was not converted by element-to-element converter,\n\t\t// we should not try to convert the style. See #8393.\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check the most detailed properties. These will be always set directly or\n\t\t// when using the \"group\" properties like: `border-(top|right|bottom|left)` or `border`.\n\t\tconst stylesToConsume = [\n\t\t\t'border-top-width',\n\t\t\t'border-top-color',\n\t\t\t'border-top-style',\n\t\t\t'border-bottom-width',\n\t\t\t'border-bottom-color',\n\t\t\t'border-bottom-style',\n\t\t\t'border-right-width',\n\t\t\t'border-right-color',\n\t\t\t'border-right-style',\n\t\t\t'border-left-width',\n\t\t\t'border-left-color',\n\t\t\t'border-left-style'\n\t\t].filter( styleName => data.viewItem.hasStyle( styleName ) );\n\n\t\tif ( !stylesToConsume.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst matcherPattern = {\n\t\t\tstyles: stylesToConsume\n\t\t};\n\n\t\t// Try to consume appropriate values from consumable values list.\n\t\tif ( !conversionApi.consumable.test( data.viewItem, matcherPattern ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelElement = [ ...data.modelRange.getItems( { shallow: true } ) ].pop();\n\n\t\tconversionApi.consumable.consume( data.viewItem, matcherPattern );\n\n\t\tconst normalizedBorder = {\n\t\t\tstyle: data.viewItem.getNormalizedStyle( 'border-style' ),\n\t\t\tcolor: data.viewItem.getNormalizedStyle( 'border-color' ),\n\t\t\twidth: data.viewItem.getNormalizedStyle( 'border-width' )\n\t\t};\n\n\t\tconst reducedBorder = {\n\t\t\tstyle: reduceBoxSidesValue( normalizedBorder.style ),\n\t\t\tcolor: reduceBoxSidesValue( normalizedBorder.color ),\n\t\t\twidth: reduceBoxSidesValue( normalizedBorder.width )\n\t\t};\n\n\t\tif ( reducedBorder.style !== defaultBorder.style ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttributes.style, reducedBorder.style, modelElement );\n\t\t}\n\n\t\tif ( reducedBorder.color !== defaultBorder.color ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttributes.color, reducedBorder.color, modelElement );\n\t\t}\n\n\t\tif ( reducedBorder.width !== defaultBorder.width ) {\n\t\t\tconversionApi.writer.setAttribute( modelAttributes.width, reducedBorder.width, modelElement );\n\t\t}\n\t} ) );\n}\n\n/**\n * Conversion helper for downcasting an attribute to a style.\n *\n * @param {module:engine/conversion/conversion~Conversion} conversion\n * @param {Object} options\n * @param {String} options.modelElement\n * @param {String} options.modelAttribute\n * @param {String} options.styleName\n */\nexport function downcastAttributeToStyle( conversion, { modelElement, modelAttribute, styleName } ) {\n\tconversion.for( 'downcast' ).attributeToAttribute( {\n\t\tmodel: {\n\t\t\tname: modelElement,\n\t\t\tkey: modelAttribute\n\t\t},\n\t\tview: modelAttributeValue => ( {\n\t\t\tkey: 'style',\n\t\t\tvalue: {\n\t\t\t\t[ styleName ]: modelAttributeValue\n\t\t\t}\n\t\t} )\n\t} );\n}\n\n/**\n * Conversion helper for downcasting attributes from the model table to a view table (not to `<figure>`).\n *\n * @param {module:engine/conversion/conversion~Conversion} conversion\n * @param {Object} options\n * @param {String} options.modelAttribute\n * @param {String} options.styleName\n */\nexport function downcastTableAttribute( conversion, { modelAttribute, styleName } ) {\n\tconversion.for( 'downcast' ).add( dispatcher => dispatcher.on( `attribute:${ modelAttribute }:table`, ( evt, data, conversionApi ) => {\n\t\tconst { item, attributeNewValue } = data;\n\t\tconst { mapper, writer } = conversionApi;\n\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst table = [ ...mapper.toViewElement( item ).getChildren() ].find( child => child.is( 'element', 'table' ) );\n\n\t\tif ( attributeNewValue ) {\n\t\t\twriter.setStyle( styleName, attributeNewValue, table );\n\t\t} else {\n\t\t\twriter.removeStyle( styleName, table );\n\t\t}\n\t} ) );\n}\n\n// Reduces the full top, right, bottom, left object to a single string if all sides are equal.\nfunction reduceBoxSidesValue( style ) {\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tconst commonValue = [ 'top', 'right', 'bottom', 'left' ]\n\t\t.map( side => style[ side ] )\n\t\t.reduce( ( result, side ) => result == side ? result : null );\n\n\treturn commonValue || style;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/converters/upcasttable\n */\n\nimport { createEmptyTableCell } from '../utils/common';\nimport { first } from 'ckeditor5/src/utils';\n\n/**\n * Returns a function that converts the table view representation:\n *\n *\t\t<figure class=\"table\"><table>...</table></figure>\n *\n * to the model representation:\n *\n *\t\t<table></table>\n *\n * @returns {Function}\n */\nexport function upcastTableFigure() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:figure', ( evt, data, conversionApi ) => {\n\t\t\t// Do not convert if this is not a \"table figure\".\n\t\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true, classes: 'table' } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Find an table element inside the figure element.\n\t\t\tconst viewTable = getViewTableFromFigure( data.viewItem );\n\n\t\t\t// Do not convert if table element is absent or was already converted.\n\t\t\tif ( !viewTable || !conversionApi.consumable.test( viewTable, { name: true } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Consume the figure to prevent other converters from processing it again.\n\t\t\tconversionApi.consumable.consume( data.viewItem, { name: true, classes: 'table' } );\n\n\t\t\t// Convert view table to model table.\n\t\t\tconst conversionResult = conversionApi.convertItem( viewTable, data.modelCursor );\n\n\t\t\t// Get table element from conversion result.\n\t\t\tconst modelTable = first( conversionResult.modelRange.getItems() );\n\n\t\t\t// When table wasn't successfully converted then finish conversion.\n\t\t\tif ( !modelTable ) {\n\t\t\t\t// Revert consumed figure so other features can convert it.\n\t\t\t\tconversionApi.consumable.revert( data.viewItem, { name: true, classes: 'table' } );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconversionApi.convertChildren( data.viewItem, conversionApi.writer.createPositionAt( modelTable, 'end' ) );\n\t\t\tconversionApi.updateConversionResult( modelTable, data );\n\t\t} );\n\t};\n}\n\n/**\n * View table element to model table element conversion helper.\n *\n * This conversion helper converts the table element as well as table rows.\n *\n * @returns {Function} Conversion helper.\n */\nexport default function upcastTable() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:table', ( evt, data, conversionApi ) => {\n\t\t\tconst viewTable = data.viewItem;\n\n\t\t\t// When element was already consumed then skip it.\n\t\t\tif ( !conversionApi.consumable.test( viewTable, { name: true } ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst { rows, headingRows, headingColumns } = scanTable( viewTable );\n\n\t\t\t// Only set attributes if values is greater then 0.\n\t\t\tconst attributes = {};\n\n\t\t\tif ( headingColumns ) {\n\t\t\t\tattributes.headingColumns = headingColumns;\n\t\t\t}\n\n\t\t\tif ( headingRows ) {\n\t\t\t\tattributes.headingRows = headingRows;\n\t\t\t}\n\n\t\t\tconst table = conversionApi.writer.createElement( 'table', attributes );\n\n\t\t\tif ( !conversionApi.safeInsert( table, data.modelCursor ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconversionApi.consumable.consume( viewTable, { name: true } );\n\n\t\t\t// Upcast table rows in proper order (heading rows first).\n\t\t\trows.forEach( row => conversionApi.convertItem( row, conversionApi.writer.createPositionAt( table, 'end' ) ) );\n\n\t\t\t// Convert everything else.\n\t\t\tconversionApi.convertChildren( viewTable, conversionApi.writer.createPositionAt( table, 'end' ) );\n\n\t\t\t// Create one row and one table cell for empty table.\n\t\t\tif ( table.isEmpty ) {\n\t\t\t\tconst row = conversionApi.writer.createElement( 'tableRow' );\n\t\t\t\tconversionApi.writer.insert( row, conversionApi.writer.createPositionAt( table, 'end' ) );\n\n\t\t\t\tcreateEmptyTableCell( conversionApi.writer, conversionApi.writer.createPositionAt( row, 'end' ) );\n\t\t\t}\n\n\t\t\tconversionApi.updateConversionResult( table, data );\n\t\t} );\n\t};\n}\n\n/**\n * A conversion helper that skips empty <tr> elements from upcasting at the beginning of the table.\n *\n * An empty row is considered a table model error but when handling clipboard data there could be rows that contain only row-spanned cells\n * and empty TR-s are used to maintain the table structure (also {@link module:table/tablewalker~TableWalker} assumes that there are only\n * rows that have related `tableRow` elements).\n *\n * *Note:* Only the first empty rows are removed because they have no meaning and it solves the issue\n * of an improper table with all empty rows.\n *\n * @returns {Function} Conversion helper.\n */\nexport function skipEmptyTableRow() {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:tr', ( evt, data ) => {\n\t\t\tif ( data.viewItem.isEmpty && data.modelCursor.index == 0 ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\t};\n}\n\n/**\n * A converter that ensures an empty paragraph is inserted in a table cell if no other content was converted.\n *\n * @returns {Function} Conversion helper.\n */\nexport function ensureParagraphInTableCell( elementName ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( `element:${ elementName }`, ( evt, data, conversionApi ) => {\n\t\t\t// The default converter will create a model range on converted table cell.\n\t\t\tif ( !data.modelRange ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Ensure a paragraph in the model for empty table cells for converted table cells.\n\t\t\tif ( data.viewItem.isEmpty ) {\n\t\t\t\tconst tableCell = data.modelRange.start.nodeAfter;\n\t\t\t\tconst modelCursor = conversionApi.writer.createPositionAt( tableCell, 0 );\n\n\t\t\t\tconversionApi.writer.insertElement( 'paragraph', modelCursor );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t};\n}\n\n// Get view `<table>` element from the view widget (`<figure>`).\n//\n// @private\n// @param {module:engine/view/element~Element} figureView\n// @returns {module:engine/view/element~Element}\nfunction getViewTableFromFigure( figureView ) {\n\tfor ( const figureChild of figureView.getChildren() ) {\n\t\tif ( figureChild.is( 'element', 'table' ) ) {\n\t\t\treturn figureChild;\n\t\t}\n\t}\n}\n\n// Scans table rows and extracts required metadata from the table:\n//\n// headingRows - The number of rows that go as table headers.\n// headingColumns - The maximum number of row headings.\n// rows - Sorted `<tr>` elements as they should go into the model - ie. if `<thead>` is inserted after `<tbody>` in the view.\n//\n// @private\n// @param {module:engine/view/element~Element} viewTable\n// @returns {{headingRows, headingColumns, rows}}\nfunction scanTable( viewTable ) {\n\tconst tableMeta = {\n\t\theadingRows: 0,\n\t\theadingColumns: 0\n\t};\n\n\t// The `<tbody>` and `<thead>` sections in the DOM do not have to be in order `<thead>` -> `<tbody>` and there might be more than one\n\t// of them.\n\t// As the model does not have these sections, rows from different sections must be sorted.\n\t// For example, below is a valid HTML table:\n\t//\n\t//\t\t<table>\n\t//\t\t\t<tbody><tr><td>2</td></tr></tbody>\n\t//\t\t\t<thead><tr><td>1</td></tr></thead>\n\t//\t\t\t<tbody><tr><td>3</td></tr></tbody>\n\t//\t\t</table>\n\t//\n\t// But browsers will render rows in order as: 1 as the heading and 2 and 3 as the body.\n\tconst headRows = [];\n\tconst bodyRows = [];\n\n\t// Currently the editor does not support more then one <thead> section.\n\t// Only the first <thead> from the view will be used as a heading row and the others will be converted to body rows.\n\tlet firstTheadElement;\n\n\tfor ( const tableChild of Array.from( viewTable.getChildren() ) ) {\n\t\t// Only `<thead>`, `<tbody>` & `<tfoot>` from allowed table children can have `<tr>`s.\n\t\t// The else is for future purposes (mainly `<caption>`).\n\t\tif ( tableChild.name === 'tbody' || tableChild.name === 'thead' || tableChild.name === 'tfoot' ) {\n\t\t\t// Save the first `<thead>` in the table as table header - all other ones will be converted to table body rows.\n\t\t\tif ( tableChild.name === 'thead' && !firstTheadElement ) {\n\t\t\t\tfirstTheadElement = tableChild;\n\t\t\t}\n\n\t\t\t// There might be some extra empty text nodes between the `<tr>`s.\n\t\t\t// Make sure further code operates on `tr`s only. (#145)\n\t\t\tconst trs = Array.from( tableChild.getChildren() ).filter( el => el.is( 'element', 'tr' ) );\n\n\t\t\tfor ( const tr of trs ) {\n\t\t\t\t// This <tr> is a child of a first <thead> element.\n\t\t\t\tif ( tr.parent.name === 'thead' && tr.parent === firstTheadElement ) {\n\t\t\t\t\ttableMeta.headingRows++;\n\t\t\t\t\theadRows.push( tr );\n\t\t\t\t} else {\n\t\t\t\t\tbodyRows.push( tr );\n\t\t\t\t\t// For other rows check how many column headings this row has.\n\n\t\t\t\t\tconst headingCols = scanRowForHeadingColumns( tr, tableMeta, firstTheadElement );\n\n\t\t\t\t\tif ( headingCols > tableMeta.headingColumns ) {\n\t\t\t\t\t\ttableMeta.headingColumns = headingCols;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\ttableMeta.rows = [ ...headRows, ...bodyRows ];\n\n\treturn tableMeta;\n}\n\n// Scans a `<tr>` element and its children for metadata:\n// - For heading row:\n// - Adds this row to either the heading or the body rows.\n// - Updates the number of heading rows.\n// - For body rows:\n// - Calculates the number of column headings.\n//\n// @private\n// @param {module:engine/view/element~Element} tr\n// @returns {Number}\nfunction scanRowForHeadingColumns( tr ) {\n\tlet headingColumns = 0;\n\tlet index = 0;\n\n\t// Filter out empty text nodes from tr children.\n\tconst children = Array.from( tr.getChildren() )\n\t\t.filter( child => child.name === 'th' || child.name === 'td' );\n\n\t// Count starting adjacent <th> elements of a <tr>.\n\twhile ( index < children.length && children[ index ].name === 'th' ) {\n\t\tconst th = children[ index ];\n\n\t\t// Adjust columns calculation by the number of spanned columns.\n\t\tconst colspan = parseInt( th.getAttribute( 'colspan' ) || 1 );\n\n\t\theadingColumns = headingColumns + colspan;\n\t\tindex++;\n\t}\n\n\treturn headingColumns;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/table\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Widget } from 'ckeditor5/src/widget';\n\nimport TableEditing from './tableediting';\nimport TableUI from './tableui';\nimport TableSelection from './tableselection';\nimport TableClipboard from './tableclipboard';\nimport TableKeyboard from './tablekeyboard';\nimport TableMouse from './tablemouse';\n\nimport '../theme/table.css';\n\n/**\n * The table plugin.\n *\n * For a detailed overview, check the {@glink features/table Table feature documentation}.\n *\n * This is a \"glue\" plugin that loads the following table features:\n *\n * * {@link module:table/tableediting~TableEditing editing feature},\n * * {@link module:table/tableselection~TableSelection selection feature},\n * * {@link module:table/tablekeyboard~TableKeyboard keyboard navigation feature},\n * * {@link module:table/tablemouse~TableMouse mouse selection feature},\n * * {@link module:table/tableclipboard~TableClipboard clipboard feature},\n * * {@link module:table/tableui~TableUI UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class Table extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableEditing, TableUI, TableSelection, TableMouse, TableKeyboard, TableClipboard, Widget ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'Table';\n\t}\n}\n\n/**\n * The configuration of the table feature. Used by the table feature in the `@ckeditor/ckeditor5-table` package.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n * \t\t\t\ttable: ... // Table feature options.\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * See {@link module:core/editor/editorconfig~EditorConfig all editor options}.\n *\n * @interface TableConfig\n */\n\n/**\n * The configuration of the {@link module:table/table~Table} feature.\n *\n * Read more in {@link module:table/table~TableConfig}.\n *\n * @member {module:table/table~TableConfig} module:core/editor/editorconfig~EditorConfig#table\n */\n\n/**\n * Number of rows and columns to render by default as table heading when inserting new tables.\n *\n * You can configure it like this:\n *\n *\t\tconst tableConfig = {\n *\t\t\tdefaultHeadings: {\n *\t\t\t\trows: 1,\n *\t\t\t\tcolumns: 1\n *\t\t\t}\n *\t\t};\n *\n * Both rows and columns properties are optional defaulting to 0 (no heading).\n *\n * @member {Object} module:table/table~TableConfig#defaultHeadings\n */\n\n/**\n * An array of color definitions (either strings or objects).\n *\n *\t\tconst colors = [\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 60%)',\n *\t\t\t\tlabel: 'Grey'\n *\t\t\t},\n *\t\t\t'hsl(0, 0%, 80%)',\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 90%)',\n *\t\t\t\tlabel: 'Light grey'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 100%)',\n *\t\t\t\tlabel: 'White',\n *\t\t\t\thasBorder: true\n *\t\t\t},\n *\t\t\t'#FF0000'\n *\t\t]\n *\n * Usually used as a configuration parameter, for instance in\n * {@link module:table/table~TableConfig#tableProperties `config.table.tableProperties`}\n * or {@link module:table/table~TableConfig#tableCellProperties `config.table.tableCellProperties`}.\n *\n * @typedef {Array.<String|Object>} module:table/table~TableColorConfig\n */\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecaption\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport TableCaptionEditing from './tablecaption/tablecaptionediting';\nimport TableCaptionUI from './tablecaption/tablecaptionui';\n\nimport '../theme/tablecaption.css';\n\n/**\n * The table caption plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableCaption extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableCaption';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableCaptionEditing, TableCaptionUI ];\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecaption/tablecaptionediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Element, enablePlaceholder } from 'ckeditor5/src/engine';\nimport { toWidgetEditable } from 'ckeditor5/src/widget';\n\nimport injectTableCaptionPostFixer from '../converters/table-caption-post-fixer';\nimport ToggleTableCaptionCommand from './toggletablecaptioncommand';\nimport { isTable, matchTableCaptionViewElement } from './utils';\n\n/**\n * The table caption editing plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableCaptionEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableCaptionEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * A map that keeps saved JSONified table captions and table model elements they are\n\t\t * associated with.\n\t\t *\n\t\t * To learn more about this system, see {@link #_saveCaption}.\n\t\t *\n\t\t * @member {WeakMap.<module:engine/model/element~Element,Object>}\n\t\t */\n\t\tthis._savedCaptionsMap = new WeakMap();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst view = editor.editing.view;\n\t\tconst t = editor.t;\n\n\t\tif ( !schema.isRegistered( 'caption' ) ) {\n\t\t\tschema.register( 'caption', {\n\t\t\t\tallowIn: 'table',\n\t\t\t\tallowContentOf: '$block',\n\t\t\t\tisLimit: true\n\t\t\t} );\n\t\t} else {\n\t\t\tschema.extend( 'caption', {\n\t\t\t\tallowIn: 'table'\n\t\t\t} );\n\t\t}\n\n\t\teditor.commands.add( 'toggleTableCaption', new ToggleTableCaptionCommand( this.editor ) );\n\n\t\t// View -> model converter for the data pipeline.\n\t\teditor.conversion.for( 'upcast' ).elementToElement( {\n\t\t\tview: matchTableCaptionViewElement,\n\t\t\tmodel: 'caption'\n\t\t} );\n\n\t\t// Model -> view converter for the data pipeline.\n\t\teditor.conversion.for( 'dataDowncast' ).elementToElement( {\n\t\t\tmodel: 'caption',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tif ( !isTable( modelElement.parent ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\treturn writer.createContainerElement( 'figcaption' );\n\t\t\t}\n\t\t} );\n\n\t\t// Model -> view converter for the editing pipeline.\n\t\teditor.conversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'caption',\n\t\t\tview: ( modelElement, { writer } ) => {\n\t\t\t\tif ( !isTable( modelElement.parent ) ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst figcaptionElement = writer.createEditableElement( 'figcaption' );\n\t\t\t\twriter.setCustomProperty( 'tableCaption', true, figcaptionElement );\n\n\t\t\t\tenablePlaceholder( {\n\t\t\t\t\tview,\n\t\t\t\t\telement: figcaptionElement,\n\t\t\t\t\ttext: t( 'Enter table caption' ),\n\t\t\t\t\tkeepOnFocus: true\n\t\t\t\t} );\n\n\t\t\t\treturn toWidgetEditable( figcaptionElement, writer );\n\t\t\t}\n\t\t} );\n\n\t\tinjectTableCaptionPostFixer( editor.model );\n\t}\n\n\t/**\n\t * Returns the saved {@link module:engine/model/element~Element#toJSON JSONified} caption\n\t * of a table model element.\n\t *\n\t * See {@link #_saveCaption}.\n\t *\n\t * @protected\n\t * @param {module:engine/model/element~Element} tableModelElement The model element the\n\t * caption should be returned for.\n\t * @returns {module:engine/model/element~Element|null} The model caption element or `null` if there is none.\n\t */\n\t_getSavedCaption( tableModelElement ) {\n\t\tconst jsonObject = this._savedCaptionsMap.get( tableModelElement );\n\n\t\treturn jsonObject ? Element.fromJSON( jsonObject ) : null;\n\t}\n\n\t/**\n\t * Saves a {@link module:engine/model/element~Element#toJSON JSONified} caption for\n\t * a table element to allow restoring it in the future.\n\t *\n\t * A caption is saved every time it gets hidden. The\n\t * user should be able to restore it on demand.\n\t *\n\t * **Note**: The caption cannot be stored in the table model element attribute because,\n\t * for instance, when the model state propagates to collaborators, the attribute would get\n\t * lost (mainly because it does not convert to anything when the caption is hidden) and\n\t * the states of collaborators' models would de-synchronize causing numerous issues.\n\t *\n\t * See {@link #_getSavedCaption}.\n\t *\n\t * @protected\n\t * @param {module:engine/model/element~Element} tableModelElement The model element the\n\t * caption is saved for.\n\t * @param {module:engine/model/element~Element} caption The caption model element to be saved.\n\t */\n\t_saveCaption( tableModelElement, caption ) {\n\t\tthis._savedCaptionsMap.set( tableModelElement, caption.toJSON() );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n* @module table/tablecaption/tablecaptionui\n*/\n\nimport { Plugin, icons } from 'ckeditor5/src/core';\nimport { ButtonView } from 'ckeditor5/src/ui';\n\nimport { getCaptionFromModelSelection } from './utils';\n\n/**\n * The table caption UI plugin. It introduces the `'toggleTableCaption'` UI button.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableCaptionUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableCaptionUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst editingView = editor.editing.view;\n\t\tconst t = editor.t;\n\n\t\teditor.ui.componentFactory.add( 'toggleTableCaption', locale => {\n\t\t\tconst command = editor.commands.get( 'toggleTableCaption' );\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\ticon: icons.caption,\n\t\t\t\ttooltip: true,\n\t\t\t\tisToggleable: true\n\t\t\t} );\n\n\t\t\tview.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\t\t\tview.bind( 'label' ).to( command, 'value', value => value ? t( 'Toggle caption off' ) : t( 'Toggle caption on' ) );\n\n\t\t\tthis.listenTo( view, 'execute', () => {\n\t\t\t\teditor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );\n\n\t\t\t\t// Scroll to the selection and highlight the caption if the caption showed up.\n\t\t\t\tif ( command.value ) {\n\t\t\t\t\tconst modelCaptionElement = getCaptionFromModelSelection( editor.model.document.selection );\n\t\t\t\t\tconst figcaptionElement = editor.editing.mapper.toViewElement( modelCaptionElement );\n\n\t\t\t\t\tif ( !figcaptionElement ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\teditingView.scrollToTheSelection();\n\t\t\t\t\teditingView.change( writer => {\n\t\t\t\t\t\twriter.addClass( 'table__caption_highlighted', figcaptionElement );\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n* @module table/tablecaption/toggletablecaptioncommand\n*/\n\nimport { Command } from 'ckeditor5/src/core';\n\nimport { getCaptionFromTableModelElement, getSelectionAffectedTable } from './utils';\n\n/**\n * The toggle table caption command.\n *\n * This command is registered by {@link module:table/tablecaption/tablecaptionediting~TableCaptionEditing} as the\n * `'toggleTableCaption'` editor command.\n *\n * Executing this command:\n *\n * * either adds or removes the table caption of a selected table (depending on whether the caption is present or not),\n * * removes the table caption if the selection is anchored in one.\n *\n *\t\t// Toggle the presence of the caption.\n *\t\teditor.execute( 'toggleTableCaption' );\n *\n * **Note**: You can move the selection to the caption right away as it shows up upon executing this command by using\n * the `focusCaptionOnShow` option:\n *\n *\t\teditor.execute( 'toggleTableCaption', { focusCaptionOnShow: true } );\n *\n * @extends module:core/command~Command\n */\nexport default class ToggleTableCaptionCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst editor = this.editor;\n\t\tconst tableElement = getSelectionAffectedTable( editor.model.document.selection );\n\n\t\tthis.isEnabled = !!tableElement;\n\n\t\tif ( !this.isEnabled ) {\n\t\t\tthis.value = false;\n\t\t} else {\n\t\t\tthis.value = !!getCaptionFromTableModelElement( tableElement );\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t *\t\teditor.execute( 'toggleTableCaption' );\n\t *\n\t * @param {Object} [options] Options for the executed command.\n\t * @param {String} [options.focusCaptionOnShow] When true and the caption shows up, the selection will be moved into it straight away.\n\t * @fires execute\n\t */\n\texecute( options = {} ) {\n\t\tconst { focusCaptionOnShow } = options;\n\n\t\tthis.editor.model.change( writer => {\n\t\t\tif ( this.value ) {\n\t\t\t\tthis._hideTableCaption( writer );\n\t\t\t} else {\n\t\t\t\tthis._showTableCaption( writer, focusCaptionOnShow );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Shows the table caption. Also:\n\t *\n\t * * it attempts to restore the caption content from the `TableCaptionEditing` caption registry,\n\t * * it moves the selection to the caption right away, it the `focusCaptionOnShow` option was set.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @param {Boolean} focusCaptionOnShow Default focus behavior when showing the caption.\n\t */\n\t_showTableCaption( writer, focusCaptionOnShow ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableElement = getSelectionAffectedTable( model.document.selection );\n\t\tconst tableCaptionEditing = this.editor.plugins.get( 'TableCaptionEditing' );\n\t\tconst savedCaptionElement = tableCaptionEditing._getSavedCaption( tableElement );\n\n\t\t// Try restoring the caption from the TableCaptionEditing plugin storage.\n\t\tconst newCaptionElement = savedCaptionElement || writer.createElement( 'caption' );\n\n\t\twriter.append( newCaptionElement, tableElement );\n\n\t\tif ( focusCaptionOnShow ) {\n\t\t\twriter.setSelection( newCaptionElement, 'in' );\n\t\t}\n\t}\n\n\t/**\n\t * Hides the caption of a selected table (or an table caption the selection is anchored to).\n\t *\n\t * The content of the caption is stored in the `TableCaptionEditing` caption registry to make this\n\t * a reversible action.\n\t *\n\t * @private\n\t * @param {module:engine/model/writer~Writer} writer\n\t */\n\t_hideTableCaption( writer ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableElement = getSelectionAffectedTable( model.document.selection );\n\t\tconst tableCaptionEditing = this.editor.plugins.get( 'TableCaptionEditing' );\n\t\tconst captionElement = getCaptionFromTableModelElement( tableElement );\n\n\t\t// Store the caption content so it can be restored quickly if the user changes their mind.\n\t\ttableCaptionEditing._saveCaption( tableElement, captionElement );\n\n\t\twriter.setSelection( writer.createRangeIn( tableElement.getChild( 0 ).getChild( 0 ) ) );\n\t\twriter.remove( captionElement );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecaption/utils\n */\n\n/**\n * Checks if the provided model element is a `table`.\n *\n * @param {module:engine/model/element~Element} modelElement Element to check if it is a table.\n * @returns {Boolean}\n */\nexport function isTable( modelElement ) {\n\treturn !!modelElement && modelElement.is( 'element', 'table' );\n}\n\n/**\n * Returns the caption model element from a given table element. Returns `null` if no caption is found.\n *\n * @param {module:engine/model/element~Element} tableModelElement Table element in which we will try to find a caption element.\n * @returns {module:engine/model/element~Element|null}\n */\nexport function getCaptionFromTableModelElement( tableModelElement ) {\n\tfor ( const node of tableModelElement.getChildren() ) {\n\t\tif ( node.is( 'element', 'caption' ) ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns the caption model element for a model selection. Returns `null` if the selection has no caption element ancestor.\n *\n * @param {module:engine/model/selection~Selection|module:engine/model/documentselection~DocumentSelection} selection\n * The selection checked for caption presence.\n * @returns {module:engine/model/element~Element|null}\n */\nexport function getCaptionFromModelSelection( selection ) {\n\tconst tableElement = getSelectionAffectedTable( selection );\n\n\tif ( !tableElement ) {\n\t\treturn null;\n\t}\n\n\treturn getCaptionFromTableModelElement( tableElement );\n}\n\n/**\n * {@link module:engine/view/matcher~Matcher} pattern. Checks if a given element is a caption.\n *\n * There are two possible forms of the valid caption:\n * - A `<figcaption>` element inside a `<figure class=\"table\">` element.\n * - A `<caption>` inside a <table>.\n *\n * @param {module:engine/view/element~Element} element\n * @returns {Object|null} Returns the object accepted by {@link module:engine/view/matcher~Matcher} or `null` if the element\n * cannot be matched.\n */\nexport function matchTableCaptionViewElement( element ) {\n\tconst parent = element.parent;\n\n\tif ( element.name == 'figcaption' && parent && parent.name == 'figure' && parent.hasClass( 'table' ) ) {\n\t\treturn { name: true };\n\t}\n\n\tif ( element.name == 'caption' && parent && parent.name == 'table' ) {\n\t\treturn { name: true };\n\t}\n\n\treturn null;\n}\n\n/**\n * Depending on the position of the selection we either return the table under cursor or look for the table higher in the hierarchy.\n *\n * @param {module:engine/model/position~Position} position\n * @returns {module:engine/model/element~Element}\n */\nexport function getSelectionAffectedTable( selection ) {\n\tconst selectedElement = selection.getSelectedElement();\n\n\t// Is the command triggered from the `tableToolbar`?\n\tif ( selectedElement && selectedElement.is( 'element', 'table' ) ) {\n\t\treturn selectedElement;\n\t}\n\n\treturn selection.getFirstPosition().findAncestor( 'table' );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport TableCellPropertiesUI from './tablecellproperties/tablecellpropertiesui';\nimport TableCellPropertiesEditing from './tablecellproperties/tablecellpropertiesediting';\n\n/**\n * The table cell properties feature. Enables support for setting properties of table cells (size, border, background, etc.).\n *\n * Read more in the {@glink features/table#table-and-cell-styling-tools Table and cell styling tools} section.\n * See also the {@link module:table/tableproperties~TableProperties} plugin.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing table cell properties editing feature} and\n * the {@link module:table/tablecellproperties/tablecellpropertiesui~TableCellPropertiesUI table cell properties UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableCellProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableCellProperties';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableCellPropertiesEditing, TableCellPropertiesUI ];\n\t}\n}\n\n/**\n * The configuration of the table cell properties user interface (balloon). It allows to define:\n *\n * * The color palette for the cell border color style field (`tableCellProperties.borderColors`),\n * * The color palette for the cell background style field (`tableCellProperties.backgroundColors`).\n *\n *\t\tconst tableConfig = {\n *\t\t\ttableCellProperties: {\n *\t\t\t\tborderColors: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tcolor: 'hsl(0, 0%, 90%)',\n *\t\t\t\t\t\tlabel: 'Light grey'\n *\t\t\t\t\t},\n *\t\t\t\t\t// ...\n *\t\t\t\t],\n *\t\t\t\tbackgroundColors: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tcolor: 'hsl(120, 75%, 60%)',\n *\t\t\t\t\t\tlabel: 'Green'\n *\t\t\t\t\t},\n *\t\t\t\t\t// ...\n *\t\t\t\t]\n *\t\t\t}\n *\t\t};\n *\n * * The default styles for table cells (`tableCellProperties.defaultProperties`):\n *\n *\t\tconst tableConfig = {\n *\t\t\ttableCellProperties: {\n *\t\t\t\tdefaultProperties: {\n *\t\t\t\t\thorizontalAlignment: 'right',\n *\t\t\t\t\tverticalAlignment: 'bottom',\n *\t\t\t\t\tpadding: '5px'\n *\t\t\t\t}\n *\t\t\t}\n *\t\t}\n *\n * \t {@link module:table/tableproperties~TablePropertiesOptions Read more about the supported properties.}\n *\n * **Note**: The `borderColors` and `backgroundColors` options do not impact the data loaded into the editor,\n * i.e. they do not limit or filter the colors in the data. They are used only in the user interface\n * allowing users to pick colors in a more convenient way. The `defaultProperties` option does impact the data.\n * Default values will not be kept in the editor model.\n *\n * The default color palettes for the cell background and the cell border are the same\n * ({@link module:table/utils/ui/table-properties~defaultColors check out their content}).\n *\n * Both color palette configurations must follow the\n * {@link module:table/table~TableColorConfig table color configuration format}.\n *\n * Read more about configuring the table feature in {@link module:table/table~TableConfig}.\n *\n * @member {Object} module:table/table~TableConfig#tableCellProperties\n */\n\n/**\n * The configuration of the table cell default properties feature.\n *\n * @typedef {Object} module:table/tablecellproperties~TableCellPropertiesOptions\n *\n * @property {String} width The default `width` of the table cell.\n *\n * @property {String} height The default `height` of the table cell.\n *\n * @property {String} padding The default `padding` of the table cell.\n *\n * @property {String} backgroundColor The default `background-color` of the table cell.\n *\n * @property {String} borderColor The default `border-color` of the table cell.\n *\n * @property {String} borderWidth The default `border-width` of the table cell.\n *\n * @property {String} [borderStyle='none'] The default `border-style` of the table cell.\n *\n * @property {String} [horizontalAlignment='center'] The default `horizontalAlignment` of the table cell.\n *\n * @property {String} [verticalAlignment='middle'] The default `verticalAlignment` of the table cell.\n */\n\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellbackgroundcolorcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\n\n/**\n * The table cell background color command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBackgroundColor'` editor command.\n *\n * To change the background color of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellBackgroundColor', {\n *\t\t\tvalue: '#f00'\n *\t\t} );\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellBackgroundColorCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBackgroundColorCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellBackgroundColor', defaultValue );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellbordercolorcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\nimport { getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table cell border color command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderColor'` editor command.\n *\n * To change the border color of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellBorderColor', {\n *\t\t\tvalue: '#f00'\n *\t\t} );\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellBorderColorCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBorderColorCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellBorderColor', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getAttribute( tableCell ) {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellborderstylecommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\nimport { getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table cell border style command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderStyle'` editor command.\n *\n * To change the border style of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellBorderStyle', {\n *\t\t\tvalue: 'dashed'\n *\t\t} );\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellBorderStyleCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBorderStyleCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellBorderStyle', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getAttribute( tableCell ) {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellborderwidthcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\nimport { addDefaultUnitToNumericValue, getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table cell border width command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellBorderWidth'` editor command.\n *\n * To change the border width of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellBorderWidth', {\n *\t\t\tvalue: '5px'\n *\t\t} );\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableCellBorderWidth', {\n *\t\t\tvalue: '5'\n *\t\t} );\n *\n * will set the `borderWidth` attribute to `'5px'` in the model.\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellBorderWidthCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellBorderWidthCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellBorderWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getAttribute( tableCell ) {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellheightcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties';\n\n/**\n * The table cell height command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellHeight'` editor command.\n *\n * To change the height of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellHeight', {\n *\t\t\tvalue: '50px'\n *\t\t} );\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableCellHeight', {\n *\t\t\tvalue: '50'\n *\t\t} );\n *\n * will set the `height` attribute to `'50px'` in the model.\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellHeightCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellHeightCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellHeight', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellhorizontalalignmentcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\n\n/**\n * The table cell horizontal alignment command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellHorizontalAlignment'` editor command.\n *\n * To change the horizontal text alignment of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellHorizontalAlignment', {\n *\t\t\tvalue: 'right'\n *\t\t} );\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellHorizontalAlignmentCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellHorizontalAlignmentCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value for the \"alignment\" attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellHorizontalAlignment', defaultValue );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellpaddingcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\nimport { addDefaultUnitToNumericValue, getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table cell padding command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellPadding'` editor command.\n *\n * To change the padding of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellPadding', {\n *\t\t\tvalue: '5px'\n *\t\t} );\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableCellPadding', {\n *\t\t\tvalue: '5'\n *\t\t} );\n *\n * will set the `padding` attribute to `'5px'` in the model.\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellPaddingCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellPaddingCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellPadding', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getAttribute( tableCell ) {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( tableCell.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellpropertycommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getSelectionAffectedTableCells } from '../../utils/selection';\n\n/**\n * The table cell attribute command.\n *\n * The command is a base command for other table cell property commands.\n *\n * @extends module:core/command~Command\n */\nexport default class TableCellPropertyCommand extends Command {\n\t/**\n\t * Creates a new `TableCellPropertyCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} attributeName Table cell attribute name.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, attributeName, defaultValue ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The attribute that will be set by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.attributeName = attributeName;\n\n\t\t/**\n\t\t * The default value for the attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {String}\n\t\t */\n\t\tthis._defaultValue = defaultValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst editor = this.editor;\n\t\tconst selectedTableCells = getSelectionAffectedTableCells( editor.model.document.selection );\n\n\t\tthis.isEnabled = !!selectedTableCells.length;\n\t\tthis.value = this._getSingleValue( selectedTableCells );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {*} [options.value] If set, the command will set the attribute on selected table cells.\n\t * If it is not set, the command will remove the attribute from the selected table cells.\n\t * @param {module:engine/model/batch~Batch} [options.batch] Pass the model batch instance to the command to aggregate changes,\n\t * for example to allow a single undo step for multiple executions.\n\t */\n\texecute( options = {} ) {\n\t\tconst { value, batch } = options;\n\t\tconst model = this.editor.model;\n\t\tconst tableCells = getSelectionAffectedTableCells( model.document.selection );\n\t\tconst valueToSet = this._getValueToSet( value );\n\n\t\tmodel.enqueueChange( batch, writer => {\n\t\t\tif ( valueToSet ) {\n\t\t\t\ttableCells.forEach( tableCell => writer.setAttribute( this.attributeName, valueToSet, tableCell ) );\n\t\t\t} else {\n\t\t\t\ttableCells.forEach( tableCell => writer.removeAttribute( this.attributeName, tableCell ) );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the attribute value for a table cell.\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @returns {String|undefined}\n\t * @private\n\t */\n\t_getAttribute( tableCell ) {\n\t\tif ( !tableCell ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = tableCell.getAttribute( this.attributeName );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Returns the proper model value. It can be used to add a default unit to numeric values.\n\t *\n\t * @private\n\t * @param {*} value\n\t * @returns {*}\n\t */\n\t_getValueToSet( value ) {\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Returns a single value for all selected table cells. If the value is the same for all cells,\n\t * it will be returned (`undefined` otherwise).\n\t *\n\t * @param {Array.<module:engine/model/element~Element>} tableCell\n\t * @returns {*}\n\t * @private\n\t */\n\t_getSingleValue( tableCell ) {\n\t\tconst firstCellValue = this._getAttribute( tableCell[ 0 ] );\n\n\t\tconst everyCellHasAttribute = tableCell.every( tableCell => this._getAttribute( tableCell ) === firstCellValue );\n\n\t\treturn everyCellHasAttribute ? firstCellValue : undefined;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellverticalalignmentcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\n\n/**\n * The table cell vertical alignment command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellVerticalAlignment'` editor command.\n *\n * To change the vertical text alignment of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellVerticalAlignment', {\n *\t\t\tvalue: 'top'\n *\t\t} );\n *\n * The following values, corresponding to the\n * [`vertical-align` CSS attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align), are allowed:\n *\n * * `'top'`\n * * `'bottom'`\n *\n * The `'middle'` value is the default one so there is no need to set it.\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellVerticalAlignmentCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellVerticalAlignmentCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value for the \"alignment\" attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellVerticalAlignment', defaultValue );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/commands/tablecellwidthcommand\n */\n\nimport TableCellPropertyCommand from './tablecellpropertycommand';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties';\n\n/**\n * The table cell width command.\n *\n * The command is registered by the {@link module:table/tablecellproperties/tablecellpropertiesediting~TableCellPropertiesEditing} as\n * the `'tableCellWidth'` editor command.\n *\n * To change the width of selected cells, execute the command:\n *\n *\t\teditor.execute( 'tableCellWidth', {\n *\t\t\tvalue: '50px'\n *\t\t} );\n *\n * **Note**: This command adds a default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableCellWidth', {\n *\t\t\tvalue: '50'\n *\t\t} );\n *\n * will set the `width` attribute to `'50px'` in the model.\n *\n * @extends module:table/tablecellproperties/commands/tablecellpropertycommand~TableCellPropertyCommand\n */\nexport default class TableCellWidthCommand extends TableCellPropertyCommand {\n\t/**\n\t * Creates a new `TableCellWidthCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableCellWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/tablecellpropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { addBorderRules, addPaddingRules, addBackgroundRules } from 'ckeditor5/src/engine';\n\nimport { downcastAttributeToStyle, upcastStyleToAttribute, upcastBorderStyles } from './../converters/tableproperties';\nimport TableEditing from './../tableediting';\nimport TableCellPaddingCommand from './commands/tablecellpaddingcommand';\nimport TableCellWidthCommand from './commands/tablecellwidthcommand';\nimport TableCellHeightCommand from './commands/tablecellheightcommand';\nimport TableCellBackgroundColorCommand from './commands/tablecellbackgroundcolorcommand';\nimport TableCellVerticalAlignmentCommand from './commands/tablecellverticalalignmentcommand';\nimport TableCellHorizontalAlignmentCommand from './commands/tablecellhorizontalalignmentcommand';\nimport TableCellBorderStyleCommand from './commands/tablecellborderstylecommand';\nimport TableCellBorderColorCommand from './commands/tablecellbordercolorcommand';\nimport TableCellBorderWidthCommand from './commands/tablecellborderwidthcommand';\nimport { getNormalizedDefaultProperties } from '../utils/table-properties';\n\nconst VALIGN_VALUES_REG_EXP = /^(top|middle|bottom)$/;\nconst ALIGN_VALUES_REG_EXP = /^(left|center|right|justify)$/;\n\n/**\n * The table cell properties editing feature.\n *\n * Introduces table cell model attributes and their conversion:\n *\n * - border: `tableCellBorderStyle`, `tableCellBorderColor` and `tableCellBorderWidth`\n * - background color: `tableCellBackgroundColor`\n * - cell padding: `tableCellPadding`\n * - horizontal and vertical alignment: `tableCellHorizontalAlignment`, `tableCellVerticalAlignment`\n * - cell width and height: `tableCellWidth`, `tableCellHeight`\n *\n * It also registers commands used to manipulate the above attributes:\n *\n * - border: the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` commands\n * - background color: the `'tableCellBackgroundColor'` command\n * - cell padding: the `'tableCellPadding'` command\n * - horizontal and vertical alignment: the `'tableCellHorizontalAlignment'` and `'tableCellVerticalAlignment'` commands\n * - width and height: the `'tableCellWidth'` and `'tableCellHeight'` commands\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableCellPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableCellPropertiesEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\n\t\teditor.config.define( 'table.tableCellProperties.defaultProperties', {} );\n\n\t\tconst defaultTableCellProperties = getNormalizedDefaultProperties(\n\t\t\teditor.config.get( 'table.tableCellProperties.defaultProperties' ),\n\t\t\t{\n\t\t\t\tincludeVerticalAlignmentProperty: true,\n\t\t\t\tincludeHorizontalAlignmentProperty: true,\n\t\t\t\tincludePaddingProperty: true,\n\t\t\t\tisRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'\n\t\t\t}\n\t\t);\n\n\t\teditor.data.addStyleProcessorRules( addBorderRules );\n\t\tenableBorderProperties( schema, conversion, {\n\t\t\tcolor: defaultTableCellProperties.borderColor,\n\t\t\tstyle: defaultTableCellProperties.borderStyle,\n\t\t\twidth: defaultTableCellProperties.borderWidth\n\t\t} );\n\t\teditor.commands.add( 'tableCellBorderStyle', new TableCellBorderStyleCommand( editor, defaultTableCellProperties.borderStyle ) );\n\t\teditor.commands.add( 'tableCellBorderColor', new TableCellBorderColorCommand( editor, defaultTableCellProperties.borderColor ) );\n\t\teditor.commands.add( 'tableCellBorderWidth', new TableCellBorderWidthCommand( editor, defaultTableCellProperties.borderWidth ) );\n\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellWidth',\n\t\t\tstyleName: 'width',\n\t\t\tdefaultValue: defaultTableCellProperties.width\n\t\t} );\n\t\teditor.commands.add( 'tableCellWidth', new TableCellWidthCommand( editor, defaultTableCellProperties.width ) );\n\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellHeight',\n\t\t\tstyleName: 'height',\n\t\t\tdefaultValue: defaultTableCellProperties.height\n\t\t} );\n\t\teditor.commands.add( 'tableCellHeight', new TableCellHeightCommand( editor, defaultTableCellProperties.height ) );\n\n\t\teditor.data.addStyleProcessorRules( addPaddingRules );\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellPadding',\n\t\t\tstyleName: 'padding',\n\t\t\treduceBoxSides: true,\n\t\t\tdefaultValue: defaultTableCellProperties.padding\n\t\t} );\n\t\teditor.commands.add( 'tableCellPadding', new TableCellPaddingCommand( editor, defaultTableCellProperties.padding ) );\n\n\t\teditor.data.addStyleProcessorRules( addBackgroundRules );\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableCellBackgroundColor',\n\t\t\tstyleName: 'background-color',\n\t\t\tdefaultValue: defaultTableCellProperties.backgroundColor\n\t\t} );\n\t\teditor.commands.add(\n\t\t\t'tableCellBackgroundColor',\n\t\t\tnew TableCellBackgroundColorCommand( editor, defaultTableCellProperties.backgroundColor )\n\t\t);\n\n\t\tenableHorizontalAlignmentProperty( schema, conversion, defaultTableCellProperties.horizontalAlignment );\n\t\teditor.commands.add(\n\t\t\t'tableCellHorizontalAlignment',\n\t\t\tnew TableCellHorizontalAlignmentCommand( editor, defaultTableCellProperties.horizontalAlignment )\n\t\t);\n\n\t\tenableVerticalAlignmentProperty( schema, conversion, defaultTableCellProperties.verticalAlignment );\n\t\teditor.commands.add(\n\t\t\t'tableCellVerticalAlignment',\n\t\t\tnew TableCellVerticalAlignmentCommand( editor, defaultTableCellProperties.verticalAlignment )\n\t\t);\n\t}\n}\n\n// Enables the `'tableCellBorderStyle'`, `'tableCellBorderColor'` and `'tableCellBorderWidth'` attributes for table cells.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {Object} defaultBorder The default border values.\n// @param {String} defaultBorder.color The default `tableCellBorderColor` value.\n// @param {String} defaultBorder.style The default `tableCellBorderStyle` value.\n// @param {String} defaultBorder.width The default `tableCellBorderWidth` value.\nfunction enableBorderProperties( schema, conversion, defaultBorder ) {\n\tconst modelAttributes = {\n\t\twidth: 'tableCellBorderWidth',\n\t\tcolor: 'tableCellBorderColor',\n\t\tstyle: 'tableCellBorderStyle'\n\t};\n\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: Object.values( modelAttributes )\n\t} );\n\n\tupcastBorderStyles( conversion, 'td', modelAttributes, defaultBorder );\n\tupcastBorderStyles( conversion, 'th', modelAttributes, defaultBorder );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.style, styleName: 'border-style' } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.color, styleName: 'border-color' } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', modelAttribute: modelAttributes.width, styleName: 'border-width' } );\n}\n\n// Enables the `'tableCellHorizontalAlignment'` attribute for table cells.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n// @param {String} defaultValue The default horizontal alignment value.\nfunction enableHorizontalAlignmentProperty( schema, conversion, defaultValue ) {\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: [ 'tableCellHorizontalAlignment' ]\n\t} );\n\n\tconversion.for( 'downcast' )\n\t\t.attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'tableCell',\n\t\t\t\tkey: 'tableCellHorizontalAlignment'\n\t\t\t},\n\t\t\tview: alignment => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t'text-align': alignment\n\t\t\t\t}\n\t\t\t} )\n\t\t} );\n\n\tconversion.for( 'upcast' )\n\t\t// Support for the `text-align:*;` CSS definition for the table cell alignment.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tstyles: {\n\t\t\t\t\t'text-align': ALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellHorizontalAlignment',\n\t\t\t\tvalue: viewElement => {\n\t\t\t\t\tconst align = viewElement.getStyle( 'text-align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t\t// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tattributes: {\n\t\t\t\t\talign: ALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellHorizontalAlignment',\n\t\t\t\tvalue: viewElement => {\n\t\t\t\t\tconst align = viewElement.getAttribute( 'align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n}\n\n// Enables the `'verticalAlignment'` attribute for table cells.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {String} defaultValue The default vertical alignment value.\nfunction enableVerticalAlignmentProperty( schema, conversion, defaultValue ) {\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: [ 'tableCellVerticalAlignment' ]\n\t} );\n\n\tconversion.for( 'downcast' )\n\t\t.attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'tableCell',\n\t\t\t\tkey: 'tableCellVerticalAlignment'\n\t\t\t},\n\t\t\tview: alignment => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t'vertical-align': alignment\n\t\t\t\t}\n\t\t\t} )\n\t\t} );\n\n\tconversion.for( 'upcast' )\n\t\t// Support for the `vertical-align:*;` CSS definition for the table cell alignment.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tstyles: {\n\t\t\t\t\t'vertical-align': VALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellVerticalAlignment',\n\t\t\t\tvalue: viewElement => {\n\t\t\t\t\tconst align = viewElement.getStyle( 'vertical-align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t\t// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(td|th)$/,\n\t\t\t\tattributes: {\n\t\t\t\t\tvalign: VALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableCellVerticalAlignment',\n\t\t\t\tvalue: viewElement => {\n\t\t\t\t\tconst valign = viewElement.getAttribute( 'valign' );\n\n\t\t\t\t\treturn valign === defaultValue ? null : valign;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n}\n\n// Enables conversion for an attribute for simple view-model mappings.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {Object} options\n// @param {String} options.modelAttribute\n// @param {String} options.styleName\n// @param {String} options.defaultValue The default value for the specified `modelAttribute`.\n// @param {Boolean} [options.reduceBoxSides=false]\nfunction enableProperty( schema, conversion, options ) {\n\tconst { modelAttribute } = options;\n\n\tschema.extend( 'tableCell', {\n\t\tallowAttributes: [ modelAttribute ]\n\t} );\n\n\tupcastStyleToAttribute( conversion, { viewElement: /^(td|th)$/, ...options } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'tableCell', ...options } );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/tablecellpropertiesui\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { ButtonView, clickOutsideHandler, ContextualBalloon, getLocalizedColorOptions, normalizeColorOptions } from 'ckeditor5/src/ui';\n\nimport TableCellPropertiesView from './ui/tablecellpropertiesview';\nimport {\n\tcolorFieldValidator,\n\tgetLocalizedColorErrorText,\n\tgetLocalizedLengthErrorText,\n\tdefaultColors,\n\tlengthFieldValidator,\n\tlineWidthFieldValidator\n} from '../utils/ui/table-properties';\nimport { debounce } from 'lodash-es';\nimport { getTableWidgetAncestor } from '../utils/ui/widget';\nimport { getBalloonCellPositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon';\n\nimport tableCellProperties from './../../theme/icons/table-cell-properties.svg';\nimport { getNormalizedDefaultProperties } from '../utils/table-properties';\n\nconst ERROR_TEXT_TIMEOUT = 500;\n\n// Map of view properties and related commands.\nconst propertyToCommandMap = {\n\tborderStyle: 'tableCellBorderStyle',\n\tborderColor: 'tableCellBorderColor',\n\tborderWidth: 'tableCellBorderWidth',\n\twidth: 'tableCellWidth',\n\theight: 'tableCellHeight',\n\tpadding: 'tableCellPadding',\n\tbackgroundColor: 'tableCellBackgroundColor',\n\thorizontalAlignment: 'tableCellHorizontalAlignment',\n\tverticalAlignment: 'tableCellVerticalAlignment'\n};\n\n/**\n * The table cell properties UI plugin. It introduces the `'tableCellProperties'` button\n * that opens a form allowing to specify the visual styling of a table cell.\n *\n * It uses the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableCellPropertiesUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableCellPropertiesUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'table.tableCellProperties', {\n\t\t\tborderColors: defaultColors,\n\t\t\tbackgroundColors: defaultColors\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\t/**\n\t\t * The default table cell properties.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:table/tablecellproperties~TableCellPropertiesOptions}\n\t\t */\n\t\tthis._defaultTableCellProperties = getNormalizedDefaultProperties(\n\t\t\teditor.config.get( 'table.tableCellProperties.defaultProperties' ),\n\t\t\t{\n\t\t\t\tincludeVerticalAlignmentProperty: true,\n\t\t\t\tincludeHorizontalAlignmentProperty: true,\n\t\t\t\tincludePaddingProperty: true,\n\t\t\t\tisRightToLeftContent: editor.locale.contentLanguageDirection === 'rtl'\n\t\t\t}\n\t\t);\n\n\t\t/**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\n\t\t/**\n\t\t * The cell properties form view displayed inside the balloon.\n\t\t *\n\t\t * @member {module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}\n\t\t */\n\t\tthis.view = this._createPropertiesView();\n\n\t\t/**\n\t\t * The batch used to undo all changes made by the form (which are live, as the user types)\n\t\t * when \"Cancel\" was pressed. Each time the view is shown, a new batch is created.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:engine/model/batch~Batch}\n\t\t */\n\t\tthis._undoStepBatch = null;\n\n\t\teditor.ui.componentFactory.add( 'tableCellProperties', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: t( 'Cell properties' ),\n\t\t\t\ticon: tableCellProperties,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tthis.listenTo( view, 'execute', () => this._showView() );\n\n\t\t\tconst commands = Object.values( propertyToCommandMap )\n\t\t\t\t.map( commandName => editor.commands.get( commandName ) );\n\n\t\t\tview.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => (\n\t\t\t\tareEnabled.some( isCommandEnabled => isCommandEnabled )\n\t\t\t) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1341.\n\t\tthis.view.destroy();\n\t}\n\n\t/**\n\t * Creates the {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} instance.\n\t *\n\t * @private\n\t * @returns {module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView} The cell\n\t * properties form view instance.\n\t */\n\t_createPropertiesView() {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\t\tconst config = editor.config.get( 'table.tableCellProperties' );\n\t\tconst borderColorsConfig = normalizeColorOptions( config.borderColors );\n\t\tconst localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig );\n\t\tconst backgroundColorsConfig = normalizeColorOptions( config.backgroundColors );\n\t\tconst localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig );\n\t\tconst view = new TableCellPropertiesView( editor.locale, {\n\t\t\tborderColors: localizedBorderColors,\n\t\t\tbackgroundColors: localizedBackgroundColors,\n\t\t\tdefaultTableCellProperties: this._defaultTableCellProperties\n\t\t} );\n\t\tconst t = editor.t;\n\n\t\t// Render the view so its #element is available for the clickOutsideHandler.\n\t\tview.render();\n\n\t\tthis.listenTo( view, 'submit', () => {\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\tthis.listenTo( view, 'cancel', () => {\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/6180\n\t\t\tif ( this._undoStepBatch.operations.length ) {\n\t\t\t\teditor.execute( 'undo', this._undoStepBatch );\n\t\t\t}\n\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\t// Close the balloon on Esc key press.\n\t\tview.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideView();\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Reposition the balloon or hide the form if a table cell is no longer selected.\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tif ( !getTableWidgetAncestor( viewDocument.selection ) ) {\n\t\t\t\tthis._hideView();\n\t\t\t} else if ( this._isViewVisible ) {\n\t\t\t\trepositionContextualBalloon( editor, 'cell' );\n\t\t\t}\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: view,\n\t\t\tactivator: () => this._isViewInBalloon,\n\t\t\tcontextElements: [ this._balloon.view.element ],\n\t\t\tcallback: () => this._hideView()\n\t\t} );\n\n\t\tconst colorErrorText = getLocalizedColorErrorText( t );\n\t\tconst lengthErrorText = getLocalizedLengthErrorText( t );\n\n\t\t// Create the \"UI -> editor data\" binding.\n\t\t// These listeners update the editor data (via table commands) when any observable\n\t\t// property of the view has changed. They also validate the value and display errors in the UI\n\t\t// when necessary. This makes the view live, which means the changes are\n\t\t// visible in the editing as soon as the user types or changes fields' values.\n\t\tview.on(\n\t\t\t'change:borderStyle',\n\t\t\tthis._getPropertyChangeCallback( 'tableCellBorderStyle', this._defaultTableCellProperties.borderStyle )\n\t\t);\n\n\t\tview.on( 'change:borderColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderColorInput,\n\t\t\tcommandName: 'tableCellBorderColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator,\n\t\t\tdefaultValue: this._defaultTableCellProperties.borderColor\n\t\t} ) );\n\n\t\tview.on( 'change:borderWidth', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderWidthInput,\n\t\t\tcommandName: 'tableCellBorderWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lineWidthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableCellProperties.borderWidth\n\t\t} ) );\n\n\t\tview.on( 'change:padding', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.paddingInput,\n\t\t\tcommandName: 'tableCellPadding',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableCellProperties.padding\n\t\t} ) );\n\n\t\tview.on( 'change:width', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.widthInput,\n\t\t\tcommandName: 'tableCellWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableCellProperties.width\n\t\t} ) );\n\n\t\tview.on( 'change:height', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.heightInput,\n\t\t\tcommandName: 'tableCellHeight',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableCellProperties.height\n\t\t} ) );\n\n\t\tview.on( 'change:backgroundColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.backgroundInput,\n\t\t\tcommandName: 'tableCellBackgroundColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator,\n\t\t\tdefaultValue: this._defaultTableCellProperties.backgroundColor\n\t\t} ) );\n\n\t\tview.on(\n\t\t\t'change:horizontalAlignment',\n\t\t\tthis._getPropertyChangeCallback( 'tableCellHorizontalAlignment', this._defaultTableCellProperties.horizontalAlignment )\n\t\t);\n\t\tview.on(\n\t\t\t'change:verticalAlignment',\n\t\t\tthis._getPropertyChangeCallback( 'tableCellVerticalAlignment', this._defaultTableCellProperties.verticalAlignment )\n\t\t);\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * In this method the \"editor data -> UI\" binding is happening.\n\t *\n\t * When executed, this method obtains selected cell property values from various table commands\n\t * and passes them to the {@link #view}.\n\t *\n\t * This way, the UI stays up–to–date with the editor data.\n\t *\n\t * @private\n\t */\n\t_fillViewFormFromCommandValues() {\n\t\tconst commands = this.editor.commands;\n\t\tconst borderStyleCommand = commands.get( 'tableCellBorderStyle' );\n\n\t\tObject.entries( propertyToCommandMap )\n\t\t\t.map( ( [ property, commandName ] ) => {\n\t\t\t\tconst defaultValue = this._defaultTableCellProperties[ property ] || '';\n\n\t\t\t\treturn [ property, commands.get( commandName ).value || defaultValue ];\n\t\t\t} )\n\t\t\t.forEach( ( [ property, value ] ) => {\n\t\t\t\t// Do not set the `border-color` and `border-width` fields if `border-style:none`.\n\t\t\t\tif ( ( property === 'borderColor' || property === 'borderWidth' ) && borderStyleCommand.value === 'none' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.view.set( property, value );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Shows the {@link #view} in the {@link #_balloon}.\n\t *\n\t * **Note**: Each time a view is shown, a new {@link #_undoStepBatch} is created. It contains\n\t * all changes made to the document when the view is visible, allowing a single undo step\n\t * for all of them.\n\t *\n\t * @protected\n\t */\n\t_showView() {\n\t\tconst editor = this.editor;\n\n\t\t// Update the view with the model values.\n\t\tthis._fillViewFormFromCommandValues();\n\n\t\tthis._balloon.add( {\n\t\t\tview: this.view,\n\t\t\tposition: getBalloonCellPositionData( editor )\n\t\t} );\n\n\t\t// Create a new batch. Clicking \"Cancel\" will undo this batch.\n\t\tthis._undoStepBatch = editor.model.createBatch();\n\n\t\t// Basic a11y.\n\t\tthis.view.focus();\n\t}\n\n\t/**\n\t * Removes the {@link #view} from the {@link #_balloon}.\n\t *\n\t * @protected\n\t */\n\t_hideView() {\n\t\tif ( !this._isViewInBalloon ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\n\t\tthis.stopListening( editor.ui, 'update' );\n\n\t\t// Blur any input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tthis.view.saveButtonView.focus();\n\n\t\tthis._balloon.remove( this.view );\n\n\t\t// Make sure the focus is not lost in the process by putting it directly\n\t\t// into the editing view.\n\t\tthis.editor.editing.view.focus();\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is visible in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isViewVisible() {\n\t\treturn this._balloon.visibleView === this.view;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isViewInBalloon() {\n\t\treturn this._balloon.hasView( this.view );\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon the {@link #view view's} property change\n\t * executes a related editor command with the new property value.\n\t *\n\t * @private\n\t * @param {String} commandName\n\t * @param {String} defaultValue The default value of the command.\n\t * @returns {Function}\n\t */\n\t_getPropertyChangeCallback( commandName, defaultValue ) {\n\t\treturn ( evt, propertyName, newValue, oldValue ) => {\n\t\t\t// If the \"oldValue\" is missing and \"newValue\" is set to the default value, do not execute the command.\n\t\t\t// It is an initial call (when opening the table properties view).\n\t\t\tif ( !oldValue && defaultValue === newValue ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( commandName, {\n\t\t\t\tvalue: newValue,\n\t\t\t\tbatch: this._undoStepBatch\n\t\t\t} );\n\t\t};\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon the {@link #view view's} property change:\n\t * * Executes a related editor command with the new property value if the value is valid,\n\t * * Or sets the error text next to the invalid field, if the value did not pass the validation.\n\t *\n\t * @private\n\t * @param {Object} options\n\t * @param {String} options.commandName\n\t * @param {module:ui/view~View} options.viewField\n\t * @param {Function} options.validator\n\t * @param {String} options.errorText\n\t * @param {String} options.defaultValue\n\t * @returns {Function}\n\t */\n\t_getValidatedPropertyChangeCallback( options ) {\n\t\tconst { commandName, viewField, validator, errorText, defaultValue } = options;\n\t\tconst setErrorTextDebounced = debounce( () => {\n\t\t\tviewField.errorText = errorText;\n\t\t}, ERROR_TEXT_TIMEOUT );\n\n\t\treturn ( evt, propertyName, newValue, oldValue ) => {\n\t\t\tsetErrorTextDebounced.cancel();\n\n\t\t\t// If the \"oldValue\" is missing and \"newValue\" is set to the default value, do not execute the command.\n\t\t\t// It is an initial call (when opening the table properties view).\n\t\t\tif ( !oldValue && defaultValue === newValue ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( validator( newValue ) ) {\n\t\t\t\tthis.editor.execute( commandName, {\n\t\t\t\t\tvalue: newValue,\n\t\t\t\t\tbatch: this._undoStepBatch\n\t\t\t\t} );\n\n\t\t\t\tviewField.errorText = null;\n\t\t\t} else {\n\t\t\t\tsetErrorTextDebounced();\n\t\t\t}\n\t\t};\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablecellproperties/ui/tablecellpropertiesview\n */\n\nimport {\n\tLabeledFieldView,\n\tcreateLabeledDropdown,\n\tcreateLabeledInputText,\n\tLabelView,\n\taddListToDropdown,\n\tToolbarView,\n\tButtonView,\n\tFocusCycler,\n\tView,\n\tViewCollection,\n\tFormHeaderView,\n\tsubmitHandler\n} from 'ckeditor5/src/ui';\nimport { KeystrokeHandler, FocusTracker } from 'ckeditor5/src/utils';\nimport { icons } from 'ckeditor5/src/core';\n\nimport {\n\tfillToolbar,\n\tgetBorderStyleDefinitions,\n\tgetBorderStyleLabels,\n\tgetLabeledColorInputCreator\n} from '../../utils/ui/table-properties';\nimport FormRowView from '../../ui/formrowview';\n\nimport '../../../theme/form.css';\nimport '../../../theme/tableform.css';\nimport '../../../theme/tablecellproperties.css';\n\nconst ALIGNMENT_ICONS = {\n\tleft: icons.alignLeft,\n\tcenter: icons.alignCenter,\n\tright: icons.alignRight,\n\tjustify: icons.alignJustify,\n\ttop: icons.alignTop,\n\tmiddle: icons.alignMiddle,\n\tbottom: icons.alignBottom\n};\n\n/**\n * The class representing a table cell properties form, allowing users to customize\n * certain style aspects of a table cell, for instance, border, padding, text alignment, etc..\n *\n * @extends module:ui/view~View\n */\nexport default class TableCellPropertiesView extends View {\n\t/**\n\t * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param {Object} options Additional configuration of the view.\n\t * @param {module:table/table~TableColorConfig} options.borderColors A configuration of the border\n\t * color palette used by the\n\t * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#borderColorInput}.\n\t * @param {module:table/table~TableColorConfig} options.backgroundColors A configuration of the background\n\t * color palette used by the\n\t * {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView#backgroundInput}.\n\t * @param {module:table/tablecellproperties~TableCellPropertiesOptions} options.defaultTableCellProperties The default\n\t * table cell properties.\n\t */\n\tconstructor( locale, options ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\t/**\n\t\t\t * The value of the cell border style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #borderStyle\n\t\t\t */\n\t\t\tborderStyle: '',\n\n\t\t\t/**\n\t\t\t * The value of the cell border width style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #borderWidth\n\t\t\t */\n\t\t\tborderWidth: '',\n\n\t\t\t/**\n\t\t\t * The value of the cell border color style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #borderColor\n\t\t\t */\n\t\t\tborderColor: '',\n\n\t\t\t/**\n\t\t\t * The value of the cell padding style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #padding\n\t\t\t */\n\t\t\tpadding: '',\n\n\t\t\t/**\n\t\t\t * The value of the cell background color style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #backgroundColor\n\t\t\t */\n\t\t\tbackgroundColor: '',\n\n\t\t\t/**\n\t\t\t * The value of the table cell width style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #width\n\t\t\t */\n\t\t\twidth: '',\n\n\t\t\t/**\n\t\t\t * The value of the table cell height style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #height\n\t\t\t */\n\t\t\theight: '',\n\n\t\t\t/**\n\t\t\t * The value of the horizontal text alignment style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #horizontalAlignment\n\t\t\t */\n\t\t\thorizontalAlignment: '',\n\n\t\t\t/**\n\t\t\t * The value of the vertical text alignment style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #verticalAlignment\n\t\t\t */\n\t\t\tverticalAlignment: ''\n\t\t} );\n\n\t\t/**\n\t\t * Options passed to the view. See {@link #constructor} to learn more.\n\t\t *\n\t\t * @member {Object}\n\t\t */\n\t\tthis.options = options;\n\n\t\tconst { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();\n\t\tconst { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();\n\t\tconst { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();\n\t\tconst { horizontalAlignmentToolbar, verticalAlignmentToolbar, alignmentLabel } = this._createAlignmentFields();\n\n\t\t/**\n\t\t * Tracks information about the DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * A collection of child views in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\t/**\n\t\t * A dropdown that allows selecting the style of the table cell border.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/dropdown/dropdownview~DropdownView}\n\t\t */\n\t\tthis.borderStyleDropdown = borderStyleDropdown;\n\n\t\t/**\n\t\t * An input that allows specifying the width of the table cell border.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.borderWidthInput = borderWidthInput;\n\n\t\t/**\n\t\t * An input that allows specifying the color of the table cell border.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:table/ui/colorinputview~ColorInputView}\n\t\t */\n\t\tthis.borderColorInput = borderColorInput;\n\n\t\t/**\n\t\t * An input that allows specifying the table cell background color.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:table/ui/colorinputview~ColorInputView}\n\t\t */\n\t\tthis.backgroundInput = backgroundInput;\n\n\t\t/**\n\t\t * An input that allows specifying the table cell padding.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.paddingInput = this._createPaddingField();\n\n\t\t/**\n\t\t * An input that allows specifying the table cell width.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.widthInput = widthInput;\n\n\t\t/**\n\t\t * An input that allows specifying the table cell height.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.heightInput = heightInput;\n\n\t\t/**\n\t\t * A toolbar with buttons that allow changing the horizontal text alignment in a table cell.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/toolbar/toolbar~ToolbarView}\n\t\t */\n\t\tthis.horizontalAlignmentToolbar = horizontalAlignmentToolbar;\n\n\t\t/**\n\t\t * A toolbar with buttons that allow changing the vertical text alignment in a table cell.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/toolbar/toolbar~ToolbarView}\n\t\t */\n\t\tthis.verticalAlignmentToolbar = verticalAlignmentToolbar;\n\n\t\t// Defer creating to make sure other fields are present and the Save button can\n\t\t// bind its #isEnabled to their error messages so there's no way to save unless all\n\t\t// fields are valid.\n\t\tconst { saveButtonView, cancelButtonView } = this._createActionButtons();\n\n\t\t/**\n\t\t * The \"Save\" button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.saveButtonView = saveButtonView;\n\n\t\t/**\n\t\t * The \"Cancel\" button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.cancelButtonView = cancelButtonView;\n\n\t\t/**\n\t\t * A collection of views that can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis._focusables = new ViewCollection();\n\n\t\t/**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// Form header.\n\t\tthis.children.add( new FormHeaderView( locale, {\n\t\t\tlabel: this.t( 'Cell properties' )\n\t\t} ) );\n\n\t\t// Border row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: borderRowLabel,\n\t\t\tchildren: [\n\t\t\t\tborderRowLabel,\n\t\t\t\tborderStyleDropdown,\n\t\t\t\tborderColorInput,\n\t\t\t\tborderWidthInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__border-row'\n\t\t} ) );\n\n\t\t// Background.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: backgroundRowLabel,\n\t\t\tchildren: [\n\t\t\t\tbackgroundRowLabel,\n\t\t\t\tbackgroundInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__background-row'\n\t\t} ) );\n\n\t\t// Dimensions row and padding.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\t// Dimensions row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tlabelView: dimensionsLabel,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tdimensionsLabel,\n\t\t\t\t\t\twidthInput,\n\t\t\t\t\t\toperatorLabel,\n\t\t\t\t\t\theightInput\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-form__dimensions-row'\n\t\t\t\t} ),\n\t\t\t\t// Padding row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tthis.paddingInput\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-cell-properties-form__padding-row'\n\t\t\t\t} )\n\t\t\t]\n\t\t} ) );\n\n\t\t// Text alignment row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: alignmentLabel,\n\t\t\tchildren: [\n\t\t\t\talignmentLabel,\n\t\t\t\thorizontalAlignmentToolbar,\n\t\t\t\tverticalAlignmentToolbar\n\t\t\t],\n\t\t\tclass: 'ck-table-cell-properties-form__alignment-row'\n\t\t} ) );\n\n\t\t// Action row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t],\n\t\t\tclass: 'ck-table-form__action-row'\n\t\t} ) );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form',\n\t\t\t\t\t'ck-table-form',\n\t\t\t\t\t'ck-table-cell-properties-form'\n\t\t\t\t],\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/90\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Enable the \"submit\" event for this view. It can be triggered by the #saveButtonView\n\t\t// which is of the \"submit\" DOM \"type\".\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\t[\n\t\t\tthis.borderStyleDropdown,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.widthInput,\n\t\t\tthis.heightInput,\n\t\t\tthis.paddingInput,\n\t\t\tthis.horizontalAlignmentToolbar,\n\t\t\tthis.verticalAlignmentToolbar,\n\t\t\tthis.saveButtonView,\n\t\t\tthis.cancelButtonView\n\t\t].forEach( view => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( view );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( view.element );\n\t\t} );\n\n\t\t// Mainly for closing using \"Esc\" and navigation using \"Tab\".\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the fist focusable field in the form.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #borderStyleDropdown},\n\t * * {@link #borderWidthInput},\n\t * * {@link #borderColorInput}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createBorderFields() {\n\t\tconst defaultTableCellProperties = this.options.defaultTableCellProperties;\n\t\tconst defaultBorder = {\n\t\t\tstyle: defaultTableCellProperties.borderStyle,\n\t\t\twidth: defaultTableCellProperties.borderWidth,\n\t\t\tcolor: defaultTableCellProperties.borderColor\n\t\t};\n\n\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.borderColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: defaultBorder.color\n\t\t} );\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst borderRowLabel = new LabelView( locale );\n\t\tborderRowLabel.text = t( 'Border' );\n\n\t\t// -- Style ---------------------------------------------------\n\n\t\tconst styleLabels = getBorderStyleLabels( t );\n\t\tconst borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );\n\t\tborderStyleDropdown.set( {\n\t\t\tlabel: t( 'Style' ),\n\t\t\tclass: 'ck-table-form__border-style'\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.set( {\n\t\t\tisOn: false,\n\t\t\twithText: true,\n\t\t\ttooltip: t( 'Style' )\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {\n\t\t\treturn styleLabels[ value ? value : 'none' ];\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.on( 'execute', evt => {\n\t\t\tthis.borderStyle = evt.source._borderStyleValue;\n\t\t} );\n\n\t\tborderStyleDropdown.bind( 'isEmpty' ).to( this, 'borderStyle', value => !value );\n\n\t\taddListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this, defaultBorder.style ) );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\tborderWidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__border-width'\n\t\t} );\n\n\t\tborderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );\n\t\tborderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\t\tborderWidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderWidth = borderWidthInput.fieldView.element.value;\n\t\t} );\n\n\t\t// -- Color ---------------------------------------------------\n\n\t\tconst borderColorInput = new LabeledFieldView( locale, colorInputCreator );\n\n\t\tborderColorInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-form__border-color'\n\t\t} );\n\n\t\tborderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );\n\t\tborderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\n\t\tborderColorInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderColor = borderColorInput.fieldView.value;\n\t\t} );\n\n\t\t// Reset the border color and width fields depending on the `border-style` value.\n\t\tthis.on( 'change:borderStyle', ( evt, name, newValue, oldValue ) => {\n\t\t\t// When removing the border (`border-style:none`), clear the remaining `border-*` properties.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/6227.\n\t\t\tif ( !isBorderStyleSet( newValue ) ) {\n\t\t\t\tthis.borderColor = '';\n\t\t\t\tthis.borderWidth = '';\n\t\t\t}\n\n\t\t\t// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.\n\t\t\tif ( !isBorderStyleSet( oldValue ) ) {\n\t\t\t\tthis.borderColor = defaultBorder.color;\n\t\t\t\tthis.borderWidth = defaultBorder.width;\n\t\t\t}\n\t\t} );\n\n\t\treturn {\n\t\t\tborderRowLabel,\n\t\t\tborderStyleDropdown,\n\t\t\tborderColorInput,\n\t\t\tborderWidthInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #backgroundInput}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createBackgroundFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst backgroundRowLabel = new LabelView( locale );\n\t\tbackgroundRowLabel.text = t( 'Background' );\n\n\t\t// -- Background color input -----------------------------------\n\n\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.backgroundColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: this.options.defaultTableCellProperties.backgroundColor\n\t\t} );\n\n\t\tconst backgroundInput = new LabeledFieldView( locale, colorInputCreator );\n\n\t\tbackgroundInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-cell-properties-form__background'\n\t\t} );\n\n\t\tbackgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );\n\t\tbackgroundInput.fieldView.on( 'input', () => {\n\t\t\tthis.backgroundColor = backgroundInput.fieldView.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tbackgroundRowLabel,\n\t\t\tbackgroundInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #widthInput}.\n\t * * {@link #heightInput}.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n\t */\n\t_createDimensionFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Label ---------------------------------------------------\n\n\t\tconst dimensionsLabel = new LabelView( locale );\n\t\tdimensionsLabel.text = t( 'Dimensions' );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst widthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\twidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__width'\n\t\t} );\n\n\t\twidthInput.fieldView.bind( 'value' ).to( this, 'width' );\n\t\twidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.width = widthInput.fieldView.element.value;\n\t\t} );\n\n\t\t// -- Operator ---------------------------------------------------\n\n\t\tconst operatorLabel = new View( locale );\n\t\toperatorLabel.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-table-form__dimension-operator'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{ text: '×' }\n\t\t\t]\n\t\t} );\n\n\t\t// -- Height ---------------------------------------------------\n\n\t\tconst heightInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\theightInput.set( {\n\t\t\tlabel: t( 'Height' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__height'\n\t\t} );\n\n\t\theightInput.fieldView.bind( 'value' ).to( this, 'height' );\n\t\theightInput.fieldView.on( 'input', () => {\n\t\t\tthis.height = heightInput.fieldView.element.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tdimensionsLabel,\n\t\t\twidthInput,\n\t\t\toperatorLabel,\n\t\t\theightInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #paddingInput}.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n\t */\n\t_createPaddingField() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\tconst paddingInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\tpaddingInput.set( {\n\t\t\tlabel: t( 'Padding' ),\n\t\t\tclass: 'ck-table-cell-properties-form__padding'\n\t\t} );\n\n\t\tpaddingInput.fieldView.bind( 'value' ).to( this, 'padding' );\n\t\tpaddingInput.fieldView.on( 'input', () => {\n\t\t\tthis.padding = paddingInput.fieldView.element.value;\n\t\t} );\n\n\t\treturn paddingInput;\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #horizontalAlignmentToolbar},\n\t * * {@link #verticalAlignmentToolbar}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createAlignmentFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\tconst alignmentLabel = new LabelView( locale );\n\n\t\talignmentLabel.text = t( 'Table cell text alignment' );\n\n\t\t// -- Horizontal ---------------------------------------------------\n\n\t\tconst horizontalAlignmentToolbar = new ToolbarView( locale );\n\t\tconst isContentRTL = this.locale.contentLanguageDirection === 'rtl';\n\n\t\thorizontalAlignmentToolbar.set( {\n\t\t\tisCompact: true,\n\t\t\tariaLabel: t( 'Horizontal text alignment toolbar' )\n\t\t} );\n\n\t\tfillToolbar( {\n\t\t\tview: this,\n\t\t\ticons: ALIGNMENT_ICONS,\n\t\t\ttoolbar: horizontalAlignmentToolbar,\n\t\t\tlabels: this._horizontalAlignmentLabels,\n\t\t\tpropertyName: 'horizontalAlignment',\n\t\t\tnameToValue: name => {\n\t\t\t\t// For the RTL content, we want to swap the buttons \"align to the left\" and \"align to the right\".\n\t\t\t\tif ( isContentRTL ) {\n\t\t\t\t\tif ( name === 'left' ) {\n\t\t\t\t\t\treturn 'right';\n\t\t\t\t\t} else if ( name === 'right' ) {\n\t\t\t\t\t\treturn 'left';\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn name;\n\t\t\t},\n\t\t\tdefaultValue: this.options.defaultTableCellProperties.horizontalAlignment\n\t\t} );\n\n\t\t// -- Vertical -----------------------------------------------------\n\n\t\tconst verticalAlignmentToolbar = new ToolbarView( locale );\n\n\t\tverticalAlignmentToolbar.set( {\n\t\t\tisCompact: true,\n\t\t\tariaLabel: t( 'Vertical text alignment toolbar' )\n\t\t} );\n\n\t\tfillToolbar( {\n\t\t\tview: this,\n\t\t\ticons: ALIGNMENT_ICONS,\n\t\t\ttoolbar: verticalAlignmentToolbar,\n\t\t\tlabels: this._verticalAlignmentLabels,\n\t\t\tpropertyName: 'verticalAlignment',\n\t\t\tdefaultValue: this.options.defaultTableCellProperties.verticalAlignment\n\t\t} );\n\n\t\treturn {\n\t\t\thorizontalAlignmentToolbar,\n\t\t\tverticalAlignmentToolbar,\n\t\t\talignmentLabel\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #saveButtonView},\n\t * * {@link #cancelButtonView}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createActionButtons() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\t\tconst saveButtonView = new ButtonView( locale );\n\t\tconst cancelButtonView = new ButtonView( locale );\n\t\tconst fieldsThatShouldValidateToSave = [\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.paddingInput\n\t\t];\n\n\t\tsaveButtonView.set( {\n\t\t\tlabel: t( 'Save' ),\n\t\t\ticon: icons.check,\n\t\t\tclass: 'ck-button-save',\n\t\t\ttype: 'submit',\n\t\t\twithText: true\n\t\t} );\n\n\t\tsaveButtonView.bind( 'isEnabled' ).toMany( fieldsThatShouldValidateToSave, 'errorText', ( ...errorTexts ) => {\n\t\t\treturn errorTexts.every( errorText => !errorText );\n\t\t} );\n\n\t\tcancelButtonView.set( {\n\t\t\tlabel: t( 'Cancel' ),\n\t\t\ticon: icons.cancel,\n\t\t\tclass: 'ck-button-cancel',\n\t\t\twithText: true\n\t\t} );\n\n\t\tcancelButtonView.delegate( 'execute' ).to( this, 'cancel' );\n\n\t\treturn {\n\t\t\tsaveButtonView, cancelButtonView\n\t\t};\n\t}\n\n\t/**\n\t * Provides localized labels for {@link #horizontalAlignmentToolbar} buttons.\n\t *\n\t * @private\n\t * @type {Object.<String,String>}\n\t */\n\tget _horizontalAlignmentLabels() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\tconst left = t( 'Align cell text to the left' );\n\t\tconst center = t( 'Align cell text to the center' );\n\t\tconst right = t( 'Align cell text to the right' );\n\t\tconst justify = t( 'Justify cell text' );\n\n\t\t// Returns object with a proper order of labels.\n\t\tif ( locale.uiLanguageDirection === 'rtl' ) {\n\t\t\treturn { right, center, left, justify };\n\t\t} else {\n\t\t\treturn { left, center, right, justify };\n\t\t}\n\t}\n\n\t/**\n\t * Provides localized labels for {@link #verticalAlignmentToolbar} buttons.\n\t *\n\t * @private\n\t * @type {Object.<String,String>}\n\t */\n\tget _verticalAlignmentLabels() {\n\t\tconst t = this.t;\n\n\t\treturn {\n\t\t\ttop: t( 'Align cell text to the top' ),\n\t\t\tmiddle: t( 'Align cell text to the middle' ),\n\t\t\tbottom: t( 'Align cell text to the bottom' )\n\t\t};\n\t}\n}\n\nfunction isBorderStyleSet( value ) {\n\treturn value !== 'none';\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableclipboard\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport TableSelection from './tableselection';\nimport TableWalker from './tablewalker';\nimport TableUtils from './tableutils';\nimport { getColumnIndexes, getRowIndexes, getSelectionAffectedTableCells, isSelectionRectangular, sortRanges } from './utils/selection';\nimport {\n\tcropTableToDimensions,\n\tgetHorizontallyOverlappingCells,\n\tgetVerticallyOverlappingCells,\n\tremoveEmptyRowsColumns,\n\tsplitHorizontally,\n\tsplitVertically,\n\ttrimTableCellIfNeeded,\n\tadjustLastRowIndex,\n\tadjustLastColumnIndex\n} from './utils/structure';\n\n/**\n * This plugin adds support for copying/cutting/pasting fragments of tables.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableClipboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableClipboard';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableSelection, TableUtils ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tthis.listenTo( viewDocument, 'copy', ( evt, data ) => this._onCopyCut( evt, data ) );\n\t\tthis.listenTo( viewDocument, 'cut', ( evt, data ) => this._onCopyCut( evt, data ) );\n\t\tthis.listenTo( editor.model, 'insertContent', ( evt, args ) => this._onInsertContent( evt, ...args ), { priority: 'high' } );\n\n\t\tthis.decorate( '_replaceTableSlotCell' );\n\t}\n\n\t/**\n\t * Copies table content to a clipboard on \"copy\" & \"cut\" events.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the handled event.\n\t * @param {Object} data Clipboard event data.\n\t */\n\t_onCopyCut( evt, data ) {\n\t\tconst tableSelection = this.editor.plugins.get( TableSelection );\n\n\t\tif ( !tableSelection.getSelectedTableCells() ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( evt.name == 'cut' && this.editor.isReadOnly ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdata.preventDefault();\n\t\tevt.stop();\n\n\t\tconst dataController = this.editor.data;\n\t\tconst viewDocument = this.editor.editing.view.document;\n\n\t\tconst content = dataController.toView( tableSelection.getSelectionAsFragment() );\n\n\t\tviewDocument.fire( 'clipboardOutput', {\n\t\t\tdataTransfer: data.dataTransfer,\n\t\t\tcontent,\n\t\t\tmethod: evt.name\n\t\t} );\n\t}\n\n\t/**\n\t * Overrides default {@link module:engine/model/model~Model#insertContent `model.insertContent()`} method to handle pasting table inside\n\t * selected table fragment.\n\t *\n\t * Depending on selected table fragment:\n\t * - If a selected table fragment is smaller than paste table it will crop pasted table to match dimensions.\n\t * - If dimensions are equal it will replace selected table fragment with a pasted table contents.\n\t *\n\t * @private\n\t * @param evt\n\t * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.\n\t * @param {module:engine/model/selection~Selectable} [selectable=model.document.selection]\n\t * The selection into which the content should be inserted. If not provided the current model document selection will be used.\n\t */\n\t_onInsertContent( evt, content, selectable ) {\n\t\tif ( selectable && !selectable.is( 'documentSelection' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst model = this.editor.model;\n\t\tconst tableUtils = this.editor.plugins.get( TableUtils );\n\n\t\t// We might need to crop table before inserting so reference might change.\n\t\tlet pastedTable = getTableIfOnlyTableInContent( content, model );\n\n\t\tif ( !pastedTable ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst selectedTableCells = getSelectionAffectedTableCells( model.document.selection );\n\n\t\tif ( !selectedTableCells.length ) {\n\t\t\tremoveEmptyRowsColumns( pastedTable, tableUtils );\n\n\t\t\treturn;\n\t\t}\n\n\t\t// Override default model.insertContent() handling at this point.\n\t\tevt.stop();\n\n\t\tmodel.change( writer => {\n\t\t\tconst pastedDimensions = {\n\t\t\t\twidth: tableUtils.getColumns( pastedTable ),\n\t\t\t\theight: tableUtils.getRows( pastedTable )\n\t\t\t};\n\n\t\t\t// Prepare the table for pasting.\n\t\t\tconst selection = prepareTableForPasting( selectedTableCells, pastedDimensions, writer, tableUtils );\n\n\t\t\t// Beyond this point we operate on a fixed content table with rectangular selection and proper last row/column values.\n\n\t\t\tconst selectionHeight = selection.lastRow - selection.firstRow + 1;\n\t\t\tconst selectionWidth = selection.lastColumn - selection.firstColumn + 1;\n\n\t\t\t// Crop pasted table if:\n\t\t\t// - Pasted table dimensions exceeds selection area.\n\t\t\t// - Pasted table has broken layout (ie some cells sticks out by the table dimensions established by the first and last row).\n\t\t\t//\n\t\t\t// Note: The table dimensions are established by the width of the first row and the total number of rows.\n\t\t\t// It is possible to programmatically create a table that has rows which would have cells anchored beyond first row width but\n\t\t\t// such table will not be created by other editing solutions.\n\t\t\tconst cropDimensions = {\n\t\t\t\tstartRow: 0,\n\t\t\t\tstartColumn: 0,\n\t\t\t\tendRow: Math.min( selectionHeight, pastedDimensions.height ) - 1,\n\t\t\t\tendColumn: Math.min( selectionWidth, pastedDimensions.width ) - 1\n\t\t\t};\n\n\t\t\tpastedTable = cropTableToDimensions( pastedTable, cropDimensions, writer );\n\n\t\t\t// Content table to which we insert a pasted table.\n\t\t\tconst selectedTable = selectedTableCells[ 0 ].findAncestor( 'table' );\n\n\t\t\tconst cellsToSelect = this._replaceSelectedCellsWithPasted( pastedTable, pastedDimensions, selectedTable, selection, writer );\n\n\t\t\tif ( this.editor.plugins.get( 'TableSelection' ).isEnabled ) {\n\t\t\t\t// Selection ranges must be sorted because the first and last selection ranges are considered\n\t\t\t\t// as anchor/focus cell ranges for multi-cell selection.\n\t\t\t\tconst selectionRanges = sortRanges( cellsToSelect.map( cell => writer.createRangeOn( cell ) ) );\n\n\t\t\t\twriter.setSelection( selectionRanges );\n\t\t\t} else {\n\t\t\t\t// Set selection inside first cell if multi-cell selection is disabled.\n\t\t\t\twriter.setSelection( cellsToSelect[ 0 ], 0 );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Replaces the part of selectedTable with pastedTable.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} pastedTable\n\t * @param {Object} pastedDimensions\n\t * @param {Number} pastedDimensions.height\n\t * @param {Number} pastedDimensions.width\n\t * @param {module:engine/model/element~Element} selectedTable\n\t * @param {Object} selection\n\t * @param {Number} selection.firstColumn\n\t * @param {Number} selection.firstRow\n\t * @param {Number} selection.lastColumn\n\t * @param {Number} selection.lastRow\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @returns {Array.<module:engine/model/element~Element>}\n\t */\n\t_replaceSelectedCellsWithPasted( pastedTable, pastedDimensions, selectedTable, selection, writer ) {\n\t\tconst { width: pastedWidth, height: pastedHeight } = pastedDimensions;\n\n\t\t// Holds two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.\n\t\tconst pastedTableLocationMap = createLocationMap( pastedTable, pastedWidth, pastedHeight );\n\n\t\tconst selectedTableMap = [ ...new TableWalker( selectedTable, {\n\t\t\tstartRow: selection.firstRow,\n\t\t\tendRow: selection.lastRow,\n\t\t\tstartColumn: selection.firstColumn,\n\t\t\tendColumn: selection.lastColumn,\n\t\t\tincludeAllSlots: true\n\t\t} ) ];\n\n\t\t// Selection must be set to pasted cells (some might be removed or new created).\n\t\tconst cellsToSelect = [];\n\n\t\t// Store next cell insert position.\n\t\tlet insertPosition;\n\n\t\t// Content table replace cells algorithm iterates over a selected table fragment and:\n\t\t//\n\t\t// - Removes existing table cells at current slot (location).\n\t\t// - Inserts cell from a pasted table for a matched slots.\n\t\t//\n\t\t// This ensures proper table geometry after the paste\n\t\tfor ( const tableSlot of selectedTableMap ) {\n\t\t\tconst { row, column } = tableSlot;\n\n\t\t\t// Save the insert position for current row start.\n\t\t\tif ( column === selection.firstColumn ) {\n\t\t\t\tinsertPosition = tableSlot.getPositionBefore();\n\t\t\t}\n\n\t\t\t// Map current table slot location to an pasted table slot location.\n\t\t\tconst pastedRow = row - selection.firstRow;\n\t\t\tconst pastedColumn = column - selection.firstColumn;\n\t\t\tconst pastedCell = pastedTableLocationMap[ pastedRow % pastedHeight ][ pastedColumn % pastedWidth ];\n\n\t\t\t// Clone cell to insert (to duplicate its attributes and children).\n\t\t\t// Cloning is required to support repeating pasted table content when inserting to a bigger selection.\n\t\t\tconst cellToInsert = pastedCell ? writer.cloneElement( pastedCell ) : null;\n\n\t\t\t// Replace the cell from the current slot with new table cell.\n\t\t\tconst newTableCell = this._replaceTableSlotCell( tableSlot, cellToInsert, insertPosition, writer );\n\n\t\t\t// The cell was only removed.\n\t\t\tif ( !newTableCell ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Trim the cell if it's row/col-spans would exceed selection area.\n\t\t\ttrimTableCellIfNeeded( newTableCell, row, column, selection.lastRow, selection.lastColumn, writer );\n\n\t\t\tcellsToSelect.push( newTableCell );\n\n\t\t\tinsertPosition = writer.createPositionAfter( newTableCell );\n\t\t}\n\n\t\t// If there are any headings, all the cells that overlap from heading must be splitted.\n\t\tconst headingRows = parseInt( selectedTable.getAttribute( 'headingRows' ) || 0 );\n\t\tconst headingColumns = parseInt( selectedTable.getAttribute( 'headingColumns' ) || 0 );\n\n\t\tconst areHeadingRowsIntersectingSelection = selection.firstRow < headingRows && headingRows <= selection.lastRow;\n\t\tconst areHeadingColumnsIntersectingSelection = selection.firstColumn < headingColumns && headingColumns <= selection.lastColumn;\n\n\t\tif ( areHeadingRowsIntersectingSelection ) {\n\t\t\tconst columnsLimit = { first: selection.firstColumn, last: selection.lastColumn };\n\t\t\tconst newCells = doHorizontalSplit( selectedTable, headingRows, columnsLimit, writer, selection.firstRow );\n\n\t\t\tcellsToSelect.push( ...newCells );\n\t\t}\n\n\t\tif ( areHeadingColumnsIntersectingSelection ) {\n\t\t\tconst rowsLimit = { first: selection.firstRow, last: selection.lastRow };\n\t\t\tconst newCells = doVerticalSplit( selectedTable, headingColumns, rowsLimit, writer );\n\n\t\t\tcellsToSelect.push( ...newCells );\n\t\t}\n\n\t\treturn cellsToSelect;\n\t}\n\n\t/**\n\t * Replaces a single table slot.\n\t *\n\t * @private\n\t * @param {module:table/tablewalker~TableSlot} tableSlot\n\t * @param {module:engine/model/element~Element} cellToInsert\n\t * @param {module:engine/model/position~Position} insertPosition\n\t * @param {module:engine/model/writer~Writer} writer\n\t * @returns {module:engine/model/element~Element|null} Inserted table cell or null if slot should remain empty.\n\t */\n\t_replaceTableSlotCell( tableSlot, cellToInsert, insertPosition, writer ) {\n\t\tconst { cell, isAnchor } = tableSlot;\n\n\t\t// If the slot is occupied by a cell in a selected table - remove it.\n\t\t// The slot of this cell will be either:\n\t\t// - Replaced by a pasted table cell.\n\t\t// - Spanned by a previously pasted table cell.\n\t\tif ( isAnchor ) {\n\t\t\twriter.remove( cell );\n\t\t}\n\n\t\t// There is no cell to insert (might be spanned by other cell in a pasted table) - advance to the next content table slot.\n\t\tif ( !cellToInsert ) {\n\t\t\treturn null;\n\t\t}\n\n\t\twriter.insert( cellToInsert, insertPosition );\n\n\t\treturn cellToInsert;\n\t}\n}\n\n/**\n * Extract table for pasting into table.\n *\n * @private\n * @param {module:engine/model/documentfragment~DocumentFragment|module:engine/model/item~Item} content The content to insert.\n * @param {module:engine/model/model~Model} model The editor model.\n * @returns {module:engine/model/element~Element|null}\n */\nexport function getTableIfOnlyTableInContent( content, model ) {\n\tif ( !content.is( 'documentFragment' ) && !content.is( 'element' ) ) {\n\t\treturn null;\n\t}\n\n\t// Table passed directly.\n\tif ( content.is( 'element', 'table' ) ) {\n\t\treturn content;\n\t}\n\n\t// We do not support mixed content when pasting table into table.\n\t// See: https://github.com/ckeditor/ckeditor5/issues/6817.\n\tif ( content.childCount == 1 && content.getChild( 0 ).is( 'element', 'table' ) ) {\n\t\treturn content.getChild( 0 );\n\t}\n\n\t// If there are only whitespaces around a table then use that table for pasting.\n\n\tconst contentRange = model.createRangeIn( content );\n\n\tfor ( const element of contentRange.getItems() ) {\n\t\tif ( element.is( 'element', 'table' ) ) {\n\t\t\t// Stop checking if there is some content before table.\n\t\t\tconst rangeBefore = model.createRange( contentRange.start, model.createPositionBefore( element ) );\n\n\t\t\tif ( model.hasContent( rangeBefore, { ignoreWhitespaces: true } ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Stop checking if there is some content after table.\n\t\t\tconst rangeAfter = model.createRange( model.createPositionAfter( element ), contentRange.end );\n\n\t\t\tif ( model.hasContent( rangeAfter, { ignoreWhitespaces: true } ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// There wasn't any content neither before nor after.\n\t\t\treturn element;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// Prepares a table for pasting and returns adjusted selection dimensions.\n//\n// @param {Array.<module:engine/model/element~Element>} selectedTableCells\n// @param {Object} pastedDimensions\n// @param {Number} pastedDimensions.height\n// @param {Number} pastedDimensions.width\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:table/tableutils~TableUtils} tableUtils\n// @returns {Object} selection\n// @returns {Number} selection.firstColumn\n// @returns {Number} selection.firstRow\n// @returns {Number} selection.lastColumn\n// @returns {Number} selection.lastRow\nfunction prepareTableForPasting( selectedTableCells, pastedDimensions, writer, tableUtils ) {\n\tconst selectedTable = selectedTableCells[ 0 ].findAncestor( 'table' );\n\n\tconst columnIndexes = getColumnIndexes( selectedTableCells );\n\tconst rowIndexes = getRowIndexes( selectedTableCells );\n\n\tconst selection = {\n\t\tfirstColumn: columnIndexes.first,\n\t\tlastColumn: columnIndexes.last,\n\t\tfirstRow: rowIndexes.first,\n\t\tlastRow: rowIndexes.last\n\t};\n\n\t// Single cell selected - expand selection to pasted table dimensions.\n\tconst shouldExpandSelection = selectedTableCells.length === 1;\n\n\tif ( shouldExpandSelection ) {\n\t\tselection.lastRow += pastedDimensions.height - 1;\n\t\tselection.lastColumn += pastedDimensions.width - 1;\n\n\t\texpandTableSize( selectedTable, selection.lastRow + 1, selection.lastColumn + 1, tableUtils );\n\t}\n\n\t// In case of expanding selection we do not reset the selection so in this case we will always try to fix selection\n\t// like in the case of a non-rectangular area. This might be fixed by re-setting selected cells array but this shortcut is safe.\n\tif ( shouldExpandSelection || !isSelectionRectangular( selectedTableCells, tableUtils ) ) {\n\t\t// For a non-rectangular selection (ie in which some cells sticks out from a virtual selection rectangle) we need to create\n\t\t// a table layout that has a rectangular selection. This will split cells so the selection become rectangular.\n\t\t// Beyond this point we will operate on fixed content table.\n\t\tsplitCellsToRectangularSelection( selectedTable, selection, writer );\n\t}\n\t// However a selected table fragment might be invalid if examined alone. Ie such table fragment:\n\t//\n\t// +---+---+---+---+\n\t// 0 | a | b | c | d |\n\t// + + +---+---+\n\t// 1 | | e | f | g |\n\t// + +---+ +---+\n\t// 2 | | h | | i | <- last row, each cell has rowspan = 2,\n\t// + + + + + so we need to return 3, not 2\n\t// 3 | | | | |\n\t// +---+---+---+---+\n\t//\n\t// is invalid as the cells \"h\" and \"i\" have rowspans.\n\t// This case needs only adjusting the selection dimension as the rest of the algorithm operates on empty slots also.\n\telse {\n\t\tselection.lastRow = adjustLastRowIndex( selectedTable, selection );\n\t\tselection.lastColumn = adjustLastColumnIndex( selectedTable, selection );\n\t}\n\n\treturn selection;\n}\n\n// Expand table (in place) to expected size.\nfunction expandTableSize( table, expectedHeight, expectedWidth, tableUtils ) {\n\tconst tableWidth = tableUtils.getColumns( table );\n\tconst tableHeight = tableUtils.getRows( table );\n\n\tif ( expectedWidth > tableWidth ) {\n\t\ttableUtils.insertColumns( table, {\n\t\t\tat: tableWidth,\n\t\t\tcolumns: expectedWidth - tableWidth\n\t\t} );\n\t}\n\n\tif ( expectedHeight > tableHeight ) {\n\t\ttableUtils.insertRows( table, {\n\t\t\tat: tableHeight,\n\t\t\trows: expectedHeight - tableHeight\n\t\t} );\n\t}\n}\n\n// Returns two-dimensional array that is addressed by [ row ][ column ] that stores cells anchored at given location.\n//\n// At given row & column location it might be one of:\n//\n// * cell - cell from pasted table anchored at this location.\n// * null - if no cell is anchored at this location.\n//\n// For instance, from a table below:\n//\n//\t\t+----+----+----+----+\n//\t\t| 00 | 01 | 02 | 03 |\n//\t\t+ +----+----+----+\n//\t\t| | 11 | 13 |\n//\t\t+----+ +----+\n//\t\t| 20 | | 23 |\n//\t\t+----+----+----+----+\n//\n// The method will return an array (numbers represents cell element):\n//\n//\tconst map = [\n//\t\t[ '00', '01', '02', '03' ],\n//\t\t[ null, '11', null, '13' ],\n//\t\t[ '20', null, null, '23' ]\n//\t]\n//\n// This allows for a quick access to table at give row & column. For instance to access table cell \"13\" from pasted table call:\n//\n//\t\tconst cell = map[ 1 ][ 3 ]\n//\nfunction createLocationMap( table, width, height ) {\n\t// Create height x width (row x column) two-dimensional table to store cells.\n\tconst map = new Array( height ).fill( null )\n\t\t.map( () => new Array( width ).fill( null ) );\n\n\tfor ( const { column, row, cell } of new TableWalker( table ) ) {\n\t\tmap[ row ][ column ] = cell;\n\t}\n\n\treturn map;\n}\n\n// Make selected cells rectangular by splitting the cells that stand out from a rectangular selection.\n//\n// In the table below a selection is shown with \"::\" and slots with anchor cells are named.\n//\n// +----+----+----+----+----+ +----+----+----+----+----+\n// | 00 | 01 | 02 | 03 | | 00 | 01 | 02 | 03 |\n// + +----+ +----+----+ | ::::::::::::::::----+\n// | | 11 | | 13 | 14 | | ::11 | | 13:: 14 | <- first row\n// +----+----+ + +----+ +----::---| | ::----+\n// | 20 | 21 | | | 24 | select cells: | 20 ::21 | | :: 24 |\n// +----+----+ +----+----+ 11 -> 33 +----::---| |---::----+\n// | 30 | | 33 | 34 | | 30 :: | | 33:: 34 | <- last row\n// + + +----+ + | :::::::::::::::: +\n// | | | 43 | | | | | 43 | |\n// +----+----+----+----+----+ +----+----+----+----+----+\n// ^ ^\n// first & last columns\n//\n// Will update table to:\n//\n// +----+----+----+----+----+\n// | 00 | 01 | 02 | 03 |\n// + +----+----+----+----+\n// | | 11 | | 13 | 14 |\n// +----+----+ + +----+\n// | 20 | 21 | | | 24 |\n// +----+----+ +----+----+\n// | 30 | | | 33 | 34 |\n// + +----+----+----+ +\n// | | | | 43 | |\n// +----+----+----+----+----+\n//\n// In th example above:\n// - Cell \"02\" which have `rowspan = 4` must be trimmed at first and at after last row.\n// - Cell \"03\" which have `rowspan = 2` and `colspan = 2` must be trimmed at first column and after last row.\n// - Cells \"00\", \"03\" & \"30\" which cannot be cut by this algorithm as they are outside the trimmed area.\n// - Cell \"13\" cannot be cut as it is inside the trimmed area.\nfunction splitCellsToRectangularSelection( table, dimensions, writer ) {\n\tconst { firstRow, lastRow, firstColumn, lastColumn } = dimensions;\n\n\tconst rowIndexes = { first: firstRow, last: lastRow };\n\tconst columnIndexes = { first: firstColumn, last: lastColumn };\n\n\t// 1. Split cells vertically in two steps as first step might create cells that needs to split again.\n\tdoVerticalSplit( table, firstColumn, rowIndexes, writer );\n\tdoVerticalSplit( table, lastColumn + 1, rowIndexes, writer );\n\n\t// 2. Split cells horizontally in two steps as first step might create cells that needs to split again.\n\tdoHorizontalSplit( table, firstRow, columnIndexes, writer );\n\tdoHorizontalSplit( table, lastRow + 1, columnIndexes, writer, firstRow );\n}\n\nfunction doHorizontalSplit( table, splitRow, limitColumns, writer, startRow = 0 ) {\n\t// If selection starts at first row then no split is needed.\n\tif ( splitRow < 1 ) {\n\t\treturn;\n\t}\n\n\tconst overlappingCells = getVerticallyOverlappingCells( table, splitRow, startRow );\n\n\t// Filter out cells that are not touching insides of the rectangular selection.\n\tconst cellsToSplit = overlappingCells.filter( ( { column, cellWidth } ) => isAffectedBySelection( column, cellWidth, limitColumns ) );\n\n\treturn cellsToSplit.map( ( { cell } ) => splitHorizontally( cell, splitRow, writer ) );\n}\n\nfunction doVerticalSplit( table, splitColumn, limitRows, writer ) {\n\t// If selection starts at first column then no split is needed.\n\tif ( splitColumn < 1 ) {\n\t\treturn;\n\t}\n\n\tconst overlappingCells = getHorizontallyOverlappingCells( table, splitColumn );\n\n\t// Filter out cells that are not touching insides of the rectangular selection.\n\tconst cellsToSplit = overlappingCells.filter( ( { row, cellHeight } ) => isAffectedBySelection( row, cellHeight, limitRows ) );\n\n\treturn cellsToSplit.map( ( { cell, column } ) => splitVertically( cell, column, splitColumn, writer ) );\n}\n\n// Checks if cell at given row (column) is affected by a rectangular selection defined by first/last column (row).\n//\n// The same check is used for row as for column.\nfunction isAffectedBySelection( index, span, limit ) {\n\tconst endIndex = index + span - 1;\n\tconst { first, last } = limit;\n\n\tconst isInsideSelection = index >= first && index <= last;\n\tconst overlapsSelectionFromOutside = index < first && endIndex >= first;\n\n\treturn isInsideSelection || overlapsSelectionFromOutside;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport upcastTable, { ensureParagraphInTableCell, skipEmptyTableRow, upcastTableFigure } from './converters/upcasttable';\nimport {\n\tconvertParagraphInTableCell,\n\tdowncastInsertCell,\n\tdowncastInsertRow,\n\tdowncastInsertTable,\n\tdowncastRemoveRow,\n\tdowncastTableHeadingColumnsChange\n} from './converters/downcast';\n\nimport InsertTableCommand from './commands/inserttablecommand';\nimport InsertRowCommand from './commands/insertrowcommand';\nimport InsertColumnCommand from './commands/insertcolumncommand';\nimport SplitCellCommand from './commands/splitcellcommand';\nimport MergeCellCommand from './commands/mergecellcommand';\nimport RemoveRowCommand from './commands/removerowcommand';\nimport RemoveColumnCommand from './commands/removecolumncommand';\nimport SetHeaderRowCommand from './commands/setheaderrowcommand';\nimport SetHeaderColumnCommand from './commands/setheadercolumncommand';\nimport MergeCellsCommand from './commands/mergecellscommand';\nimport SelectRowCommand from './commands/selectrowcommand';\nimport SelectColumnCommand from './commands/selectcolumncommand';\nimport TableUtils from '../src/tableutils';\n\nimport injectTableLayoutPostFixer from './converters/table-layout-post-fixer';\nimport injectTableCellParagraphPostFixer from './converters/table-cell-paragraph-post-fixer';\nimport injectTableCellRefreshPostFixer from './converters/table-cell-refresh-post-fixer';\nimport injectTableHeadingRowsRefreshPostFixer from './converters/table-heading-rows-refresh-post-fixer';\n\nimport '../theme/tableediting.css';\n\n/**\n * The table editing feature.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst schema = model.schema;\n\t\tconst conversion = editor.conversion;\n\n\t\tschema.register( 'table', {\n\t\t\tallowWhere: '$block',\n\t\t\tallowAttributes: [ 'headingRows', 'headingColumns' ],\n\t\t\tisObject: true,\n\t\t\tisBlock: true\n\t\t} );\n\n\t\tschema.register( 'tableRow', {\n\t\t\tallowIn: 'table',\n\t\t\tisLimit: true\n\t\t} );\n\n\t\tschema.register( 'tableCell', {\n\t\t\tallowIn: 'tableRow',\n\t\t\tallowChildren: '$block',\n\t\t\tallowAttributes: [ 'colspan', 'rowspan' ],\n\t\t\tisLimit: true,\n\t\t\tisSelectable: true\n\t\t} );\n\n\t\t// Figure conversion.\n\t\tconversion.for( 'upcast' ).add( upcastTableFigure() );\n\n\t\t// Table conversion.\n\t\tconversion.for( 'upcast' ).add( upcastTable() );\n\n\t\tconversion.for( 'editingDowncast' ).add( downcastInsertTable( { asWidget: true } ) );\n\t\tconversion.for( 'dataDowncast' ).add( downcastInsertTable() );\n\n\t\t// Table row conversion.\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableRow', view: 'tr' } );\n\t\tconversion.for( 'upcast' ).add( skipEmptyTableRow() );\n\n\t\tconversion.for( 'editingDowncast' ).add( downcastInsertRow() );\n\t\tconversion.for( 'editingDowncast' ).add( downcastRemoveRow() );\n\n\t\t// Table cell conversion.\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableCell', view: 'td' } );\n\t\tconversion.for( 'upcast' ).elementToElement( { model: 'tableCell', view: 'th' } );\n\t\tconversion.for( 'upcast' ).add( ensureParagraphInTableCell( 'td' ) );\n\t\tconversion.for( 'upcast' ).add( ensureParagraphInTableCell( 'th' ) );\n\n\t\tconversion.for( 'editingDowncast' ).add( downcastInsertCell() );\n\n\t\t// Duplicates code - needed to properly refresh paragraph inside a table cell.\n\t\tconversion.for( 'editingDowncast' ).elementToElement( {\n\t\t\tmodel: 'paragraph',\n\t\t\tview: convertParagraphInTableCell,\n\t\t\tconverterPriority: 'high'\n\t\t} );\n\n\t\t// Table attributes conversion.\n\t\tconversion.for( 'downcast' ).attributeToAttribute( { model: 'colspan', view: 'colspan' } );\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tmodel: { key: 'colspan', value: upcastCellSpan( 'colspan' ) },\n\t\t\tview: 'colspan'\n\t\t} );\n\n\t\tconversion.for( 'downcast' ).attributeToAttribute( { model: 'rowspan', view: 'rowspan' } );\n\t\tconversion.for( 'upcast' ).attributeToAttribute( {\n\t\t\tmodel: { key: 'rowspan', value: upcastCellSpan( 'rowspan' ) },\n\t\t\tview: 'rowspan'\n\t\t} );\n\n\t\t// Table heading columns conversion (a change of heading rows requires a reconversion of the whole table).\n\t\tconversion.for( 'editingDowncast' ).add( downcastTableHeadingColumnsChange() );\n\n\t\t// Manually adjust model position mappings in a special case, when a table cell contains a paragraph, which is bound\n\t\t// to its parent (to the table cell). This custom model-to-view position mapping is necessary in data pipeline only,\n\t\t// because only during this conversion a paragraph can be bound to its parent.\n\t\teditor.data.mapper.on( 'modelToViewPosition', mapTableCellModelPositionToView() );\n\n\t\t// Define the config.\n\t\teditor.config.define( 'table.defaultHeadings.rows', 0 );\n\t\teditor.config.define( 'table.defaultHeadings.columns', 0 );\n\n\t\t// Define all the commands.\n\t\teditor.commands.add( 'insertTable', new InsertTableCommand( editor ) );\n\t\teditor.commands.add( 'insertTableRowAbove', new InsertRowCommand( editor, { order: 'above' } ) );\n\t\teditor.commands.add( 'insertTableRowBelow', new InsertRowCommand( editor, { order: 'below' } ) );\n\t\teditor.commands.add( 'insertTableColumnLeft', new InsertColumnCommand( editor, { order: 'left' } ) );\n\t\teditor.commands.add( 'insertTableColumnRight', new InsertColumnCommand( editor, { order: 'right' } ) );\n\n\t\teditor.commands.add( 'removeTableRow', new RemoveRowCommand( editor ) );\n\t\teditor.commands.add( 'removeTableColumn', new RemoveColumnCommand( editor ) );\n\n\t\teditor.commands.add( 'splitTableCellVertically', new SplitCellCommand( editor, { direction: 'vertically' } ) );\n\t\teditor.commands.add( 'splitTableCellHorizontally', new SplitCellCommand( editor, { direction: 'horizontally' } ) );\n\n\t\teditor.commands.add( 'mergeTableCells', new MergeCellsCommand( editor ) );\n\n\t\teditor.commands.add( 'mergeTableCellRight', new MergeCellCommand( editor, { direction: 'right' } ) );\n\t\teditor.commands.add( 'mergeTableCellLeft', new MergeCellCommand( editor, { direction: 'left' } ) );\n\t\teditor.commands.add( 'mergeTableCellDown', new MergeCellCommand( editor, { direction: 'down' } ) );\n\t\teditor.commands.add( 'mergeTableCellUp', new MergeCellCommand( editor, { direction: 'up' } ) );\n\n\t\teditor.commands.add( 'setTableColumnHeader', new SetHeaderColumnCommand( editor ) );\n\t\teditor.commands.add( 'setTableRowHeader', new SetHeaderRowCommand( editor ) );\n\n\t\teditor.commands.add( 'selectTableRow', new SelectRowCommand( editor ) );\n\t\teditor.commands.add( 'selectTableColumn', new SelectColumnCommand( editor ) );\n\n\t\tinjectTableHeadingRowsRefreshPostFixer( model );\n\t\tinjectTableLayoutPostFixer( model );\n\t\tinjectTableCellRefreshPostFixer( model, editor.editing.mapper );\n\t\tinjectTableCellParagraphPostFixer( model );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableUtils ];\n\t}\n}\n\n// Creates a mapper callback to adjust model position mappings in a table cell containing a paragraph, which is bound to its parent\n// (to the table cell). Only positions after this paragraph have to be adjusted, because after binding this paragraph to the table cell,\n// elements located after this paragraph would point either to a non-existent offset inside `tableCell` (if paragraph is empty), or after\n// the first character of the paragraph's text. See https://github.com/ckeditor/ckeditor5/issues/10116.\n//\n// <tableCell><paragraph></paragraph>^</tableCell> -> <td>^ </td>\n//\n// <tableCell><paragraph>foobar</paragraph>^</tableCell> -> <td>foobar^</td>\n//\n// @returns {Function}\nfunction mapTableCellModelPositionToView() {\n\treturn ( evt, data ) => {\n\t\tconst modelParent = data.modelPosition.parent;\n\t\tconst modelNodeBefore = data.modelPosition.nodeBefore;\n\n\t\tif ( !modelParent.is( 'element', 'tableCell' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !modelNodeBefore || !modelNodeBefore.is( 'element', 'paragraph' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewNodeBefore = data.mapper.toViewElement( modelNodeBefore );\n\t\tconst viewParent = data.mapper.toViewElement( modelParent );\n\n\t\tif ( viewNodeBefore === viewParent ) {\n\t\t\t// Since the paragraph has already been bound to its parent, update the current position in the model with paragraph's\n\t\t\t// max offset, so it points to the place which should normally (in all other cases) be the end position of this paragraph.\n\t\t\tdata.viewPosition = data.mapper.findPositionIn( viewParent, modelNodeBefore.maxOffset );\n\t\t}\n\t};\n}\n\n// Returns fixed colspan and rowspan attrbutes values.\n//\n// @private\n// @param {String} type colspan or rowspan.\n// @returns {Function} conversion value function.\nfunction upcastCellSpan( type ) {\n\treturn cell => {\n\t\tconst span = parseInt( cell.getAttribute( type ) );\n\n\t\tif ( Number.isNaN( span ) || span <= 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn span;\n\t};\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablekeyboard\n */\n\nimport TableSelection from './tableselection';\nimport TableWalker from './tablewalker';\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { getLocalizedArrowKeyCodeDirection } from 'ckeditor5/src/utils';\nimport { getSelectedTableCells, getTableCellsContainingSelection } from './utils/selection';\n\n/**\n * This plugin enables keyboard navigation for tables.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableKeyboard extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableKeyboard';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableSelection ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst view = this.editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t// Handle Tab key navigation.\n\t\tthis.editor.keystrokes.set( 'Tab', ( ...args ) => this._handleTabOnSelectedTable( ...args ), { priority: 'low' } );\n\t\tthis.editor.keystrokes.set( 'Tab', this._getTabHandler( true ), { priority: 'low' } );\n\t\tthis.editor.keystrokes.set( 'Shift+Tab', this._getTabHandler( false ), { priority: 'low' } );\n\n\t\tthis.listenTo( viewDocument, 'arrowKey', ( ...args ) => this._onArrowKey( ...args ), { context: 'table' } );\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events for the <kbd>Tab</kbd> key executed\n\t * when the table widget is selected.\n\t *\n\t * @private\n\t * @param {module:engine/view/observer/keyobserver~KeyEventData} data Key event data.\n\t * @param {Function} cancel The stop/stopPropagation/preventDefault function.\n\t */\n\t_handleTabOnSelectedTable( data, cancel ) {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\tif ( !selectedElement || !selectedElement.is( 'element', 'table' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcancel();\n\n\t\teditor.model.change( writer => {\n\t\t\twriter.setSelection( writer.createRangeIn( selectedElement.getChild( 0 ).getChild( 0 ) ) );\n\t\t} );\n\t}\n\n\t/**\n\t * Returns a handler for {@link module:engine/view/document~Document#event:keydown keydown} events for the <kbd>Tab</kbd> key executed\n\t * inside table cells.\n\t *\n\t * @private\n\t * @param {Boolean} isForward Whether this handler will move the selection to the next or the previous cell.\n\t */\n\t_getTabHandler( isForward ) {\n\t\tconst editor = this.editor;\n\n\t\treturn ( domEventData, cancel ) => {\n\t\t\tconst selection = editor.model.document.selection;\n\t\t\tlet tableCell = getTableCellsContainingSelection( selection )[ 0 ];\n\n\t\t\tif ( !tableCell ) {\n\t\t\t\ttableCell = this.editor.plugins.get( 'TableSelection' ).getFocusCell();\n\t\t\t}\n\n\t\t\tif ( !tableCell ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcancel();\n\n\t\t\tconst tableRow = tableCell.parent;\n\t\t\tconst table = tableRow.parent;\n\n\t\t\tconst currentRowIndex = table.getChildIndex( tableRow );\n\t\t\tconst currentCellIndex = tableRow.getChildIndex( tableCell );\n\n\t\t\tconst isFirstCellInRow = currentCellIndex === 0;\n\n\t\t\tif ( !isForward && isFirstCellInRow && currentRowIndex === 0 ) {\n\t\t\t\t// Set the selection over the whole table if the selection was in the first table cell.\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\twriter.setSelection( writer.createRangeOn( table ) );\n\t\t\t\t} );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\t\tconst isLastCellInRow = currentCellIndex === tableRow.childCount - 1;\n\t\t\tconst isLastRow = currentRowIndex === tableUtils.getRows( table ) - 1;\n\n\t\t\tif ( isForward && isLastRow && isLastCellInRow ) {\n\t\t\t\teditor.execute( 'insertTableRowBelow' );\n\n\t\t\t\t// Check if the command actually added a row. If `insertTableRowBelow` execution didn't add a row (because it was disabled\n\t\t\t\t// or it got overwritten) set the selection over the whole table to mirror the first cell case.\n\t\t\t\tif ( currentRowIndex === tableUtils.getRows( table ) - 1 ) {\n\t\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\t\twriter.setSelection( writer.createRangeOn( table ) );\n\t\t\t\t\t} );\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet cellToFocus;\n\n\t\t\t// Move to the first cell in the next row.\n\t\t\tif ( isForward && isLastCellInRow ) {\n\t\t\t\tconst nextRow = table.getChild( currentRowIndex + 1 );\n\n\t\t\t\tcellToFocus = nextRow.getChild( 0 );\n\t\t\t}\n\t\t\t// Move to the last cell in the previous row.\n\t\t\telse if ( !isForward && isFirstCellInRow ) {\n\t\t\t\tconst previousRow = table.getChild( currentRowIndex - 1 );\n\n\t\t\t\tcellToFocus = previousRow.getChild( previousRow.childCount - 1 );\n\t\t\t}\n\t\t\t// Move to the next/previous cell.\n\t\t\telse {\n\t\t\t\tcellToFocus = tableRow.getChild( currentCellIndex + ( isForward ? 1 : -1 ) );\n\t\t\t}\n\n\t\t\teditor.model.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeIn( cellToFocus ) );\n\t\t\t} );\n\t\t};\n\t}\n\n\t/**\n\t * Handles {@link module:engine/view/document~Document#event:keydown keydown} events.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} eventInfo\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t */\n\t_onArrowKey( eventInfo, domEventData ) {\n\t\tconst editor = this.editor;\n\t\tconst keyCode = domEventData.keyCode;\n\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( keyCode, editor.locale.contentLanguageDirection );\n\t\tconst wasHandled = this._handleArrowKeys( direction, domEventData.shiftKey );\n\n\t\tif ( wasHandled ) {\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Handles arrow keys to move the selection around the table.\n\t *\n\t * @private\n\t * @param {'left'|'up'|'right'|'down'} direction The direction of the arrow key.\n\t * @param {Boolean} expandSelection If the current selection should be expanded.\n\t * @returns {Boolean} Returns `true` if key was handled.\n\t */\n\t_handleArrowKeys( direction, expandSelection ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst isForward = [ 'right', 'down' ].includes( direction );\n\n\t\t// In case one or more table cells are selected (from outside),\n\t\t// move the selection to a cell adjacent to the selected table fragment.\n\t\tconst selectedCells = getSelectedTableCells( selection );\n\n\t\tif ( selectedCells.length ) {\n\t\t\tlet focusCell;\n\n\t\t\tif ( expandSelection ) {\n\t\t\t\tfocusCell = this.editor.plugins.get( 'TableSelection' ).getFocusCell();\n\t\t\t} else {\n\t\t\t\tfocusCell = isForward ? selectedCells[ selectedCells.length - 1 ] : selectedCells[ 0 ];\n\t\t\t}\n\n\t\t\tthis._navigateFromCellInDirection( focusCell, direction, expandSelection );\n\n\t\t\treturn true;\n\t\t}\n\n\t\t// Abort if we're not in a table cell.\n\t\tconst tableCell = selection.focus.findAncestor( 'tableCell' );\n\n\t\t/* istanbul ignore if: paranoid check */\n\t\tif ( !tableCell ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// When the selection is not collapsed.\n\t\tif ( !selection.isCollapsed ) {\n\t\t\tif ( expandSelection ) {\n\t\t\t\t// Navigation is in the opposite direction than the selection direction so this is shrinking of the selection.\n\t\t\t\t// Selection for sure will not approach cell edge.\n\t\t\t\t//\n\t\t\t\t// With a special case when all cell content is selected - then selection should expand to the other cell.\n\t\t\t\t// Note: When the entire cell gets selected using CTRL+A, the selection is always forward.\n\t\t\t\tif ( selection.isBackward == isForward && !selection.containsEntireContent( tableCell ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst selectedElement = selection.getSelectedElement();\n\n\t\t\t\t// It will collapse for non-object selected so it's not going to move to other cell.\n\t\t\t\tif ( !selectedElement || !model.schema.isObject( selectedElement ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Let's check if the selection is at the beginning/end of the cell.\n\t\tif ( this._isSelectionAtCellEdge( selection, tableCell, isForward ) ) {\n\t\t\tthis._navigateFromCellInDirection( tableCell, direction, expandSelection );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Returns `true` if the selection is at the boundary of a table cell according to the navigation direction.\n\t *\n\t * @private\n\t * @param {module:engine/model/selection~Selection} selection The current selection.\n\t * @param {module:engine/model/element~Element} tableCell The current table cell element.\n\t * @param {Boolean} isForward The expected navigation direction.\n\t * @returns {Boolean}\n\t */\n\t_isSelectionAtCellEdge( selection, tableCell, isForward ) {\n\t\tconst model = this.editor.model;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst focus = isForward ? selection.getLastPosition() : selection.getFirstPosition();\n\n\t\t// If the current limit element is not table cell we are for sure not at the cell edge.\n\t\t// Also `modifySelection` will not let us out of it.\n\t\tif ( !schema.getLimitElement( focus ).is( 'element', 'tableCell' ) ) {\n\t\t\tconst boundaryPosition = model.createPositionAt( tableCell, isForward ? 'end' : 0 );\n\n\t\t\treturn boundaryPosition.isTouching( focus );\n\t\t}\n\n\t\tconst probe = model.createSelection( focus );\n\n\t\tmodel.modifySelection( probe, { direction: isForward ? 'forward' : 'backward' } );\n\n\t\t// If there was no change in the focus position, then it's not possible to move the selection there.\n\t\treturn focus.isEqual( probe.focus );\n\t}\n\n\t/**\n\t * Moves the selection from the given table cell in the specified direction.\n\t *\n\t * @protected\n\t * @param {module:engine/model/element~Element} focusCell The table cell that is current multi-cell selection focus.\n\t * @param {'left'|'up'|'right'|'down'} direction Direction in which selection should move.\n\t * @param {Boolean} [expandSelection=false] If the current selection should be expanded.\n\t */\n\t_navigateFromCellInDirection( focusCell, direction, expandSelection = false ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst table = focusCell.findAncestor( 'table' );\n\t\tconst tableMap = [ ...new TableWalker( table, { includeAllSlots: true } ) ];\n\t\tconst { row: lastRow, column: lastColumn } = tableMap[ tableMap.length - 1 ];\n\n\t\tconst currentCellInfo = tableMap.find( ( { cell } ) => cell == focusCell );\n\t\tlet { row, column } = currentCellInfo;\n\n\t\tswitch ( direction ) {\n\t\t\tcase 'left':\n\t\t\t\tcolumn--;\n\t\t\t\tbreak;\n\n\t\t\tcase 'up':\n\t\t\t\trow--;\n\t\t\t\tbreak;\n\n\t\t\tcase 'right':\n\t\t\t\tcolumn += currentCellInfo.cellWidth;\n\t\t\t\tbreak;\n\n\t\t\tcase 'down':\n\t\t\t\trow += currentCellInfo.cellHeight;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tconst isOutsideVertically = row < 0 || row > lastRow;\n\t\tconst isBeforeFirstCell = column < 0 && row <= 0;\n\t\tconst isAfterLastCell = column > lastColumn && row >= lastRow;\n\n\t\t// Note that if the table cell at the end of a row is row-spanned then isAfterLastCell will never be true.\n\t\t// However, we don't know if user was navigating on the last row or not, so let's stay in the table.\n\n\t\tif ( isOutsideVertically || isBeforeFirstCell || isAfterLastCell ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( writer.createRangeOn( table ) );\n\t\t\t} );\n\n\t\t\treturn;\n\t\t}\n\n\t\tif ( column < 0 ) {\n\t\t\tcolumn = expandSelection ? 0 : lastColumn;\n\t\t\trow--;\n\t\t} else if ( column > lastColumn ) {\n\t\t\tcolumn = expandSelection ? lastColumn : 0;\n\t\t\trow++;\n\t\t}\n\n\t\tconst cellToSelect = tableMap.find( cellInfo => cellInfo.row == row && cellInfo.column == column ).cell;\n\t\tconst isForward = [ 'right', 'down' ].includes( direction );\n\t\tconst tableSelection = this.editor.plugins.get( 'TableSelection' );\n\n\t\tif ( expandSelection && tableSelection.isEnabled ) {\n\t\t\tconst anchorCell = tableSelection.getAnchorCell() || focusCell;\n\n\t\t\ttableSelection.setCellSelection( anchorCell, cellToSelect );\n\t\t} else {\n\t\t\tconst positionToSelect = model.createPositionAt( cellToSelect, isForward ? 0 : 'end' );\n\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.setSelection( positionToSelect );\n\t\t\t} );\n\t\t}\n\t}\n}\n\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablemouse\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport TableSelection from './tableselection';\nimport MouseEventsObserver from './tablemouse/mouseeventsobserver';\n\nimport { getTableCellsContainingSelection } from './utils/selection';\n\n/**\n * This plugin enables a table cells' selection with the mouse.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableMouse extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableMouse';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableSelection ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Currently the MouseObserver only handles `mousedown` and `mouseup` events.\n\t\t// TODO move to the engine?\n\t\teditor.editing.view.addObserver( MouseEventsObserver );\n\n\t\tthis._enableShiftClickSelection();\n\t\tthis._enableMouseDragSelection();\n\t}\n\n\t/**\n\t * Enables making cells selection by <kbd>Shift</kbd>+click. Creates a selection from the cell which previously held\n\t * the selection to the cell which was clicked. It can be the same cell, in which case it selects a single cell.\n\t *\n\t * @private\n\t */\n\t_enableShiftClickSelection() {\n\t\tconst editor = this.editor;\n\t\tlet blockSelectionChange = false;\n\n\t\tconst tableSelection = editor.plugins.get( TableSelection );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mousedown', ( evt, domEventData ) => {\n\t\t\tif ( !this.isEnabled || !tableSelection.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !domEventData.domEvent.shiftKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst anchorCell = tableSelection.getAnchorCell() || getTableCellsContainingSelection( editor.model.document.selection )[ 0 ];\n\n\t\t\tif ( !anchorCell ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst targetCell = this._getModelTableCellFromDomEvent( domEventData );\n\n\t\t\tif ( targetCell && haveSameTableParent( anchorCell, targetCell ) ) {\n\t\t\t\tblockSelectionChange = true;\n\t\t\t\ttableSelection.setCellSelection( anchorCell, targetCell );\n\n\t\t\t\tdomEventData.preventDefault();\n\t\t\t}\n\t\t} );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mouseup', () => {\n\t\t\tblockSelectionChange = false;\n\t\t} );\n\n\t\t// We need to ignore a `selectionChange` event that is fired after we render our new table cells selection.\n\t\t// When downcasting table cells selection to the view, we put the view selection in the last selected cell\n\t\t// in a place that may not be natively a \"correct\" location. This is – we put it directly in the `<td>` element.\n\t\t// All browsers fire the native `selectionchange` event.\n\t\t// However, all browsers except Safari return the selection in the exact place where we put it\n\t\t// (even though it's visually normalized). Safari returns `<td><p>^foo` that makes our selection observer\n\t\t// fire our `selectionChange` event (because the view selection that we set in the first step differs from the DOM selection).\n\t\t// Since `selectionChange` is fired, we automatically update the model selection that moves it that paragraph.\n\t\t// This breaks our dear cells selection.\n\t\t//\n\t\t// Theoretically this issue concerns only Safari that is the only browser that do normalize the selection.\n\t\t// However, to avoid code branching and to have a good coverage for this event blocker, I enabled it for all browsers.\n\t\t//\n\t\t// Note: I'm keeping the `blockSelectionChange` state separately for shift+click and mouse drag (exact same logic)\n\t\t// so I don't have to try to analyze whether they don't overlap in some weird cases. Probably they don't.\n\t\t// But I have other things to do, like writing this comment.\n\t\tthis.listenTo( editor.editing.view.document, 'selectionChange', evt => {\n\t\t\tif ( blockSelectionChange ) {\n\t\t\t\t// @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );\n\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Enables making cells selection by dragging.\n\t *\n\t * The selection is made only on mousemove. Mouse tracking is started on mousedown.\n\t * However, the cells selection is enabled only after the mouse cursor left the anchor cell.\n\t * Thanks to that normal text selection within one cell works just fine. However, you can still select\n\t * just one cell by leaving the anchor cell and moving back to it.\n\t *\n\t * @private\n\t */\n\t_enableMouseDragSelection() {\n\t\tconst editor = this.editor;\n\t\tlet anchorCell, targetCell;\n\t\tlet beganCellSelection = false;\n\t\tlet blockSelectionChange = false;\n\n\t\tconst tableSelection = editor.plugins.get( TableSelection );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mousedown', ( evt, domEventData ) => {\n\t\t\tif ( !this.isEnabled || !tableSelection.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Make sure to not conflict with the shift+click listener and any other possible handler.\n\t\t\tif ( domEventData.domEvent.shiftKey || domEventData.domEvent.ctrlKey || domEventData.domEvent.altKey ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tanchorCell = this._getModelTableCellFromDomEvent( domEventData );\n\t\t} );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mousemove', ( evt, domEventData ) => {\n\t\t\tif ( !domEventData.domEvent.buttons ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !anchorCell ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst newTargetCell = this._getModelTableCellFromDomEvent( domEventData );\n\n\t\t\tif ( newTargetCell && haveSameTableParent( anchorCell, newTargetCell ) ) {\n\t\t\t\ttargetCell = newTargetCell;\n\n\t\t\t\t// Switch to the cell selection mode after the mouse cursor left the anchor cell.\n\t\t\t\t// Switch off only on mouseup (makes selecting a single cell possible).\n\t\t\t\tif ( !beganCellSelection && targetCell != anchorCell ) {\n\t\t\t\t\tbeganCellSelection = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Yep, not making a cell selection yet. See method docs.\n\t\t\tif ( !beganCellSelection ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tblockSelectionChange = true;\n\t\t\ttableSelection.setCellSelection( anchorCell, targetCell );\n\n\t\t\tdomEventData.preventDefault();\n\t\t} );\n\n\t\tthis.listenTo( editor.editing.view.document, 'mouseup', () => {\n\t\t\tbeganCellSelection = false;\n\t\t\tblockSelectionChange = false;\n\t\t\tanchorCell = null;\n\t\t\ttargetCell = null;\n\t\t} );\n\n\t\t// See the explanation in `_enableShiftClickSelection()`.\n\t\tthis.listenTo( editor.editing.view.document, 'selectionChange', evt => {\n\t\t\tif ( blockSelectionChange ) {\n\t\t\t\t// @if CK_DEBUG // console.log( 'Blocked selectionChange to avoid breaking table cells selection.' );\n\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Returns the model table cell element based on the target element of the passed DOM event.\n\t *\n\t * @private\n\t * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData\n\t * @returns {module:engine/model/element~Element|undefined} Returns the table cell or `undefined`.\n\t */\n\t_getModelTableCellFromDomEvent( domEventData ) {\n\t\t// Note: Work with positions (not element mapping) because the target element can be an attribute or other non-mapped element.\n\t\tconst viewTargetElement = domEventData.target;\n\t\tconst viewPosition = this.editor.editing.view.createPositionAt( viewTargetElement, 0 );\n\t\tconst modelPosition = this.editor.editing.mapper.toModelPosition( viewPosition );\n\t\tconst modelElement = modelPosition.parent;\n\n\t\treturn modelElement.findAncestor( 'tableCell', { includeSelf: true } );\n\t}\n}\n\nfunction haveSameTableParent( cellA, cellB ) {\n\treturn cellA.parent.parent == cellB.parent.parent;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableselection/mouseeventsobserver\n */\n\nimport { DomEventObserver } from 'ckeditor5/src/engine';\n\n/**\n * The mouse selection event observer.\n *\n * It registers listeners for the following DOM events:\n *\n * - `'mousemove'`\n * - `'mouseup'`\n * - `'mouseleave'`\n *\n * Note that this observer is disabled by default. To enable this observer, it needs to be added to\n * {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * The observer is registered by the {@link module:table/tableselection~TableSelection} plugin.\n *\n * @extends module:engine/view/observer/domeventobserver~DomEventObserver\n */\nexport default class MouseEventsObserver extends DomEventObserver {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( view ) {\n\t\tsuper( view );\n\n\t\tthis.domEventType = [ 'mousemove', 'mouseleave' ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tonDomEvent( domEvent ) {\n\t\tthis.fire( domEvent.type, domEvent );\n\t}\n}\n\n/**\n * Fired when the mouse is moved over one of the editables.\n *\n * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.\n *\n * Note that this event is not available by default. To make it available,\n * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added\n * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:table/tableselection/mouseeventsobserver~MouseEventsObserver\n * @event module:engine/view/document~Document#event:mousemove\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n\n/**\n * Fired when the mouse is moved out of one of the editables.\n *\n * Introduced by {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver}.\n *\n * Note that this event is not available by default. To make it available,\n * {@link module:table/tableselection/mouseeventsobserver~MouseEventsObserver} needs to be added\n * to {@link module:engine/view/view~View} using the {@link module:engine/view/view~View#addObserver} method.\n *\n * @see module:table/tableselection/mouseeventsobserver~MouseEventsObserver\n * @event module:engine/view/document~Document#event:mouseleave\n * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.\n */\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport TablePropertiesEditing from './tableproperties/tablepropertiesediting';\nimport TablePropertiesUI from './tableproperties/tablepropertiesui';\n\n/**\n * The table properties feature. Enables support for setting properties of tables (size, border, background, etc.).\n *\n * Read more in the {@glink features/table#table-and-cell-styling-tools Table and cell styling tools} section.\n * See also the {@link module:table/tablecellproperties~TableCellProperties} plugin.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing table properties editing feature} and\n * the {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI table properties UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableProperties';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TablePropertiesEditing, TablePropertiesUI ];\n\t}\n}\n\n/**\n * The configuration of the table properties user interface (balloon). It allows to define:\n *\n * * The color palette for the table border color style field (`tableProperties.borderColors`),\n * * The color palette for the table background style field (`tableProperties.backgroundColors`).\n *\n *\t\tconst tableConfig = {\n *\t\t\ttableProperties: {\n *\t\t\t\tborderColors: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tcolor: 'hsl(0, 0%, 90%)',\n *\t\t\t\t\t\tlabel: 'Light grey'\n *\t\t\t\t\t},\n *\t\t\t\t\t// ...\n *\t\t\t\t],\n *\t\t\t\tbackgroundColors: [\n *\t\t\t\t\t{\n *\t\t\t\t\t\tcolor: 'hsl(120, 75%, 60%)',\n *\t\t\t\t\t\tlabel: 'Green'\n *\t\t\t\t\t},\n *\t\t\t\t\t// ...\n *\t\t\t\t]\n *\t\t\t}\n *\t\t};\n *\n * * The default styles for tables (`tableProperties.defaultProperties`):\n *\n *\t\tconst tableConfig = {\n *\t\t\ttableProperties: {\n *\t\t\t\tdefaultProperties: {\n *\t\t\t\t\tborderStyle: 'dashed',\n *\t\t\t\t\tborderColor: 'hsl(0, 0%, 90%)',\n *\t\t\t\t\tborderWidth: '3px',\n *\t\t\t\t\talignment: 'left'\n *\t\t\t\t}\n *\t\t\t}\n *\t\t}\n *\n * \t {@link module:table/tableproperties~TablePropertiesOptions Read more about the supported properties.}\n *\n * **Note**: The `borderColors` and `backgroundColors` options do not impact the data loaded into the editor,\n * i.e. they do not limit or filter the colors in the data. They are used only in the user interface\n * allowing users to pick colors in a more convenient way. The `defaultProperties` option does impact the data.\n * Default values will not be kept in the editor model.\n *\n * The default color palettes for the table background and the table border are the same\n * ({@link module:table/utils/ui/table-properties~defaultColors check out their content}).\n *\n * Both color palette configurations must follow the\n * {@link module:table/table~TableColorConfig table color configuration format}.\n *\n * Read more about configuring the table feature in {@link module:table/table~TableConfig}.\n *\n * @member {Object} module:table/table~TableConfig#tableProperties\n */\n\n/**\n * The configuration of the table default properties feature.\n *\n * @typedef {Object} module:table/tableproperties~TablePropertiesOptions\n *\n * @property {String} width The default `width` of the table.\n *\n * @property {String} height The default `height` of the table.\n *\n * @property {String} backgroundColor The default `background-color` of the table.\n *\n * @property {String} borderColor The default `border-color` of the table.\n *\n * @property {String} borderWidth The default `border-width` of the table.\n *\n * @property {String} [borderStyle='none'] The default `border-style` of the table.\n *\n * @property {String} [alignment='center'] The default `alignment` of the table.\n */\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablealignmentcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\n\n/**\n * The table alignment command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableAlignment'` editor command.\n *\n * To change the alignment of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableAlignment', {\n *\t\t\tvalue: 'right'\n *\t\t} );\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableAlignmentCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableAlignmentCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value for the \"alignment\" attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableAlignment', defaultValue );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablebackgroundcolorcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\n\n/**\n * The table background color command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBackgroundColor'` editor command.\n *\n * To change the background color of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableBackgroundColor', {\n *\t\t\tvalue: '#f00'\n *\t\t} );\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableBackgroundColorCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBackgroundColorCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableBackgroundColor', defaultValue );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablebordercolorcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\nimport { getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table border color command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderColor'` editor command.\n *\n * To change the border color of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableBorderColor', {\n *\t\t\tvalue: '#f00'\n *\t\t} );\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableBorderColorCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBorderColorCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableBorderColor', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValue( table ) {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( table.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tableborderstylecommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\nimport { getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table style border command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderStyle'` editor command.\n *\n * To change the border style of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableBorderStyle', {\n *\t\t\tvalue: 'dashed'\n *\t\t} );\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableBorderStyleCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBorderStyleCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableBorderStyle', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValue( table ) {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( table.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tableborderwidthcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\nimport { addDefaultUnitToNumericValue, getSingleValue } from '../../utils/table-properties';\n\n/**\n * The table width border command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableBorderWidth'` editor command.\n *\n * To change the border width of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableBorderWidth', {\n *\t\t\tvalue: '5px'\n *\t\t} );\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableBorderWidth', {\n *\t\t\tvalue: '5'\n *\t\t} );\n *\n * will set the `borderWidth` attribute to `'5px'` in the model.\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableBorderWidthCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableBorderWidthCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableBorderWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValue( table ) {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = getSingleValue( table.getAttribute( this.attributeName ) );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tableheightcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties';\n\n/**\n * The table height command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableHeight'` editor command.\n *\n * To change the height of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableHeight', {\n *\t\t\tvalue: '500px'\n *\t\t} );\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableHeight', {\n *\t\t\tvalue: '50'\n *\t\t} );\n *\n * will set the `height` attribute to `'50px'` in the model.\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableHeightCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableHeightCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableHeight', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablepropertycommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\n/**\n * The table cell attribute command.\n *\n * This command is a base command for other table property commands.\n *\n * @extends module:core/command~Command\n */\nexport default class TablePropertyCommand extends Command {\n\t/**\n\t * Creates a new `TablePropertyCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} attributeName Table cell attribute name.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, attributeName, defaultValue ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The attribute that will be set by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {String}\n\t\t */\n\t\tthis.attributeName = attributeName;\n\n\t\t/**\n\t\t * The default value for the attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {String}\n\t\t */\n\t\tthis._defaultValue = defaultValue;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst editor = this.editor;\n\t\tconst selection = editor.model.document.selection;\n\n\t\tconst table = selection.getFirstPosition().findAncestor( 'table' );\n\n\t\tthis.isEnabled = !!table;\n\t\tthis.value = this._getValue( table );\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {*} [options.value] If set, the command will set the attribute on the selected table.\n\t * If not set, the command will remove the attribute from the selected table.\n\t * @param {module:engine/model/batch~Batch} [options.batch] Pass the model batch instance to the command to aggregate changes,\n\t * for example, to allow a single undo step for multiple executions.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\n\t\tconst { value, batch } = options;\n\n\t\tconst table = selection.getFirstPosition().findAncestor( 'table' );\n\t\tconst valueToSet = this._getValueToSet( value );\n\n\t\tmodel.enqueueChange( batch, writer => {\n\t\t\tif ( valueToSet ) {\n\t\t\t\twriter.setAttribute( this.attributeName, valueToSet, table );\n\t\t\t} else {\n\t\t\t\twriter.removeAttribute( this.attributeName, table );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the attribute value for a table.\n\t *\n\t * @param {module:engine/model/element~Element} table\n\t * @returns {String|undefined}\n\t * @private\n\t */\n\t_getValue( table ) {\n\t\tif ( !table ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst value = table.getAttribute( this.attributeName );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n\n\t/**\n\t * Returns the proper model value. It can be used to add a default unit to numeric values.\n\t *\n\t * @private\n\t * @param {*} value\n\t * @returns {*}\n\t */\n\t_getValueToSet( value ) {\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/commands/tablewidthcommand\n */\n\nimport TablePropertyCommand from './tablepropertycommand';\nimport { addDefaultUnitToNumericValue } from '../../utils/table-properties';\n\n/**\n * The table width command.\n *\n * The command is registered by the {@link module:table/tableproperties/tablepropertiesediting~TablePropertiesEditing} as\n * the `'tableWidth'` editor command.\n *\n * To change the width of the selected table, execute the command:\n *\n *\t\teditor.execute( 'tableWidth', {\n *\t\t\tvalue: '400px'\n *\t\t} );\n *\n * **Note**: This command adds the default `'px'` unit to numeric values. Executing:\n *\n *\t\teditor.execute( 'tableWidth', {\n *\t\t\tvalue: '50'\n *\t\t} );\n *\n * will set the `width` attribute to `'50px'` in the model.\n *\n * @extends module:table/tableproperties/commands/tablepropertycommand~TablePropertyCommand\n */\nexport default class TableWidthCommand extends TablePropertyCommand {\n\t/**\n\t * Creates a new `TableWidthCommand` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor An editor in which this command will be used.\n\t * @param {String} defaultValue The default value of the attribute.\n\t */\n\tconstructor( editor, defaultValue ) {\n\t\tsuper( editor, 'tableWidth', defaultValue );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\t_getValueToSet( value ) {\n\t\tvalue = addDefaultUnitToNumericValue( value, 'px' );\n\n\t\tif ( value === this._defaultValue ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn value;\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/tablepropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { addBackgroundRules, addBorderRules } from 'ckeditor5/src/engine';\n\nimport TableEditing from '../tableediting';\nimport {\n\tdowncastAttributeToStyle,\n\tdowncastTableAttribute,\n\tupcastBorderStyles,\n\tupcastStyleToAttribute\n} from '../converters/tableproperties';\nimport TableBackgroundColorCommand from './commands/tablebackgroundcolorcommand';\nimport TableBorderColorCommand from './commands/tablebordercolorcommand';\nimport TableBorderStyleCommand from './commands/tableborderstylecommand';\nimport TableBorderWidthCommand from './commands/tableborderwidthcommand';\nimport TableWidthCommand from './commands/tablewidthcommand';\nimport TableHeightCommand from './commands/tableheightcommand';\nimport TableAlignmentCommand from './commands/tablealignmentcommand';\nimport { getNormalizedDefaultProperties } from '../utils/table-properties';\n\nconst ALIGN_VALUES_REG_EXP = /^(left|center|right)$/;\nconst FLOAT_VALUES_REG_EXP = /^(left|none|right)$/;\n\n/**\n * The table properties editing feature.\n *\n * Introduces table's model attributes and their conversion:\n *\n * - border: `tableBorderStyle`, `tableBorderColor` and `tableBorderWidth`\n * - background color: `tableBackgroundColor`\n * - horizontal alignment: `tableAlignment`\n * - width & height: `tableWidth` & `tableHeight`\n *\n * It also registers commands used to manipulate the above attributes:\n *\n * - border: `'tableBorderStyle'`, `'tableBorderColor'` and `'tableBorderWidth'` commands\n * - background color: `'tableBackgroundColor'`\n * - horizontal alignment: `'tableAlignment'`\n * - width & height: `'tableWidth'` & `'tableHeight'`\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TablePropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TablePropertiesEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst schema = editor.model.schema;\n\t\tconst conversion = editor.conversion;\n\n\t\teditor.config.define( 'table.tableProperties.defaultProperties', {} );\n\n\t\tconst defaultTableProperties = getNormalizedDefaultProperties( editor.config.get( 'table.tableProperties.defaultProperties' ), {\n\t\t\tincludeAlignmentProperty: true\n\t\t} );\n\n\t\teditor.data.addStyleProcessorRules( addBorderRules );\n\t\tenableBorderProperties( schema, conversion, {\n\t\t\tcolor: defaultTableProperties.borderColor,\n\t\t\tstyle: defaultTableProperties.borderStyle,\n\t\t\twidth: defaultTableProperties.borderWidth\n\t\t} );\n\t\teditor.commands.add( 'tableBorderColor', new TableBorderColorCommand( editor, defaultTableProperties.borderColor ) );\n\t\teditor.commands.add( 'tableBorderStyle', new TableBorderStyleCommand( editor, defaultTableProperties.borderStyle ) );\n\t\teditor.commands.add( 'tableBorderWidth', new TableBorderWidthCommand( editor, defaultTableProperties.borderWidth ) );\n\n\t\tenableAlignmentProperty( schema, conversion, defaultTableProperties.alignment );\n\t\teditor.commands.add( 'tableAlignment', new TableAlignmentCommand( editor, defaultTableProperties.alignment ) );\n\n\t\tenableTableToFigureProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableWidth',\n\t\t\tstyleName: 'width',\n\t\t\tdefaultValue: defaultTableProperties.width\n\t\t} );\n\t\teditor.commands.add( 'tableWidth', new TableWidthCommand( editor, defaultTableProperties.width ) );\n\n\t\tenableTableToFigureProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableHeight',\n\t\t\tstyleName: 'height',\n\t\t\tdefaultValue: defaultTableProperties.height\n\t\t} );\n\t\teditor.commands.add( 'tableHeight', new TableHeightCommand( editor, defaultTableProperties.height ) );\n\n\t\teditor.data.addStyleProcessorRules( addBackgroundRules );\n\t\tenableProperty( schema, conversion, {\n\t\t\tmodelAttribute: 'tableBackgroundColor',\n\t\t\tstyleName: 'background-color',\n\t\t\tdefaultValue: defaultTableProperties.backgroundColor\n\t\t} );\n\t\teditor.commands.add(\n\t\t\t'tableBackgroundColor',\n\t\t\tnew TableBackgroundColorCommand( editor, defaultTableProperties.backgroundColor )\n\t\t);\n\t}\n}\n\n// Enables `tableBorderStyle'`, `tableBorderColor'` and `tableBorderWidth'` attributes for table.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {Object} defaultBorder The default border values.\n// @param {String} defaultBorder.color The default `tableBorderColor` value.\n// @param {String} defaultBorder.style The default `tableBorderStyle` value.\n// @param {String} defaultBorder.width The default `tableBorderWidth` value.\nfunction enableBorderProperties( schema, conversion, defaultBorder ) {\n\tconst modelAttributes = {\n\t\twidth: 'tableBorderWidth',\n\t\tcolor: 'tableBorderColor',\n\t\tstyle: 'tableBorderStyle'\n\t};\n\n\tschema.extend( 'table', {\n\t\tallowAttributes: Object.values( modelAttributes )\n\t} );\n\n\tupcastBorderStyles( conversion, 'table', modelAttributes, defaultBorder );\n\n\tdowncastTableAttribute( conversion, { modelAttribute: modelAttributes.color, styleName: 'border-color' } );\n\tdowncastTableAttribute( conversion, { modelAttribute: modelAttributes.style, styleName: 'border-style' } );\n\tdowncastTableAttribute( conversion, { modelAttribute: modelAttributes.width, styleName: 'border-width' } );\n}\n\n// Enables the `'alignment'` attribute for table.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {String} defaultValue The default alignment value.\nfunction enableAlignmentProperty( schema, conversion, defaultValue ) {\n\tschema.extend( 'table', {\n\t\tallowAttributes: [ 'tableAlignment' ]\n\t} );\n\n\tconversion.for( 'downcast' )\n\t\t.attributeToAttribute( {\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tkey: 'tableAlignment'\n\t\t\t},\n\t\t\tview: alignment => ( {\n\t\t\t\tkey: 'style',\n\t\t\t\tvalue: {\n\t\t\t\t\t// Model: `alignment:center` => CSS: `float:none`.\n\t\t\t\t\tfloat: alignment === 'center' ? 'none' : alignment\n\t\t\t\t}\n\t\t\t} ),\n\t\t\tconverterPriority: 'high'\n\t\t} );\n\n\tconversion.for( 'upcast' )\n\t\t// Support for the `float:*;` CSS definition for the table alignment.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tname: /^(table|figure)$/,\n\t\t\t\tstyles: {\n\t\t\t\t\tfloat: FLOAT_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tkey: 'tableAlignment',\n\t\t\t\tvalue: viewElement => {\n\t\t\t\t\tlet align = viewElement.getStyle( 'float' );\n\n\t\t\t\t\t// CSS: `float:none` => Model: `alignment:center`.\n\t\t\t\t\tif ( align === 'none' ) {\n\t\t\t\t\t\talign = 'center';\n\t\t\t\t\t}\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} )\n\t\t// Support for the `align` attribute as the backward compatibility while pasting from other sources.\n\t\t.attributeToAttribute( {\n\t\t\tview: {\n\t\t\t\tattributes: {\n\t\t\t\t\talign: ALIGN_VALUES_REG_EXP\n\t\t\t\t}\n\t\t\t},\n\t\t\tmodel: {\n\t\t\t\tname: 'table',\n\t\t\t\tkey: 'tableAlignment',\n\t\t\t\tvalue: viewElement => {\n\t\t\t\t\tconst align = viewElement.getAttribute( 'align' );\n\n\t\t\t\t\treturn align === defaultValue ? null : align;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n}\n\n// Enables conversion for an attribute for simple view-model mappings.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {Object} options\n// @param {String} options.modelAttribute\n// @param {String} options.styleName\n// @param {String} options.defaultValue The default value for the specified `modelAttribute`.\nfunction enableProperty( schema, conversion, options ) {\n\tconst { modelAttribute } = options;\n\n\tschema.extend( 'table', {\n\t\tallowAttributes: [ modelAttribute ]\n\t} );\n\tupcastStyleToAttribute( conversion, { viewElement: 'table', ...options } );\n\tdowncastTableAttribute( conversion, options );\n}\n\n// Enables conversion for an attribute for simple view (figure) to model (table) mappings.\n//\n// @param {module:engine/model/schema~Schema} schema\n// @param {module:engine/conversion/conversion~Conversion} conversion\n// @param {Object} options\n// @param {String} options.modelAttribute\n// @param {String} options.styleName\nfunction enableTableToFigureProperty( schema, conversion, options ) {\n\tconst { modelAttribute } = options;\n\n\tschema.extend( 'table', {\n\t\tallowAttributes: [ modelAttribute ]\n\t} );\n\tupcastStyleToAttribute( conversion, { viewElement: /^(table|figure)$/, ...options } );\n\tdowncastAttributeToStyle( conversion, { modelElement: 'table', ...options } );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/tablepropertiesui\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { ButtonView, ContextualBalloon, clickOutsideHandler, getLocalizedColorOptions, normalizeColorOptions } from 'ckeditor5/src/ui';\n\nimport { debounce } from 'lodash-es';\n\nimport TablePropertiesView from './ui/tablepropertiesview';\nimport tableProperties from './../../theme/icons/table-properties.svg';\nimport {\n\tcolorFieldValidator,\n\tgetLocalizedColorErrorText,\n\tgetLocalizedLengthErrorText,\n\tlengthFieldValidator,\n\tlineWidthFieldValidator,\n\tdefaultColors\n} from '../utils/ui/table-properties';\nimport { getTableWidgetAncestor } from '../utils/ui/widget';\nimport { getBalloonTablePositionData, repositionContextualBalloon } from '../utils/ui/contextualballoon';\nimport { getNormalizedDefaultProperties } from '../utils/table-properties';\n\nconst ERROR_TEXT_TIMEOUT = 500;\n\n// Map of view properties and related commands.\nconst propertyToCommandMap = {\n\tborderStyle: 'tableBorderStyle',\n\tborderColor: 'tableBorderColor',\n\tborderWidth: 'tableBorderWidth',\n\tbackgroundColor: 'tableBackgroundColor',\n\twidth: 'tableWidth',\n\theight: 'tableHeight',\n\talignment: 'tableAlignment'\n};\n\n/**\n * The table properties UI plugin. It introduces the `'tableProperties'` button\n * that opens a form allowing to specify visual styling of an entire table.\n *\n * It uses the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon plugin}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TablePropertiesUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ContextualBalloon ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TablePropertiesUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'table.tableProperties', {\n\t\t\tborderColors: defaultColors,\n\t\t\tbackgroundColors: defaultColors\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\n\t\t/**\n\t\t * The default table properties.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:table/tableproperties~TablePropertiesOptions}\n\t\t */\n\t\tthis._defaultTableProperties = getNormalizedDefaultProperties( editor.config.get( 'table.tableProperties.defaultProperties' ), {\n\t\t\tincludeAlignmentProperty: true\n\t\t} );\n\n\t\t/**\n\t\t * The contextual balloon plugin instance.\n\t\t *\n\t\t * @private\n\t\t * @member {module:ui/panel/balloon/contextualballoon~ContextualBalloon}\n\t\t */\n\t\tthis._balloon = editor.plugins.get( ContextualBalloon );\n\n\t\t/**\n\t\t * The properties form view displayed inside the balloon.\n\t\t *\n\t\t * @member {module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}\n\t\t */\n\t\tthis.view = this._createPropertiesView();\n\n\t\t/**\n\t\t * The batch used to undo all changes made by the form (which are live, as the user types)\n\t\t * when \"Cancel\" was pressed. Each time the view is shown, a new batch is created.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:engine/model/batch~Batch}\n\t\t */\n\t\tthis._undoStepBatch = null;\n\n\t\teditor.ui.componentFactory.add( 'tableProperties', locale => {\n\t\t\tconst view = new ButtonView( locale );\n\n\t\t\tview.set( {\n\t\t\t\tlabel: t( 'Table properties' ),\n\t\t\t\ticon: tableProperties,\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tthis.listenTo( view, 'execute', () => this._showView() );\n\n\t\t\tconst commands = Object.values( propertyToCommandMap )\n\t\t\t\t.map( commandName => editor.commands.get( commandName ) );\n\n\t\t\tview.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => (\n\t\t\t\tareEnabled.some( isCommandEnabled => isCommandEnabled )\n\t\t\t) );\n\n\t\t\treturn view;\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\t// Destroy created UI components as they are not automatically destroyed.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1341.\n\t\tthis.view.destroy();\n\t}\n\n\t/**\n\t * Creates the {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} instance.\n\t *\n\t * @private\n\t * @returns {module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} The table\n\t * properties form view instance.\n\t */\n\t_createPropertiesView() {\n\t\tconst editor = this.editor;\n\t\tconst config = editor.config.get( 'table.tableProperties' );\n\t\tconst borderColorsConfig = normalizeColorOptions( config.borderColors );\n\t\tconst localizedBorderColors = getLocalizedColorOptions( editor.locale, borderColorsConfig );\n\t\tconst backgroundColorsConfig = normalizeColorOptions( config.backgroundColors );\n\t\tconst localizedBackgroundColors = getLocalizedColorOptions( editor.locale, backgroundColorsConfig );\n\n\t\tconst view = new TablePropertiesView( editor.locale, {\n\t\t\tborderColors: localizedBorderColors,\n\t\t\tbackgroundColors: localizedBackgroundColors,\n\t\t\tdefaultTableProperties: this._defaultTableProperties\n\t\t} );\n\t\tconst t = editor.t;\n\n\t\t// Render the view so its #element is available for the clickOutsideHandler.\n\t\tview.render();\n\n\t\tthis.listenTo( view, 'submit', () => {\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\tthis.listenTo( view, 'cancel', () => {\n\t\t\t// https://github.com/ckeditor/ckeditor5/issues/6180\n\t\t\tif ( this._undoStepBatch.operations.length ) {\n\t\t\t\teditor.execute( 'undo', this._undoStepBatch );\n\t\t\t}\n\n\t\t\tthis._hideView();\n\t\t} );\n\n\t\t// Close the balloon on Esc key press.\n\t\tview.keystrokes.set( 'Esc', ( data, cancel ) => {\n\t\t\tthis._hideView();\n\t\t\tcancel();\n\t\t} );\n\n\t\t// Close on click outside of balloon panel element.\n\t\tclickOutsideHandler( {\n\t\t\temitter: view,\n\t\t\tactivator: () => this._isViewInBalloon,\n\t\t\tcontextElements: [ this._balloon.view.element ],\n\t\t\tcallback: () => this._hideView()\n\t\t} );\n\n\t\tconst colorErrorText = getLocalizedColorErrorText( t );\n\t\tconst lengthErrorText = getLocalizedLengthErrorText( t );\n\n\t\t// Create the \"UI -> editor data\" binding.\n\t\t// These listeners update the editor data (via table commands) when any observable\n\t\t// property of the view has changed. They also validate the value and display errors in the UI\n\t\t// when necessary. This makes the view live, which means the changes are\n\t\t// visible in the editing as soon as the user types or changes fields' values.\n\t\tview.on(\n\t\t\t'change:borderStyle',\n\t\t\tthis._getPropertyChangeCallback( 'tableBorderStyle', this._defaultTableProperties.borderStyle )\n\t\t);\n\n\t\tview.on( 'change:borderColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderColorInput,\n\t\t\tcommandName: 'tableBorderColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator,\n\t\t\tdefaultValue: this._defaultTableProperties.borderColor\n\t\t} ) );\n\n\t\tview.on( 'change:borderWidth', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.borderWidthInput,\n\t\t\tcommandName: 'tableBorderWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lineWidthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableProperties.borderWidth\n\t\t} ) );\n\n\t\tview.on( 'change:backgroundColor', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.backgroundInput,\n\t\t\tcommandName: 'tableBackgroundColor',\n\t\t\terrorText: colorErrorText,\n\t\t\tvalidator: colorFieldValidator,\n\t\t\tdefaultValue: this._defaultTableProperties.backgroundColor\n\t\t} ) );\n\n\t\tview.on( 'change:width', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.widthInput,\n\t\t\tcommandName: 'tableWidth',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableProperties.width\n\t\t} ) );\n\n\t\tview.on( 'change:height', this._getValidatedPropertyChangeCallback( {\n\t\t\tviewField: view.heightInput,\n\t\t\tcommandName: 'tableHeight',\n\t\t\terrorText: lengthErrorText,\n\t\t\tvalidator: lengthFieldValidator,\n\t\t\tdefaultValue: this._defaultTableProperties.height\n\t\t} ) );\n\n\t\tview.on(\n\t\t\t'change:alignment',\n\t\t\tthis._getPropertyChangeCallback( 'tableAlignment', this._defaultTableProperties.alignment )\n\t\t);\n\n\t\treturn view;\n\t}\n\n\t/**\n\t * In this method the \"editor data -> UI\" binding is happening.\n\t *\n\t * When executed, this method obtains selected table property values from various table commands\n\t * and passes them to the {@link #view}.\n\t *\n\t * This way, the UI stays up–to–date with the editor data.\n\t *\n\t * @private\n\t */\n\t_fillViewFormFromCommandValues() {\n\t\tconst commands = this.editor.commands;\n\t\tconst borderStyleCommand = commands.get( 'tableBorderStyle' );\n\n\t\tObject.entries( propertyToCommandMap )\n\t\t\t.map( ( [ property, commandName ] ) => {\n\t\t\t\tconst defaultValue = this._defaultTableProperties[ property ] || '';\n\n\t\t\t\treturn [ property, commands.get( commandName ).value || defaultValue ];\n\t\t\t} )\n\t\t\t.forEach( ( [ property, value ] ) => {\n\t\t\t\t// Do not set the `border-color` and `border-width` fields if `border-style:none`.\n\t\t\t\tif ( ( property === 'borderColor' || property === 'borderWidth' ) && borderStyleCommand.value === 'none' ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.view.set( property, value );\n\t\t\t} );\n\t}\n\n\t/**\n\t * Shows the {@link #view} in the {@link #_balloon}.\n\t *\n\t * **Note**: Each time a view is shown, the new {@link #_undoStepBatch} is created that contains\n\t * all changes made to the document when the view is visible, allowing a single undo step\n\t * for all of them.\n\t *\n\t * @protected\n\t */\n\t_showView() {\n\t\tconst editor = this.editor;\n\n\t\tthis.listenTo( editor.ui, 'update', () => {\n\t\t\tthis._updateView();\n\t\t} );\n\n\t\t// Update the view with the model values.\n\t\tthis._fillViewFormFromCommandValues();\n\n\t\tthis._balloon.add( {\n\t\t\tview: this.view,\n\t\t\tposition: getBalloonTablePositionData( editor )\n\t\t} );\n\n\t\t// Create a new batch. Clicking \"Cancel\" will undo this batch.\n\t\tthis._undoStepBatch = editor.model.createBatch();\n\n\t\t// Basic a11y.\n\t\tthis.view.focus();\n\t}\n\n\t/**\n\t * Removes the {@link #view} from the {@link #_balloon}.\n\t *\n\t * @protected\n\t */\n\t_hideView() {\n\t\tconst editor = this.editor;\n\n\t\tthis.stopListening( editor.ui, 'update' );\n\n\t\t// Blur any input element before removing it from DOM to prevent issues in some browsers.\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/1501.\n\t\tthis.view.saveButtonView.focus();\n\n\t\tthis._balloon.remove( this.view );\n\n\t\t// Make sure the focus is not lost in the process by putting it directly\n\t\t// into the editing view.\n\t\tthis.editor.editing.view.focus();\n\t}\n\n\t/**\n\t * Repositions the {@link #_balloon} or hides the {@link #view} if a table is no longer selected.\n\t *\n\t * @protected\n\t */\n\t_updateView() {\n\t\tconst editor = this.editor;\n\t\tconst viewDocument = editor.editing.view.document;\n\n\t\tif ( !getTableWidgetAncestor( viewDocument.selection ) ) {\n\t\t\tthis._hideView();\n\t\t} else if ( this._isViewVisible ) {\n\t\t\trepositionContextualBalloon( editor, 'table' );\n\t\t}\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is the visible in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isViewVisible() {\n\t\treturn this._balloon.visibleView === this.view;\n\t}\n\n\t/**\n\t * Returns `true` when the {@link #view} is in the {@link #_balloon}.\n\t *\n\t * @private\n\t * @type {Boolean}\n\t */\n\tget _isViewInBalloon() {\n\t\treturn this._balloon.hasView( this.view );\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon {@link #view view's} property change\n\t * executes a related editor command with the new property value.\n\t *\n\t * If new value will be set to the default value, the command will not be executed.\n\t *\n\t * @private\n\t * @param {String} commandName The command that will be executed.\n\t * @param {String} defaultValue The default value of the command.\n\t * @returns {Function}\n\t */\n\t_getPropertyChangeCallback( commandName, defaultValue ) {\n\t\treturn ( evt, propertyName, newValue, oldValue ) => {\n\t\t\t// If the \"oldValue\" is missing and \"newValue\" is set to the default value, do not execute the command.\n\t\t\t// It is an initial call (when opening the table properties view).\n\t\t\tif ( !oldValue && defaultValue === newValue ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( commandName, {\n\t\t\t\tvalue: newValue,\n\t\t\t\tbatch: this._undoStepBatch\n\t\t\t} );\n\t\t};\n\t}\n\n\t/**\n\t * Creates a callback that when executed upon {@link #view view's} property change:\n\t * * executes a related editor command with the new property value if the value is valid,\n\t * * or sets the error text next to the invalid field, if the value did not pass the validation.\n\t *\n\t * @private\n\t * @param {Object} options\n\t * @param {String} options.commandName\n\t * @param {module:ui/view~View} options.viewField\n\t * @param {Function} options.validator\n\t * @param {String} options.errorText\n\t * @param {String} options.defaultValue\n\t * @returns {Function}\n\t */\n\t_getValidatedPropertyChangeCallback( options ) {\n\t\tconst { commandName, viewField, validator, errorText, defaultValue } = options;\n\t\tconst setErrorTextDebounced = debounce( () => {\n\t\t\tviewField.errorText = errorText;\n\t\t}, ERROR_TEXT_TIMEOUT );\n\n\t\treturn ( evt, propertyName, newValue, oldValue ) => {\n\t\t\tsetErrorTextDebounced.cancel();\n\n\t\t\t// If the \"oldValue\" is missing and \"newValue\" is set to the default value, do not execute the command.\n\t\t\t// It is an initial call (when opening the table properties view).\n\t\t\tif ( !oldValue && defaultValue === newValue ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( validator( newValue ) ) {\n\t\t\t\tthis.editor.execute( commandName, {\n\t\t\t\t\tvalue: newValue,\n\t\t\t\t\tbatch: this._undoStepBatch\n\t\t\t\t} );\n\n\t\t\t\tviewField.errorText = null;\n\t\t\t} else {\n\t\t\t\tsetErrorTextDebounced();\n\t\t\t}\n\t\t};\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableproperties/ui/tablepropertiesview\n */\n\nimport {\n\tButtonView,\n\tFocusCycler,\n\tFormHeaderView,\n\tLabelView,\n\tLabeledFieldView,\n\tToolbarView,\n\tView,\n\tViewCollection,\n\taddListToDropdown,\n\tcreateLabeledDropdown,\n\tcreateLabeledInputText,\n\tsubmitHandler\n} from 'ckeditor5/src/ui';\nimport { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';\nimport { icons } from 'ckeditor5/src/core';\n\nimport {\n\tfillToolbar,\n\tgetBorderStyleDefinitions,\n\tgetBorderStyleLabels,\n\tgetLabeledColorInputCreator\n} from '../../utils/ui/table-properties';\nimport FormRowView from '../../ui/formrowview';\n\nimport '../../../theme/form.css';\nimport '../../../theme/tableform.css';\nimport '../../../theme/tableproperties.css';\n\nconst ALIGNMENT_ICONS = {\n\tleft: icons.objectLeft,\n\tcenter: icons.objectCenter,\n\tright: icons.objectRight\n};\n\n/**\n * The class representing a table properties form, allowing users to customize\n * certain style aspects of a table, for instance, border, background color, alignment, etc..\n *\n * @extends module:ui/view~View\n */\nexport default class TablePropertiesView extends View {\n\t/**\n\t * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param {Object} options Additional configuration of the view.\n\t * @param {module:table/table~TableColorConfig} options.borderColors A configuration of the border\n\t * color palette used by the\n\t * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#borderColorInput}.\n\t * @param {module:table/table~TableColorConfig} options.backgroundColors A configuration of the background\n\t * color palette used by the\n\t * {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView#backgroundInput}.\n\t * @param {module:table/tableproperties~TablePropertiesOptions} options.defaultTableProperties The default table properties.\n\t */\n\tconstructor( locale, options ) {\n\t\tsuper( locale );\n\n\t\tthis.set( {\n\t\t\t/**\n\t\t\t * The value of the border style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #borderStyle\n\t\t\t */\n\t\t\tborderStyle: '',\n\n\t\t\t/**\n\t\t\t * The value of the border width style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #borderWidth\n\t\t\t */\n\t\t\tborderWidth: '',\n\n\t\t\t/**\n\t\t\t * The value of the border color style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #borderColor\n\t\t\t */\n\t\t\tborderColor: '',\n\n\t\t\t/**\n\t\t\t * The value of the background color style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #backgroundColor\n\t\t\t */\n\t\t\tbackgroundColor: '',\n\n\t\t\t/**\n\t\t\t * The value of the table width style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #width\n\t\t\t */\n\t\t\twidth: '',\n\n\t\t\t/**\n\t\t\t * The value of the table height style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #height\n\t\t\t */\n\t\t\theight: '',\n\n\t\t\t/**\n\t\t\t * The value of the table alignment style.\n\t\t\t *\n\t\t\t * @observable\n\t\t\t * @default ''\n\t\t\t * @member #alignment\n\t\t\t */\n\t\t\talignment: ''\n\t\t} );\n\n\t\t/**\n\t\t * Options passed to the view. See {@link #constructor} to learn more.\n\t\t *\n\t\t * @protected\n\t\t * @member {Object}\n\t\t */\n\t\tthis.options = options;\n\n\t\tconst { borderStyleDropdown, borderWidthInput, borderColorInput, borderRowLabel } = this._createBorderFields();\n\t\tconst { backgroundRowLabel, backgroundInput } = this._createBackgroundFields();\n\t\tconst { widthInput, operatorLabel, heightInput, dimensionsLabel } = this._createDimensionFields();\n\t\tconst { alignmentToolbar, alignmentLabel } = this._createAlignmentFields();\n\n\t\t/**\n\t\t * Tracks information about the DOM focus in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/focustracker~FocusTracker}\n\t\t */\n\t\tthis.focusTracker = new FocusTracker();\n\n\t\t/**\n\t\t * An instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/keystrokehandler~KeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new KeystrokeHandler();\n\n\t\t/**\n\t\t * A collection of child views in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\t/**\n\t\t * A dropdown that allows selecting the style of the table border.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/dropdown/dropdownview~DropdownView}\n\t\t */\n\t\tthis.borderStyleDropdown = borderStyleDropdown;\n\n\t\t/**\n\t\t * An input that allows specifying the width of the table border.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.borderWidthInput = borderWidthInput;\n\n\t\t/**\n\t\t * An input that allows specifying the color of the table border.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:table/ui/colorinputview~ColorInputView}\n\t\t */\n\t\tthis.borderColorInput = borderColorInput;\n\n\t\t/**\n\t\t * An input that allows specifying the table background color.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:table/ui/colorinputview~ColorInputView}\n\t\t */\n\t\tthis.backgroundInput = backgroundInput;\n\n\t\t/**\n\t\t * An input that allows specifying the table width.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.widthInput = widthInput;\n\n\t\t/**\n\t\t * An input that allows specifying the table height.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis.heightInput = heightInput;\n\n\t\t/**\n\t\t * A toolbar with buttons that allow changing the alignment of an entire table.\n\t\t * @readonly\n\t\t * @member {module:ui/toolbar/toolbar~ToolbarView}\n\t\t */\n\t\tthis.alignmentToolbar = alignmentToolbar;\n\n\t\t// Defer creating to make sure other fields are present and the Save button can\n\t\t// bind its #isEnabled to their error messages so there's no way to save unless all\n\t\t// fields are valid.\n\t\tconst { saveButtonView, cancelButtonView } = this._createActionButtons();\n\n\t\t/**\n\t\t * The \"Save\" button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.saveButtonView = saveButtonView;\n\n\t\t/**\n\t\t * The \"Cancel\" button view.\n\t\t *\n\t\t * @member {module:ui/button/buttonview~ButtonView}\n\t\t */\n\t\tthis.cancelButtonView = cancelButtonView;\n\n\t\t/**\n\t\t * A collection of views that can be focused in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis._focusables = new ViewCollection();\n\n\t\t/**\n\t\t * Helps cycling over {@link #_focusables} in the form.\n\t\t *\n\t\t * @readonly\n\t\t * @protected\n\t\t * @member {module:ui/focuscycler~FocusCycler}\n\t\t */\n\t\tthis._focusCycler = new FocusCycler( {\n\t\t\tfocusables: this._focusables,\n\t\t\tfocusTracker: this.focusTracker,\n\t\t\tkeystrokeHandler: this.keystrokes,\n\t\t\tactions: {\n\t\t\t\t// Navigate form fields backwards using the Shift + Tab keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate form fields forwards using the Tab key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// Form header.\n\t\tthis.children.add( new FormHeaderView( locale, {\n\t\t\tlabel: this.t( 'Table properties' )\n\t\t} ) );\n\n\t\t// Border row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: borderRowLabel,\n\t\t\tchildren: [\n\t\t\t\tborderRowLabel,\n\t\t\t\tborderStyleDropdown,\n\t\t\t\tborderColorInput,\n\t\t\t\tborderWidthInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__border-row'\n\t\t} ) );\n\n\t\t// Background row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tlabelView: backgroundRowLabel,\n\t\t\tchildren: [\n\t\t\t\tbackgroundRowLabel,\n\t\t\t\tbackgroundInput\n\t\t\t],\n\t\t\tclass: 'ck-table-form__background-row'\n\t\t} ) );\n\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\t// Dimensions row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tlabelView: dimensionsLabel,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\tdimensionsLabel,\n\t\t\t\t\t\twidthInput,\n\t\t\t\t\t\toperatorLabel,\n\t\t\t\t\t\theightInput\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-form__dimensions-row'\n\t\t\t\t} ),\n\t\t\t\t// Alignment row.\n\t\t\t\tnew FormRowView( locale, {\n\t\t\t\t\tlabelView: alignmentLabel,\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\talignmentLabel,\n\t\t\t\t\t\talignmentToolbar\n\t\t\t\t\t],\n\t\t\t\t\tclass: 'ck-table-properties-form__alignment-row'\n\t\t\t\t} )\n\t\t\t]\n\t\t} ) );\n\n\t\t// Action row.\n\t\tthis.children.add( new FormRowView( locale, {\n\t\t\tchildren: [\n\t\t\t\tthis.saveButtonView,\n\t\t\t\tthis.cancelButtonView\n\t\t\t],\n\t\t\tclass: 'ck-table-form__action-row'\n\t\t} ) );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'form',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form',\n\t\t\t\t\t'ck-table-form',\n\t\t\t\t\t'ck-table-properties-form'\n\t\t\t\t],\n\t\t\t\t// https://github.com/ckeditor/ckeditor5-link/issues/90\n\t\t\t\ttabindex: '-1'\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\t// Enable the \"submit\" event for this view. It can be triggered by the #saveButtonView\n\t\t// which is of the \"submit\" DOM \"type\".\n\t\tsubmitHandler( {\n\t\t\tview: this\n\t\t} );\n\n\t\t[\n\t\t\tthis.borderStyleDropdown,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.widthInput,\n\t\t\tthis.heightInput,\n\t\t\tthis.alignmentToolbar,\n\t\t\tthis.saveButtonView,\n\t\t\tthis.cancelButtonView\n\t\t].forEach( view => {\n\t\t\t// Register the view as focusable.\n\t\t\tthis._focusables.add( view );\n\n\t\t\t// Register the view in the focus tracker.\n\t\t\tthis.focusTracker.add( view.element );\n\t\t} );\n\n\t\t// Mainly for closing using \"Esc\" and navigation using \"Tab\".\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tsuper.destroy();\n\n\t\tthis.focusTracker.destroy();\n\t\tthis.keystrokes.destroy();\n\t}\n\n\t/**\n\t * Focuses the fist focusable field in the form.\n\t */\n\tfocus() {\n\t\tthis._focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #borderStyleDropdown},\n\t * * {@link #borderWidthInput},\n\t * * {@link #borderColorInput}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createBorderFields() {\n\t\tconst defaultTableProperties = this.options.defaultTableProperties;\n\t\tconst defaultBorder = {\n\t\t\tstyle: defaultTableProperties.borderStyle,\n\t\t\twidth: defaultTableProperties.borderWidth,\n\t\t\tcolor: defaultTableProperties.borderColor\n\t\t};\n\n\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.borderColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: defaultBorder.color\n\t\t} );\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst borderRowLabel = new LabelView( locale );\n\t\tborderRowLabel.text = t( 'Border' );\n\n\t\t// -- Style ---------------------------------------------------\n\n\t\tconst styleLabels = getBorderStyleLabels( this.t );\n\t\tconst borderStyleDropdown = new LabeledFieldView( locale, createLabeledDropdown );\n\t\tborderStyleDropdown.set( {\n\t\t\tlabel: t( 'Style' ),\n\t\t\tclass: 'ck-table-form__border-style'\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.set( {\n\t\t\tisOn: false,\n\t\t\twithText: true,\n\t\t\ttooltip: t( 'Style' )\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.buttonView.bind( 'label' ).to( this, 'borderStyle', value => {\n\t\t\treturn styleLabels[ value ? value : 'none' ];\n\t\t} );\n\n\t\tborderStyleDropdown.fieldView.on( 'execute', evt => {\n\t\t\tthis.borderStyle = evt.source._borderStyleValue;\n\t\t} );\n\n\t\tborderStyleDropdown.bind( 'isEmpty' ).to( this, 'borderStyle', value => !value );\n\n\t\taddListToDropdown( borderStyleDropdown.fieldView, getBorderStyleDefinitions( this, defaultBorder.style ) );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst borderWidthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\tborderWidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__border-width'\n\t\t} );\n\n\t\tborderWidthInput.fieldView.bind( 'value' ).to( this, 'borderWidth' );\n\t\tborderWidthInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\t\tborderWidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderWidth = borderWidthInput.fieldView.element.value;\n\t\t} );\n\n\t\t// -- Color ---------------------------------------------------\n\n\t\tconst borderColorInput = new LabeledFieldView( locale, colorInputCreator );\n\n\t\tborderColorInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-form__border-color'\n\t\t} );\n\n\t\tborderColorInput.fieldView.bind( 'value' ).to( this, 'borderColor' );\n\t\tborderColorInput.bind( 'isEnabled' ).to( this, 'borderStyle', isBorderStyleSet );\n\n\t\tborderColorInput.fieldView.on( 'input', () => {\n\t\t\tthis.borderColor = borderColorInput.fieldView.value;\n\t\t} );\n\n\t\t// Reset the border color and width fields depending on the `border-style` value.\n\t\tthis.on( 'change:borderStyle', ( evt, name, newValue, oldValue ) => {\n\t\t\t// When removing the border (`border-style:none`), clear the remaining `border-*` properties.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/6227.\n\t\t\tif ( !isBorderStyleSet( newValue ) ) {\n\t\t\t\tthis.borderColor = '';\n\t\t\t\tthis.borderWidth = '';\n\t\t\t}\n\n\t\t\t// When setting the `border-style` from `none`, set the default `border-color` and `border-width` properties.\n\t\t\tif ( !isBorderStyleSet( oldValue ) ) {\n\t\t\t\tthis.borderColor = defaultBorder.color;\n\t\t\t\tthis.borderWidth = defaultBorder.width;\n\t\t\t}\n\t\t} );\n\n\t\treturn {\n\t\t\tborderRowLabel,\n\t\t\tborderStyleDropdown,\n\t\t\tborderColorInput,\n\t\t\tborderWidthInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #backgroundInput}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createBackgroundFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Group label ---------------------------------------------\n\n\t\tconst backgroundRowLabel = new LabelView( locale );\n\t\tbackgroundRowLabel.text = t( 'Background' );\n\n\t\t// -- Background color input -----------------------------------\n\n\t\tconst backgroundInputCreator = getLabeledColorInputCreator( {\n\t\t\tcolorConfig: this.options.backgroundColors,\n\t\t\tcolumns: 5,\n\t\t\tdefaultColorValue: this.options.defaultTableProperties.backgroundColor\n\t\t} );\n\n\t\tconst backgroundInput = new LabeledFieldView( locale, backgroundInputCreator );\n\n\t\tbackgroundInput.set( {\n\t\t\tlabel: t( 'Color' ),\n\t\t\tclass: 'ck-table-properties-form__background'\n\t\t} );\n\n\t\tbackgroundInput.fieldView.bind( 'value' ).to( this, 'backgroundColor' );\n\t\tbackgroundInput.fieldView.on( 'input', () => {\n\t\t\tthis.backgroundColor = backgroundInput.fieldView.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tbackgroundRowLabel,\n\t\t\tbackgroundInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #widthInput}.\n\t * * {@link #heightInput}.\n\t *\n\t * @private\n\t * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n\t */\n\t_createDimensionFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Label ---------------------------------------------------\n\n\t\tconst dimensionsLabel = new LabelView( locale );\n\t\tdimensionsLabel.text = t( 'Dimensions' );\n\n\t\t// -- Width ---------------------------------------------------\n\n\t\tconst widthInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\twidthInput.set( {\n\t\t\tlabel: t( 'Width' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__width'\n\t\t} );\n\n\t\twidthInput.fieldView.bind( 'value' ).to( this, 'width' );\n\t\twidthInput.fieldView.on( 'input', () => {\n\t\t\tthis.width = widthInput.fieldView.element.value;\n\t\t} );\n\n\t\t// -- Operator ---------------------------------------------------\n\n\t\tconst operatorLabel = new View( locale );\n\t\toperatorLabel.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-table-form__dimension-operator'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\t{ text: '×' }\n\t\t\t]\n\t\t} );\n\n\t\t// -- Height ---------------------------------------------------\n\n\t\tconst heightInput = new LabeledFieldView( locale, createLabeledInputText );\n\n\t\theightInput.set( {\n\t\t\tlabel: t( 'Height' ),\n\t\t\tclass: 'ck-table-form__dimensions-row__height'\n\t\t} );\n\n\t\theightInput.fieldView.bind( 'value' ).to( this, 'height' );\n\t\theightInput.fieldView.on( 'input', () => {\n\t\t\tthis.height = heightInput.fieldView.element.value;\n\t\t} );\n\n\t\treturn {\n\t\t\tdimensionsLabel,\n\t\t\twidthInput,\n\t\t\toperatorLabel,\n\t\t\theightInput\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form fields:\n\t *\n\t * * {@link #alignmentToolbar},\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createAlignmentFields() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\t// -- Label ---------------------------------------------------\n\n\t\tconst alignmentLabel = new LabelView( locale );\n\t\talignmentLabel.text = t( 'Alignment' );\n\n\t\t// -- Toolbar ---------------------------------------------------\n\n\t\tconst alignmentToolbar = new ToolbarView( locale );\n\t\talignmentToolbar.set( {\n\t\t\tisCompact: true,\n\t\t\tariaLabel: t( 'Table alignment toolbar' )\n\t\t} );\n\n\t\tfillToolbar( {\n\t\t\tview: this,\n\t\t\ticons: ALIGNMENT_ICONS,\n\t\t\ttoolbar: alignmentToolbar,\n\t\t\tlabels: this._alignmentLabels,\n\t\t\tpropertyName: 'alignment',\n\t\t\tdefaultValue: this.options.defaultTableProperties.alignment\n\t\t} );\n\n\t\treturn {\n\t\t\talignmentLabel,\n\t\t\talignmentToolbar\n\t\t};\n\t}\n\n\t/**\n\t * Creates the following form controls:\n\t *\n\t * * {@link #saveButtonView},\n\t * * {@link #cancelButtonView}.\n\t *\n\t * @private\n\t * @returns {Object.<String,module:ui/view~View>}\n\t */\n\t_createActionButtons() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\tconst saveButtonView = new ButtonView( locale );\n\t\tconst cancelButtonView = new ButtonView( locale );\n\t\tconst fieldsThatShouldValidateToSave = [\n\t\t\tthis.borderWidthInput,\n\t\t\tthis.borderColorInput,\n\t\t\tthis.backgroundInput,\n\t\t\tthis.widthInput,\n\t\t\tthis.heightInput\n\t\t];\n\n\t\tsaveButtonView.set( {\n\t\t\tlabel: t( 'Save' ),\n\t\t\ticon: icons.check,\n\t\t\tclass: 'ck-button-save',\n\t\t\ttype: 'submit',\n\t\t\twithText: true\n\t\t} );\n\n\t\tsaveButtonView.bind( 'isEnabled' ).toMany( fieldsThatShouldValidateToSave, 'errorText', ( ...errorTexts ) => {\n\t\t\treturn errorTexts.every( errorText => !errorText );\n\t\t} );\n\n\t\tcancelButtonView.set( {\n\t\t\tlabel: t( 'Cancel' ),\n\t\t\ticon: icons.cancel,\n\t\t\tclass: 'ck-button-cancel',\n\t\t\twithText: true\n\t\t} );\n\n\t\tcancelButtonView.delegate( 'execute' ).to( this, 'cancel' );\n\n\t\treturn {\n\t\t\tsaveButtonView, cancelButtonView\n\t\t};\n\t}\n\n\t/**\n\t * Provides localized labels for {@link #alignmentToolbar} buttons.\n\t *\n\t * @private\n\t * @type {Object.<String,String>}\n\t */\n\tget _alignmentLabels() {\n\t\tconst locale = this.locale;\n\t\tconst t = this.t;\n\n\t\tconst left = t( 'Align table to the left' );\n\t\tconst center = t( 'Center table' );\n\t\tconst right = t( 'Align table to the right' );\n\n\t\t// Returns object with a proper order of labels.\n\t\tif ( locale.uiLanguageDirection === 'rtl' ) {\n\t\t\treturn { right, center, left };\n\t\t} else {\n\t\t\treturn { left, center, right };\n\t\t}\n\t}\n}\n\nfunction isBorderStyleSet( value ) {\n\treturn value !== 'none';\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableselection\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\n\nimport TableWalker from './tablewalker';\nimport TableUtils from './tableutils';\n\nimport { cropTableToDimensions, adjustLastRowIndex, adjustLastColumnIndex } from './utils/structure';\nimport { getColumnIndexes, getRowIndexes, getSelectedTableCells, isSelectionRectangular } from './utils/selection';\n\nimport '../theme/tableselection.css';\n\n/**\n * This plugin enables the advanced table cells, rows and columns selection.\n * It is loaded automatically by the {@link module:table/table~Table} plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableSelection extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableSelection';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TableUtils ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tthis.listenTo( model, 'deleteContent', ( evt, args ) => this._handleDeleteContent( evt, args ), { priority: 'high' } );\n\n\t\tthis._defineSelectionConverter();\n\t\tthis._enablePluginDisabling(); // sic!\n\t}\n\n\t/**\n\t * Returns the currently selected table cells or `null` if it is not a table cells selection.\n\t *\n\t * @returns {Array.<module:engine/model/element~Element>|null}\n\t */\n\tgetSelectedTableCells() {\n\t\tconst selection = this.editor.model.document.selection;\n\n\t\tconst selectedCells = getSelectedTableCells( selection );\n\n\t\tif ( selectedCells.length == 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// This should never happen, but let's know if it ever happens.\n\t\t// @if CK_DEBUG //\t/* istanbul ignore next */\n\t\t// @if CK_DEBUG //\tif ( selectedCells.length != selection.rangeCount ) {\n\t\t// @if CK_DEBUG //\t\tconsole.warn( 'Mixed selection warning. The selection contains table cells and some other ranges.' );\n\t\t// @if CK_DEBUG //\t}\n\n\t\treturn selectedCells;\n\t}\n\n\t/**\n\t * Returns the selected table fragment as a document fragment.\n\t *\n\t * @returns {module:engine/model/documentfragment~DocumentFragment|null}\n\t */\n\tgetSelectionAsFragment() {\n\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\tif ( !selectedCells ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.editor.model.change( writer => {\n\t\t\tconst documentFragment = writer.createDocumentFragment();\n\t\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\n\t\t\tconst { first: firstColumn, last: lastColumn } = getColumnIndexes( selectedCells );\n\t\t\tconst { first: firstRow, last: lastRow } = getRowIndexes( selectedCells );\n\n\t\t\tconst sourceTable = selectedCells[ 0 ].findAncestor( 'table' );\n\n\t\t\tlet adjustedLastRow = lastRow;\n\t\t\tlet adjustedLastColumn = lastColumn;\n\n\t\t\t// If the selection is rectangular there could be a case of all cells in the last row/column spanned over\n\t\t\t// next row/column so the real lastRow/lastColumn should be updated.\n\t\t\tif ( isSelectionRectangular( selectedCells, tableUtils ) ) {\n\t\t\t\tconst dimensions = {\n\t\t\t\t\tfirstColumn,\n\t\t\t\t\tlastColumn,\n\t\t\t\t\tfirstRow,\n\t\t\t\t\tlastRow\n\t\t\t\t};\n\n\t\t\t\tadjustedLastRow = adjustLastRowIndex( sourceTable, dimensions );\n\t\t\t\tadjustedLastColumn = adjustLastColumnIndex( sourceTable, dimensions );\n\t\t\t}\n\n\t\t\tconst cropDimensions = {\n\t\t\t\tstartRow: firstRow,\n\t\t\t\tstartColumn: firstColumn,\n\t\t\t\tendRow: adjustedLastRow,\n\t\t\t\tendColumn: adjustedLastColumn\n\t\t\t};\n\n\t\t\tconst table = cropTableToDimensions( sourceTable, cropDimensions, writer );\n\n\t\t\twriter.insert( table, documentFragment, 0 );\n\n\t\t\treturn documentFragment;\n\t\t} );\n\t}\n\n\t/**\n\t * Sets the model selection based on given anchor and target cells (can be the same cell).\n\t * Takes care of setting the backward flag.\n\t *\n\t *\t\tconst modelRoot = editor.model.document.getRoot();\n\t *\t\tconst firstCell = modelRoot.getNodeByPath( [ 0, 0, 0 ] );\n\t *\t\tconst lastCell = modelRoot.getNodeByPath( [ 0, 0, 1 ] );\n\t *\n\t *\t\tconst tableSelection = editor.plugins.get( 'TableSelection' );\n\t *\t\ttableSelection.setCellSelection( firstCell, lastCell );\n\t *\n\t * @param {module:engine/model/element~Element} anchorCell\n\t * @param {module:engine/model/element~Element} targetCell\n\t */\n\tsetCellSelection( anchorCell, targetCell ) {\n\t\tconst cellsToSelect = this._getCellsToSelect( anchorCell, targetCell );\n\n\t\tthis.editor.model.change( writer => {\n\t\t\twriter.setSelection(\n\t\t\t\tcellsToSelect.cells.map( cell => writer.createRangeOn( cell ) ),\n\t\t\t\t{ backward: cellsToSelect.backward }\n\t\t\t);\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the focus cell from the current selection.\n\t *\n\t * @returns {module:engine/model/element~Element}\n\t */\n\tgetFocusCell() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst focusCellRange = [ ...selection.getRanges() ].pop();\n\t\tconst element = focusCellRange.getContainedElement();\n\n\t\tif ( element && element.is( 'element', 'tableCell' ) ) {\n\t\t\treturn element;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Returns the anchor cell from the current selection.\n\t *\n\t * @returns {module:engine/model/element~Element} anchorCell\n\t */\n\tgetAnchorCell() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst anchorCellRange = first( selection.getRanges() );\n\t\tconst element = anchorCellRange.getContainedElement();\n\n\t\tif ( element && element.is( 'element', 'tableCell' ) ) {\n\t\t\treturn element;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Defines a selection converter which marks the selected cells with a specific class.\n\t *\n\t * The real DOM selection is put in the last cell. Since the order of ranges is dependent on whether the\n\t * selection is backward or not, the last cell will usually be close to the \"focus\" end of the selection\n\t * (a selection has anchor and focus).\n\t *\n\t * The real DOM selection is then hidden with CSS.\n\t *\n\t * @private\n\t */\n\t_defineSelectionConverter() {\n\t\tconst editor = this.editor;\n\t\tconst highlighted = new Set();\n\n\t\teditor.conversion.for( 'editingDowncast' ).add( dispatcher => dispatcher.on( 'selection', ( evt, data, conversionApi ) => {\n\t\t\tconst viewWriter = conversionApi.writer;\n\n\t\t\tclearHighlightedTableCells( viewWriter );\n\n\t\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\t\tif ( !selectedCells ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor ( const tableCell of selectedCells ) {\n\t\t\t\tconst viewElement = conversionApi.mapper.toViewElement( tableCell );\n\n\t\t\t\tviewWriter.addClass( 'ck-editor__editable_selected', viewElement );\n\t\t\t\thighlighted.add( viewElement );\n\t\t\t}\n\n\t\t\tconst lastViewCell = conversionApi.mapper.toViewElement( selectedCells[ selectedCells.length - 1 ] );\n\t\t\tviewWriter.setSelection( lastViewCell, 0 );\n\t\t}, { priority: 'lowest' } ) );\n\n\t\tfunction clearHighlightedTableCells( writer ) {\n\t\t\tfor ( const previouslyHighlighted of highlighted ) {\n\t\t\t\twriter.removeClass( 'ck-editor__editable_selected', previouslyHighlighted );\n\t\t\t}\n\n\t\t\thighlighted.clear();\n\t\t}\n\t}\n\n\t/**\n\t * Creates a listener that reacts to changes in {@link #isEnabled} and, if the plugin was disabled,\n\t * it collapses the multi-cell selection to a regular selection placed inside a table cell.\n\t *\n\t * This listener helps features that disable the table selection plugin bring the selection\n\t * to a clear state they can work with (for instance, because they don't support multiple cell selection).\n\t */\n\t_enablePluginDisabling() {\n\t\tconst editor = this.editor;\n\n\t\tthis.on( 'change:isEnabled', () => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tconst selectedCells = this.getSelectedTableCells();\n\n\t\t\t\tif ( !selectedCells ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\teditor.model.change( writer => {\n\t\t\t\t\tconst position = writer.createPositionAt( selectedCells[ 0 ], 0 );\n\t\t\t\t\tconst range = editor.model.schema.getNearestSelectionRange( position );\n\n\t\t\t\t\twriter.setSelection( range );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Overrides the default `model.deleteContent()` behavior over a selected table fragment.\n\t *\n\t * @private\n\t * @param {module:utils/eventinfo~EventInfo} event\n\t * @param {Array.<*>} args Delete content method arguments.\n\t */\n\t_handleDeleteContent( event, args ) {\n\t\tconst [ selection, options ] = args;\n\t\tconst model = this.editor.model;\n\t\tconst isBackward = !options || options.direction == 'backward';\n\t\tconst selectedTableCells = getSelectedTableCells( selection );\n\n\t\tif ( !selectedTableCells.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tevent.stop();\n\n\t\tmodel.change( writer => {\n\t\t\tconst tableCellToSelect = selectedTableCells[ isBackward ? selectedTableCells.length - 1 : 0 ];\n\n\t\t\tmodel.change( writer => {\n\t\t\t\tfor ( const tableCell of selectedTableCells ) {\n\t\t\t\t\tmodel.deleteContent( writer.createSelection( tableCell, 'in' ) );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tconst rangeToSelect = model.schema.getNearestSelectionRange( writer.createPositionAt( tableCellToSelect, 0 ) );\n\n\t\t\t// Note: we ignore the case where rangeToSelect may be null because deleteContent() will always (unless someone broke it)\n\t\t\t// create an empty paragraph to accommodate the selection.\n\n\t\t\tif ( selection.is( 'documentSelection' ) ) {\n\t\t\t\twriter.setSelection( rangeToSelect );\n\t\t\t} else {\n\t\t\t\tselection.setTo( rangeToSelect );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns an array of table cells that should be selected based on the\n\t * given anchor cell and target (focus) cell.\n\t *\n\t * The cells are returned in a reverse direction if the selection is backward.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} anchorCell\n\t * @param {module:engine/model/element~Element} targetCell\n\t * @returns {Array.<module:engine/model/element~Element>}\n\t */\n\t_getCellsToSelect( anchorCell, targetCell ) {\n\t\tconst tableUtils = this.editor.plugins.get( 'TableUtils' );\n\t\tconst startLocation = tableUtils.getCellLocation( anchorCell );\n\t\tconst endLocation = tableUtils.getCellLocation( targetCell );\n\n\t\tconst startRow = Math.min( startLocation.row, endLocation.row );\n\t\tconst endRow = Math.max( startLocation.row, endLocation.row );\n\n\t\tconst startColumn = Math.min( startLocation.column, endLocation.column );\n\t\tconst endColumn = Math.max( startLocation.column, endLocation.column );\n\n\t\t// 2-dimensional array of the selected cells to ease flipping the order of cells for backward selections.\n\t\tconst selectionMap = new Array( endRow - startRow + 1 ).fill( null ).map( () => [] );\n\n\t\tconst walkerOptions = {\n\t\t\tstartRow,\n\t\t\tendRow,\n\t\t\tstartColumn,\n\t\t\tendColumn\n\t\t};\n\n\t\tfor ( const { row, cell } of new TableWalker( anchorCell.findAncestor( 'table' ), walkerOptions ) ) {\n\t\t\tselectionMap[ row - startRow ].push( cell );\n\t\t}\n\n\t\tconst flipVertically = endLocation.row < startLocation.row;\n\t\tconst flipHorizontally = endLocation.column < startLocation.column;\n\n\t\tif ( flipVertically ) {\n\t\t\tselectionMap.reverse();\n\t\t}\n\n\t\tif ( flipHorizontally ) {\n\t\t\tselectionMap.forEach( row => row.reverse() );\n\t\t}\n\n\t\treturn {\n\t\t\tcells: selectionMap.flat(),\n\t\t\tbackward: flipVertically || flipHorizontally\n\t\t};\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tabletoolbar\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { WidgetToolbarRepository } from 'ckeditor5/src/widget';\nimport { getSelectedTableWidget, getTableWidgetAncestor } from './utils/ui/widget';\n\n/**\n * The table toolbar class. It creates toolbars for the table feature and its content (for now only for the table cell content).\n *\n * The table toolbar shows up when a table widget is selected. Its components (e.g. buttons) are created based on the\n * {@link module:table/table~TableConfig#tableToolbar `table.tableToolbar` configuration option}.\n *\n * Table content toolbar shows up when the selection is inside the content of a table. It creates its component based on the\n * {@link module:table/table~TableConfig#contentToolbar `table.contentToolbar` configuration option}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableToolbar extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ WidgetToolbarRepository ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableToolbar';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.t;\n\t\tconst widgetToolbarRepository = editor.plugins.get( WidgetToolbarRepository );\n\n\t\tconst tableContentToolbarItems = editor.config.get( 'table.contentToolbar' );\n\n\t\tconst tableToolbarItems = editor.config.get( 'table.tableToolbar' );\n\n\t\tif ( tableContentToolbarItems ) {\n\t\t\twidgetToolbarRepository.register( 'tableContent', {\n\t\t\t\tariaLabel: t( 'Table toolbar' ),\n\t\t\t\titems: tableContentToolbarItems,\n\t\t\t\tgetRelatedElement: getTableWidgetAncestor\n\t\t\t} );\n\t\t}\n\n\t\tif ( tableToolbarItems ) {\n\t\t\twidgetToolbarRepository.register( 'table', {\n\t\t\t\tariaLabel: t( 'Table toolbar' ),\n\t\t\t\titems: tableToolbarItems,\n\t\t\t\tgetRelatedElement: getSelectedTableWidget\n\t\t\t} );\n\t\t}\n\t}\n}\n\n/**\n * Items to be placed in the table content toolbar.\n * The {@link module:table/tabletoolbar~TableToolbar} plugin is required to make this toolbar work.\n *\n * Assuming that you use the {@link module:table/tableui~TableUI} feature, the following toolbar items will be available\n * in {@link module:ui/componentfactory~ComponentFactory}:\n *\n * * `'tableRow'`,\n * * `'tableColumn'`,\n * * `'mergeTableCells'`.\n *\n * You can thus configure the toolbar like this:\n *\n *\t\tconst tableConfig = {\n *\t\t\tcontentToolbar: [ 'tableRow', 'tableColumn', 'mergeTableCells' ]\n *\t\t};\n *\n * Of course, the same buttons can also be used in the\n * {@link module:core/editor/editorconfig~EditorConfig#toolbar main editor toolbar}.\n *\n * Read more about configuring the toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>} module:table/table~TableConfig#contentToolbar\n */\n\n/**\n * Items to be placed in the table toolbar.\n * The {@link module:table/tabletoolbar~TableToolbar} plugin is required to make this toolbar work.\n *\n * You can thus configure the toolbar like this:\n *\n *\t\tconst tableConfig = {\n *\t\t\ttableToolbar: [ 'blockQuote' ]\n *\t\t};\n *\n * Of course, the same buttons can also be used in the\n * {@link module:core/editor/editorconfig~EditorConfig#toolbar main editor toolbar}.\n *\n * Read more about configuring the toolbar in {@link module:core/editor/editorconfig~EditorConfig#toolbar}.\n *\n * @member {Array.<String>} module:table/table~TableConfig#tableToolbar\n */\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableui\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { addListToDropdown, createDropdown, Model, SplitButtonView } from 'ckeditor5/src/ui';\nimport { Collection } from 'ckeditor5/src/utils';\n\nimport InsertTableView from './ui/inserttableview';\n\nimport tableIcon from './../theme/icons/table.svg';\nimport tableColumnIcon from './../theme/icons/table-column.svg';\nimport tableRowIcon from './../theme/icons/table-row.svg';\nimport tableMergeCellIcon from './../theme/icons/table-merge-cell.svg';\n\n/**\n * The table UI plugin. It introduces:\n *\n * * The `'insertTable'` dropdown,\n * * The `'tableColumn'` dropdown,\n * * The `'tableRow'` dropdown,\n * * The `'mergeTableCells'` split button.\n *\n * The `'tableColumn'`, `'tableRow'` and `'mergeTableCells'` dropdowns work best with {@link module:table/tabletoolbar~TableToolbar}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = this.editor.t;\n\t\tconst contentLanguageDirection = editor.locale.contentLanguageDirection;\n\t\tconst isContentLtr = contentLanguageDirection === 'ltr';\n\n\t\teditor.ui.componentFactory.add( 'insertTable', locale => {\n\t\t\tconst command = editor.commands.get( 'insertTable' );\n\t\t\tconst dropdownView = createDropdown( locale );\n\n\t\t\tdropdownView.bind( 'isEnabled' ).to( command );\n\n\t\t\t// Decorate dropdown's button.\n\t\t\tdropdownView.buttonView.set( {\n\t\t\t\ticon: tableIcon,\n\t\t\t\tlabel: t( 'Insert table' ),\n\t\t\t\ttooltip: true\n\t\t\t} );\n\n\t\t\tlet insertTableView;\n\n\t\t\tdropdownView.on( 'change:isOpen', () => {\n\t\t\t\tif ( insertTableView ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Prepare custom view for dropdown's panel.\n\t\t\t\tinsertTableView = new InsertTableView( locale );\n\t\t\t\tdropdownView.panelView.children.add( insertTableView );\n\n\t\t\t\tinsertTableView.delegate( 'execute' ).to( dropdownView );\n\n\t\t\t\tdropdownView.buttonView.on( 'open', () => {\n\t\t\t\t\t// Reset the chooser before showing it to the user.\n\t\t\t\t\tinsertTableView.rows = 0;\n\t\t\t\t\tinsertTableView.columns = 0;\n\t\t\t\t} );\n\n\t\t\t\tdropdownView.on( 'execute', () => {\n\t\t\t\t\teditor.execute( 'insertTable', { rows: insertTableView.rows, columns: insertTableView.columns } );\n\t\t\t\t\teditor.editing.view.focus();\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\treturn dropdownView;\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'tableColumn', locale => {\n\t\t\tconst options = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'switchbutton',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'setTableColumnHeader',\n\t\t\t\t\t\tlabel: t( 'Header column' ),\n\t\t\t\t\t\tbindIsOn: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ type: 'separator' },\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'insertTableColumnLeft' : 'insertTableColumnRight',\n\t\t\t\t\t\tlabel: t( 'Insert column left' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'insertTableColumnRight' : 'insertTableColumnLeft',\n\t\t\t\t\t\tlabel: t( 'Insert column right' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'removeTableColumn',\n\t\t\t\t\t\tlabel: t( 'Delete column' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'selectTableColumn',\n\t\t\t\t\t\tlabel: t( 'Select column' )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t];\n\n\t\t\treturn this._prepareDropdown( t( 'Column' ), tableColumnIcon, options, locale );\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'tableRow', locale => {\n\t\t\tconst options = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'switchbutton',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'setTableRowHeader',\n\t\t\t\t\t\tlabel: t( 'Header row' ),\n\t\t\t\t\t\tbindIsOn: true\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ type: 'separator' },\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'insertTableRowAbove',\n\t\t\t\t\t\tlabel: t( 'Insert row above' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'insertTableRowBelow',\n\t\t\t\t\t\tlabel: t( 'Insert row below' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'removeTableRow',\n\t\t\t\t\t\tlabel: t( 'Delete row' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'selectTableRow',\n\t\t\t\t\t\tlabel: t( 'Select row' )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t];\n\n\t\t\treturn this._prepareDropdown( t( 'Row' ), tableRowIcon, options, locale );\n\t\t} );\n\n\t\teditor.ui.componentFactory.add( 'mergeTableCells', locale => {\n\t\t\tconst options = [\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'mergeTableCellUp',\n\t\t\t\t\t\tlabel: t( 'Merge cell up' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'mergeTableCellRight' : 'mergeTableCellLeft',\n\t\t\t\t\t\tlabel: t( 'Merge cell right' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'mergeTableCellDown',\n\t\t\t\t\t\tlabel: t( 'Merge cell down' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: isContentLtr ? 'mergeTableCellLeft' : 'mergeTableCellRight',\n\t\t\t\t\t\tlabel: t( 'Merge cell left' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ type: 'separator' },\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'splitTableCellVertically',\n\t\t\t\t\t\tlabel: t( 'Split cell vertically' )\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttype: 'button',\n\t\t\t\t\tmodel: {\n\t\t\t\t\t\tcommandName: 'splitTableCellHorizontally',\n\t\t\t\t\t\tlabel: t( 'Split cell horizontally' )\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t];\n\n\t\t\treturn this._prepareMergeSplitButtonDropdown( t( 'Merge cells' ), tableMergeCellIcon, options, locale );\n\t\t} );\n\t}\n\n\t/**\n\t * Creates a dropdown view from a set of options.\n\t *\n\t * @private\n\t * @param {String} label The dropdown button label.\n\t * @param {String} icon An icon for the dropdown button.\n\t * @param {Array.<module:ui/dropdown/utils~ListDropdownItemDefinition>} options The list of options for the dropdown.\n\t * @param {module:utils/locale~Locale} locale\n\t * @returns {module:ui/dropdown/dropdownview~DropdownView}\n\t */\n\t_prepareDropdown( label, icon, options, locale ) {\n\t\tconst editor = this.editor;\n\t\tconst dropdownView = createDropdown( locale );\n\t\tconst commands = this._fillDropdownWithListOptions( dropdownView, options );\n\n\t\t// Decorate dropdown's button.\n\t\tdropdownView.buttonView.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true\n\t\t} );\n\n\t\t// Make dropdown button disabled when all options are disabled.\n\t\tdropdownView.bind( 'isEnabled' ).toMany( commands, 'isEnabled', ( ...areEnabled ) => {\n\t\t\treturn areEnabled.some( isEnabled => isEnabled );\n\t\t} );\n\n\t\tthis.listenTo( dropdownView, 'execute', evt => {\n\t\t\teditor.execute( evt.source.commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn dropdownView;\n\t}\n\n\t/**\n\t * Creates a dropdown view with a {@link module:ui/dropdown/button/splitbuttonview~SplitButtonView} for\n\t * merge (and split)–related commands.\n\t *\n\t * @private\n\t * @param {String} label The dropdown button label.\n\t * @param {String} icon An icon for the dropdown button.\n\t * @param {Array.<module:ui/dropdown/utils~ListDropdownItemDefinition>} options The list of options for the dropdown.\n\t * @param {module:utils/locale~Locale} locale\n\t * @returns {module:ui/dropdown/dropdownview~DropdownView}\n\t */\n\t_prepareMergeSplitButtonDropdown( label, icon, options, locale ) {\n\t\tconst editor = this.editor;\n\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\tconst mergeCommandName = 'mergeTableCells';\n\n\t\t// Main command.\n\t\tconst mergeCommand = editor.commands.get( mergeCommandName );\n\n\t\t// Subcommands in the dropdown.\n\t\tconst commands = this._fillDropdownWithListOptions( dropdownView, options );\n\n\t\tdropdownView.buttonView.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true,\n\t\t\tisEnabled: true\n\t\t} );\n\n\t\t// Make dropdown button disabled when all options are disabled together with the main command.\n\t\tdropdownView.bind( 'isEnabled' ).toMany( [ mergeCommand, ...commands ], 'isEnabled', ( ...areEnabled ) => {\n\t\t\treturn areEnabled.some( isEnabled => isEnabled );\n\t\t} );\n\n\t\t// Merge selected table cells when the main part of the split button is clicked.\n\t\tthis.listenTo( dropdownView.buttonView, 'execute', () => {\n\t\t\teditor.execute( mergeCommandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\t// Execute commands for events coming from the list in the dropdown panel.\n\t\tthis.listenTo( dropdownView, 'execute', evt => {\n\t\t\teditor.execute( evt.source.commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn dropdownView;\n\t}\n\n\t/**\n\t * Injects a {@link module:ui/list/listview~ListView} into the passed dropdown with buttons\n\t * which execute editor commands as configured in passed options.\n\t *\n\t * @private\n\t * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView\n\t * @param {Array.<module:ui/dropdown/utils~ListDropdownItemDefinition>} options The list of options for the dropdown.\n\t * @returns {Array.<module:core/command~Command>} Commands the list options are interacting with.\n\t */\n\t_fillDropdownWithListOptions( dropdownView, options ) {\n\t\tconst editor = this.editor;\n\t\tconst commands = [];\n\t\tconst itemDefinitions = new Collection();\n\n\t\tfor ( const option of options ) {\n\t\t\taddListOption( option, editor, commands, itemDefinitions );\n\t\t}\n\n\t\taddListToDropdown( dropdownView, itemDefinitions, editor.ui.componentFactory );\n\n\t\treturn commands;\n\t}\n}\n\n// Adds an option to a list view.\n//\n// @param {module:table/tableui~DropdownOption} option A configuration option.\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:core/command~Command>} commands The list of commands to update.\n// @param {Iterable.<module:ui/dropdown/utils~ListDropdownItemDefinition>} itemDefinitions\n// A collection of dropdown items to update with the given option.\nfunction addListOption( option, editor, commands, itemDefinitions ) {\n\tconst model = option.model = new Model( option.model );\n\tconst { commandName, bindIsOn } = option.model;\n\n\tif ( option.type === 'button' || option.type === 'switchbutton' ) {\n\t\tconst command = editor.commands.get( commandName );\n\n\t\tcommands.push( command );\n\n\t\tmodel.set( { commandName } );\n\n\t\tmodel.bind( 'isEnabled' ).to( command );\n\n\t\tif ( bindIsOn ) {\n\t\t\tmodel.bind( 'isOn' ).to( command, 'value' );\n\t\t}\n\t}\n\n\tmodel.set( {\n\t\twithText: true\n\t} );\n\n\titemDefinitions.add( option );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tableutils\n */\n\nimport { CKEditorError } from 'ckeditor5/src/utils';\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport TableWalker from './tablewalker';\nimport { createEmptyTableCell, updateNumericAttribute } from './utils/common';\nimport { removeEmptyColumns, removeEmptyRows } from './utils/structure';\n\n/**\n * The table utilities plugin.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TableUtils extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TableUtils';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tthis.decorate( 'insertColumns' );\n\t\tthis.decorate( 'insertRows' );\n\t}\n\n\t/**\n\t * Returns the table cell location as an object with table row and table column indexes.\n\t *\n\t * For instance, in the table below:\n\t *\n\t *\t\t 0 1 2 3\n\t *\t\t +---+---+---+---+\n\t *\t\t0 | a | b | c |\n\t *\t\t + + +---+\n\t *\t\t1 | | | d |\n\t *\t\t +---+---+ +---+\n\t *\t\t2 | e | | f |\n\t *\t\t +---+---+---+---+\n\t *\n\t * the method will return:\n\t *\n\t *\t\tconst cellA = table.getNodeByPath( [ 0, 0 ] );\n\t *\t\teditor.plugins.get( 'TableUtils' ).getCellLocation( cellA );\n\t *\t\t// will return { row: 0, column: 0 }\n\t *\n\t *\t\tconst cellD = table.getNodeByPath( [ 1, 0 ] );\n\t *\t\teditor.plugins.get( 'TableUtils' ).getCellLocation( cellD );\n\t *\t\t// will return { row: 1, column: 3 }\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @returns {Object} Returns a `{row, column}` object.\n\t */\n\tgetCellLocation( tableCell ) {\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst rowIndex = table.getChildIndex( tableRow );\n\n\t\tconst tableWalker = new TableWalker( table, { row: rowIndex } );\n\n\t\tfor ( const { cell, row, column } of tableWalker ) {\n\t\t\tif ( cell === tableCell ) {\n\t\t\t\treturn { row, column };\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Creates an empty table with a proper structure. The table needs to be inserted into the model,\n\t * for example, by using the {@link module:engine/model/model~Model#insertContent} function.\n\t *\n\t *\t\tmodel.change( ( writer ) => {\n\t *\t\t\t// Create a table of 2 rows and 7 columns:\n\t *\t\t\tconst table = tableUtils.createTable( writer, { rows: 2, columns: 7 } );\n\t *\n\t *\t\t\t// Insert a table to the model at the best position taking the current selection:\n\t *\t\t\tmodel.insertContent( table );\n\t *\t\t}\n\t *\n\t * @param {module:engine/model/writer~Writer} writer The model writer.\n\t * @param {Object} options\n\t * @param {Number} [options.rows=2] The number of rows to create.\n\t * @param {Number} [options.columns=2] The number of columns to create.\n\t * @param {Number} [options.headingRows=0] The number of heading rows.\n\t * @param {Number} [options.headingColumns=0] The number of heading columns.\n\t * @returns {module:engine/model/element~Element} The created table element.\n\t */\n\tcreateTable( writer, options ) {\n\t\tconst table = writer.createElement( 'table' );\n\n\t\tconst rows = parseInt( options.rows ) || 2;\n\t\tconst columns = parseInt( options.columns ) || 2;\n\n\t\tcreateEmptyRows( writer, table, 0, rows, columns );\n\n\t\tif ( options.headingRows ) {\n\t\t\tupdateNumericAttribute( 'headingRows', Math.min( options.headingRows, rows ), table, writer, 0 );\n\t\t}\n\n\t\tif ( options.headingColumns ) {\n\t\t\tupdateNumericAttribute( 'headingColumns', Math.min( options.headingColumns, columns ), table, writer, 0 );\n\t\t}\n\n\t\treturn table;\n\t}\n\n\t/**\n\t * Inserts rows into a table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).insertRows( table, { at: 1, rows: 2 } );\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *\t\trow index\n\t *\t\t 0 +---+---+---+ `at` = 1, +---+---+---+ 0\n\t *\t\t | a | b | c | `rows` = 2, | a | b | c |\n\t *\t\t 1 + +---+---+ <-- insert here + +---+---+ 1\n\t *\t\t | | d | e | | | | |\n\t *\t\t 2 + +---+---+ will give: + +---+---+ 2\n\t *\t\t | | f | g | | | | |\n\t *\t\t 3 +---+---+---+ + +---+---+ 3\n\t *\t\t | | d | e |\n\t *\t\t + +---+---+ 4\n\t *\t\t + + f | g |\n\t *\t\t +---+---+---+ 5\n\t *\n\t * @param {module:engine/model/element~Element} table The table model element where the rows will be inserted.\n\t * @param {Object} options\n\t * @param {Number} [options.at=0] The row index at which the rows will be inserted.\n\t * @param {Number} [options.rows=1] The number of rows to insert.\n\t * @param {Boolean|undefined} [options.copyStructureFromAbove] The flag for copying row structure. Note that\n\t * the row structure will not be copied if this option is not provided.\n\t */\n\tinsertRows( table, options = {} ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst rowsToInsert = options.rows || 1;\n\t\tconst isCopyStructure = options.copyStructureFromAbove !== undefined;\n\t\tconst copyStructureFrom = options.copyStructureFromAbove ? insertAt - 1 : insertAt;\n\n\t\tconst rows = this.getRows( table );\n\t\tconst columns = this.getColumns( table );\n\n\t\tif ( insertAt > rows ) {\n\t\t\t/**\n\t\t\t * The `options.at` points at a row position that does not exist.\n\t\t\t *\n\t\t\t * @error tableutils-insertrows-insert-out-of-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'tableutils-insertrows-insert-out-of-range',\n\t\t\t\tthis,\n\t\t\t\t{ options }\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t// Inserting rows inside heading section requires to update `headingRows` attribute as the heading section will grow.\n\t\t\tif ( headingRows > insertAt ) {\n\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + rowsToInsert, table, writer, 0 );\n\t\t\t}\n\n\t\t\t// Inserting at the end or at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( !isCopyStructure && ( insertAt === 0 || insertAt === rows ) ) {\n\t\t\t\tcreateEmptyRows( writer, table, insertAt, rowsToInsert, columns );\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Iterate over all the rows above the inserted rows in order to check for the row-spanned cells.\n\t\t\tconst walkerEndRow = isCopyStructure ? Math.max( insertAt, copyStructureFrom ) : insertAt;\n\t\t\tconst tableIterator = new TableWalker( table, { endRow: walkerEndRow } );\n\n\t\t\t// Store spans of the reference row to reproduce it's structure. This array is column number indexed.\n\t\t\tconst rowColSpansMap = new Array( columns ).fill( 1 );\n\n\t\t\tfor ( const { row, column, cellHeight, cellWidth, cell } of tableIterator ) {\n\t\t\t\tconst lastCellRow = row + cellHeight - 1;\n\n\t\t\t\tconst isOverlappingInsertedRow = row < insertAt && insertAt <= lastCellRow;\n\t\t\t\tconst isReferenceRow = row <= copyStructureFrom && copyStructureFrom <= lastCellRow;\n\n\t\t\t\t// If the cell is row-spanned and overlaps the inserted row, then reserve space for it in the row map.\n\t\t\t\tif ( isOverlappingInsertedRow ) {\n\t\t\t\t\t// This cell overlaps the inserted rows so we need to expand it further.\n\t\t\t\t\twriter.setAttribute( 'rowspan', cellHeight + rowsToInsert, cell );\n\n\t\t\t\t\t// Mark this cell with negative number to indicate how many cells should be skipped when adding the new cells.\n\t\t\t\t\trowColSpansMap[ column ] = -cellWidth;\n\t\t\t\t}\n\t\t\t\t// Store the colspan from reference row.\n\t\t\t\telse if ( isCopyStructure && isReferenceRow ) {\n\t\t\t\t\trowColSpansMap[ column ] = cellWidth;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( let rowIndex = 0; rowIndex < rowsToInsert; rowIndex++ ) {\n\t\t\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\t\t\twriter.insert( tableRow, table, insertAt );\n\n\t\t\t\tfor ( let cellIndex = 0; cellIndex < rowColSpansMap.length; cellIndex++ ) {\n\t\t\t\t\tconst colspan = rowColSpansMap[ cellIndex ];\n\t\t\t\t\tconst insertPosition = writer.createPositionAt( tableRow, 'end' );\n\n\t\t\t\t\t// Insert the empty cell only if this slot is not row-spanned from any other cell.\n\t\t\t\t\tif ( colspan > 0 ) {\n\t\t\t\t\t\tcreateEmptyTableCell( writer, insertPosition, colspan > 1 ? { colspan } : null );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Skip the col-spanned slots, there won't be any cells.\n\t\t\t\t\tcellIndex += Math.abs( colspan ) - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Inserts columns into a table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).insertColumns( table, { at: 1, columns: 2 } );\n\t *\n\t * Assuming the table on the left, the above code will transform it to the table on the right:\n\t *\n\t *\t\t0 1 2 3 0 1 2 3 4 5\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t| a | b | | a | b |\n\t *\t\t+ +---+ + +---+\n\t *\t\t| | c | | | c |\n\t *\t\t+---+---+---+ will give: +---+---+---+---+---+\n\t *\t\t| d | e | f | | d | | | e | f |\n\t *\t\t+---+ +---+ +---+---+---+ +---+\n\t *\t\t| g | | h | | g | | | | h |\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t| i | | i |\n\t *\t\t+---+---+---+ +---+---+---+---+---+\n\t *\t\t ^---- insert here, `at` = 1, `columns` = 2\n\t *\n\t * @param {module:engine/model/element~Element} table The table model element where the columns will be inserted.\n\t * @param {Object} options\n\t * @param {Number} [options.at=0] The column index at which the columns will be inserted.\n\t * @param {Number} [options.columns=1] The number of columns to insert.\n\t */\n\tinsertColumns( table, options = {} ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst insertAt = options.at || 0;\n\t\tconst columnsToInsert = options.columns || 1;\n\n\t\tmodel.change( writer => {\n\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' );\n\n\t\t\t// Inserting columns inside heading section requires to update `headingColumns` attribute as the heading section will grow.\n\t\t\tif ( insertAt < headingColumns ) {\n\t\t\t\twriter.setAttribute( 'headingColumns', headingColumns + columnsToInsert, table );\n\t\t\t}\n\n\t\t\tconst tableColumns = this.getColumns( table );\n\n\t\t\t// Inserting at the end and at the beginning of a table doesn't require to calculate anything special.\n\t\t\tif ( insertAt === 0 || tableColumns === insertAt ) {\n\t\t\t\tfor ( const tableRow of table.getChildren() ) {\n\t\t\t\t\t// Ignore non-row elements inside the table (e.g. caption).\n\t\t\t\t\tif ( !tableRow.is( 'element', 'tableRow' ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tcreateCells( columnsToInsert, writer, writer.createPositionAt( tableRow, insertAt ? 'end' : 0 ) );\n\t\t\t\t}\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst tableWalker = new TableWalker( table, { column: insertAt, includeAllSlots: true } );\n\n\t\t\tfor ( const tableSlot of tableWalker ) {\n\t\t\t\tconst { row, cell, cellAnchorColumn, cellAnchorRow, cellWidth, cellHeight } = tableSlot;\n\n\t\t\t\t// When iterating over column the table walker outputs either:\n\t\t\t\t// - cells at given column index (cell \"e\" from method docs),\n\t\t\t\t// - spanned columns (spanned cell from row between cells \"g\" and \"h\" - spanned by \"e\", only if `includeAllSlots: true`),\n\t\t\t\t// - or a cell from the same row which spans over this column (cell \"a\").\n\n\t\t\t\tif ( cellAnchorColumn < insertAt ) {\n\t\t\t\t\t// If cell is anchored in previous column, it is a cell that spans over an inserted column (cell \"a\" & \"i\").\n\t\t\t\t\t// For such cells expand them by a number of columns inserted.\n\t\t\t\t\twriter.setAttribute( 'colspan', cellWidth + columnsToInsert, cell );\n\n\t\t\t\t\t// This cell will overlap cells in rows below so skip them (because of `includeAllSlots` option) - (cell \"a\")\n\t\t\t\t\tconst lastCellRow = cellAnchorRow + cellHeight - 1;\n\n\t\t\t\t\tfor ( let i = row; i <= lastCellRow; i++ ) {\n\t\t\t\t\t\ttableWalker.skipRow( i );\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// It's either cell at this column index or spanned cell by a row-spanned cell from row above.\n\t\t\t\t\t// In table above it's cell \"e\" and a spanned position from row below (empty cell between cells \"g\" and \"h\")\n\t\t\t\t\tcreateCells( columnsToInsert, writer, tableSlot.getPositionBefore() );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes rows from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including `rowspan` attribute of table cells overlapping removed rows\n\t * and table headings values.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).removeRows( table, { at: 1, rows: 2 } );\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *\t\trow index\n\t *\t\t ┌───┬───┬───┐ `at` = 1 ┌───┬───┬───┐\n\t *\t\t 0 │ a │ b │ c │ `rows` = 2 │ a │ b │ c │ 0\n\t *\t\t │ ├───┼───┤ │ ├───┼───┤\n\t *\t\t 1 │ │ d │ e │ <-- remove from here │ │ d │ g │ 1\n\t *\t\t │ │ ├───┤ will give: ├───┼───┼───┤\n\t *\t\t 2 │ │ │ f │ │ h │ i │ j │ 2\n\t *\t\t │ │ ├───┤ └───┴───┴───┘\n\t *\t\t 3 │ │ │ g │\n\t *\t\t ├───┼───┼───┤\n\t *\t\t 4 │ h │ i │ j │\n\t *\t\t └───┴───┴───┘\n\t *\n\t * @param {module:engine/model/element~Element} table\n\t * @param {Object} options\n\t * @param {Number} options.at The row index at which the removing rows will start.\n\t * @param {Number} [options.rows=1] The number of rows to remove.\n\t */\n\tremoveRows( table, options ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst rowsToRemove = options.rows || 1;\n\t\tconst rowCount = this.getRows( table );\n\t\tconst first = options.at;\n\t\tconst last = first + rowsToRemove - 1;\n\n\t\tif ( last > rowCount - 1 ) {\n\t\t\t/**\n\t\t\t * The `options.at` param must point at existing row and `options.rows` must not exceed the rows in the table.\n\t\t\t *\n\t\t\t * @error tableutils-removerows-row-index-out-of-range\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'tableutils-removerows-row-index-out-of-range',\n\t\t\t\tthis,\n\t\t\t\t{ table, options }\n\t\t\t);\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\t// Removing rows from the table require that most calculations to be done prior to changing table structure.\n\t\t\t// Preparations must be done in the same enqueueChange callback to use the current table structure.\n\n\t\t\t// 1. Preparation - get row-spanned cells that have to be modified after removing rows.\n\t\t\tconst { cellsToMove, cellsToTrim } = getCellsToMoveAndTrimOnRemoveRow( table, first, last );\n\n\t\t\t// 2. Execution\n\n\t\t\t// 2a. Move cells from removed rows that extends over a removed section - must be done before removing rows.\n\t\t\t// This will fill any gaps in a rows below that previously were empty because of row-spanned cells.\n\t\t\tif ( cellsToMove.size ) {\n\t\t\t\tconst rowAfterRemovedSection = last + 1;\n\t\t\t\tmoveCellsToRow( table, rowAfterRemovedSection, cellsToMove, writer );\n\t\t\t}\n\n\t\t\t// 2b. Remove all required rows.\n\t\t\tfor ( let i = last; i >= first; i-- ) {\n\t\t\t\twriter.remove( table.getChild( i ) );\n\t\t\t}\n\n\t\t\t// 2c. Update cells from rows above that overlap removed section. Similar to step 2 but does not involve moving cells.\n\t\t\tfor ( const { rowspan, cell } of cellsToTrim ) {\n\t\t\t\tupdateNumericAttribute( 'rowspan', rowspan, cell, writer );\n\t\t\t}\n\n\t\t\t// 2d. Adjust heading rows if removed rows were in a heading section.\n\t\t\tupdateHeadingRows( table, first, last, writer );\n\n\t\t\t// 2e. Remove empty columns (without anchored cells) if there are any.\n\t\t\tif ( !removeEmptyColumns( table, this ) ) {\n\t\t\t\t// If there wasn't any empty columns then we still need to check if this wasn't called\n\t\t\t\t// because of cleaning empty rows and we only removed one of them.\n\t\t\t\tremoveEmptyRows( table, this );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes columns from the given `table`.\n\t *\n\t * This method re-calculates the table geometry including the `colspan` attribute of table cells overlapping removed columns\n\t * and table headings values.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).removeColumns( table, { at: 1, columns: 2 } );\n\t *\n\t * Executing the above code in the context of the table on the left will transform its structure as presented on the right:\n\t *\n\t *\t\t 0 1 2 3 4 0 1 2\n\t *\t\t┌───────────────┬───┐ ┌───────┬───┐\n\t *\t\t│ a │ b │ │ a │ b │\n\t *\t\t│ ├───┤ │ ├───┤\n\t *\t\t│ │ c │ │ │ c │\n\t *\t\t├───┬───┬───┬───┼───┤ will give: ├───┬───┼───┤\n\t *\t\t│ d │ e │ f │ g │ h │ │ d │ g │ h │\n\t *\t\t├───┼───┼───┤ ├───┤ ├───┤ ├───┤\n\t *\t\t│ i │ j │ k │ │ l │ │ i │ │ l │\n\t *\t\t├───┴───┴───┴───┴───┤ ├───┴───┴───┤\n\t *\t\t│ m │ │ m │\n\t *\t\t└───────────────────┘ └───────────┘\n\t *\t\t ^---- remove from here, `at` = 1, `columns` = 2\n\t *\n\t * @param {module:engine/model/element~Element} table\n\t * @param {Object} options\n\t * @param {Number} options.at The row index at which the removing columns will start.\n\t * @param {Number} [options.columns=1] The number of columns to remove.\n\t */\n\tremoveColumns( table, options ) {\n\t\tconst model = this.editor.model;\n\t\tconst first = options.at;\n\t\tconst columnsToRemove = options.columns || 1;\n\t\tconst last = options.at + columnsToRemove - 1;\n\n\t\tmodel.change( writer => {\n\t\t\tadjustHeadingColumns( table, { first, last }, writer );\n\n\t\t\tfor ( let removedColumnIndex = last; removedColumnIndex >= first; removedColumnIndex-- ) {\n\t\t\t\tfor ( const { cell, column, cellWidth } of [ ...new TableWalker( table ) ] ) {\n\t\t\t\t\t// If colspaned cell overlaps removed column decrease its span.\n\t\t\t\t\tif ( column <= removedColumnIndex && cellWidth > 1 && column + cellWidth > removedColumnIndex ) {\n\t\t\t\t\t\tupdateNumericAttribute( 'colspan', cellWidth - 1, cell, writer );\n\t\t\t\t\t} else if ( column === removedColumnIndex ) {\n\t\t\t\t\t\t// The cell in removed column has colspan of 1.\n\t\t\t\t\t\twriter.remove( cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove empty rows that could appear after removing columns.\n\t\t\tif ( !removeEmptyRows( table, this ) ) {\n\t\t\t\t// If there wasn't any empty rows then we still need to check if this wasn't called\n\t\t\t\t// because of cleaning empty columns and we only removed one of them.\n\t\t\t\tremoveEmptyColumns( table, this );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell vertically into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating colspans of other cells in a column\n\t * and inserting cells (columns) after that cell.\n\t *\n\t * In the table below, if cell \"a\" is split into 3 cells:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * it will result in the table below:\n\t *\n\t *\t\t+---+---+---+---+---+\n\t *\t\t| a | | | b | c |\n\t *\t\t+---+---+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+---+---+\n\t *\n\t * So cell \"d\" will get its `colspan` updated to `3` and 2 cells will be added (2 columns will be created).\n\t *\n\t * Splitting a cell that already has a `colspan` attribute set will distribute the cell `colspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a |\n\t *\t\t+---+---+---+\n\t *\t\t| b | c | d |\n\t *\t\t+---+---+---+\n\t *\n\t * Splitting cell \"a\" with `colspan=3` into 2 cells will create 1 cell with a `colspan=a` and cell \"a\" that will have `colspan=2`:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | |\n\t *\t\t+---+---+---+\n\t *\t\t| b | c | d |\n\t *\t\t+---+---+---+\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {Number} numberOfCells\n\t */\n\tsplitCellVertically( tableCell, numberOfCells = 2 ) {\n\t\tconst model = this.editor.model;\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( colspan > 1 ) {\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( colspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'colspan', updatedSpan, tableCell, writer );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tconst cellsToInsert = colspan > numberOfCells ? numberOfCells - 1 : colspan - 1;\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\t\t\t}\n\n\t\t\t// Second check - the cell has colspan of 1 or we need to create more cells then the currently one spans over.\n\t\t\tif ( colspan < numberOfCells ) {\n\t\t\t\tconst cellsToInsert = numberOfCells - colspan;\n\n\t\t\t\t// First step: expand cells on the same column as split cell.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\t\t\t\t// Get the column index of split cell.\n\t\t\t\tconst { column: splitCellColumn } = tableMap.find( ( { cell } ) => cell === tableCell );\n\n\t\t\t\t// Find cells which needs to be expanded vertically - those on the same column or those that spans over split cell's column.\n\t\t\t\tconst cellsToUpdate = tableMap.filter( ( { cell, cellWidth, column } ) => {\n\t\t\t\t\tconst isOnSameColumn = cell !== tableCell && column === splitCellColumn;\n\t\t\t\t\tconst spansOverColumn = ( column < splitCellColumn && column + cellWidth > splitCellColumn );\n\n\t\t\t\t\treturn isOnSameColumn || spansOverColumn;\n\t\t\t\t} );\n\n\t\t\t\t// Expand cells vertically.\n\t\t\t\tfor ( const { cell, cellWidth } of cellsToUpdate ) {\n\t\t\t\t\twriter.setAttribute( 'colspan', cellWidth + cellsToInsert, cell );\n\t\t\t\t}\n\n\t\t\t\t// Second step: create columns after split cell.\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\n\t\t\t\t// Copy rowspan of split cell.\n\t\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = rowspan;\n\t\t\t\t}\n\n\t\t\t\tcreateCells( cellsToInsert, writer, writer.createPositionAfter( tableCell ), newCellsAttributes );\n\n\t\t\t\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tif ( headingColumns > splitCellColumn ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingColumns', headingColumns + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Divides a table cell horizontally into several ones.\n\t *\n\t * The cell will be visually split into more cells by updating rowspans of other cells in the row and inserting rows with a single cell\n\t * below.\n\t *\n\t * If in the table below cell \"b\" is split into 3 cells:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * It will result in the table below:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+ +\n\t *\t\t| | | |\n\t *\t\t+ +---+ +\n\t *\t\t| | | |\n\t *\t\t+---+---+---+\n\t *\t\t| d | e | f |\n\t *\t\t+---+---+---+\n\t *\n\t * So cells \"a\" and \"b\" will get their `rowspan` updated to `3` and 2 rows with a single cell will be added.\n\t *\n\t * Splitting a cell that already has a `rowspan` attribute set will distribute the cell `rowspan` evenly and the remainder\n\t * will be left to the original cell:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+---+\n\t *\t\t| | d | e |\n\t *\t\t+ +---+---+\n\t *\t\t| | f | g |\n\t *\t\t+ +---+---+\n\t *\t\t| | h | i |\n\t *\t\t+---+---+---+\n\t *\n\t * Splitting cell \"a\" with `rowspan=4` into 3 cells will create 2 cells with a `rowspan=1` and cell \"a\" will have `rowspan=2`:\n\t *\n\t *\t\t+---+---+---+\n\t *\t\t| a | b | c |\n\t *\t\t+ +---+---+\n\t *\t\t| | d | e |\n\t *\t\t+---+---+---+\n\t *\t\t| | f | g |\n\t *\t\t+---+---+---+\n\t *\t\t| | h | i |\n\t *\t\t+---+---+---+\n\t *\n\t * @param {module:engine/model/element~Element} tableCell\n\t * @param {Number} numberOfCells\n\t */\n\tsplitCellHorizontally( tableCell, numberOfCells = 2 ) {\n\t\tconst model = this.editor.model;\n\n\t\tconst tableRow = tableCell.parent;\n\t\tconst table = tableRow.parent;\n\t\tconst splitCellRow = table.getChildIndex( tableRow );\n\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\tmodel.change( writer => {\n\t\t\t// First check - the cell spans over multiple rows so before doing anything else just split this cell.\n\t\t\tif ( rowspan > 1 ) {\n\t\t\t\t// Cache table map before updating table.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, {\n\t\t\t\t\tstartRow: splitCellRow,\n\t\t\t\t\tendRow: splitCellRow + rowspan - 1,\n\t\t\t\t\tincludeAllSlots: true\n\t\t\t\t} ) ];\n\n\t\t\t\t// Get spans of new (inserted) cells and span to update of split cell.\n\t\t\t\tconst { newCellsSpan, updatedSpan } = breakSpanEvenly( rowspan, numberOfCells );\n\n\t\t\t\tupdateNumericAttribute( 'rowspan', updatedSpan, tableCell, writer );\n\n\t\t\t\tconst { column: cellColumn } = tableMap.find( ( { cell } ) => cell === tableCell );\n\n\t\t\t\t// Each inserted cell will have the same attributes:\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Do not store default value in the model.\n\t\t\t\tif ( newCellsSpan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.rowspan = newCellsSpan;\n\t\t\t\t}\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tfor ( const tableSlot of tableMap ) {\n\t\t\t\t\tconst { column, row } = tableSlot;\n\n\t\t\t\t\t// As both newly created cells and the split cell might have rowspan,\n\t\t\t\t\t// the insertion of new cells must go to appropriate rows:\n\t\t\t\t\t//\n\t\t\t\t\t// 1. It's a row after split cell + it's height.\n\t\t\t\t\tconst isAfterSplitCell = row >= splitCellRow + updatedSpan;\n\t\t\t\t\t// 2. Is on the same column.\n\t\t\t\t\tconst isOnSameColumn = column === cellColumn;\n\t\t\t\t\t// 3. And it's row index is after previous cell height.\n\t\t\t\t\tconst isInEvenlySplitRow = ( row + splitCellRow + updatedSpan ) % newCellsSpan === 0;\n\n\t\t\t\t\tif ( isAfterSplitCell && isOnSameColumn && isInEvenlySplitRow ) {\n\t\t\t\t\t\tcreateCells( 1, writer, tableSlot.getPositionBefore(), newCellsAttributes );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Second check - the cell has rowspan of 1 or we need to create more cells than the current cell spans over.\n\t\t\tif ( rowspan < numberOfCells ) {\n\t\t\t\t// We already split the cell in check one so here we split to the remaining number of cells only.\n\t\t\t\tconst cellsToInsert = numberOfCells - rowspan;\n\n\t\t\t\t// This check is needed since we need to check if there are any cells from previous rows than spans over this cell's row.\n\t\t\t\tconst tableMap = [ ...new TableWalker( table, { startRow: 0, endRow: splitCellRow } ) ];\n\n\t\t\t\t// First step: expand cells.\n\t\t\t\tfor ( const { cell, cellHeight, row } of tableMap ) {\n\t\t\t\t\t// Expand rowspan of cells that are either:\n\t\t\t\t\t// - on the same row as current cell,\n\t\t\t\t\t// - or are below split cell row and overlaps that row.\n\t\t\t\t\tif ( cell !== tableCell && row + cellHeight > splitCellRow ) {\n\t\t\t\t\t\tconst rowspanToSet = cellHeight + cellsToInsert;\n\n\t\t\t\t\t\twriter.setAttribute( 'rowspan', rowspanToSet, cell );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Second step: create rows with single cell below split cell.\n\t\t\t\tconst newCellsAttributes = {};\n\n\t\t\t\t// Copy colspan of split cell.\n\t\t\t\tif ( colspan > 1 ) {\n\t\t\t\t\tnewCellsAttributes.colspan = colspan;\n\t\t\t\t}\n\n\t\t\t\tcreateEmptyRows( writer, table, splitCellRow + 1, cellsToInsert, 1, newCellsAttributes );\n\n\t\t\t\t// Update heading section if split cell is in heading section.\n\t\t\t\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\t\t\t\tif ( headingRows > splitCellRow ) {\n\t\t\t\t\tupdateNumericAttribute( 'headingRows', headingRows + cellsToInsert, table, writer );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the number of columns for a given table.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).getColumns( table );\n\t *\n\t * @param {module:engine/model/element~Element} table The table to analyze.\n\t * @returns {Number}\n\t */\n\tgetColumns( table ) {\n\t\t// Analyze first row only as all the rows should have the same width.\n\t\t// Using the first row without checking if it's a tableRow because we expect\n\t\t// that table will have only tableRow model elements at the beginning.\n\t\tconst row = table.getChild( 0 );\n\n\t\treturn [ ...row.getChildren() ].reduce( ( columns, row ) => {\n\t\t\tconst columnWidth = parseInt( row.getAttribute( 'colspan' ) || 1 );\n\n\t\t\treturn columns + columnWidth;\n\t\t}, 0 );\n\t}\n\n\t/**\n\t * Returns the number of rows for a given table. Any other element present in the table model is omitted.\n\t *\n\t *\t\teditor.plugins.get( 'TableUtils' ).getRows( table );\n\t *\n\t * @param {module:engine/model/element~Element} table The table to analyze.\n\t * @returns {Number}\n\t */\n\tgetRows( table ) {\n\t\t// Rowspan not included due to #6427.\n\t\treturn Array.from( table.getChildren() )\n\t\t\t.reduce( ( rowCount, child ) => child.is( 'element', 'tableRow' ) ? rowCount + 1 : rowCount, 0 );\n\t}\n}\n\n// Creates empty rows at the given index in an existing table.\n//\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/element~Element} table\n// @param {Number} insertAt The row index of row insertion.\n// @param {Number} rows The number of rows to create.\n// @param {Number} tableCellToInsert The number of cells to insert in each row.\nfunction createEmptyRows( writer, table, insertAt, rows, tableCellToInsert, attributes = {} ) {\n\tfor ( let i = 0; i < rows; i++ ) {\n\t\tconst tableRow = writer.createElement( 'tableRow' );\n\n\t\twriter.insert( tableRow, table, insertAt );\n\n\t\tcreateCells( tableCellToInsert, writer, writer.createPositionAt( tableRow, 'end' ), attributes );\n\t}\n}\n\n// Creates cells at a given position.\n//\n// @param {Number} columns The number of columns to create\n// @param {module:engine/model/writer~Writer} writer\n// @param {module:engine/model/position~Position} insertPosition\nfunction createCells( cells, writer, insertPosition, attributes = {} ) {\n\tfor ( let i = 0; i < cells; i++ ) {\n\t\tcreateEmptyTableCell( writer, insertPosition, attributes );\n\t}\n}\n\n// Evenly distributes the span of a cell to a number of provided cells.\n// The resulting spans will always be integer values.\n//\n// For instance breaking a span of 7 into 3 cells will return:\n//\n//\t\t{ newCellsSpan: 2, updatedSpan: 3 }\n//\n// as two cells will have a span of 2 and the remainder will go the first cell so its span will change to 3.\n//\n// @param {Number} span The span value do break.\n// @param {Number} numberOfCells The number of resulting spans.\n// @returns {{newCellsSpan: Number, updatedSpan: Number}}\nfunction breakSpanEvenly( span, numberOfCells ) {\n\tif ( span < numberOfCells ) {\n\t\treturn { newCellsSpan: 1, updatedSpan: 1 };\n\t}\n\n\tconst newCellsSpan = Math.floor( span / numberOfCells );\n\tconst updatedSpan = ( span - newCellsSpan * numberOfCells ) + newCellsSpan;\n\n\treturn { newCellsSpan, updatedSpan };\n}\n\n// Updates heading columns attribute if removing a row from head section.\nfunction adjustHeadingColumns( table, removedColumnIndexes, writer ) {\n\tconst headingColumns = table.getAttribute( 'headingColumns' ) || 0;\n\n\tif ( headingColumns && removedColumnIndexes.first < headingColumns ) {\n\t\tconst headingsRemoved = Math.min( headingColumns - 1 /* Other numbers are 0-based */, removedColumnIndexes.last ) -\n\t\t\tremovedColumnIndexes.first + 1;\n\n\t\twriter.setAttribute( 'headingColumns', headingColumns - headingsRemoved, table );\n\t}\n}\n\n// Calculates a new heading rows value for removing rows from heading section.\nfunction updateHeadingRows( table, first, last, writer ) {\n\tconst headingRows = table.getAttribute( 'headingRows' ) || 0;\n\n\tif ( first < headingRows ) {\n\t\tconst newRows = last < headingRows ? headingRows - ( last - first + 1 ) : first;\n\n\t\tupdateNumericAttribute( 'headingRows', newRows, table, writer, 0 );\n\t}\n}\n\n// Finds cells that will be:\n// - trimmed - Cells that are \"above\" removed rows sections and overlap the removed section - their rowspan must be trimmed.\n// - moved - Cells from removed rows section might stick out of. These cells are moved to the next row after a removed section.\n//\n// Sample table with overlapping & sticking out cells:\n//\n// +----+----+----+----+----+\n// | 00 | 01 | 02 | 03 | 04 |\n// +----+ + + + +\n// | 10 | | | | |\n// +----+----+ + + +\n// | 20 | 21 | | | | <-- removed row\n// + + +----+ + +\n// | | | 32 | | | <-- removed row\n// +----+ + +----+ +\n// | 40 | | | 43 | |\n// +----+----+----+----+----+\n//\n// In a table above:\n// - cells to trim: '02', '03' & '04'.\n// - cells to move: '21' & '32'.\nfunction getCellsToMoveAndTrimOnRemoveRow( table, first, last ) {\n\tconst cellsToMove = new Map();\n\tconst cellsToTrim = [];\n\n\tfor ( const { row, column, cellHeight, cell } of new TableWalker( table, { endRow: last } ) ) {\n\t\tconst lastRowOfCell = row + cellHeight - 1;\n\n\t\tconst isCellStickingOutFromRemovedRows = row >= first && row <= last && lastRowOfCell > last;\n\n\t\tif ( isCellStickingOutFromRemovedRows ) {\n\t\t\tconst rowspanInRemovedSection = last - row + 1;\n\t\t\tconst rowSpanToSet = cellHeight - rowspanInRemovedSection;\n\n\t\t\tcellsToMove.set( column, {\n\t\t\t\tcell,\n\t\t\t\trowspan: rowSpanToSet\n\t\t\t} );\n\t\t}\n\n\t\tconst isCellOverlappingRemovedRows = row < first && lastRowOfCell >= first;\n\n\t\tif ( isCellOverlappingRemovedRows ) {\n\t\t\tlet rowspanAdjustment;\n\n\t\t\t// Cell fully covers removed section - trim it by removed rows count.\n\t\t\tif ( lastRowOfCell >= last ) {\n\t\t\t\trowspanAdjustment = last - first + 1;\n\t\t\t}\n\t\t\t// Cell partially overlaps removed section - calculate cell's span that is in removed section.\n\t\t\telse {\n\t\t\t\trowspanAdjustment = lastRowOfCell - first + 1;\n\t\t\t}\n\n\t\t\tcellsToTrim.push( {\n\t\t\t\tcell,\n\t\t\t\trowspan: cellHeight - rowspanAdjustment\n\t\t\t} );\n\t\t}\n\t}\n\treturn { cellsToMove, cellsToTrim };\n}\n\nfunction moveCellsToRow( table, targetRowIndex, cellsToMove, writer ) {\n\tconst tableWalker = new TableWalker( table, {\n\t\tincludeAllSlots: true,\n\t\trow: targetRowIndex\n\t} );\n\n\tconst tableRowMap = [ ...tableWalker ];\n\tconst row = table.getChild( targetRowIndex );\n\n\tlet previousCell;\n\n\tfor ( const { column, cell, isAnchor } of tableRowMap ) {\n\t\tif ( cellsToMove.has( column ) ) {\n\t\t\tconst { cell: cellToMove, rowspan } = cellsToMove.get( column );\n\n\t\t\tconst targetPosition = previousCell ?\n\t\t\t\twriter.createPositionAfter( previousCell ) :\n\t\t\t\twriter.createPositionAt( row, 0 );\n\n\t\t\twriter.move( writer.createRangeOn( cellToMove ), targetPosition );\n\t\t\tupdateNumericAttribute( 'rowspan', rowspan, cellToMove, writer );\n\n\t\t\tpreviousCell = cellToMove;\n\t\t} else if ( isAnchor ) {\n\t\t\t// If cell is spanned then `cell` holds reference to overlapping cell. See ckeditor/ckeditor5#6502.\n\t\t\tpreviousCell = cell;\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/tablewalker\n */\n\n// @if CK_DEBUG // import { CKEditorError } from 'ckeditor5/src/utils';\n\n/**\n * The table iterator class. It allows to iterate over table cells. For each cell the iterator yields\n * {@link module:table/tablewalker~TableSlot} with proper table cell attributes.\n */\nexport default class TableWalker {\n\t/**\n\t * Creates an instance of the table walker.\n\t *\n\t * The table walker iterates internally by traversing the table from row index = 0 and column index = 0.\n\t * It walks row by row and column by column in order to output values defined in the constructor.\n\t * By default it will output only the locations that are occupied by a cell. To include also spanned rows and columns,\n\t * pass the `includeAllSlots` option to the constructor.\n\t *\n\t * The most important values of the iterator are column and row indexes of a cell.\n\t *\n\t * See {@link module:table/tablewalker~TableSlot} what values are returned by the table walker.\n\t *\n\t * To iterate over a given row:\n\t *\n\t *\t\tconst tableWalker = new TableWalker( table, { startRow: 1, endRow: 2 } );\n\t *\n\t *\t\tfor ( const tableSlot of tableWalker ) {\n\t *\t\t\tconsole.log( 'A cell at row', tableSlot.row, 'and column', tableSlot.column );\n\t *\t\t}\n\t *\n\t * For instance the code above for the following table:\n\t *\n\t *\t\t+----+----+----+----+----+----+\n\t *\t\t| 00 | 02 | 03 | 04 | 05 |\n\t *\t\t| +----+----+----+----+\n\t *\t\t| | 12 | 14 | 15 |\n\t *\t\t| +----+----+----+ +\n\t *\t\t| | 22 | |\n\t *\t\t|----+----+----+----+----+ +\n\t *\t\t| 30 | 31 | 32 | 33 | 34 | |\n\t *\t\t+----+----+----+----+----+----+\n\t *\n\t * will log in the console:\n\t *\n\t *\t\t'A cell at row 1 and column 2'\n\t *\t\t'A cell at row 1 and column 4'\n\t *\t\t'A cell at row 1 and column 5'\n\t *\t\t'A cell at row 2 and column 2'\n\t *\n\t * To also iterate over spanned cells:\n\t *\n\t *\t\tconst tableWalker = new TableWalker( table, { row: 1, includeAllSlots: true } );\n\t *\n\t *\t\tfor ( const tableSlot of tableWalker ) {\n\t *\t\t\tconsole.log( 'Slot at', tableSlot.row, 'x', tableSlot.column, ':', tableSlot.isAnchor ? 'is anchored' : 'is spanned' );\n\t *\t\t}\n\t *\n\t * will log in the console for the table from the previous example:\n\t *\n\t *\t\t'Cell at 1 x 0 : is spanned'\n\t *\t\t'Cell at 1 x 1 : is spanned'\n\t *\t\t'Cell at 1 x 2 : is anchored'\n\t *\t\t'Cell at 1 x 3 : is spanned'\n\t *\t\t'Cell at 1 x 4 : is anchored'\n\t *\t\t'Cell at 1 x 5 : is anchored'\n\t *\n\t * **Note**: Option `row` is a shortcut that sets both `startRow` and `endRow` to the same row.\n\t * (Use either `row` or `startRow` and `endRow` but never together). Similarly the `column` option sets both `startColumn`\n\t * and `endColumn` to the same column (Use either `column` or `startColumn` and `endColumn` but never together).\n\t *\n\t * @constructor\n\t * @param {module:engine/model/element~Element} table A table over which the walker iterates.\n\t * @param {Object} [options={}] An object with configuration.\n\t * @param {Number} [options.row] A row index for which this iterator will output cells.\n\t * Can't be used together with `startRow` and `endRow`.\n\t * @param {Number} [options.startRow=0] A row index from which this iterator should start. Can't be used together with `row`.\n\t * @param {Number} [options.endRow] A row index at which this iterator should end. Can't be used together with `row`.\n\t * @param {Number} [options.column] A column index for which this iterator will output cells.\n\t * Can't be used together with `startColumn` and `endColumn`.\n\t * @param {Number} [options.startColumn=0] A column index from which this iterator should start. Can't be used together with `column`.\n\t * @param {Number} [options.endColumn] A column index at which this iterator should end. Can't be used together with `column`.\n\t * @param {Boolean} [options.includeAllSlots=false] Also return values for spanned cells.\n\t */\n\tconstructor( table, options = {} ) {\n\t\t/**\n\t\t * The walker's table element.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element}\n\t\t * @protected\n\t\t */\n\t\tthis._table = table;\n\n\t\t/**\n\t\t * A row index from which this iterator will start.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._startRow = options.row !== undefined ? options.row : options.startRow || 0;\n\n\t\t/**\n\t\t * A row index at which this iterator will end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._endRow = options.row !== undefined ? options.row : options.endRow;\n\n\t\t/**\n\t\t * If set, the table walker will only output cells from a given column and following ones or cells that overlap them.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._startColumn = options.column !== undefined ? options.column : options.startColumn || 0;\n\n\t\t/**\n\t\t * If set, the table walker will only output cells up to a given column.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._endColumn = options.column !== undefined ? options.column : options.endColumn;\n\n\t\t/**\n\t\t * Enables output of spanned cells that are normally not yielded.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean}\n\t\t * @private\n\t\t */\n\t\tthis._includeAllSlots = !!options.includeAllSlots;\n\n\t\t/**\n\t\t * Row indexes to skip from the iteration.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Set<Number>}\n\t\t * @private\n\t\t */\n\t\tthis._skipRows = new Set();\n\n\t\t/**\n\t\t * The current row index.\n\t\t *\n\t\t * @member {Number}\n\t\t * @protected\n\t\t */\n\t\tthis._row = 0;\n\n\t\t/**\n\t\t * The index of the current row element in the table.\n\t\t *\n\t\t * @type {Number}\n\t\t * @protected\n\t\t */\n\t\tthis._rowIndex = 0;\n\n\t\t/**\n\t\t * The current column index.\n\t\t *\n\t\t * @member {Number}\n\t\t * @protected\n\t\t */\n\t\tthis._column = 0;\n\n\t\t/**\n\t\t * The cell index in a parent row. For spanned cells when {@link #_includeAllSlots} is set to `true`,\n\t\t * this represents the index of the next table cell.\n\t\t *\n\t\t * @member {Number}\n\t\t * @protected\n\t\t */\n\t\tthis._cellIndex = 0;\n\n\t\t/**\n\t\t * Holds a map of spanned cells in a table.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Map.<Number, Map.<Number, Object>>}\n\t\t * @private\n\t\t */\n\t\tthis._spannedCells = new Map();\n\n\t\t/**\n\t\t * Index of the next column where a cell is anchored.\n\t\t *\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._nextCellAtColumn = -1;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:table/tablewalker~TableSlot>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Gets the next table walker's value.\n\t *\n\t * @returns {module:table/tablewalker~TableSlot} The next table walker's value.\n\t */\n\tnext() {\n\t\tconst row = this._table.getChild( this._rowIndex );\n\n\t\t// Iterator is done when there's no row (table ended) or the row is after `endRow` limit.\n\t\tif ( !row || this._isOverEndRow() ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We step over current element when it is not a tableRow instance.\n\t\tif ( !row.is( 'element', 'tableRow' ) ) {\n\t\t\tthis._rowIndex++;\n\n\t\t\treturn this.next();\n\t\t}\n\n\t\tif ( this._isOverEndColumn() ) {\n\t\t\treturn this._advanceToNextRow();\n\t\t}\n\n\t\tlet outValue = null;\n\n\t\tconst spanData = this._getSpanned();\n\n\t\tif ( spanData ) {\n\t\t\tif ( this._includeAllSlots && !this._shouldSkipSlot() ) {\n\t\t\t\toutValue = this._formatOutValue( spanData.cell, spanData.row, spanData.column );\n\t\t\t}\n\t\t} else {\n\t\t\tconst cell = row.getChild( this._cellIndex );\n\n\t\t\tif ( !cell ) {\n\t\t\t\t// If there are no more cells left in row advance to the next row.\n\t\t\t\treturn this._advanceToNextRow();\n\t\t\t}\n\n\t\t\tconst colspan = parseInt( cell.getAttribute( 'colspan' ) || 1 );\n\t\t\tconst rowspan = parseInt( cell.getAttribute( 'rowspan' ) || 1 );\n\n\t\t\t// Record this cell spans if it's not 1x1 cell.\n\t\t\tif ( colspan > 1 || rowspan > 1 ) {\n\t\t\t\tthis._recordSpans( cell, rowspan, colspan );\n\t\t\t}\n\n\t\t\tif ( !this._shouldSkipSlot() ) {\n\t\t\t\toutValue = this._formatOutValue( cell );\n\t\t\t}\n\n\t\t\tthis._nextCellAtColumn = this._column + colspan;\n\t\t}\n\n\t\t// Advance to the next column before returning value.\n\t\tthis._column++;\n\n\t\tif ( this._column == this._nextCellAtColumn ) {\n\t\t\tthis._cellIndex++;\n\t\t}\n\n\t\t// The current value will be returned only if current row and column are not skipped.\n\t\treturn outValue || this.next();\n\t}\n\n\t/**\n\t * Marks a row to skip in the next iteration. It will also skip cells from the current row if there are any cells from the current row\n\t * to output.\n\t *\n\t * @param {Number} row The row index to skip.\n\t */\n\tskipRow( row ) {\n\t\tthis._skipRows.add( row );\n\t}\n\n\t/**\n\t * Advances internal cursor to the next row.\n\t *\n\t * @private\n\t * @returns {module:table/tablewalker~TableSlot}\n\t */\n\t_advanceToNextRow() {\n\t\tthis._row++;\n\t\tthis._rowIndex++;\n\t\tthis._column = 0;\n\t\tthis._cellIndex = 0;\n\t\tthis._nextCellAtColumn = -1;\n\n\t\treturn this.next();\n\t}\n\n\t/**\n\t * Checks if the current row is over {@link #_endRow}.\n\t *\n\t * @private\n\t * @returns {Boolean}\n\t */\n\t_isOverEndRow() {\n\t\t// If #_endRow is defined skip all rows after it.\n\t\treturn this._endRow !== undefined && this._row > this._endRow;\n\t}\n\n\t/**\n\t * Checks if the current cell is over {@link #_endColumn}\n\t *\n\t * @private\n\t * @returns {Boolean}\n\t */\n\t_isOverEndColumn() {\n\t\t// If #_endColumn is defined skip all cells after it.\n\t\treturn this._endColumn !== undefined && this._column > this._endColumn;\n\t}\n\n\t/**\n\t * A common method for formatting the iterator's output value.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} cell The table cell to output.\n\t * @param {Number} [anchorRow] The row index of a cell anchor slot.\n\t * @param {Number} [anchorColumn] The column index of a cell anchor slot.\n\t * @returns {{done: Boolean, value: {cell: *, row: Number, column: *, rowspan: *, colspan: *, cellIndex: Number}}}\n\t */\n\t_formatOutValue( cell, anchorRow = this._row, anchorColumn = this._column ) {\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: new TableSlot( this, cell, anchorRow, anchorColumn )\n\t\t};\n\t}\n\n\t/**\n\t * Checks if the current slot should be skipped.\n\t *\n\t * @private\n\t * @returns {Boolean}\n\t */\n\t_shouldSkipSlot() {\n\t\tconst rowIsMarkedAsSkipped = this._skipRows.has( this._row );\n\t\tconst rowIsBeforeStartRow = this._row < this._startRow;\n\n\t\tconst columnIsBeforeStartColumn = this._column < this._startColumn;\n\t\tconst columnIsAfterEndColumn = this._endColumn !== undefined && this._column > this._endColumn;\n\n\t\treturn rowIsMarkedAsSkipped || rowIsBeforeStartRow || columnIsBeforeStartColumn || columnIsAfterEndColumn;\n\t}\n\n\t/**\n\t * Returns the cell element that is spanned over the current cell location.\n\t *\n\t * @private\n\t * @returns {module:engine/model/element~Element}\n\t */\n\t_getSpanned() {\n\t\tconst rowMap = this._spannedCells.get( this._row );\n\n\t\t// No spans for given row.\n\t\tif ( !rowMap ) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// If spans for given rows has entry for column it means that this location if spanned by other cell.\n\t\treturn rowMap.get( this._column ) || null;\n\t}\n\n\t/**\n\t * Updates spanned cells map relative to the current cell location and its span dimensions.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} cell A cell that is spanned.\n\t * @param {Number} rowspan Cell height.\n\t * @param {Number} colspan Cell width.\n\t */\n\t_recordSpans( cell, rowspan, colspan ) {\n\t\tconst data = {\n\t\t\tcell,\n\t\t\trow: this._row,\n\t\t\tcolumn: this._column\n\t\t};\n\n\t\tfor ( let rowToUpdate = this._row; rowToUpdate < this._row + rowspan; rowToUpdate++ ) {\n\t\t\tfor ( let columnToUpdate = this._column; columnToUpdate < this._column + colspan; columnToUpdate++ ) {\n\t\t\t\tif ( rowToUpdate != this._row || columnToUpdate != this._column ) {\n\t\t\t\t\tthis._markSpannedCell( rowToUpdate, columnToUpdate, data );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Marks the cell location as spanned by another cell.\n\t *\n\t * @private\n\t * @param {Number} row The row index of the cell location.\n\t * @param {Number} column The column index of the cell location.\n\t * @param {Object} data A spanned cell details (cell element, anchor row and column).\n\t */\n\t_markSpannedCell( row, column, data ) {\n\t\tif ( !this._spannedCells.has( row ) ) {\n\t\t\tthis._spannedCells.set( row, new Map() );\n\t\t}\n\n\t\tconst rowSpans = this._spannedCells.get( row );\n\n\t\trowSpans.set( column, data );\n\t}\n}\n\n/**\n * An object returned by {@link module:table/tablewalker~TableWalker} when traversing table cells.\n */\nclass TableSlot {\n\t/**\n\t * Creates an instance of the table walker value.\n\t *\n\t * @protected\n\t * @param {module:table/tablewalker~TableWalker} tableWalker The table walker instance.\n\t * @param {module:engine/model/element~Element} cell The current table cell.\n\t * @param {Number} anchorRow The row index of a cell anchor slot.\n\t * @param {Number} anchorColumn The column index of a cell anchor slot.\n\t */\n\tconstructor( tableWalker, cell, anchorRow, anchorColumn ) {\n\t\t/**\n\t\t * The current table cell.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element}\n\t\t */\n\t\tthis.cell = cell;\n\n\t\t/**\n\t\t * The row index of a table slot.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.row = tableWalker._row;\n\n\t\t/**\n\t\t * The column index of a table slot.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.column = tableWalker._column;\n\n\t\t/**\n\t\t * The row index of a cell anchor slot.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.cellAnchorRow = anchorRow;\n\n\t\t/**\n\t\t * The column index of a cell anchor slot.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t */\n\t\tthis.cellAnchorColumn = anchorColumn;\n\n\t\t/**\n\t\t * The index of the current cell in the parent row.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._cellIndex = tableWalker._cellIndex;\n\n\t\t/**\n\t\t * The index of the current row element in the table.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Number}\n\t\t * @private\n\t\t */\n\t\tthis._rowIndex = tableWalker._rowIndex;\n\n\t\t/**\n\t\t * The table element.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/element~Element}\n\t\t * @private\n\t\t */\n\t\tthis._table = tableWalker._table;\n\t}\n\n\t/**\n\t * Whether the cell is anchored in the current slot.\n\t *\n\t * @readonly\n\t * @returns {Boolean}\n\t */\n\tget isAnchor() {\n\t\treturn this.row === this.cellAnchorRow && this.column === this.cellAnchorColumn;\n\t}\n\n\t/**\n\t * The width of a cell defined by a `colspan` attribute. If the model attribute is not present, it is set to `1`.\n\t *\n\t * @readonly\n\t * @returns {Number}\n\t */\n\tget cellWidth() {\n\t\treturn parseInt( this.cell.getAttribute( 'colspan' ) || 1 );\n\t}\n\n\t/**\n\t * The height of a cell defined by a `rowspan` attribute. If the model attribute is not present, it is set to `1`.\n\t *\n\t * @readonly\n\t * @returns {Number}\n\t */\n\tget cellHeight() {\n\t\treturn parseInt( this.cell.getAttribute( 'rowspan' ) || 1 );\n\t}\n\n\t/**\n\t * The index of the current row element in the table.\n\t *\n\t * @readonly\n\t * @returns {Number}\n\t */\n\tget rowIndex() {\n\t\treturn this._rowIndex;\n\t}\n\n\t/**\n\t * Returns the {@link module:engine/model/position~Position} before the table slot.\n\t *\n\t * @returns {module:engine/model/position~Position}\n\t */\n\tgetPositionBefore() {\n\t\tconst model = this._table.root.document.model;\n\n\t\treturn model.createPositionAt( this._table.getChild( this.row ), this._cellIndex );\n\t}\n\n\t// @if CK_DEBUG // get isSpanned() { throwMissingGetterError( 'isSpanned' ); }\n\t// @if CK_DEBUG // get colspan() { throwMissingGetterError( 'colspan' ); }\n\t// @if CK_DEBUG // get rowspan() { throwMissingGetterError( 'rowspan' ); }\n\t// @if CK_DEBUG // get cellIndex() { throwMissingGetterError( 'cellIndex' ); }\n}\n\n/**\n * This `TableSlot`'s getter (property) was removed in CKEditor 5 v20.0.0.\n *\n * Check out the new `TableWalker`'s API in the documentation.\n *\n * @error tableslot-getter-removed\n * @param {String} getterName\n */\n\n// @if CK_DEBUG // function throwMissingGetterError( getterName ) {\n// @if CK_DEBUG //\t\tthrow new CKEditorError( 'tableslot-getter-removed', this, {\n// @if CK_DEBUG //\t\t\tgetterName\n// @if CK_DEBUG //\t\t} );\n// @if CK_DEBUG // }\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/ui/colorinputview\n */\n\nimport { View, InputTextView, ButtonView, createDropdown, ColorGridView } from 'ckeditor5/src/ui';\nimport { icons } from 'ckeditor5/src/core';\n\nimport '../../theme/colorinput.css';\n\n/**\n * The color input view class. It allows the user to type in a color (hex, rgb, etc.)\n * or choose it from the configurable color palette with a preview.\n *\n * @private\n * @extends module:ui/view~View\n */\nexport default class ColorInputView extends View {\n\t/**\n\t * Creates an instance of the color input view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The locale instance.\n\t * @param {Object} options The input options.\n\t * @param {Array.<module:ui/colorgrid/colorgrid~ColorDefinition>} options.colorDefinitions The colors to be displayed\n\t * in the palette inside the input's dropdown.\n\t * @param {Number} options.columns The number of columns in which the colors will be displayed.\n\t * @param {String} [options.defaultColorValue] If specified, the color input view will replace the \"Remove color\" button with\n\t * the \"Restore default\" button. Instead of clearing the input field, the default color value will be set.\n\t */\n\tconstructor( locale, options ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * The value of the input.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #value\n\t\t * @default ''\n\t\t */\n\t\tthis.set( 'value', '' );\n\n\t\t/**\n\t\t * The `id` attribute of the input (i.e. to pair with the `<label>` element).\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #id\n\t\t */\n\t\tthis.set( 'id' );\n\n\t\t/**\n\t\t * Controls whether the input view is in read-only mode.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t * @default false\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * Set to `true` when the field has some error. Usually controlled via\n\t\t * {@link module:ui/labeledinput/labeledinputview~LabeledInputView#errorText}.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #hasError\n\t\t * @default false\n\t\t */\n\t\tthis.set( 'hasError', false );\n\n\t\t/**\n\t\t * An observable flag set to `true` when the input is focused by the user.\n\t\t * `false` otherwise.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #isFocused\n\t\t * @default false\n\t\t */\n\t\tthis.set( 'isFocused', false );\n\n\t\t/**\n\t\t * An observable flag set to `true` when the input contains no text.\n\t\t *\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {Boolean} #isEmpty\n\t\t * @default true\n\t\t */\n\t\tthis.set( 'isEmpty', true );\n\n\t\t/**\n\t\t * The `id` of the element describing this field. When the field has\n\t\t * some error, it helps screen readers read the error text.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #ariaDescribedById\n\t\t */\n\t\tthis.set( 'ariaDescribedById' );\n\n\t\t/**\n\t\t * A cached reference to the options passed to the constructor.\n\t\t *\n\t\t * @member {Object}\n\t\t */\n\t\tthis.options = options;\n\n\t\t/**\n\t\t * An instance of the dropdown allowing to select a color from a grid.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:ui/dropdown/dropdown~DropdownView}\n\t\t */\n\t\tthis._dropdownView = this._createDropdownView();\n\n\t\t/**\n\t\t * An instance of the input allowing the user to type a color value.\n\t\t *\n\t\t * @protected\n\t\t * @member {module:ui/inputtext/inputtextview~InputTextView}\n\t\t */\n\t\tthis._inputView = this._createInputTextView();\n\n\t\t/**\n\t\t * The flag that indicates whether the user is still typing.\n\t\t * If set to true, it means that the text input field ({@link #_inputView}) still has the focus.\n\t\t * So, we should interrupt the user by replacing the input's value.\n\t\t *\n\t\t * @protected\n\t\t * @member {Boolean}\n\t\t */\n\t\tthis._stillTyping = false;\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-input-color',\n\t\t\t\t\tbind.if( 'hasError', 'ck-error' )\n\t\t\t\t],\n\t\t\t\tid: bind.to( 'id' ),\n\t\t\t\t'aria-invalid': bind.if( 'hasError', true ),\n\t\t\t\t'aria-describedby': bind.to( 'ariaDescribedById' )\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis._dropdownView,\n\t\t\t\tthis._inputView\n\t\t\t]\n\t\t} );\n\n\t\tthis.on( 'change:value', ( evt, name, inputValue ) => this._setInputValue( inputValue ) );\n\t}\n\n\t/**\n\t * Focuses the input.\n\t */\n\tfocus() {\n\t\tthis._inputView.focus();\n\t}\n\n\t/**\n\t * Creates and configures the {@link #_dropdownView}.\n\t *\n\t * @private\n\t */\n\t_createDropdownView() {\n\t\tconst locale = this.locale;\n\t\tconst t = locale.t;\n\t\tconst bind = this.bindTemplate;\n\t\tconst colorGrid = this._createColorGrid( locale );\n\t\tconst dropdown = createDropdown( locale );\n\t\tconst colorPreview = new View();\n\t\tconst removeColorButton = this._createRemoveColorButton();\n\n\t\tcolorPreview.setTemplate( {\n\t\t\ttag: 'span',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-input-color__button__preview'\n\t\t\t\t],\n\t\t\t\tstyle: {\n\t\t\t\t\tbackgroundColor: bind.to( 'value' )\n\t\t\t\t}\n\t\t\t},\n\t\t\tchildren: [ {\n\t\t\t\ttag: 'span',\n\t\t\t\tattributes: {\n\t\t\t\t\tclass: [\n\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t'ck-input-color__button__preview__no-color-indicator',\n\t\t\t\t\t\tbind.if( 'value', 'ck-hidden', value => value != '' )\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t} ]\n\t\t} );\n\n\t\tdropdown.buttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\tclass: 'ck-input-color__button'\n\t\t\t}\n\t\t} );\n\n\t\tdropdown.buttonView.children.add( colorPreview );\n\t\tdropdown.buttonView.tooltip = t( 'Color picker' );\n\n\t\tdropdown.panelPosition = locale.uiLanguageDirection === 'rtl' ? 'se' : 'sw';\n\t\tdropdown.panelView.children.add( removeColorButton );\n\t\tdropdown.panelView.children.add( colorGrid );\n\t\tdropdown.bind( 'isEnabled' ).to( this, 'isReadOnly', value => !value );\n\n\t\treturn dropdown;\n\t}\n\n\t/**\n\t * Creates and configures an instance of {@link module:ui/inputtext/inputtextview~InputTextView}.\n\t *\n\t * @private\n\t * @returns {module:ui/inputtext/inputtextview~InputTextView} A configured instance to be set as {@link #_inputView}.\n\t */\n\t_createInputTextView() {\n\t\tconst locale = this.locale;\n\t\tconst inputView = new InputTextView( locale );\n\n\t\tinputView.extendTemplate( {\n\t\t\ton: {\n\t\t\t\tblur: inputView.bindTemplate.to( 'blur' )\n\t\t\t}\n\t\t} );\n\n\t\tinputView.value = this.value;\n\t\tinputView.bind( 'isReadOnly', 'hasError' ).to( this );\n\t\tthis.bind( 'isFocused', 'isEmpty' ).to( inputView );\n\n\t\tinputView.on( 'input', () => {\n\t\t\tconst inputValue = inputView.element.value;\n\t\t\t// Check if the value matches one of our defined colors' label.\n\t\t\tconst mappedColor = this.options.colorDefinitions.find( def => inputValue === def.label );\n\n\t\t\tthis._stillTyping = true;\n\t\t\tthis.value = mappedColor && mappedColor.color || inputValue;\n\t\t} );\n\n\t\tinputView.on( 'blur', () => {\n\t\t\tthis._stillTyping = false;\n\t\t\tthis._setInputValue( inputView.element.value );\n\t\t} );\n\n\t\tinputView.delegate( 'input' ).to( this );\n\n\t\treturn inputView;\n\t}\n\n\t/**\n\t * Creates and configures the button that clears the color.\n\t *\n\t * @private\n\t */\n\t_createRemoveColorButton() {\n\t\tconst locale = this.locale;\n\t\tconst t = locale.t;\n\t\tconst removeColorButton = new ButtonView( locale );\n\t\tconst defaultColor = this.options.defaultColorValue || '';\n\t\tconst removeColorButtonLabel = defaultColor ? t( 'Restore default' ) : t( 'Remove color' );\n\n\t\tremoveColorButton.class = 'ck-input-color__remove-color';\n\t\tremoveColorButton.withText = true;\n\t\tremoveColorButton.icon = icons.eraser;\n\t\tremoveColorButton.label = removeColorButtonLabel;\n\t\tremoveColorButton.on( 'execute', () => {\n\t\t\tthis.value = defaultColor;\n\t\t\tthis._dropdownView.isOpen = false;\n\t\t\tthis.fire( 'input' );\n\t\t} );\n\n\t\treturn removeColorButton;\n\t}\n\n\t/**\n\t * Creates and configures the color grid inside the {@link #_dropdownView}.\n\t *\n\t * @private\n\t */\n\t_createColorGrid( locale ) {\n\t\tconst colorGrid = new ColorGridView( locale, {\n\t\t\tcolorDefinitions: this.options.colorDefinitions,\n\t\t\tcolumns: this.options.columns\n\t\t} );\n\n\t\tcolorGrid.on( 'execute', ( evtData, data ) => {\n\t\t\tthis.value = data.value;\n\t\t\tthis._dropdownView.isOpen = false;\n\t\t\tthis.fire( 'input' );\n\t\t} );\n\t\tcolorGrid.bind( 'selectedColor' ).to( this, 'value' );\n\n\t\treturn colorGrid;\n\t}\n\n\t/**\n\t * Sets {@link #_inputView}'s value property to the color value or color label,\n\t * if there is one and the user is not typing.\n\t *\n\t * Handles cases like:\n\t *\n\t * * Someone picks the color in the grid.\n\t * * The color is set from the plugin level.\n\t *\n\t * @private\n\t * @param {String} inputValue Color value to be set.\n\t */\n\t_setInputValue( inputValue ) {\n\t\tif ( !this._stillTyping ) {\n\t\t\tconst normalizedInputValue = normalizeColor( inputValue );\n\t\t\t// Check if the value matches one of our defined colors.\n\t\t\tconst mappedColor = this.options.colorDefinitions.find( def => normalizedInputValue === normalizeColor( def.color ) );\n\n\t\t\tif ( mappedColor ) {\n\t\t\t\tthis._inputView.value = mappedColor.label;\n\t\t\t} else {\n\t\t\t\tthis._inputView.value = inputValue || '';\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Normalizes color value, by stripping extensive whitespace.\n// For example., transforms:\n// * ` rgb( 25 50 0 )` to `rgb(25 50 0)`,\n// * \"\\t rgb( 25 , 50,0 )\t\t\" to `rgb(25 50 0)`.\n//\n// @param {String} colorString The value to be normalized.\n// @returns {String}\nfunction normalizeColor( colorString ) {\n\treturn colorString\n\t\t// Remove any whitespace right after `(` or `,`.\n\t\t.replace( /([(,])\\s+/g, '$1' )\n\t\t// Remove any whitespace at the beginning or right before the end, `)`, `,`, or another whitespace.\n\t\t.replace( /^\\s+|\\s+(?=[),\\s]|$)/g, '' )\n\t\t// Then, replace `,` or whitespace with a single space.\n\t\t.replace( /,|\\s/g, ' ' );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/ui/formrowview\n */\n\nimport { View } from 'ckeditor5/src/ui';\n\nimport '../../theme/formrow.css';\n\n/**\n * The class representing a single row in a complex form,\n * used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}.\n *\n * **Note**: For now this class is private. When more use cases arrive (beyond ckeditor5-table),\n * it will become a component in ckeditor5-ui.\n *\n * @private\n * @extends module:ui/view~View\n */\nexport default class FormRowView extends View {\n\t/**\n\t * Creates an instance of the form row class.\n\t *\n\t * @param {module:utils/locale~Locale} locale The locale instance.\n\t * @param {Object} options\n\t * @param {Array.<module:ui/view~View>} options.children\n\t * @param {String} [options.class]\n\t * @param {module:ui/view~View} [options.labelView] When passed, the row gets the `group` and `aria-labelledby`\n\t * DOM attributes and gets described by the label.\n\t */\n\tconstructor( locale, options = {} ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * An additional CSS class added to the {@link #element}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #class\n\t\t */\n\t\tthis.set( 'class', options.class || null );\n\n\t\t/**\n\t\t * A collection of row items (buttons, dropdowns, etc.).\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\tif ( options.children ) {\n\t\t\toptions.children.forEach( child => this.children.add( child ) );\n\t\t}\n\n\t\t/**\n\t\t * The role property reflected by the `role` DOM attribute of the {@link #element}.\n\t\t *\n\t\t * **Note**: Used only when a `labelView` is passed to constructor `options`.\n\t\t *\n\t\t * @private\n\t\t * @observable\n\t\t * @member {String} #role\n\t\t */\n\t\tthis.set( '_role', null );\n\n\t\t/**\n\t\t * The ARIA property reflected by the `aria-labelledby` DOM attribute of the {@link #element}.\n\t\t *\n\t\t * **Note**: Used only when a `labelView` is passed to constructor `options`.\n\t\t *\n\t\t * @private\n\t\t * @observable\n\t\t * @member {String} #ariaLabelledBy\n\t\t */\n\t\tthis.set( '_ariaLabelledBy', null );\n\n\t\tif ( options.labelView ) {\n\t\t\tthis.set( {\n\t\t\t\t_role: 'group',\n\t\t\t\t_ariaLabelledBy: options.labelView.id\n\t\t\t} );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-form__row',\n\t\t\t\t\tbind.to( 'class' )\n\t\t\t\t],\n\t\t\t\trole: bind.to( '_role' ),\n\t\t\t\t'aria-labelledby': bind.to( '_ariaLabelledBy' )\n\t\t\t},\n\t\t\tchildren: this.children\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/ui/inserttableview\n */\n\nimport { View } from 'ckeditor5/src/ui';\n\nimport './../../theme/inserttable.css';\n\n/**\n * The table size view.\n *\n * It renders a 10x10 grid to choose the inserted table size.\n *\n * @extends module:ui/view~View\n * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable\n */\nexport default class InsertTableView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * A collection of table size box items.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection}\n\t\t */\n\t\tthis.items = this._createGridCollection();\n\n\t\t/**\n\t\t * The currently selected number of rows of the new table.\n\t\t *\n\t\t * @observable\n\t\t * @member {Number} #rows\n\t\t */\n\t\tthis.set( 'rows', 0 );\n\n\t\t/**\n\t\t * The currently selected number of columns of the new table.\n\t\t *\n\t\t * @observable\n\t\t * @member {Number} #columns\n\t\t */\n\t\tthis.set( 'columns', 0 );\n\n\t\t/**\n\t\t * The label text displayed under the boxes.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t */\n\t\tthis.bind( 'label' )\n\t\t\t.to( this, 'columns', this, 'rows', ( columns, rows ) => `${ rows } × ${ columns }` );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [ 'ck' ]\n\t\t\t},\n\n\t\t\tchildren: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [ 'ck-insert-table-dropdown__grid' ]\n\t\t\t\t\t},\n\t\t\t\t\ton: {\n\t\t\t\t\t\t'mouseover@.ck-insert-table-dropdown-grid-box': bind.to( 'boxover' )\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.items\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'div',\n\t\t\t\t\tattributes: {\n\t\t\t\t\t\tclass: [ 'ck-insert-table-dropdown__label' ]\n\t\t\t\t\t},\n\t\t\t\t\tchildren: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttext: bind.to( 'label' )\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t],\n\n\t\t\ton: {\n\t\t\t\tmousedown: bind.to( evt => {\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t} ),\n\n\t\t\t\tclick: bind.to( () => {\n\t\t\t\t\tthis.fire( 'execute' );\n\t\t\t\t} )\n\t\t\t}\n\t\t} );\n\n\t\tthis.on( 'boxover', ( evt, domEvt ) => {\n\t\t\tconst { row, column } = domEvt.target.dataset;\n\n\t\t\t// As row & column indexes are zero-based transform it to number of selected rows & columns.\n\t\t\tthis.set( {\n\t\t\t\trows: parseInt( row ),\n\t\t\t\tcolumns: parseInt( column )\n\t\t\t} );\n\t\t} );\n\n\t\tthis.on( 'change:columns', () => {\n\t\t\tthis._highlightGridBoxes();\n\t\t} );\n\n\t\tthis.on( 'change:rows', () => {\n\t\t\tthis._highlightGridBoxes();\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocus() {\n\t\t// The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.\n\t\t// The method should be implemented while working on keyboard support for this view. See #22.\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocusLast() {\n\t\t// The dropdown panel expects DropdownPanelFocusable interface on views passed to dropdown panel. See #30.\n\t\t// The method should be implemented while working on keyboard support for this view. See #22.\n\t}\n\n\t/**\n\t * Highlights grid boxes depending on rows and columns selected.\n\t *\n\t * @private\n\t */\n\t_highlightGridBoxes() {\n\t\tconst rows = this.rows;\n\t\tconst columns = this.columns;\n\n\t\tthis.items.map( ( boxView, index ) => {\n\t\t\t// Translate box index to the row & column index.\n\t\t\tconst itemRow = Math.floor( index / 10 );\n\t\t\tconst itemColumn = index % 10;\n\n\t\t\t// Grid box is highlighted when its row & column index belongs to selected number of rows & columns.\n\t\t\tconst isOn = itemRow < rows && itemColumn < columns;\n\n\t\t\tboxView.set( 'isOn', isOn );\n\t\t} );\n\t}\n\n\t/**\n\t * @private\n\t * @returns {module:ui/viewcollection~ViewCollection} A view collection containing boxes to be placed in a table grid.\n\t */\n\t_createGridCollection() {\n\t\tconst boxes = [];\n\n\t\t// Add grid boxes to table selection view.\n\t\tfor ( let index = 0; index < 100; index++ ) {\n\t\t\tconst row = Math.floor( index / 10 );\n\t\t\tconst column = index % 10;\n\n\t\t\tboxes.push( new TableSizeGridBoxView( this.locale, row + 1, column + 1 ) );\n\t\t}\n\n\t\treturn this.createCollection( boxes );\n\t}\n\n\t/**\n\t * Fired when the mouse hover over one of the {@link #items child grid boxes}.\n\t *\n\t * @event boxover\n\t */\n}\n\n/**\n * A single grid box view element.\n *\n * This class is used to render the table size selection grid in {@link module:table/ui/inserttableview~InsertTableView}.\n *\n * @private\n */\nclass TableSizeGridBoxView extends View {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( locale, row, column ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * Controls whether the grid box view is \"on\".\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isOn\n\t\t */\n\t\tthis.set( 'isOn', false );\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: [\n\t\t\t\t\t'ck-insert-table-dropdown-grid-box',\n\t\t\t\t\tbind.if( 'isOn', 'ck-on' )\n\t\t\t\t],\n\t\t\t\t'data-row': row,\n\t\t\t\t'data-column': column\n\t\t\t}\n\t\t} );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/common\n */\n\n/**\n * A common method to update the numeric value. If a value is the default one, it will be unset.\n *\n * @param {String} key An attribute key.\n * @param {*} value The new attribute value.\n * @param {module:engine/model/item~Item} item A model item on which the attribute will be set.\n * @param {module:engine/model/writer~Writer} writer\n * @param {*} defaultValue The default attribute value. If a value is lower or equal, it will be unset.\n */\nexport function updateNumericAttribute( key, value, item, writer, defaultValue = 1 ) {\n\tif ( value > defaultValue ) {\n\t\twriter.setAttribute( key, value, item );\n\t} else {\n\t\twriter.removeAttribute( key, item );\n\t}\n}\n\n/**\n * A common method to create an empty table cell. It creates a proper model structure as a table cell must have at least one block inside.\n *\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @param {module:engine/model/position~Position} insertPosition The position at which the table cell should be inserted.\n * @param {Object} attributes The element attributes.\n * @returns {module:engine/model/element~Element} Created table cell.\n */\nexport function createEmptyTableCell( writer, insertPosition, attributes = {} ) {\n\tconst tableCell = writer.createElement( 'tableCell', attributes );\n\n\twriter.insertElement( 'paragraph', tableCell );\n\twriter.insert( tableCell, insertPosition );\n\n\treturn tableCell;\n}\n\n/**\n * Checks if a table cell belongs to the heading column section.\n *\n * @param {module:table/tableutils~TableUtils} tableUtils\n * @param {module:engine/model/element~Element} tableCell\n * @returns {Boolean}\n */\nexport function isHeadingColumnCell( tableUtils, tableCell ) {\n\tconst table = tableCell.parent.parent;\n\tconst headingColumns = parseInt( table.getAttribute( 'headingColumns' ) || 0 );\n\tconst { column } = tableUtils.getCellLocation( tableCell );\n\n\treturn !!headingColumns && column < headingColumns;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/selection\n */\n\nimport TableWalker from '../tablewalker';\n\n/**\n * Returns all model table cells that are fully selected (from the outside)\n * within the provided model selection's ranges.\n *\n * To obtain the cells selected from the inside, use\n * {@link module:table/utils/selection~getTableCellsContainingSelection}.\n *\n * @param {module:engine/model/selection~Selection} selection\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getSelectedTableCells( selection ) {\n\tconst cells = [];\n\n\tfor ( const range of sortRanges( selection.getRanges() ) ) {\n\t\tconst element = range.getContainedElement();\n\n\t\tif ( element && element.is( 'element', 'tableCell' ) ) {\n\t\t\tcells.push( element );\n\t\t}\n\t}\n\n\treturn cells;\n}\n\n/**\n * Returns all model table cells that the provided model selection's ranges\n * {@link module:engine/model/range~Range#start} inside.\n *\n * To obtain the cells selected from the outside, use\n * {@link module:table/utils/selection~getSelectedTableCells}.\n *\n * @param {module:engine/model/selection~Selection} selection\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getTableCellsContainingSelection( selection ) {\n\tconst cells = [];\n\n\tfor ( const range of selection.getRanges() ) {\n\t\tconst cellWithSelection = range.start.findAncestor( 'tableCell' );\n\n\t\tif ( cellWithSelection ) {\n\t\t\tcells.push( cellWithSelection );\n\t\t}\n\t}\n\n\treturn cells;\n}\n\n/**\n * Returns all model table cells that are either completely selected\n * by selection ranges or host selection range\n * {@link module:engine/model/range~Range#start start positions} inside them.\n *\n * Combines {@link module:table/utils/selection~getTableCellsContainingSelection} and\n * {@link module:table/utils/selection~getSelectedTableCells}.\n *\n * @param {module:engine/model/selection~Selection} selection\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getSelectionAffectedTableCells( selection ) {\n\tconst selectedCells = getSelectedTableCells( selection );\n\n\tif ( selectedCells.length ) {\n\t\treturn selectedCells;\n\t}\n\n\treturn getTableCellsContainingSelection( selection );\n}\n\n/**\n * Returns an object with the `first` and `last` row index contained in the given `tableCells`.\n *\n *\t\tconst selectedTableCells = getSelectedTableCells( editor.model.document.selection );\n *\n *\t\tconst { first, last } = getRowIndexes( selectedTableCells );\n *\n *\t\tconsole.log( `Selected rows: ${ first } to ${ last }` );\n *\n * @param {Array.<module:engine/model/element~Element>} tableCells\n * @returns {Object} Returns an object with the `first` and `last` table row indexes.\n */\nexport function getRowIndexes( tableCells ) {\n\tconst indexes = tableCells.map( cell => cell.parent.index );\n\n\treturn getFirstLastIndexesObject( indexes );\n}\n\n/**\n * Returns an object with the `first` and `last` column index contained in the given `tableCells`.\n *\n *\t\tconst selectedTableCells = getSelectedTableCells( editor.model.document.selection );\n *\n *\t\tconst { first, last } = getColumnIndexes( selectedTableCells );\n *\n *\t\tconsole.log( `Selected columns: ${ first } to ${ last }` );\n *\n * @param {Array.<module:engine/model/element~Element>} tableCells\n * @returns {Object} Returns an object with the `first` and `last` table column indexes.\n */\nexport function getColumnIndexes( tableCells ) {\n\tconst table = tableCells[ 0 ].findAncestor( 'table' );\n\tconst tableMap = [ ...new TableWalker( table ) ];\n\n\tconst indexes = tableMap\n\t\t.filter( entry => tableCells.includes( entry.cell ) )\n\t\t.map( entry => entry.column );\n\n\treturn getFirstLastIndexesObject( indexes );\n}\n\n/**\n * Checks if the selection contains cells that do not exceed rectangular selection.\n *\n * In a table below:\n *\n *\t\t┌───┬───┬───┬───┐\n *\t\t│ a │ b │ c │ d │\n *\t\t├───┴───┼───┤ │\n *\t\t│ e │ f │ │\n *\t\t│ ├───┼───┤\n *\t\t│ │ g │ h │\n *\t\t└───────┴───┴───┘\n *\n * Valid selections are these which create a solid rectangle (without gaps), such as:\n * - a, b (two horizontal cells)\n * - c, f (two vertical cells)\n * - a, b, e (cell \"e\" spans over four cells)\n * - c, d, f (cell d spans over a cell in the row below)\n *\n * While an invalid selection would be:\n * - a, c (the unselected cell \"b\" creates a gap)\n * - f, g, h (cell \"d\" spans over a cell from the row of \"f\" cell - thus creates a gap)\n *\n * @param {Array.<module:engine/model/element~Element>} selectedTableCells\n * @param {module:table/tableutils~TableUtils} tableUtils\n * @returns {Boolean}\n */\nexport function isSelectionRectangular( selectedTableCells, tableUtils ) {\n\tif ( selectedTableCells.length < 2 || !areCellInTheSameTableSection( selectedTableCells ) ) {\n\t\treturn false;\n\t}\n\n\t// A valid selection is a fully occupied rectangle composed of table cells.\n\t// Below we will calculate the area of a selected table cells and the area of valid selection.\n\t// The area of a valid selection is defined by top-left and bottom-right cells.\n\tconst rows = new Set();\n\tconst columns = new Set();\n\n\tlet areaOfSelectedCells = 0;\n\n\tfor ( const tableCell of selectedTableCells ) {\n\t\tconst { row, column } = tableUtils.getCellLocation( tableCell );\n\t\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\t\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\t\t// Record row & column indexes of current cell.\n\t\trows.add( row );\n\t\tcolumns.add( column );\n\n\t\t// For cells that spans over multiple rows add also the last row that this cell spans over.\n\t\tif ( rowspan > 1 ) {\n\t\t\trows.add( row + rowspan - 1 );\n\t\t}\n\n\t\t// For cells that spans over multiple columns add also the last column that this cell spans over.\n\t\tif ( colspan > 1 ) {\n\t\t\tcolumns.add( column + colspan - 1 );\n\t\t}\n\n\t\tareaOfSelectedCells += ( rowspan * colspan );\n\t}\n\n\t// We can only merge table cells that are in adjacent rows...\n\tconst areaOfValidSelection = getBiggestRectangleArea( rows, columns );\n\n\treturn areaOfValidSelection == areaOfSelectedCells;\n}\n\n/**\n * Returns array of sorted ranges.\n *\n * @param {Iterable.<module:engine/model/range~Range>} ranges\n * @return {Array.<module:engine/model/range~Range>}\n */\nexport function sortRanges( ranges ) {\n\treturn Array.from( ranges ).sort( compareRangeOrder );\n}\n\n// Helper method to get an object with `first` and `last` indexes from an unsorted array of indexes.\nfunction getFirstLastIndexesObject( indexes ) {\n\tconst allIndexesSorted = indexes.sort( ( indexA, indexB ) => indexA - indexB );\n\n\tconst first = allIndexesSorted[ 0 ];\n\tconst last = allIndexesSorted[ allIndexesSorted.length - 1 ];\n\n\treturn { first, last };\n}\n\nfunction compareRangeOrder( rangeA, rangeB ) {\n\t// Since table cell ranges are disjoint, it's enough to check their start positions.\n\tconst posA = rangeA.start;\n\tconst posB = rangeB.start;\n\n\t// Checking for equal position (returning 0) is not needed because this would be either:\n\t// a. Intersecting range (not allowed by model)\n\t// b. Collapsed range on the same position (allowed by model but should not happen).\n\treturn posA.isBefore( posB ) ? -1 : 1;\n}\n\n// Calculates the area of a maximum rectangle that can span over the provided row & column indexes.\n//\n// @param {Array.<Number>} rows\n// @param {Array.<Number>} columns\n// @returns {Number}\nfunction getBiggestRectangleArea( rows, columns ) {\n\tconst rowsIndexes = Array.from( rows.values() );\n\tconst columnIndexes = Array.from( columns.values() );\n\n\tconst lastRow = Math.max( ...rowsIndexes );\n\tconst firstRow = Math.min( ...rowsIndexes );\n\tconst lastColumn = Math.max( ...columnIndexes );\n\tconst firstColumn = Math.min( ...columnIndexes );\n\n\treturn ( lastRow - firstRow + 1 ) * ( lastColumn - firstColumn + 1 );\n}\n\n// Checks if the selection does not mix a header (column or row) with other cells.\n//\n// For instance, in the table below valid selections consist of cells with the same letter only.\n// So, a-a (same heading row and column) or d-d (body cells) are valid while c-d or a-b are not.\n//\n//\t\t header columns\n//\t\t ↓ ↓\n//\t\t┌───┬───┬───┬───┐\n//\t\t│ a │ a │ b │ b │ ← header row\n//\t\t├───┼───┼───┼───┤\n//\t\t│ c │ c │ d │ d │\n//\t\t├───┼───┼───┼───┤\n//\t\t│ c │ c │ d │ d │\n//\t\t└───┴───┴───┴───┘\nfunction areCellInTheSameTableSection( tableCells ) {\n\tconst table = tableCells[ 0 ].findAncestor( 'table' );\n\n\tconst rowIndexes = getRowIndexes( tableCells );\n\tconst headingRows = parseInt( table.getAttribute( 'headingRows' ) || 0 );\n\n\t// Calculating row indexes is a bit cheaper so if this check fails we can't merge.\n\tif ( !areIndexesInSameSection( rowIndexes, headingRows ) ) {\n\t\treturn false;\n\t}\n\n\tconst headingColumns = parseInt( table.getAttribute( 'headingColumns' ) || 0 );\n\tconst columnIndexes = getColumnIndexes( tableCells );\n\n\t// Similarly cells must be in same column section.\n\treturn areIndexesInSameSection( columnIndexes, headingColumns );\n}\n\n// Unified check if table rows/columns indexes are in the same heading/body section.\nfunction areIndexesInSameSection( { first, last }, headingSectionSize ) {\n\tconst firstCellIsInHeading = first < headingSectionSize;\n\tconst lastCellIsInHeading = last < headingSectionSize;\n\n\treturn firstCellIsInHeading === lastCellIsInHeading;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/structure\n */\n\nimport TableWalker from '../tablewalker';\nimport { createEmptyTableCell, updateNumericAttribute } from './common';\n\n/**\n * Returns a cropped table according to given dimensions.\n\n * To return a cropped table that starts at first row and first column and end in third row and column:\n *\n *\t\tconst croppedTable = cropTableToDimensions( table, {\n *\t\t\tstartRow: 1,\n *\t\t\tendRow: 3,\n *\t\t\tstartColumn: 1,\n *\t\t\tendColumn: 3\n *\t\t}, writer );\n *\n * Calling the code above for the table below:\n *\n *\t\t 0 1 2 3 4 0 1 2\n *\t\t ┌───┬───┬───┬───┬───┐\n *\t\t 0 │ a │ b │ c │ d │ e │\n *\t\t ├───┴───┤ ├───┴───┤ ┌───┬───┬───┐\n *\t\t 1 │ f │ │ g │ │ │ │ g │ 0\n *\t\t ├───┬───┴───┼───┬───┤ will return: ├───┴───┼───┤\n *\t\t 2 │ h │ i │ j │ k │ │ i │ j │ 1\n *\t\t ├───┤ ├───┤ │ │ ├───┤\n *\t\t 3 │ l │ │ m │ │ │ │ m │ 2\n *\t\t ├───┼───┬───┤ ├───┤ └───────┴───┘\n *\t\t 4 │ n │ o │ p │ │ q │\n *\t\t └───┴───┴───┴───┴───┘\n *\n * @param {module:engine/model/element~Element} sourceTable\n * @param {Object} cropDimensions\n * @param {Number} cropDimensions.startRow\n * @param {Number} cropDimensions.startColumn\n * @param {Number} cropDimensions.endRow\n * @param {Number} cropDimensions.endColumn\n * @param {module:engine/model/writer~Writer} writer\n * @returns {module:engine/model/element~Element}\n */\nexport function cropTableToDimensions( sourceTable, cropDimensions, writer ) {\n\tconst { startRow, startColumn, endRow, endColumn } = cropDimensions;\n\n\t// Create empty table with empty rows equal to crop height.\n\tconst croppedTable = writer.createElement( 'table' );\n\tconst cropHeight = endRow - startRow + 1;\n\n\tfor ( let i = 0; i < cropHeight; i++ ) {\n\t\twriter.insertElement( 'tableRow', croppedTable, 'end' );\n\t}\n\n\tconst tableMap = [ ...new TableWalker( sourceTable, { startRow, endRow, startColumn, endColumn, includeAllSlots: true } ) ];\n\n\t// Iterate over source table slots (including empty - spanned - ones).\n\tfor ( const { row: sourceRow, column: sourceColumn, cell: tableCell, isAnchor, cellAnchorRow, cellAnchorColumn } of tableMap ) {\n\t\t// Row index in cropped table.\n\t\tconst rowInCroppedTable = sourceRow - startRow;\n\t\tconst row = croppedTable.getChild( rowInCroppedTable );\n\n\t\t// For empty slots: fill the gap with empty table cell.\n\t\tif ( !isAnchor ) {\n\t\t\t// But fill the gap only if the spanning cell is anchored outside cropped area.\n\t\t\t// In the table from method jsdoc those cells are: \"c\" & \"f\".\n\t\t\tif ( cellAnchorRow < startRow || cellAnchorColumn < startColumn ) {\n\t\t\t\tcreateEmptyTableCell( writer, writer.createPositionAt( row, 'end' ) );\n\t\t\t}\n\t\t}\n\t\t// Otherwise clone the cell with all children and trim if it exceeds cropped area.\n\t\telse {\n\t\t\tconst tableCellCopy = writer.cloneElement( tableCell );\n\n\t\t\twriter.append( tableCellCopy, row );\n\n\t\t\t// Trim table if it exceeds cropped area.\n\t\t\t// In the table from method jsdoc those cells are: \"g\" & \"m\".\n\t\t\ttrimTableCellIfNeeded( tableCellCopy, sourceRow, sourceColumn, endRow, endColumn, writer );\n\t\t}\n\t}\n\n\t// Adjust heading rows & columns in cropped table if crop selection includes headings parts.\n\taddHeadingsToCroppedTable( croppedTable, sourceTable, startRow, startColumn, writer );\n\n\treturn croppedTable;\n}\n\n/**\n * Returns slot info of cells that starts above and overlaps a given row.\n *\n * In a table below, passing `overlapRow = 3`\n *\n *\t\t ┌───┬───┬───┬───┬───┐\n *\t\t0 │ a │ b │ c │ d │ e │\n *\t\t │ ├───┼───┼───┼───┤\n *\t\t1 │ │ f │ g │ h │ i │\n *\t\t ├───┤ ├───┼───┤ │\n *\t\t2 │ j │ │ k │ l │ │\n *\t\t │ │ │ ├───┼───┤\n *\t\t3 │ │ │ │ m │ n │ <- overlap row to check\n *\t\t ├───┼───┤ │ ├───│\n *\t\t4 │ o │ p │ │ │ q │\n *\t\t └───┴───┴───┴───┴───┘\n *\n * will return slot info for cells: \"j\", \"f\", \"k\".\n *\n * @param {module:engine/model/element~Element} table The table to check.\n * @param {Number} overlapRow The index of the row to check.\n * @param {Number} [startRow=0] A row to start analysis. Use it when it is known that the cells above that row will not overlap.\n * @returns {Array.<module:table/tablewalker~TableSlot>}\n */\nexport function getVerticallyOverlappingCells( table, overlapRow, startRow = 0 ) {\n\tconst cells = [];\n\n\tconst tableWalker = new TableWalker( table, { startRow, endRow: overlapRow - 1 } );\n\n\tfor ( const slotInfo of tableWalker ) {\n\t\tconst { row, cellHeight } = slotInfo;\n\t\tconst cellEndRow = row + cellHeight - 1;\n\n\t\tif ( row < overlapRow && overlapRow <= cellEndRow ) {\n\t\t\tcells.push( slotInfo );\n\t\t}\n\t}\n\n\treturn cells;\n}\n\n/**\n * Splits the table cell horizontally.\n *\n * @param {module:engine/model/element~Element} tableCell\n * @param {Number} splitRow\n * @param {module:engine/model/writer~Writer} writer\n * @returns {module:engine/model/element~Element} Created table cell.\n */\nexport function splitHorizontally( tableCell, splitRow, writer ) {\n\tconst tableRow = tableCell.parent;\n\tconst table = tableRow.parent;\n\tconst rowIndex = tableRow.index;\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) );\n\tconst newRowspan = splitRow - rowIndex;\n\n\tconst newCellAttributes = {};\n\tconst newCellRowSpan = rowspan - newRowspan;\n\n\tif ( newCellRowSpan > 1 ) {\n\t\tnewCellAttributes.rowspan = newCellRowSpan;\n\t}\n\n\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\n\tif ( colspan > 1 ) {\n\t\tnewCellAttributes.colspan = colspan;\n\t}\n\n\tconst startRow = rowIndex;\n\tconst endRow = startRow + newRowspan;\n\tconst tableMap = [ ...new TableWalker( table, { startRow, endRow, includeAllSlots: true } ) ];\n\n\tlet newCell = null;\n\tlet columnIndex;\n\n\tfor ( const tableSlot of tableMap ) {\n\t\tconst { row, column, cell } = tableSlot;\n\n\t\tif ( cell === tableCell && columnIndex === undefined ) {\n\t\t\tcolumnIndex = column;\n\t\t}\n\n\t\tif ( columnIndex !== undefined && columnIndex === column && row === endRow ) {\n\t\t\tnewCell = createEmptyTableCell( writer, tableSlot.getPositionBefore(), newCellAttributes );\n\t\t}\n\t}\n\n\t// Update the rowspan attribute after updating table.\n\tupdateNumericAttribute( 'rowspan', newRowspan, tableCell, writer );\n\n\treturn newCell;\n}\n\n/**\n * Returns slot info of cells that starts before and overlaps a given column.\n *\n * In a table below, passing `overlapColumn = 3`\n *\n *\t\t 0 1 2 3 4\n *\t\t┌───────┬───────┬───┐\n *\t\t│ a │ b │ c │\n *\t\t│───┬───┴───────┼───┤\n *\t\t│ d │ e │ f │\n *\t\t├───┼───┬───────┴───┤\n *\t\t│ g │ h │ i │\n *\t\t├───┼───┼───┬───────┤\n *\t\t│ j │ k │ l │ m │\n *\t\t├───┼───┴───┼───┬───┤\n *\t\t│ n │ o │ p │ q │\n *\t\t└───┴───────┴───┴───┘\n *\t\t ^\n *\t\t Overlap column to check\n *\n * will return slot info for cells: \"b\", \"e\", \"i\".\n *\n * @param {module:engine/model/element~Element} table The table to check.\n * @param {Number} overlapColumn The index of the column to check.\n * @returns {Array.<module:table/tablewalker~TableSlot>}\n */\nexport function getHorizontallyOverlappingCells( table, overlapColumn ) {\n\tconst cellsToSplit = [];\n\n\tconst tableWalker = new TableWalker( table );\n\n\tfor ( const slotInfo of tableWalker ) {\n\t\tconst { column, cellWidth } = slotInfo;\n\t\tconst cellEndColumn = column + cellWidth - 1;\n\n\t\tif ( column < overlapColumn && overlapColumn <= cellEndColumn ) {\n\t\t\tcellsToSplit.push( slotInfo );\n\t\t}\n\t}\n\n\treturn cellsToSplit;\n}\n\n/**\n * Splits the table cell vertically.\n *\n * @param {module:engine/model/element~Element} tableCell\n * @param {Number} columnIndex The table cell column index.\n * @param {Number} splitColumn The index of column to split cell on.\n * @param {module:engine/model/writer~Writer} writer\n * @returns {module:engine/model/element~Element} Created table cell.\n */\nexport function splitVertically( tableCell, columnIndex, splitColumn, writer ) {\n\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) );\n\tconst newColspan = splitColumn - columnIndex;\n\n\tconst newCellAttributes = {};\n\tconst newCellColSpan = colspan - newColspan;\n\n\tif ( newCellColSpan > 1 ) {\n\t\tnewCellAttributes.colspan = newCellColSpan;\n\t}\n\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\n\tif ( rowspan > 1 ) {\n\t\tnewCellAttributes.rowspan = rowspan;\n\t}\n\n\tconst newCell = createEmptyTableCell( writer, writer.createPositionAfter( tableCell ), newCellAttributes );\n\n\t// Update the colspan attribute after updating table.\n\tupdateNumericAttribute( 'colspan', newColspan, tableCell, writer );\n\n\treturn newCell;\n}\n\n/**\n * Adjusts table cell dimensions to not exceed limit row and column.\n *\n * If table cell width (or height) covers a column (or row) that is after a limit column (or row)\n * this method will trim \"colspan\" (or \"rowspan\") attribute so the table cell will fit in a defined limits.\n *\n * @param {module:engine/model/element~Element} tableCell\n * @param {Number} cellRow\n * @param {Number} cellColumn\n * @param {Number} limitRow\n * @param {Number} limitColumn\n * @param {module:engine/model/writer~Writer} writer\n */\nexport function trimTableCellIfNeeded( tableCell, cellRow, cellColumn, limitRow, limitColumn, writer ) {\n\tconst colspan = parseInt( tableCell.getAttribute( 'colspan' ) || 1 );\n\tconst rowspan = parseInt( tableCell.getAttribute( 'rowspan' ) || 1 );\n\n\tconst endColumn = cellColumn + colspan - 1;\n\n\tif ( endColumn > limitColumn ) {\n\t\tconst trimmedSpan = limitColumn - cellColumn + 1;\n\n\t\tupdateNumericAttribute( 'colspan', trimmedSpan, tableCell, writer, 1 );\n\t}\n\n\tconst endRow = cellRow + rowspan - 1;\n\n\tif ( endRow > limitRow ) {\n\t\tconst trimmedSpan = limitRow - cellRow + 1;\n\n\t\tupdateNumericAttribute( 'rowspan', trimmedSpan, tableCell, writer, 1 );\n\t}\n}\n\n// Sets proper heading attributes to a cropped table.\nfunction addHeadingsToCroppedTable( croppedTable, sourceTable, startRow, startColumn, writer ) {\n\tconst headingRows = parseInt( sourceTable.getAttribute( 'headingRows' ) || 0 );\n\n\tif ( headingRows > 0 ) {\n\t\tconst headingRowsInCrop = headingRows - startRow;\n\t\tupdateNumericAttribute( 'headingRows', headingRowsInCrop, croppedTable, writer, 0 );\n\t}\n\n\tconst headingColumns = parseInt( sourceTable.getAttribute( 'headingColumns' ) || 0 );\n\n\tif ( headingColumns > 0 ) {\n\t\tconst headingColumnsInCrop = headingColumns - startColumn;\n\t\tupdateNumericAttribute( 'headingColumns', headingColumnsInCrop, croppedTable, writer, 0 );\n\t}\n}\n\n/**\n * Removes columns that have no cells anchored.\n *\n * In table below:\n *\n * +----+----+----+----+----+----+----+\n * | 00 | 01 | 03 | 04 | 06 |\n * +----+----+----+----+ +----+\n * | 10 | 11 | 13 | | 16 |\n * +----+----+----+----+----+----+----+\n * | 20 | 21 | 23 | 24 | 26 |\n * +----+----+----+----+----+----+----+\n * ^--- empty ---^\n *\n * Will remove columns 2 and 5.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a column from a table use {@link module:table/tableutils~TableUtils#removeColumns `TableUtils.removeColumns()`}.\n *\n * @protected\n * @param {module:engine/model/element~Element} table\n * @param {module:table/tableutils~TableUtils} tableUtils\n * @returns {Boolean} True if removed some columns.\n */\nexport function removeEmptyColumns( table, tableUtils ) {\n\tconst width = tableUtils.getColumns( table );\n\tconst columnsMap = new Array( width ).fill( 0 );\n\n\tfor ( const { column } of new TableWalker( table ) ) {\n\t\tcolumnsMap[ column ]++;\n\t}\n\n\tconst emptyColumns = columnsMap.reduce( ( result, cellsCount, column ) => {\n\t\treturn cellsCount ? result : [ ...result, column ];\n\t}, [] );\n\n\tif ( emptyColumns.length > 0 ) {\n\t\t// Remove only last empty column because it will recurrently trigger removing empty rows.\n\t\tconst emptyColumn = emptyColumns[ emptyColumns.length - 1 ];\n\n\t\t// @if CK_DEBUG_TABLE // console.log( `Removing empty column: ${ emptyColumn }.` );\n\t\ttableUtils.removeColumns( table, { at: emptyColumn } );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Removes rows that have no cells anchored.\n *\n * In table below:\n *\n * +----+----+----+\n * | 00 | 01 | 02 |\n * +----+----+----+\n * | 10 | 11 | 12 |\n * + + + +\n * | | | | <-- empty\n * +----+----+----+\n * | 30 | 31 | 32 |\n * +----+----+----+\n * | 40 | 42 |\n * + + +\n * | | | <-- empty\n * +----+----+----+\n * | 60 | 61 | 62 |\n * +----+----+----+\n *\n * Will remove rows 2 and 5.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a row from a table use {@link module:table/tableutils~TableUtils#removeRows `TableUtils.removeRows()`}.\n *\n * @protected\n * @param {module:engine/model/element~Element} table\n * @param {module:table/tableutils~TableUtils} tableUtils\n * @returns {Boolean} True if removed some rows.\n */\nexport function removeEmptyRows( table, tableUtils ) {\n\tconst emptyRows = [];\n\tconst tableRowCount = tableUtils.getRows( table );\n\n\tfor ( let rowIndex = 0; rowIndex < tableRowCount; rowIndex++ ) {\n\t\tconst tableRow = table.getChild( rowIndex );\n\n\t\tif ( tableRow.isEmpty ) {\n\t\t\temptyRows.push( rowIndex );\n\t\t}\n\t}\n\n\tif ( emptyRows.length > 0 ) {\n\t\t// Remove only last empty row because it will recurrently trigger removing empty columns.\n\t\tconst emptyRow = emptyRows[ emptyRows.length - 1 ];\n\n\t\t// @if CK_DEBUG_TABLE // console.log( `Removing empty row: ${ emptyRow }.` );\n\t\ttableUtils.removeRows( table, { at: emptyRow } );\n\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Removes rows and columns that have no cells anchored.\n *\n * In table below:\n *\n * +----+----+----+----+\n * | 00 | 02 |\n * +----+----+ +\n * | 10 | |\n * +----+----+----+----+\n * | 20 | 22 | 23 |\n * + + + +\n * | | | | <-- empty row\n * +----+----+----+----+\n * ^--- empty column\n *\n * Will remove row 3 and column 1.\n *\n * **Note:** This is a low-level helper method for clearing invalid model state when doing table modifications.\n * To remove a rows from a table use {@link module:table/tableutils~TableUtils#removeRows `TableUtils.removeRows()`} and\n * {@link module:table/tableutils~TableUtils#removeColumns `TableUtils.removeColumns()`} to remove a column.\n *\n * @protected\n * @param {module:engine/model/element~Element} table\n * @param {module:table/tableutils~TableUtils} tableUtils\n */\nexport function removeEmptyRowsColumns( table, tableUtils ) {\n\tconst removedColumns = removeEmptyColumns( table, tableUtils );\n\n\t// If there was some columns removed then cleaning empty rows was already triggered.\n\tif ( !removedColumns ) {\n\t\tremoveEmptyRows( table, tableUtils );\n\t}\n}\n\n/**\n * Returns adjusted last row index if selection covers part of a row with empty slots (spanned by other cells).\n * The `dimensions.lastRow` is equal to last row index but selection might be bigger.\n *\n * This happens *only* on rectangular selection so we analyze a case like this:\n *\n * +---+---+---+---+\n * 0 | a | b | c | d |\n * + + +---+---+\n * 1 | | e | f | g |\n * + +---+ +---+\n * 2 | | h | | i | <- last row, each cell has rowspan = 2,\n * + + + + + so we need to return 3, not 2\n * 3 | | | | |\n * +---+---+---+---+\n *\n * @param {module:engine/model/element~Element} table\n * @param {Object} dimensions\n * @param {Number} dimensions.firstRow\n * @param {Number} dimensions.firstColumn\n * @param {Number} dimensions.lastRow\n * @param {Number} dimensions.lastColumn\n * @returns {Number} Adjusted last row index.\n */\nexport function adjustLastRowIndex( table, dimensions ) {\n\tconst lastRowMap = Array.from( new TableWalker( table, {\n\t\tstartColumn: dimensions.firstColumn,\n\t\tendColumn: dimensions.lastColumn,\n\t\trow: dimensions.lastRow\n\t} ) );\n\n\tconst everyCellHasSingleRowspan = lastRowMap.every( ( { cellHeight } ) => cellHeight === 1 );\n\n\t// It is a \"flat\" row, so the last row index is OK.\n\tif ( everyCellHasSingleRowspan ) {\n\t\treturn dimensions.lastRow;\n\t}\n\n\t// Otherwise get any cell's rowspan and adjust the last row index.\n\tconst rowspanAdjustment = lastRowMap[ 0 ].cellHeight - 1;\n\treturn dimensions.lastRow + rowspanAdjustment;\n}\n\n/**\n * Returns adjusted last column index if selection covers part of a column with empty slots (spanned by other cells).\n * The `dimensions.lastColumn` is equal to last column index but selection might be bigger.\n *\n * This happens *only* on rectangular selection so we analyze a case like this:\n *\n * 0 1 2 3\n * +---+---+---+---+\n * | a |\n * +---+---+---+---+\n * | b | c | d |\n * +---+---+---+---+\n * | e | f |\n * +---+---+---+---+\n * | g | h |\n * +---+---+---+---+\n * ^\n * last column, each cell has colspan = 2, so we need to return 3, not 2\n *\n * @param {module:engine/model/element~Element} table\n * @param {Object} dimensions\n * @param {Number} dimensions.firstRow\n * @param {Number} dimensions.firstColumn\n * @param {Number} dimensions.lastRow\n * @param {Number} dimensions.lastColumn\n * @returns {Number} Adjusted last column index.\n */\nexport function adjustLastColumnIndex( table, dimensions ) {\n\tconst lastColumnMap = Array.from( new TableWalker( table, {\n\t\tstartRow: dimensions.firstRow,\n\t\tendRow: dimensions.lastRow,\n\t\tcolumn: dimensions.lastColumn\n\t} ) );\n\n\tconst everyCellHasSingleColspan = lastColumnMap.every( ( { cellWidth } ) => cellWidth === 1 );\n\n\t// It is a \"flat\" column, so the last column index is OK.\n\tif ( everyCellHasSingleColspan ) {\n\t\treturn dimensions.lastColumn;\n\t}\n\n\t// Otherwise get any cell's colspan and adjust the last column index.\n\tconst colspanAdjustment = lastColumnMap[ 0 ].cellWidth - 1;\n\treturn dimensions.lastColumn + colspanAdjustment;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/table-properties\n */\n\nimport { isObject } from 'lodash-es';\n\n/**\n * Returns a string if all four values of box sides are equal.\n *\n * If a string is passed, it is treated as a single value (pass-through).\n *\n *\t\t// Returns 'foo':\n *\t\tgetSingleValue( { top: 'foo', right: 'foo', bottom: 'foo', left: 'foo' } );\n *\t\tgetSingleValue( 'foo' );\n *\n *\t\t// Returns undefined:\n *\t\tgetSingleValue( { top: 'foo', right: 'foo', bottom: 'bar', left: 'foo' } );\n *\t\tgetSingleValue( { top: 'foo', right: 'foo' } );\n *\n * @param objectOrString\n * @returns {module:engine/view/stylesmap~BoxSides|String}\n */\nexport function getSingleValue( objectOrString ) {\n\tif ( !objectOrString || !isObject( objectOrString ) ) {\n\t\treturn objectOrString;\n\t}\n\n\tconst { top, right, bottom, left } = objectOrString;\n\n\tif ( top == right && right == bottom && bottom == left ) {\n\t\treturn top;\n\t}\n}\n\n/**\n * Adds a unit to a value if the value is a number or a string representing a number.\n *\n * **Note**: It does nothing to non-numeric values.\n *\n *\t\tgetSingleValue( 25, 'px' );\t\t// '25px'\n *\t\tgetSingleValue( 25, 'em' );\t\t// '25em'\n *\t\tgetSingleValue( '25em', 'px' );\t// '25em'\n *\t\tgetSingleValue( 'foo', 'px' );\t// 'foo'\n *\n * @param {*} value\n * @param {String} defaultUnit A default unit added to a numeric value.\n * @returns {String|*}\n */\nexport function addDefaultUnitToNumericValue( value, defaultUnit ) {\n\tconst numericValue = parseFloat( value );\n\n\tif ( Number.isNaN( numericValue ) ) {\n\t\treturn value;\n\t}\n\n\tif ( String( numericValue ) !== String( value ) ) {\n\t\treturn value;\n\t}\n\n\treturn `${ numericValue }${ defaultUnit }`;\n}\n\n/**\n * Returns the normalized configuration.\n *\n * @param {Object} config\n * @param {Object} [options={}]\n * @param {Boolean} [options.includeAlignmentProperty=false] Whether the \"alignment\" property should be added.\n * @param {Boolean} [options.includePaddingProperty=false] Whether the \"padding\" property should be added.\n * @param {Boolean} [options.includeVerticalAlignmentProperty=false] Whether the \"verticalAlignment\" property should be added.\n * @param {Boolean} [options.includeHorizontalAlignmentProperty=false] Whether the \"horizontalAlignment\" property should be added.\n * @param {Boolean} [options.isRightToLeftContent=false] Whether the content is right-to-left.\n * @returns {Object}\n */\nexport function getNormalizedDefaultProperties( config, options = {} ) {\n\tconst normalizedConfig = Object.assign( {\n\t\tborderStyle: 'none',\n\t\tborderWidth: '',\n\t\tborderColor: '',\n\t\tbackgroundColor: '',\n\t\twidth: '',\n\t\theight: ''\n\t}, config );\n\n\tif ( options.includeAlignmentProperty && !normalizedConfig.alignment ) {\n\t\tnormalizedConfig.alignment = 'center';\n\t}\n\n\tif ( options.includePaddingProperty && !normalizedConfig.padding ) {\n\t\tnormalizedConfig.padding = '';\n\t}\n\n\tif ( options.includeVerticalAlignmentProperty && !normalizedConfig.verticalAlignment ) {\n\t\tnormalizedConfig.verticalAlignment = 'middle';\n\t}\n\n\tif ( options.includeHorizontalAlignmentProperty && !normalizedConfig.horizontalAlignment ) {\n\t\tnormalizedConfig.horizontalAlignment = options.isRightToLeftContent ? 'right' : 'left';\n\t}\n\n\treturn normalizedConfig;\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/ui/contextualballoon\n */\n\nimport { Rect } from 'ckeditor5/src/utils';\nimport { BalloonPanelView } from 'ckeditor5/src/ui';\n\nimport { getTableWidgetAncestor } from './widget';\n\nconst DEFAULT_BALLOON_POSITIONS = BalloonPanelView.defaultPositions;\n\nconst BALLOON_POSITIONS = [\n\tDEFAULT_BALLOON_POSITIONS.northArrowSouth,\n\tDEFAULT_BALLOON_POSITIONS.northArrowSouthWest,\n\tDEFAULT_BALLOON_POSITIONS.northArrowSouthEast,\n\tDEFAULT_BALLOON_POSITIONS.southArrowNorth,\n\tDEFAULT_BALLOON_POSITIONS.southArrowNorthWest,\n\tDEFAULT_BALLOON_POSITIONS.southArrowNorthEast,\n\tDEFAULT_BALLOON_POSITIONS.viewportStickyNorth\n];\n\n/**\n * A helper utility that positions the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} instance\n * with respect to the table in the editor content, if one is selected.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @param {String} target Either \"cell\" or \"table\". Determines the target the balloon will\n * be attached to.\n */\nexport function repositionContextualBalloon( editor, target ) {\n\tconst balloon = editor.plugins.get( 'ContextualBalloon' );\n\n\tif ( getTableWidgetAncestor( editor.editing.view.document.selection ) ) {\n\t\tlet position;\n\n\t\tif ( target === 'cell' ) {\n\t\t\tposition = getBalloonCellPositionData( editor );\n\t\t} else {\n\t\t\tposition = getBalloonTablePositionData( editor );\n\t\t}\n\n\t\tballoon.updatePosition( position );\n\t}\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected table in the editor content.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @returns {module:utils/dom/position~Options}\n */\nexport function getBalloonTablePositionData( editor ) {\n\tconst firstPosition = editor.model.document.selection.getFirstPosition();\n\tconst modelTable = firstPosition.findAncestor( 'table' );\n\tconst viewTable = editor.editing.mapper.toViewElement( modelTable );\n\n\treturn {\n\t\ttarget: editor.editing.view.domConverter.viewToDom( viewTable ),\n\t\tpositions: BALLOON_POSITIONS\n\t};\n}\n\n/**\n * Returns the positioning options that control the geometry of the\n * {@link module:ui/panel/balloon/contextualballoon~ContextualBalloon contextual balloon} with respect\n * to the selected table cell in the editor content.\n *\n * @param {module:core/editor/editor~Editor} editor The editor instance.\n * @returns {module:utils/dom/position~Options}\n */\nexport function getBalloonCellPositionData( editor ) {\n\tconst mapper = editor.editing.mapper;\n\tconst domConverter = editor.editing.view.domConverter;\n\tconst selection = editor.model.document.selection;\n\n\tif ( selection.rangeCount > 1 ) {\n\t\treturn {\n\t\t\ttarget: () => createBoundingRect( selection.getRanges(), editor ),\n\t\t\tpositions: BALLOON_POSITIONS\n\t\t};\n\t}\n\n\tconst modelTableCell = getTableCellAtPosition( selection.getFirstPosition() );\n\tconst viewTableCell = mapper.toViewElement( modelTableCell );\n\n\treturn {\n\t\ttarget: domConverter.viewToDom( viewTableCell ),\n\t\tpositions: BALLOON_POSITIONS\n\t};\n}\n\n// Returns the first selected table cell from a multi-cell or in-cell selection.\n//\n// @param {module:engine/model/position~Position} position Document position.\n// @returns {module:engine/model/element~Element}\nfunction getTableCellAtPosition( position ) {\n\tconst isTableCellSelected = position.nodeAfter && position.nodeAfter.is( 'element', 'tableCell' );\n\n\treturn isTableCellSelected ? position.nodeAfter : position.findAncestor( 'tableCell' );\n}\n\n// Returns bounding rectangle for given model ranges.\n//\n// @param {Iterable.<module:engine/model/range~Range>} ranges Model ranges that the bounding rect should be returned for.\n// @param {module:core/editor/editor~Editor} editor The editor instance.\n// @returns {module:utils/dom/rect~Rect}\nfunction createBoundingRect( ranges, editor ) {\n\tconst mapper = editor.editing.mapper;\n\tconst domConverter = editor.editing.view.domConverter;\n\tconst rects = Array.from( ranges ).map( range => {\n\t\tconst modelTableCell = getTableCellAtPosition( range.start );\n\t\tconst viewTableCell = mapper.toViewElement( modelTableCell );\n\t\treturn new Rect( domConverter.viewToDom( viewTableCell ) );\n\t} );\n\n\treturn Rect.getBoundingRect( rects );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/ui/table-properties\n */\n\nimport { ButtonView, Model } from 'ckeditor5/src/ui';\nimport { Collection } from 'ckeditor5/src/utils';\nimport { isColor, isLength, isPercentage } from 'ckeditor5/src/engine';\n\nimport ColorInputView from '../../ui/colorinputview';\n\nconst isEmpty = val => val === '';\n\n/**\n * Returns an object containing pairs of CSS border style values and their localized UI\n * labels. Used by {@link module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView}\n * and {@link module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView}.\n *\n * @param {module:utils/locale~Locale#t} t The \"t\" function provided by the editor\n * that is used to localize strings.\n * @returns {Object.<String,String>}\n */\nexport function getBorderStyleLabels( t ) {\n\treturn {\n\t\tnone: t( 'None' ),\n\t\tsolid: t( 'Solid' ),\n\t\tdotted: t( 'Dotted' ),\n\t\tdashed: t( 'Dashed' ),\n\t\tdouble: t( 'Double' ),\n\t\tgroove: t( 'Groove' ),\n\t\tridge: t( 'Ridge' ),\n\t\tinset: t( 'Inset' ),\n\t\toutset: t( 'Outset' )\n\t};\n}\n\n/**\n * Returns a localized error string that can be displayed next to color (background, border)\n * fields that have an invalid value.\n *\n * @param {module:utils/locale~Locale#t} t The \"t\" function provided by the editor\n * that is used to localize strings.\n * @returns {String}\n */\nexport function getLocalizedColorErrorText( t ) {\n\treturn t( 'The color is invalid. Try \"#FF0000\" or \"rgb(255,0,0)\" or \"red\".' );\n}\n\n/**\n * Returns a localized error string that can be displayed next to length (padding, border width)\n * fields that have an invalid value.\n *\n * @param {module:utils/locale~Locale#t} t The \"t\" function provided by the editor\n * that is used to localize strings.\n * @returns {String}\n */\nexport function getLocalizedLengthErrorText( t ) {\n\treturn t( 'The value is invalid. Try \"10px\" or \"2em\" or simply \"2\".' );\n}\n\n/**\n * Returns `true` when the passed value is an empty string or a valid CSS color expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isColor}.\n *\n * @param {String} value\n * @returns {Boolean}\n */\nexport function colorFieldValidator( value ) {\n\tvalue = value.trim();\n\n\treturn isEmpty( value ) || isColor( value );\n}\n\n/**\n * Returns `true` when the passed value is an empty string, a number without a unit or a valid CSS length expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isLength}.\n * See {@link module:engine/view/styles/utils~isPercentage}.\n *\n * @param {String} value\n * @returns {Boolean}\n */\nexport function lengthFieldValidator( value ) {\n\tvalue = value.trim();\n\n\treturn isEmpty( value ) || isNumberString( value ) || isLength( value ) || isPercentage( value );\n}\n\n/**\n * Returns `true` when the passed value is an empty string, a number without a unit or a valid CSS length expression.\n * Otherwise, `false` is returned.\n *\n * See {@link module:engine/view/styles/utils~isLength}.\n *\n * @param {String} value\n * @returns {Boolean}\n */\nexport function lineWidthFieldValidator( value ) {\n\tvalue = value.trim();\n\n\treturn isEmpty( value ) || isNumberString( value ) || isLength( value );\n}\n\n/**\n * Generates item definitions for a UI dropdown that allows changing the border style of a table or a table cell.\n *\n * @param {module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView|\n * module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} view\n * @param {String} defaultStyle The default border.\n * @returns {Iterable.<module:ui/dropdown/utils~ListDropdownItemDefinition>}\n */\nexport function getBorderStyleDefinitions( view, defaultStyle ) {\n\tconst itemDefinitions = new Collection();\n\tconst styleLabels = getBorderStyleLabels( view.t );\n\n\tfor ( const style in styleLabels ) {\n\t\tconst definition = {\n\t\t\ttype: 'button',\n\t\t\tmodel: new Model( {\n\t\t\t\t_borderStyleValue: style,\n\t\t\t\tlabel: styleLabels[ style ],\n\t\t\t\twithText: true\n\t\t\t} )\n\t\t};\n\n\t\tif ( style === 'none' ) {\n\t\t\tdefinition.model.bind( 'isOn' ).to( view, 'borderStyle', value => {\n\t\t\t\tif ( defaultStyle === 'none' ) {\n\t\t\t\t\treturn !value;\n\t\t\t\t}\n\n\t\t\t\treturn value === style;\n\t\t\t} );\n\t\t} else {\n\t\t\tdefinition.model.bind( 'isOn' ).to( view, 'borderStyle', value => {\n\t\t\t\treturn value === style;\n\t\t\t} );\n\t\t}\n\n\t\titemDefinitions.add( definition );\n\t}\n\n\treturn itemDefinitions;\n}\n\n/**\n * A helper that fills a toolbar with buttons that:\n *\n * * have some labels,\n * * have some icons,\n * * set a certain UI view property value upon execution.\n *\n * @param {Object} options\n * @param {module:table/tablecellproperties/ui/tablecellpropertiesview~TableCellPropertiesView|\n * module:table/tableproperties/ui/tablepropertiesview~TablePropertiesView} options.view\n * @param {Array.<String>} options.icons\n * @param {module:ui/toolbar/toolbarview~ToolbarView} options.toolbar\n * @param {Object.<String,String>} labels\n * @param {String} propertyName\n * @param {Function} nameToValue A function that maps a button name to a value. By default names are the same as values.\n */\nexport function fillToolbar( options ) {\n\tconst { view, icons, toolbar, labels, propertyName, nameToValue, defaultValue } = options;\n\tfor ( const name in labels ) {\n\t\tconst button = new ButtonView( view.locale );\n\n\t\tbutton.set( {\n\t\t\tlabel: labels[ name ],\n\t\t\ticon: icons[ name ],\n\t\t\ttooltip: labels[ name ]\n\t\t} );\n\n\t\t// If specified the `nameToValue()` callback, map the value based on the option's name.\n\t\tconst buttonValue = nameToValue ? nameToValue( name ) : name;\n\n\t\tbutton.bind( 'isOn' ).to( view, propertyName, value => {\n\t\t\t// `value` comes from `view[ propertyName ]`.\n\t\t\tlet valueToCompare = value;\n\n\t\t\t// If it's empty, and the `defaultValue` is specified, use it instead.\n\t\t\tif ( value === '' && defaultValue ) {\n\t\t\t\tvalueToCompare = defaultValue;\n\t\t\t}\n\n\t\t\treturn buttonValue === valueToCompare;\n\t\t} );\n\n\t\tbutton.on( 'execute', () => {\n\t\t\tview[ propertyName ] = buttonValue;\n\t\t} );\n\n\t\ttoolbar.items.add( button );\n\t}\n}\n\n/**\n * A default color palette used by various user interfaces related to tables, for instance,\n * by {@link module:table/tablecellproperties/tablecellpropertiesui~TableCellPropertiesUI} or\n * {@link module:table/tableproperties/tablepropertiesui~TablePropertiesUI}.\n *\n * The color palette follows the {@link module:table/table~TableColorConfig table color configuration format}\n * and contains the following color definitions:\n *\n *\t\tconst defaultColors = [\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 0%)',\n *\t\t\t\tlabel: 'Black'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 30%)',\n *\t\t\t\tlabel: 'Dim grey'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 60%)',\n *\t\t\t\tlabel: 'Grey'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 90%)',\n *\t\t\t\tlabel: 'Light grey'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 0%, 100%)',\n *\t\t\t\tlabel: 'White',\n *\t\t\t\thasBorder: true\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(0, 75%, 60%)',\n *\t\t\t\tlabel: 'Red'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(30, 75%, 60%)',\n *\t\t\t\tlabel: 'Orange'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(60, 75%, 60%)',\n *\t\t\t\tlabel: 'Yellow'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(90, 75%, 60%)',\n *\t\t\t\tlabel: 'Light green'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(120, 75%, 60%)',\n *\t\t\t\tlabel: 'Green'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(150, 75%, 60%)',\n *\t\t\t\tlabel: 'Aquamarine'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(180, 75%, 60%)',\n *\t\t\t\tlabel: 'Turquoise'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(210, 75%, 60%)',\n *\t\t\t\tlabel: 'Light blue'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(240, 75%, 60%)',\n *\t\t\t\tlabel: 'Blue'\n *\t\t\t},\n *\t\t\t{\n *\t\t\t\tcolor: 'hsl(270, 75%, 60%)',\n *\t\t\t\tlabel: 'Purple'\n *\t\t\t}\n *\t\t];\n */\nexport const defaultColors = [\n\t{\n\t\tcolor: 'hsl(0, 0%, 0%)',\n\t\tlabel: 'Black'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 30%)',\n\t\tlabel: 'Dim grey'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 60%)',\n\t\tlabel: 'Grey'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 90%)',\n\t\tlabel: 'Light grey'\n\t},\n\t{\n\t\tcolor: 'hsl(0, 0%, 100%)',\n\t\tlabel: 'White',\n\t\thasBorder: true\n\t},\n\t{\n\t\tcolor: 'hsl(0, 75%, 60%)',\n\t\tlabel: 'Red'\n\t},\n\t{\n\t\tcolor: 'hsl(30, 75%, 60%)',\n\t\tlabel: 'Orange'\n\t},\n\t{\n\t\tcolor: 'hsl(60, 75%, 60%)',\n\t\tlabel: 'Yellow'\n\t},\n\t{\n\t\tcolor: 'hsl(90, 75%, 60%)',\n\t\tlabel: 'Light green'\n\t},\n\t{\n\t\tcolor: 'hsl(120, 75%, 60%)',\n\t\tlabel: 'Green'\n\t},\n\t{\n\t\tcolor: 'hsl(150, 75%, 60%)',\n\t\tlabel: 'Aquamarine'\n\t},\n\t{\n\t\tcolor: 'hsl(180, 75%, 60%)',\n\t\tlabel: 'Turquoise'\n\t},\n\t{\n\t\tcolor: 'hsl(210, 75%, 60%)',\n\t\tlabel: 'Light blue'\n\t},\n\t{\n\t\tcolor: 'hsl(240, 75%, 60%)',\n\t\tlabel: 'Blue'\n\t},\n\t{\n\t\tcolor: 'hsl(270, 75%, 60%)',\n\t\tlabel: 'Purple'\n\t}\n];\n\n/**\n * Returns a creator for a color input with a label.\n *\n * For given options, it returns a function that creates an instance of a\n * {@link module:table/ui/colorinputview~ColorInputView color input} logically related to\n * a {@link module:ui/labeledfield/labeledfieldview~LabeledFieldView labeled view} in the DOM.\n *\n * The helper does the following:\n *\n * * It sets the color input `id` and `ariaDescribedById` attributes.\n * * It binds the color input `isReadOnly` to the labeled view.\n * * It binds the color input `hasError` to the labeled view.\n * * It enables a logic that cleans up the error when the user starts typing in the color input.\n *\n * Usage:\n *\n *\t\tconst colorInputCreator = getLabeledColorInputCreator( {\n *\t\t\tcolorConfig: [ ... ],\n *\t\t\tcolumns: 3,\n *\t\t} );\n *\n *\t\tconst labeledInputView = new LabeledFieldView( locale, colorInputCreator );\n *\t\tconsole.log( labeledInputView.view ); // A color input instance.\n *\n * @private\n * @param options Color input options.\n * @param {module:table/table~TableColorConfig} options.colorConfig The configuration of the color palette\n * displayed in the input's dropdown.\n * @param {Number} options.columns The configuration of the number of columns the color palette consists of\n * in the input's dropdown.\n * @param {String} [options.defaultColorValue] If specified, the color input view will replace the \"Remove color\" button with\n * the \"Restore default\" button. Instead of clearing the input field, the default color value will be set.\n * @returns {Function}\n */\nexport function getLabeledColorInputCreator( options ) {\n\treturn ( labeledFieldView, viewUid, statusUid ) => {\n\t\tconst inputView = new ColorInputView( labeledFieldView.locale, {\n\t\t\tcolorDefinitions: colorConfigToColorGridDefinitions( options.colorConfig ),\n\t\t\tcolumns: options.columns,\n\t\t\tdefaultColorValue: options.defaultColorValue\n\t\t} );\n\n\t\tinputView.set( {\n\t\t\tid: viewUid,\n\t\t\tariaDescribedById: statusUid\n\t\t} );\n\n\t\tinputView.bind( 'isReadOnly' ).to( labeledFieldView, 'isEnabled', value => !value );\n\t\tinputView.bind( 'hasError' ).to( labeledFieldView, 'errorText', value => !!value );\n\n\t\tinputView.on( 'input', () => {\n\t\t\t// UX: Make the error text disappear and disable the error indicator as the user\n\t\t\t// starts fixing the errors.\n\t\t\tlabeledFieldView.errorText = null;\n\t\t} );\n\n\t\tlabeledFieldView.bind( 'isEmpty', 'isFocused' ).to( inputView );\n\n\t\treturn inputView;\n\t};\n}\n\n// A simple helper method to detect number strings.\n// I allows full number notation, so omitting 0 is not allowed:\nfunction isNumberString( value ) {\n\tconst parsedValue = parseFloat( value );\n\n\treturn !Number.isNaN( parsedValue ) && value === String( parsedValue );\n}\n\n// @param {Array.<Object>} colorConfig\n// @returns {Array.<module:ui/colorgrid/colorgrid~ColorDefinition>}\nfunction colorConfigToColorGridDefinitions( colorConfig ) {\n\treturn colorConfig.map( item => ( {\n\t\tcolor: item.model,\n\t\tlabel: item.label,\n\t\toptions: {\n\t\t\thasBorder: item.hasBorder\n\t\t}\n\t} ) );\n}\n","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table/utils/ui/widget\n */\n\nimport { isWidget } from 'ckeditor5/src/widget';\n\n/**\n * Returns a table widget editing view element if one is selected.\n *\n * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection\n * @returns {module:engine/view/element~Element|null}\n */\nexport function getSelectedTableWidget( selection ) {\n\tconst viewElement = selection.getSelectedElement();\n\n\tif ( viewElement && isTableWidget( viewElement ) ) {\n\t\treturn viewElement;\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns a table widget editing view element if one is among the selection's ancestors.\n *\n * @param {module:engine/view/selection~Selection|module:engine/view/documentselection~DocumentSelection} selection\n * @returns {module:engine/view/element~Element|null}\n */\nexport function getTableWidgetAncestor( selection ) {\n\tlet parent = selection.getFirstPosition().parent;\n\n\twhile ( parent ) {\n\t\tif ( parent.is( 'element' ) && isTableWidget( parent ) ) {\n\t\t\treturn parent;\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn null;\n}\n\n// Checks if a given view element is a table widget.\n//\n// @param {module:engine/view/element~Element} viewElement\n// @returns {Boolean}\nfunction isTableWidget( viewElement ) {\n\treturn !!viewElement.getCustomProperty( 'table' ) && isWidget( viewElement );\n}\n","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/core.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/engine.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/ui.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/utils.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/widget.js\");","module.exports = CKEditor5.dll;","import root from './_root.js';\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nexport default Symbol;\n","import Symbol from './_Symbol.js';\nimport getRawTag from './_getRawTag.js';\nimport objectToString from './_objectToString.js';\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nexport default baseGetTag;\n","import trimmedEndIndex from './_trimmedEndIndex.js';\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nexport default baseTrim;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nexport default freeGlobal;\n","import Symbol from './_Symbol.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nexport default getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nexport default objectToString;\n","import freeGlobal from './_freeGlobal.js';\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nexport default root;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nexport default trimmedEndIndex;\n","import isObject from './isObject.js';\nimport now from './now.js';\nimport toNumber from './toNumber.js';\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nexport default debounce;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nexport default isObject;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nexport default isObjectLike;\n","import baseGetTag from './_baseGetTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n","import root from './_root.js';\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\nexport default now;\n","import baseTrim from './_baseTrim.js';\nimport isObject from './isObject.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nexport default toNumber;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * @license Copyright (c) 2003-2022, CKSource Holding sp. z o.o. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module table\n */\n\nexport { default as Table } from './table';\nexport { default as TableEditing } from './tableediting';\nexport { default as TableUI } from './tableui';\nexport { default as TableToolbar } from './tabletoolbar';\nexport { default as TableCellProperties } from './tablecellproperties';\nexport { default as TableCellPropertiesEditing } from './tablecellproperties/tablecellpropertiesediting';\nexport { default as TableCellPropertiesUI } from './tablecellproperties/tablecellpropertiesui';\nexport { default as TableProperties } from './tableproperties';\nexport { default as TablePropertiesEditing } from './tableproperties/tablepropertiesediting';\nexport { default as TablePropertiesUI } from './tableproperties/tablepropertiesui';\nexport { default as TableCaption } from './tablecaption';\nexport { default as TableCaptionEditing } from './tablecaption/tablecaptionediting';\nexport { default as TableCaptionUI } from './tablecaption/tablecaptionui';\nexport { default as TableClipboard } from './tableclipboard';\nexport { default as TableMouse } from './tablemouse';\nexport { default as TableKeyboard } from './tablekeyboard';\nexport { default as TableSelection } from './tableselection';\nexport { default as TableUtils } from './tableutils';\n"],"sourceRoot":""}