@ckeditor/ckeditor5-list 35.2.0 → 35.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/build/list.js.map +1 -1
  2. package/package.json +36 -36
package/build/list.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["webpack://CKEditor5.list/./theme/collapsible.css","webpack://CKEditor5.list/./theme/documentlist.css","webpack://CKEditor5.list/./theme/listproperties.css","webpack://CKEditor5.list/./theme/liststyles.css","webpack://CKEditor5.list/./theme/todolist.css","webpack://CKEditor5.list/../node_modules/css-loader/dist/runtime/api.js","webpack://CKEditor5.list/../node_modules/css-loader/dist/runtime/cssWithMappingToString.js","webpack://CKEditor5.list/./theme/icons/bulletedlist.svg","webpack://CKEditor5.list/./theme/icons/liststylecircle.svg","webpack://CKEditor5.list/./theme/icons/liststyledecimal.svg","webpack://CKEditor5.list/./theme/icons/liststyledecimalleadingzero.svg","webpack://CKEditor5.list/./theme/icons/liststyledisc.svg","webpack://CKEditor5.list/./theme/icons/liststylelowerlatin.svg","webpack://CKEditor5.list/./theme/icons/liststylelowerroman.svg","webpack://CKEditor5.list/./theme/icons/liststylesquare.svg","webpack://CKEditor5.list/./theme/icons/liststyleupperlatin.svg","webpack://CKEditor5.list/./theme/icons/liststyleupperroman.svg","webpack://CKEditor5.list/./theme/icons/numberedlist.svg","webpack://CKEditor5.list/./theme/icons/todolist.svg","webpack://CKEditor5.list/../ckeditor5-ui/theme/icons/dropdown-arrow.svg","webpack://CKEditor5.list/./theme/collapsible.css?56dc","webpack://CKEditor5.list/./theme/documentlist.css?7eef","webpack://CKEditor5.list/./theme/listproperties.css?da79","webpack://CKEditor5.list/./theme/liststyles.css?bcba","webpack://CKEditor5.list/./theme/todolist.css?40fa","webpack://CKEditor5.list/../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack://CKEditor5.list/./src/documentlist.js","webpack://CKEditor5.list/./src/documentlist/converters.js","webpack://CKEditor5.list/./src/documentlist/documentlistcommand.js","webpack://CKEditor5.list/./src/documentlist/documentlistediting.js","webpack://CKEditor5.list/./src/documentlist/documentlistindentcommand.js","webpack://CKEditor5.list/./src/documentlist/documentlistmergecommand.js","webpack://CKEditor5.list/./src/documentlist/documentlistsplitcommand.js","webpack://CKEditor5.list/./src/documentlist/utils/listwalker.js","webpack://CKEditor5.list/./src/documentlist/utils/model.js","webpack://CKEditor5.list/./src/documentlist/utils/postfixers.js","webpack://CKEditor5.list/./src/documentlist/utils/view.js","webpack://CKEditor5.list/./src/documentlistproperties.js","webpack://CKEditor5.list/./src/documentlistproperties/converters.js","webpack://CKEditor5.list/./src/documentlistproperties/documentlistpropertiesediting.js","webpack://CKEditor5.list/./src/documentlistproperties/documentlistreversedcommand.js","webpack://CKEditor5.list/./src/documentlistproperties/documentliststartcommand.js","webpack://CKEditor5.list/./src/documentlistproperties/documentliststylecommand.js","webpack://CKEditor5.list/./src/documentlistproperties/utils/style.js","webpack://CKEditor5.list/./src/list.js","webpack://CKEditor5.list/./src/list/converters.js","webpack://CKEditor5.list/./src/list/indentcommand.js","webpack://CKEditor5.list/./src/list/listcommand.js","webpack://CKEditor5.list/./src/list/listediting.js","webpack://CKEditor5.list/./src/list/listui.js","webpack://CKEditor5.list/./src/list/utils.js","webpack://CKEditor5.list/./src/listproperties.js","webpack://CKEditor5.list/./src/listproperties/listpropertiesediting.js","webpack://CKEditor5.list/./src/listproperties/listpropertiesui.js","webpack://CKEditor5.list/./src/listproperties/listreversedcommand.js","webpack://CKEditor5.list/./src/listproperties/liststartcommand.js","webpack://CKEditor5.list/./src/listproperties/liststylecommand.js","webpack://CKEditor5.list/./src/listproperties/ui/collapsibleview.js","webpack://CKEditor5.list/./src/listproperties/ui/listpropertiesview.js","webpack://CKEditor5.list/./src/todolist.js","webpack://CKEditor5.list/./src/todolist/checktodolistcommand.js","webpack://CKEditor5.list/./src/todolist/todolistconverters.js","webpack://CKEditor5.list/./src/todolist/todolistediting.js","webpack://CKEditor5.list/./src/todolist/todolistui.js","webpack://CKEditor5.list/delegated \"./src/core.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/engine.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/enter.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/typing.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/ui.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/utils.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/external var \"CKEditor5.dll\"","webpack://CKEditor5.list/webpack/bootstrap","webpack://CKEditor5.list/webpack/runtime/compat get default export","webpack://CKEditor5.list/webpack/runtime/define property getters","webpack://CKEditor5.list/webpack/runtime/hasOwnProperty shorthand","webpack://CKEditor5.list/webpack/runtime/make namespace object","webpack://CKEditor5.list/webpack/runtime/nonce","webpack://CKEditor5.list/./src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gHAAgH,aAAa,MAAM,0DAA0D,iCAAiC,gBAAgB,gBAAgB,yDAAyD,WAAW,uCAAuC,uBAAuB,wIAAwI,uBAAuB,yBAAyB,gBAAgB,0CAA0C,sCAAsC,uCAAuC,6CAA6C,0DAA0D,mEAAmE,yBAAyB,OAAO,8lBAA8lB,mCAAmC,oBAAoB,KAAK,GAAG,0LAA0L,iEAAiE,GAAG,wBAAwB,uBAAuB,kBAAkB,wBAAwB,gEAAgE,uBAAuB,iBAAiB,gCAAgC,OAAO,sDAAsD,gCAAgC,kCAAkC,yBAAyB,OAAO,sBAAsB,+CAA+C,gDAAgD,OAAO,KAAK,qCAAqC,iEAAiE,KAAK,kCAAkC,kCAAkC,kCAAkC,OAAO,KAAK,GAAG,qBAAqB;AAC1hF;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,wFAAwF,cAAc,OAAO,qVAAqV,mBAAmB,GAAG,qBAAqB;AAC7e;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,mGAAmG,gCAAgC,2DAA2D,eAAe,6DAA6D,sCAAsC,wFAAwF,qCAAqC,mFAAmF,iDAAiD,+GAA+G,WAAW,iHAAiH,sCAAsC,8EAA8E,eAAe,WAAW,uEAAuE,uBAAuB,8CAA8C,eAAe,gBAAgB,2JAA2J,gBAAgB,yBAAyB,gBAAgB,OAAO,mkBAAmkB,6GAA6G,uCAAuC,eAAe,wBAAwB,iBAAiB,iDAAiD,SAAS,OAAO,KAAK,iPAAiP,gCAAgC,iDAAiD,OAAO,gHAAgH,0DAA0D,yCAAyC,iBAAiB,wBAAwB,qBAAqB,qDAAqD,aAAa,WAAW,SAAS,OAAO,KAAK,gEAAgE,sBAAsB,kBAAkB,KAAK,yDAAyD,8BAA8B,sBAAsB,uBAAuB,uDAAuD,2BAA2B,yBAAyB,kCAAkC,yBAAyB,OAAO,KAAK,GAAG,qBAAqB;AAC5vG;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,kEAAkE,aAAa,MAAM,iCAAiC,wBAAwB,oCAAoC,qCAAqC,gCAAgC,iCAAiC,mCAAmC,uBAAuB,SAAS,UAAU,+EAA+E,wCAAwC,uCAAuC,OAAO,0hBAA0hB,kBAAkB,GAAG,0LAA0L,sCAAsC,GAAG,6BAA6B,6CAA6C,sCAAsC,yCAAyC,qCAAqC,oBAAoB,4HAA4H,+CAA+C,iBAAiB,+JAA+J,mRAAmR,oBAAoB,gDAAgD,iDAAiD,OAAO,KAAK,GAAG,qBAAqB;AACrvE;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gDAAgD,mCAAmC,uBAAuB,gBAAgB,0BAA0B,kBAAkB,qCAAqC,eAAe,+CAA+C,wBAAwB,SAAS,qBAAqB,0CAA0C,WAAW,cAAc,mBAAmB,kBAAkB,QAAQ,sBAAsB,yCAAyC,sDAAsD,sBAAsB,kBAAkB,sBAAsB,aAAa,cAAc,YAAY,kBAAkB,2FAA2F,WAAW,qDAAqD,yBAAyB,mBAAmB,uGAAuG,uBAAuB,aAAa,cAAc,oDAAoD,gDAAgD,oBAAoB,kBAAkB,iDAAiD,wBAAwB,mDAAmD,+DAA+D,mBAAmB,qBAAqB,8DAA8D,kBAAkB,wEAAwE,sBAAsB,6CAA6C,OAAO,kBAAkB,eAAe,YAAY,wDAAwD,eAAe,qEAAqE,oCAAoC,OAAO,64BAA64B,wCAAwC,GAAG,4BAA4B,qBAAqB,YAAY,yBAAyB,sBAAsB,wBAAwB,OAAO,KAAK,2BAA2B,iBAAiB,iCAAiC,8BAA8B,2BAA2B,kDAAkD,mDAAmD,+BAA+B,+CAA+C,8CAA8C,4BAA4B,iBAAiB,uBAAuB,qBAAqB,yBAAyB,6BAA6B,iCAAiC,sBAAsB,sBAAsB,uBAAuB,4CAA4C,6BAA6B,2GAA2G,SAAS,oBAAoB,yBAAyB,6BAA6B,kCAAkC,+BAA+B,sBAAsB,mKAAmK,gEAAgE,kEAAkE,mEAAmE,8BAA8B,oCAAoC,0HAA0H,mCAAmC,SAAS,sBAAsB,qBAAqB,2CAA2C,6CAA6C,WAAW,sBAAsB,2CAA2C,WAAW,SAAS,OAAO,0CAA0C,+BAA+B,OAAO,KAAK,GAAG,0EAA0E,YAAY,oBAAoB,iBAAiB,uBAAuB,GAAG,8LAA8L,oBAAoB,uBAAuB,iDAAiD,KAAK,GAAG,qBAAqB;AAC5oK;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,qcAAqc;;;;;;;;;;;;;;;ACApd,iEAAe,8hBAA8hB;;;;;;;;;;;;;;;ACA7iB,iEAAe,mrDAAmrD;;;;;;;;;;;;;;;ACAlsD,iEAAe,4xGAA4xG;;;;;;;;;;;;;;;ACA3yG,iEAAe,ybAAyb;;;;;;;;;;;;;;;ACAxc,iEAAe,ykEAAykE;;;;;;;;;;;;;;;ACAxlE,iEAAe,yyBAAyyB;;;;;;;;;;;;;;;ACAxzB,iEAAe,+XAA+X;;;;;;;;;;;;;;;ACA9Y,iEAAe,oqDAAoqD;;;;;;;;;;;;;;;ACAnrD,iEAAe,6lBAA6lB;;;;;;;;;;;;;;;ACA5mB,iEAAe,kaAAka;;;;;;;;;;;;;;;ACAjb,iEAAe,knBAAknB;;;;;;;;;;;;;;;ACAjoB,iEAAe,uNAAuN;;;;;;;;;;;;;;;;;;ACAvI;AAC/F,YAAgL;;AAEhL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,4JAAO;;;;AAIxB,iEAAe,mKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAiL;;AAEjL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,6JAAO;;;;AAIxB,iEAAe,oKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAmL;;AAEnL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,+JAAO;;;;AAIxB,iEAAe,sKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA+K;;AAE/K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,2JAAO;;;;AAIxB,iEAAe,kKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA6K;;AAE7K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,yJAAO;;;;AAIxB,iEAAe,gKAAc,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;;AAE4C;AACyB;AAClC;;AAEnC;AACA;AACA;AACA,2CAA2C;AAC3C,oBAAoB,KAAK,qDAAqD;AAC9E;AACA;AACA;AACe,2BAA2B,sDAAM;AAChD;AACA;AACA;AACA;AACA,WAAW,yEAAmB,EAAE,oDAAM;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAOuB;AAOD;AACoD;AACb;;AAET;;AAEpD;AACA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA,UAAU,iBAAiB;;AAE3B;AACA;AACA;;AAEA,wDAAwD,gBAAgB;AACxE;;AAEA;AACA;AACA;;AAEA;AACA,eAAe,0DAAgB;AAC/B,eAAe,sDAAS;AACxB;AACA;;AAEA;AACA;AACA,SAAS,6DAAe;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA,wDAAwD,aAAa;AACrE;AACA;;AAEA,yBAAyB,8DAAY;;AAErC;AACA,SAAS,2DAAc,cAAc,uDAAU;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,8DAA8D;AACzE,WAAW,gBAAgB;AAC3B,WAAW,kEAAkE;AAC7E,YAAY;AACZ;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,0EAAuB;;AAE3B;AACA;AACA,KAAK,0EAAuB;AAC5B,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,IAAI,0EAAuB;AAC3B;AACA;AACA;AACA;;AAEA;AACA,KAAK,0EAAuB;;AAE5B;AACA,MAAM,0EAAuB;;AAE7B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,MAAM,UAAU,6DAAe;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAgB,iBAAiB,GAAG,2EAAwB;AAC5D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAkB,+DAAiB,UAAU,uBAAuB;;AAEpE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,2DAAc;AAC3C,yBAAyB,uDAAU;;AAEnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,oCAAoC;AAClD,cAAc,QAAQ;AACtB;AACA,yCAAyC,qCAAqC;AAC9E;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,4FAA4F;AACvG,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;;AAEA;AACA,UAAU,6BAA6B;;AAEvC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO,kDAAkD,eAAe,KAAK;AAC7E,0BAA0B,SAAS;AACnC;AACA;AACA;AACA;;AAEA,+DAA+D,mCAAmC;;AAElG;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,wCAAwC;AACnD,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,oCAAoC,aAAa;AACjD,8BAA8B,kEAAqB;AACnD,0BAA0B,8DAAiB;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAoB,+DAAgB,qBAAqB,oBAAoB;;AAE7E;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+BAA+B,eAAe;AAC9C;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,iEAAiE,kEAAoB;AACrF,OAAO,6DAAe;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACrdA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAYtB;;AAEvB;AACA,wCAAwC,kEAAkE;AAC1G;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,uBAAuB;AACnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA,8BAA8B,oEAAsB;;AAEpD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,uBAAuB,+DAAiB,eAAe,uBAAuB;AAC9E;;AAEA;AACA,4BAA4B,iEAAmB;AAC/C;;AAEA;AACA,2BAA2B,kEAAoB;;AAE/C;AACA,2BAA2B,mEAAqB;;AAEhD;AACA;AACA;AACA,0EAA0E,6DAAe;AACzF,0BAA0B,0DAAY;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mBAAmB,0DAAgB;AACnC;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,0BAA0B,6EAA+B,WAAW,oBAAoB;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,oCAAoC;AAC7F;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvNA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACA;AACE;AACM;;AAEgB;AACZ;AACU;AACA;AAO5C;AAKM;AASL;AAID;AAIM;;AAEU;;AAEtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACe,kCAAkC,sDAAM;AACvD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,sDAAK,EAAE,wDAAM;AACxB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA,aAAa,8DAAa,4CAA4C,gCAAgC;AACtG;;AAEA,uCAAuC,wCAAwC;AAC/E,mCAAmC,wCAAwC;AAC3E,yCAAyC,wCAAwC;;AAEjF;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA,2CAA2C,4DAAmB;AAC9D,2CAA2C,4DAAmB;;AAE9D,yCAAyC,kEAAyB;AAClE,0CAA0C,kEAAyB;;AAEnE,oDAAoD,iEAAwB;AAC5E,mDAAmD,iEAAwB;;AAE3E,kDAAkD,iEAAwB;AAC1E,iDAAiD,iEAAwB;;AAEzE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gEAAgE,mBAAmB;AACnF;;AAEA;AACA;AACA;AACA,kEAAkE,qBAAqB;AACvF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAA+D;AAC3E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC,yDAAyD;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,QAAQ,qEAAsB;AAC9B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,WAAW,8DAAe;AAC1B;AACA;;AAEA,2BAA2B,gEAAgB;AAC3C;AACA;AACA,OAAO;;AAEP;AACA;AACA,YAAY,oEAAqB;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,KAAK;AACL,GAAG,IAAI,gBAAgB;AACvB;;AAEA;AACA,gCAAgC,wDAAwD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,8DAAe;AACnB;AACA;AACA;AACA,yBAAyB,qEAAsB;AAC/C,wBAAwB,oEAAqB;;AAE7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B,mEAAoB;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,gCAAgC,sDAAsD;AACtF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAwB,iCAAiC;AACzD;AACA,iCAAiC,oEAAuB;AACxD,iCAAiC,gEAAmB,MAAM,mBAAmB;AAC7E,iCAAiC,gEAAmB,MAAM,mBAAmB;AAC7E,KAAK;;AAEL;AACA;AACA;AACA,UAAU,kEAAqB;AAC/B;AACA,KAAK;;AAEL;AACA;AACA;AACA,UAAU,kEAAqB,oBAAoB,qBAAqB;AACxE;AACA,KAAK;;AAEL;AACA;AACA,gCAAgC,sEAAyB;AACzD,KAAK;;AAEL,gDAAgD,uEAA0B;;AAE1E;AACA,4CAA4C,+BAA+B;AAC3E;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,4CAA4C,+BAA+B;AAC3E;AACA,wBAAwB,2EAA6B;AACrD,sBAAsB,yEAA2B;AACjD;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC,oBAAoB;AACrD,gBAAgB,iEAAc;AAC9B,GAAG,IAAI,mBAAmB;;AAE1B;AACA,iCAAiC,6BAA6B;AAC9D,gBAAgB,iEAAc;AAC9B,GAAG,IAAI,mBAAmB;AAC1B;;AAEA;AACA,mDAAmD,qDAAqD;AACxG,KAAK,yDAAyD;AAC9D;AACA;AACA;AACA;AACA;;AAEA,iFAAiF,mBAAmB;;AAEpG;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,oCAAoC,+DAAgB;;AAEpD;AACA,4BAA4B,mEAAoB;AAChD;AACA,IAAI;AACJ;AACA;;AAEA;AACA,aAAa,QAAQ;AACrB,cAAc,eAAe;AAC7B,cAAc,QAAQ;AACtB,cAAc,UAAU;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,mCAAmC;AAC9C,WAAW,gBAAgB;AAC3B,WAAW,kEAAkE;AAC7E,aAAa,SAAS;AACtB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,GAAG,0EAAuB;;AAE1B;AACA;AACA,IAAI,0EAAuB;AAC3B;;AAEA;AACA,iBAAiB,oCAAoC;AACrD,SAAS,8DAAe;AACxB,KAAK,0EAAuB;AAC5B;AACA;AACA;AACA;AACA;AACA,GAAG,0EAAuB;AAC1B;AACA;AACA;AACA,GAAG,0EAAuB;;AAE1B;AACA,IAAI,0EAAuB;AAC3B;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,qCAAqC;AAClD,aAAa,mCAAmC;AAChD,aAAa,cAAc;AAC3B,aAAa,QAAQ;AACrB,eAAe,SAAS;AACxB;AACA;AACA,kBAAkB,kEAAkB;AACpC;AACA;AACA;AACA,IAAI;AACJ;;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;;AAEA,QAAQ,8DAAe;AACvB;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA,OAAO,8DAAe;AACtB;AACA,IAAI,UAAU,8DAAe;AAC7B;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB,OAAO,GAAG,4EAAwB;AACnD;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,sBAAsB;AACjC,aAAa;AACb;AACA;;AAEA;AACA,UAAU,qEAAsB;AAChC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,QAAQ,+DAAgB;AACxB;;;;;;;;;;;;;;;;;;;ACntBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAUtB;AACqB;;AAE5C;AACA,wDAAwD,yDAAyD;AACjH;AACA;AACA;AACe,wCAAwC,uDAAO;AAC9D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,sBAAsB;AAClC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C,mBAAmB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,QAAQ,8DAAgB,eAAe,oEAAsB;AAC7D;AACA;AACA,4BAA4B,0DAAY;AACxC;;AAEA;AACA;AACA,2BAA2B,iEAAmB;AAC9C;AACA;AACA;AACA;AACA;AACA,4BAA4B,0DAAY,oBAAoB,eAAe;AAC3E,MAAM;AACN,4BAA4B,oEAAsB;AAClD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,8BAA8B,+DAAgB,WAAW,mBAAmB;;AAE5E;AACA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,0CAA0C;AACnG;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,OAAO,8DAAgB,eAAe,oEAAsB;AAC5D;AACA;;AAEA,WAAW,6EAA+B;AAC1C;;AAEA;AACA,sBAAsB,+DAAgB,gBAAgB,mBAAmB;;AAEzE;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,4DAA4D,6DAAe;;AAE3E;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACpLA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAUtB;AACqB;;AAE5C;AACA,uDAAuD,yDAAyD;AAChH;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,sBAAsB;AAClC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mDAAmD,mBAAmB;AACtE;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,gBAAgB;AAC5B,UAAU,qDAAqD;AAC/D;AACA;AACA,YAAY,0CAA0C,KAAK;AAC3D;AACA;AACA;;AAEA;AACA,WAAW,4BAA4B;;AAEvC;AACA;AACA;;AAEA;AACA,oCAAoC,iEAAmB;;AAEvD,2BAA2B,0DAAY;AACvC;;AAEA;AACA;AACA,MAAM;AACN;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAAgC,iDAAiD;;AAEjF;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,4BAA4B,iEAAmB;AAC/C;AACA,KAAK;AACL,2BAA2B,iEAAmB;AAC9C;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,yCAAyC;AAClG;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA,8BAA8B,oEAAsB;;AAEpD;AACA;;AAEA,SAAS,6DAAe;AACxB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,QAAQ,8DAAgB;AACxB;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,SAAS,6DAAe;AACxB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,yCAAyC;AACrD,YAAY,SAAS;AACrB,KAAK,qDAAqD;AAC1D,cAAc,QAAQ;AACtB,cAAc,qCAAqC;AACnD,cAAc,qCAAqC;AACnD;AACA;AACA;AACA,8BAA8B,oEAAsB;AACpD;;AAEA;AACA;AACA,wBAAwB,oEAAsB;;AAE9C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAgB,oBAAoB,sCAAsC;AAC9F,MAAM;AACN;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA,WAAW;AACX;AACA;;;;;;;;;;;;;;;;;;AC1OA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAMtB;;AAEvB;AACA;AACA;AACA,sBAAsB,kEAAkE;AACxF;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,kBAAkB;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB,iEAAmB;;AAE5C;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,yCAAyC;AAClG;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;;AAEA;AACA,GAAG,6DAAe;AAClB,IAAI,oEAAsB;AAC1B;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACjHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEqD;AACX;;AAE1C;AACA;AACA;AACe;AACf;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,sBAAsB;AAClC,YAAY,SAAS;AACrB,YAAY,uBAAuB;AACnC,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,yBAAyB,4DAAO;;AAEhC;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,sBAAsB;AAClC,YAAY,SAAS;AACrB,YAAY,uBAAuB;AACnC,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA,SAAS,0DAAK;AACd;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA,gBAAgB,OAAO;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,sBAAsB;AACjC,aAAa,wEAAwE;AACrF,IAAI,iDAAiD;AACrD;AACO;AACP;AACA;;AAEA,SAAS,uDAAe;AACxB,UAAU;;AAEV;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACO;AACP;AACA,YAAY,qCAAqC;AACjD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,+BAA+B;AAC7C,cAAc,+BAA+B;AAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnQA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEmD;AACiB;;AAEpE;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS,wDAAG;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,YAAY;AACZ;AACO,sDAAsD;AAC7D;AACA,oCAAoC,oCAAoC;AACxE,oCAAoC,mCAAmC;AACvE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,sBAAsB;AACjC,WAAW,SAAS;AACpB;AACA,aAAa;AACb;AACO,mDAAmD;AAC1D;;AAEA,+BAA+B,mDAAU;AACzC;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,wBAAwB,mDAAU;AAClC;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,4BAA4B,mDAAU;AACtC;AACA;AACA,GAAG;;AAEH,2BAA2B,mDAAU;AACrC;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,yBAAyB,yDAAgB;AACzC;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,qBAAqB,yDAAgB;AACrC;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iFAAiF;AAC5F,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO,+DAA+D;AACtE,UAAU,4DAAO;;AAEjB;AACA;;AAEA;AACA,0DAA0D,eAAe;AACzE;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iFAAiF;AAC5F,aAAa;AACb;AACO;AACP,UAAU,4DAAO;;AAEjB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP,gDAAgD,uBAAuB;AACvE;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA,gDAAgD,uBAAuB;;AAEvE;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,WAAW,mCAAmC;AAC9C,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACO,yCAAyC,uBAAuB,KAAK;AAC5E,UAAU,4DAAO;;AAEjB;AACA;;AAEA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,WAAW,mCAAmC;AAC9C;AACO;AACP,UAAU,4DAAO;;AAEjB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,2BAA2B,yDAAgB,WAAW,oBAAoB;AAC1E;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP,UAAU,4DAAO;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,6CAA6C;AACxD,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,GAAG,qEAAwB;AACjD;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,gDAAgD;AAC3D,aAAa,6CAA6C;AAC1D;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,0CAA0C;AACvD;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,4DAA4D,uBAAuB;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACrhBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwD;AACkB;;AAE1E;AACA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,WAAW,+EAA+E;AAC1F;AACA;AACO;AACP;;AAEA,OAAO,uDAAe;AACtB;;AAEA,OAAO,uDAAe;AACtB;AACA;AACA,GAAG;AACH;;AAEA,UAAU,iBAAiB,GAAG,qEAAwB;AACtD;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,wEAAwE;AACnF,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACO;AACP,oBAAoB;AACpB,sBAAsB;AACtB;AACA;;AAEA,eAAe,OAAO;AACtB;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,wEAAwE;AACnF,WAAW,cAAc;AACzB,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACO;AACP;AACA;;AAEA,eAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,oDAAgB;AAChC;;AAEA;;AAEA,uBAAuB,yDAAiB,UAAU,uBAAuB;AACzE;;AAEA;AACA;AACA,iBAAiB,oDAAgB;AACjC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;ACzIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;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,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,QAAQ;AACnB,WAAW,uBAAuB;AAClC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,WAAW,uBAAuB;AAClC,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uBAAuB;AAClC,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP,iBAAiB,MAAM,IAAI,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;ACnJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACuD;AAClC;;AAEjE;AACA;AACA;AACA;AACA,IAAI;AACJ,oBAAoB,SAAS,8FAA8F;AAC3H;AACA;AACA;AACe,qCAAqC,sDAAM;AAC1D;AACA;AACA;AACA;AACA,WAAW,6FAA6B,EAAE,wEAAgB;AAC1D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,aAAa;AACb;AACO;AACP;AACA,UAAU,6BAA6B;;AAEvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kDAAkD,gBAAgB;AAClE;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;ACxDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAE0B;AACJ;AACA;AACM;AACX;AAMtC;;AAEvB;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,sDAAsD;AACvE;AACA;AACA;AACe,4CAA4C,sDAAM;AACjE;AACA;AACA;AACA;AACA,WAAW,yEAAmB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,yEAAmB;;AAErE;AACA;;AAEA;AACA;;AAEA,wCAAwC,0CAA0C;AAClF,oCAAoC,0CAA0C;AAC9E,0CAA0C,0CAA0C;;AAEpF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,iCAAiC,0EAA6B;AAC9D,iCAAiC,0EAA6B;AAC9D;AACA,IAAI;;AAEJ;AACA,2DAA2D,+BAA+B;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA,gDAAgD,oBAAoB;AACpE,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,gDAAgD,oBAAoB;AACpE,qCAAqC;;AAErC,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;;AAEA;AACA;;AAEA,mCAAmC;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,gBAAgB;;AAE7B;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,cAAc,QAAQ;AACtB,cAAc,GAAG;AACjB,cAAc,QAAQ;AACtB,IAAI,sFAAsF;AAC1F,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,gBAAgB;AAC3B,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa;AACb;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAsB,2BAA2B;;AAEjD;AACA,yBAAyB,uEAAyB;;AAElD;AACA,4DAA4D,+EAAiC;AAC7F;;AAEA,0CAA0C,iEAAwB;AAClE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,WAAW,0EAA4B;AACvC,IAAI;;AAEJ;AACA;AACA;AACA,oBAAoB,+EAAiC;;AAErD;AACA;;AAEA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,YAAY,+EAAiC;AAC7C;;AAEA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,sBAAsB,wBAAwB;;AAE9C;AACA,6CAA6C,oEAA2B;AACxE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,sBAAsB,qBAAqB;;AAE3C;AACA,0CAA0C,iEAAwB;AAClE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACxXA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;AAIP;;AAErC;AACA;AACA;AACA,sBAAsB,wFAAwF;AAC9G;AACA;AACA;AACe,0CAA0C,uDAAO;AAChE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA,uBAAuB;AACvB;AACA;;AAEA;AACA,qBAAqB,0EAAe;;AAEpC,WAAW,yFAA8B;;AAEzC;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,cAAc;AAC5B;AACA;AACA;AACA;;AAEA,gBAAgB,0DAAK;;AAErB,OAAO,0EAAe;AACtB;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;AAIP;;AAErC;AACA;AACA;AACA,sBAAsB,wFAAwF;AAC9G;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,uBAAuB;AACvB;AACA;;AAEA;AACA,qBAAqB,0EAAe;;AAEpC,WAAW,yFAA8B;;AAEzC;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA;AACA;;AAEA,gBAAgB,0DAAK;;AAErB,gBAAgB,0EAAe;AAC/B;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;AAIP;AACwB;;AAE7D;AACA;AACA;AACA,sBAAsB,wFAAwF;AAC9G;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA,uBAAuB;AACvB;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,YAAY,yFAA8B;;AAE1C;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,mBAAmB,0DAAK;;AAExB,OAAO,0EAAe;AACtB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;;AAEA,mBAAmB,0EAA4B;;AAE/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AClKA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAG,gEAAgE;AACnE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,gEAAgE;AACnE,GAAG,8EAA8E;AACjF,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG;AACH;;AAEA,cAAc,qCAAqC;AACnD;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,YAAY;AACZ;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;;;;;;;;;;;;;;;;;;ACzEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACV;;AAES;;AAE5C;AACA;AACA;AACA,2CAA2C;AAC3C,QAAQ,qDAAqD;AAC7D;AACA;AACA;AACe,mBAAmB,sDAAM;AACxC;AACA;AACA;AACA;AACA,WAAW,yDAAW,EAAE,oDAAM;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,kCAAkC;AAC/D,YAAY,2DAA2D;AACvE;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,QAAQ,sEAAsE;AAC9E;AACA;AACA;;AAEA;AACA,6BAA6B,6BAA6B,iBAAiB,6CAA6C;AACxH;AACA,iBAAiB,kCAAkC;AACnD;AACA,YAAY,oCAAoC;AAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkD;;AAQjC;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,mBAAmB,sDAAc;;AAEjC,EAAE,sDAAc;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG,sDAAc;AACjB;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA,UAAU,mEAAmE;AAC7E;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,oEAAoE,sDAAsD;AAC1H;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA,CAAC,sDAAc;AACf,CAAC,sDAAc;AACf;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG,sDAAc;AACjB;;AAEA;AACA;;AAEA;AACA,EAAE,sDAAc;;AAEhB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wDAAwD,yCAAyC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;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;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;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;;AAEA;AACA;AACA,sBAAsB,sDAAc;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG,sDAAc;AACjB;AACA;AACA;;AAEA;AACA,wDAAwD,yCAAyC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,CAAC,sDAAc;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP,yDAAyD,aAAa;AACtE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP,sDAAsD,aAAa;AACnE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP,sDAAsD,aAAa;AACnE;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,uEAAuE,6CAA6C;AACpH;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAM;AACN;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iEAAiE,6CAA6C;AAC9G;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB;AACxB;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,OAAO,mBAAmB,oDAAoD;AACzF;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,yCAAyC;AACpD,WAAW,+DAA+D;AAC1E,aAAa,uCAAuC;AACpD;AACA,SAAS,iBAAiB;;AAE1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;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;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,wBAAwB,4DAAU,IAAI,gBAAgB;;AAEtD;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0DAAkB;AACzC;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAkB,+DAAuB;;AAEzC;AACA;AACA;AACA;AACA;;AAEA,GAAG,sDAAc;AACjB,GAAG,sDAAc;AACjB;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;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;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACriCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;;AAE5C;AACA,+CAA+C,yCAAyC;AACxF;AACA;AACA;AACe,4BAA4B,uDAAO;AAClD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,sBAAsB;AAClC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C,mBAAmB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,gBAAgB;AAC1C;AACA,0DAA0D,8BAA8B;AACxF;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA,mBAAmB,0DAAK;;AAExB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACrJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;;AAE5C;AACA,wCAAwC,yCAAyC;AACjF;AACA;AACA;AACe,0BAA0B,uDAAO;AAChD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,uBAAuB;AACnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;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;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;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAqB,uCAAuC;;AAE5D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,6BAA6B,oCAAoC;AACjE;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,gBAAgB;AAC1C;AACA,0DAA0D,4BAA4B;AACtF;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA,mBAAmB,0DAAK;;AAExB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,0DAAK;;AAE1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,WAAW,SAAS;AACpB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa;AACb;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACtUA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwC;AACI;;AAEA;AACA;AACE;;AAiBxB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACe,0BAA0B,sDAAM;AAC/C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,sDAAK,EAAE,wDAAM;AACxB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA,qDAAqD,iEAAoB;;AAEzE;AACA;;AAEA,4CAA4C,gEAAmB;AAC/D,4CAA4C,gEAAmB;AAC/D,yCAAyC,gEAAmB;;AAE5D;AACA;AACA,6BAA6B,+DAAsB,IAAI,mBAAmB;AAC1E,sCAAsC,+DAAkB;AACxD,kDAAkD,4DAAmB,IAAI,mBAAmB;AAC5F,kDAAkD,sEAA6B,IAAI,kBAAkB;AACrG,oDAAoD,kEAAqB;AACzE,sCAAsC,4DAAe;AACrD,6BAA6B,4DAAmB,IAAI,kBAAkB;AACtE,KAAK;;AAEL;AACA;AACA,6BAA6B,+DAAsB,IAAI,mBAAmB;AAC1E,sCAAsC,+DAAkB;AACxD,KAAK;;AAEL;AACA;AACA,iCAAiC,kDAAS,IAAI,mBAAmB;AACjE,iCAAiC,kDAAS,IAAI,mBAAmB;AACjE,iCAAiC,sDAAa,IAAI,mBAAmB;AACrE,iCAAiC,2DAAkB;AACnD,KAAK;;AAEL;AACA,oCAAoC,8DAAqB,IAAI,mBAAmB;;AAEhF;AACA,2CAA2C,oDAAW;AACtD,2CAA2C,oDAAW;;AAEtD;AACA,yCAAyC,sDAAa;AACtD,0CAA0C,sDAAa;;AAEvD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG,IAAI,gBAAgB;;AAEvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;AACvB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;AC1NA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAEsB;AACA;;AAEtB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACe,qBAAqB,sDAAM;AAC1C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAE,yDAAiB,qDAAqD,qEAAgB;AACxF,EAAE,yDAAiB,qDAAqD,qEAAgB;AACxF;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEmE;AACrB;;AAE9C;AACA,wBAAwB,2DAA2D;AACnF;AACA,WAAW,kDAAkD;AAC7D,aAAa;AACb;AACO;AACP;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,+DAA+D;AAC1E,aAAa,sDAAsD;AACnE;AACO;AACP;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,WAAW,sDAAsD;AACjE,WAAW,+DAA+D;AAC1E,WAAW,iCAAiC;AAC5C;AACO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+CAA+C,yBAAyB;;AAExE;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,8BAA8B;AACzC,WAAW,8BAA8B;AACzC,aAAa,2CAA2C;AACxD;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sCAAsC;AACjD,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB,WAAW,sBAAsB;AACjC,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACO;AACP;AACA;AACA,yBAAyB,wDAAU;;AAEnC;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,YAAY;AACZ;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,WAAW,sBAAsB;AACjC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4DAAU;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,aAAa,aAAa;AAC1B;AACA;;AAEA;AACA;AACA;;AAEA,QAAQ,sEAAoB;AAC5B;;;;;;;;;;;;;;;;;;;ACxcA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC+B;AACV;;AAEjE;AACA;AACA;AACA,2CAA2C;AAC3C,oBAAoB,SAAS,8FAA8F;AAC3H;AACA;AACA;AACe,6BAA6B,sDAAM;AAClD;AACA;AACA;AACA;AACA,WAAW,6EAAqB,EAAE,wEAAgB;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,iEAAiE;AAC9F,IAAI,0FAA0F;AAC9F;AACA;AACA,wBAAwB,iFAAiF;AACzG,IAAI,iFAAiF;AACrF,IAAI,0FAA0F;AAC9F,IAAI,yGAAyG;AAC7G,IAAI,yGAAyG;AAC7G,IAAI,kHAAkH;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ,KAAK,sEAAsE;AAC3E;AACA;AACA,YAAY,8DAA8D;AAC1E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;;AAEA;AACA,6BAA6B,iDAAiD;AAC9E,IAAI,0FAA0F;AAC9F;AACA,iBAAiB,sDAAsD;AACvE;AACA,YAAY,iDAAiD;AAC7D;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,yFAAyF;AAC1I;AACA;AACA,YAAY,SAAS;AACrB;;;;;;;;;;;;;;;;;;;;;;ACtIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACE;AACI;AACM;AACN;AACkB;;AAEpE;;AAEA;AACA;AACA;AACA,0DAA0D,0CAA0C;AACpG;AACA;AACA;AACA,iBAAiB,sDAAsD;AACvE;AACA;AACA;AACe,oCAAoC,sDAAM;AACzD;AACA;AACA;AACA;AACA,WAAW,yDAAW;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB,qDAAqD;AAC9E;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,4EAA4E;AACxF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,+DAAkB;AAC/C;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG,IAAI,mBAAmB;;AAE1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,+DAAkB;AACtD;AACA;AACA;AACA,MAAM;;AAEN;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ,4DAAe;AACvB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,GAAG,IAAI,kBAAkB;AACzB;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,cAAc,QAAQ;AACtB,cAAc,GAAG;AACjB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C,yDAAgB;AAC1D,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,4DAAmB;AAChE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C,yDAAgB;AAC1D,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,IAAI,kBAAkB;AACzB;AACA;;AAEA;AACA;AACA;AACA,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;AACA,gCAAgC,wBAAwB;AACxD;AACA;;AAEA,4BAA4B,+DAAkB;AAC9C;AACA;AACA;AACA,MAAM;;AAEN;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,IAAI,kBAAkB;AAC1B;AACA;;AAEA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,0CAA0C;AACtD,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,+DAAkB;AACvC;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;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;AACA,WAAW,kCAAkC;AAC7C,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,0CAA0C;AACrD,WAAW,qCAAqC;AAChD,WAAW,qDAAqD;AAChE,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,0CAA0C;AACrD,WAAW,qCAAqC;AAChD,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA,WAAW,gBAAgB;AAC3B,aAAa;AACb;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC10BA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC6D;;AAEhD;;AAES;AACA;;AAEE;AACI;AACA;AACE;AAC0B;AACpB;AACA;AACA;AACA;;AAE5C;;AAEpC;AACA;AACA;AACA;AACA,kFAAkF;AAClF;AACA;AACA;AACA;AACe,+BAA+B,sDAAM;AACpD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qEAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sEAAiB;AAC7B,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,wEAAmB;AAC/B,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,wEAAmB;AAC/B;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qEAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yEAAoB;AAChC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,oFAAmC;AAC/C,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,kCAAkC;AAC7C,WAAW,+BAA+B;AAC1C;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,UAAU,6CAA6C,sDAAsD;AAC1H,mCAAmC,2FAA2F;AAC9H;;AAEA,YAAY,4BAA4B;AACxC,cAAc;AACd;AACA,uBAAuB,gEAAc,UAAU,6DAAe;AAC9D;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,kCAAkC;AAC7C,WAAW,gDAAgD;AAC3D,WAAW,+BAA+B;AAC1C;AACA,aAAa,UAAU,6CAA6C,sDAAsD;AAC1H,kCAAkC,8CAA8C;AAChF;AACA;;AAEA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc;AACd,YAAY,6BAA6B;AACzC,qBAAqB,wDAAU;;AAE/B,gBAAgB,uBAAuB;;AAEvC;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA,oCAAoC,sCAAsC;AAC1E;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C,MAAM;AACN;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,kCAAkC;AAC7C,WAAW,8CAA8C;AACzD,WAAW,+BAA+B;AAC1C;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;AACA;;AAEA,gCAAgC,8DAAkB;AAClD;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,EAAE,0EAAwB;AAC1B;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,qCAAqC,wBAAwB;AAC7D,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACxUA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACQ;;AAErD;AACA;AACA;AACA,sBAAsB,wEAAwE;AAC9F;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA,uBAAuB;AACvB;AACA,oBAAoB,iEAAoB;AACxC;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,cAAc;AAC5B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC/DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACQ;;AAErD;AACA;AACA,sBAAsB,wEAAwE;AAC9F;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,uBAAuB;AACvB;AACA,oBAAoB,iEAAoB;AACxC;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,cAAc;AAC5B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC9DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACsC;;AAEnF;AACA;AACA;AACA;AACA;AACA,sBAAsB,wEAAwE;AAC9F;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA,uBAAuB;AACvB;;AAEA;AACA,oBAAoB,iEAAoB;;AAExC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA,mBAAmB,yEAA4B;;AAE/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACnIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEoD;;AAEpD;AACsF;;AAE9C;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACe,8BAA8B,kDAAI;AACjD;AACA;AACA;AACA,YAAY,4BAA4B,YAAY,+CAA+C;AACnG,YAAY,6BAA6B;AACzC;AACA;AACA;AACA;;AAEA;;AAEA;AACA,qCAAqC,iBAAiB;AACtD;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA,4BAA4B,kBAAkB;AAC9C;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA,kFAAkF,gBAAgB;AAClG;AACA;AACA,cAAc,wCAAwC;AACtD;AACA;;AAEA;AACA,4EAA4E,kBAAkB;AAC9F;AACA;AACA,cAAc,yCAAyC;AACvD;AACA;;AAEA;AACA,qCAAqC,mBAAmB;AACxD,qEAAqE,uBAAuB;AAC5F;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,sBAAsB,mBAAmB;AACzC;AACA;AACA,cAAc;AACd;AACA;AACA,yBAAyB,wDAAU;AACnC;;AAEA;AACA;AACA,SAAS,6FAAiB;AAC1B,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACvJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAU0B;AAKG;;AAEmB;;AAEL;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACe,iCAAiC,kDAAI;AACpD;AACA;AACA;AACA,YAAY,4BAA4B,YAAY,+CAA+C;AACnG,YAAY,QAAQ;AACpB,YAAY,yBAAyB;AACrC;AACA,YAAY,qDAAqD;AACjE;AACA,YAAY,QAAQ;AACpB;AACA,wBAAwB,0DAA0D;AAClF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,qEAAqE,4BAA4B;AACjG,MAAM,gCAAgC,sCAAsC,iCAAiC;AAC7G;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC,mBAAmB,4BAA4B,IAAI,iCAAiC;AACpF;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;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,cAAc;AACd;AACA,wBAAwB,4DAAc;;AAEtC;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA,cAAc;AACd;AACA,yBAAyB,yDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,GAAG,4EAA0B;AAC7B;AACA;AACA;AACA;AACA;AACA,2BAA2B,+EACL;AACtB;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,IAAI,mBAAmB;;AAE3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,gDAAgD;AAC5D,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA,yBAAyB,kDAAI;;AAE7B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA,gCAAgC,6DAAY;AAC5C,8BAA8B,iEAAgB;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;AACA,aAAa,4BAA4B,QAAQ,iCAAiC;AAClF;AACA;AACA,YAAY,yBAAyB;AACrC,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD,wDAAe;;AAEjE;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kCAAkC,8DAAgB,eAAe,sEAAwB;;AAEzF;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL,8BAA8B,aAAa;AAC3C;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iCAAiC,8DAAgB;;AAEjD;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;;AAEA;AACA,2DAA2D,2BAA2B;AACtF;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;;AAEA;AACA,0DAA0D,gCAAgC;AAC1F;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC7aA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyD;AACV;AACH;AACb;;AAE/B;AACA;AACA;AACA,2CAA2C;AAC3C,YAAY,uEAAuE;AACnF;AACA;AACA;AACe,uBAAuB,sDAAM;AAC5C;AACA;AACA;AACA;AACA,WAAW,iEAAe,EAAE,4DAAU;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAE7C;;AAEA;AACA;AACA;AACA,qCAAqC,4DAA4D;AACjG;AACA;AACA;AACA;AACe,mCAAmC,uDAAO;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM,wDAAwD;AAC9D;AACA;AACA;AACA,cAAc,SAAS;AACvB;;AAEA;AACA,iDAAiD,8CAA8C;AAC/F;AACA;AACA;AACA,cAAc,6CAA6C;AAC3D;;AAEA;AACA,iDAAiD,8CAA8C;AAC/F;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,sBAAsB;AAC7B;;AAEA;AACA,2BAA2B,cAAc,KAAK,kBAAkB;AAChE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+CAA+C,8CAA8C;AAC7F;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;;;;;;ACrHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEoD;;AAEoD;;AAExG;AACA;AACA;AACA,yEAAyE;AACzE;AACA;AACA,kBAAkB,mEAAmE;AACrF;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,UAAU;AACrB,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,2DAAc;;AAEjC;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA,EAAE,2DAAc;AAChB;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,6DAA6D;AAC/E;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,2DAAc;;AAEjC;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA,EAAE,2DAAc;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,6DAA6D;AAC/E;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA,qDAAqD,aAAa;AAClE;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI,kEAAkE;AACtE;AACA;AACA,kCAAkC,uDAAuD;AACzF,IAAI,iEAAiE;AACrE;AACA,kBAAkB,mEAAmE;AACrF;AACA;AACA,WAAW,UAAU;AACrB,WAAW,8BAA8B;AACzC,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA,sBAAsB,2DAAc;;AAEpC,4BAA4B,oEAAuB;AACnD;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAiB,kEAAkE;AACnF;AACA,kBAAkB,mEAAmE;AACrF;AACA;AACA,WAAW,UAAU;AACrB,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,UAAU,6BAA6B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,YAAY;AACZ;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,kDAAkD;AAC7D,WAAW,SAAS;AACpB,WAAW,UAAU;AACrB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,oBAAoB,kEAAa,uBAAuB,mBAAmB;;AAE3E;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACrVA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAKf;;AAEiB;AACA;AACY;AAQ5B;;AAE9B,8BAA8B,mEAAc;;AAE5C;AACA;AACA;AACA,iDAAiD,oEAAoE;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,8BAA8B,sDAAM;AACnD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,yDAAW;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAU,uBAAuB;;AAEjC;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,uCAAuC,yDAAW;;AAElD,mCAAmC,6DAAoB;;AAEvD;AACA;AACA;;AAEA;AACA,iDAAiD,2EAAsB,aAAa,mBAAmB;AACvG,6CAA6C,gFAA+B,IAAI,mBAAmB;;AAEnG;AACA;AACA,GAAG,uEAAkB;AACrB,KAAK;AACL;AACA;AACA;AACA,GAAG,wEAAmB;AACtB;AACA;AACA;AACA,GAAG,2EAAsB;AACzB;;AAEA,4CAA4C,2EAAsB;AAClE,yCAAyC,2EAAsB;;AAE/D;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,oHAAoH,gBAAgB;;AAEpI;AACA;AACA,QAAQ,4DAAO;AACf;AACA;AACA;AACA,GAAG,IAAI,mBAAmB;;AAE1B;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,4BAA4B;AACvC,aAAa,UAAU;AACvB;AACA;AACA,oBAAoB,sFAAiC;;AAErD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACjOA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkD;AACQ;AACd;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACe,yBAAyB,sDAAM;AAC9C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,EAAE,8DAAiB,8CAA8C,iEAAY;AAC7E;AACA;;;;;;;;;;;ACnCA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;UCAA;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;;;;;WCNA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyD;AAC2B;AACP;AACqC;AACzE;AACmB;AACV;AACW;AAC6B;AACV;AAC/B;AACuB;AACV","file":"list.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-collapsible.ck-collapsible_collapsed>.ck-collapsible__children{display:none}:root{--ck-collapsible-arrow-size:calc(var(--ck-icon-size)*0.5)}.ck.ck-collapsible>.ck.ck-button{border-radius:0;font-weight:700;padding:var(--ck-spacing-medium) var(--ck-spacing-large);width:100%}.ck.ck-collapsible>.ck.ck-button:focus{background:transparent}.ck.ck-collapsible>.ck.ck-button:active,.ck.ck-collapsible>.ck.ck-button:hover:not(:focus),.ck.ck-collapsible>.ck.ck-button:not(:focus){background:transparent;border-color:transparent;box-shadow:none}.ck.ck-collapsible>.ck.ck-button>.ck-icon{margin-right:var(--ck-spacing-medium);width:var(--ck-collapsible-arrow-size)}.ck.ck-collapsible>.ck-collapsible__children{padding:0 var(--ck-spacing-large) var(--ck-spacing-large)}.ck.ck-collapsible.ck-collapsible_collapsed>.ck.ck-button .ck-icon{transform:rotate(-90deg)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/collapsible.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-list/collapsible.css\"],\"names\":[],\"mappings\":\"AAMC,sEACC,YACD,CCHD,MACC,yDACD,CAGC,iCAIC,eAAgB,CAFhB,eAAiB,CACjB,wDAAyD,CAFzD,UAmBD,CAdC,uCACC,sBACD,CAEA,wIACC,sBAAuB,CACvB,wBAAyB,CACzB,eACD,CAEA,0CACC,qCAAsC,CACtC,sCACD,CAGD,6CACC,yDACD,CAGC,mEACC,wBACD\",\"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-collapsible.ck-collapsible_collapsed {\\n\\t& > .ck-collapsible__children {\\n\\t\\tdisplay: none;\\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:root {\\n\\t--ck-collapsible-arrow-size: calc(0.5 * var(--ck-icon-size));\\n}\\n\\n.ck.ck-collapsible {\\n\\t& > .ck.ck-button {\\n\\t\\twidth: 100%;\\n\\t\\tfont-weight: bold;\\n\\t\\tpadding: var(--ck-spacing-medium) var(--ck-spacing-large);\\n\\t\\tborder-radius: 0;\\n\\n\\t\\t&:focus {\\n\\t\\t\\tbackground: transparent;\\n\\t\\t}\\n\\n\\t\\t&:active, &:not(:focus), &:hover:not(:focus) {\\n\\t\\t\\tbackground: transparent;\\n\\t\\t\\tborder-color: transparent;\\n\\t\\t\\tbox-shadow: none;\\n\\t\\t}\\n\\n\\t\\t& > .ck-icon {\\n\\t\\t\\tmargin-right: var(--ck-spacing-medium);\\n\\t\\t\\twidth: var(--ck-collapsible-arrow-size);\\n\\t\\t}\\n\\t}\\n\\n\\t& > .ck-collapsible__children {\\n\\t\\tpadding: 0 var(--ck-spacing-large) var(--ck-spacing-large);\\n\\t}\\n\\n\\t&.ck-collapsible_collapsed {\\n\\t\\t& > .ck.ck-button .ck-icon {\\n\\t\\t\\ttransform: rotate(-90deg);\\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-editor__editable .ck-list-bogus-paragraph{display:block}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/documentlist.css\"],\"names\":[],\"mappings\":\"AAKA,8CACC,aACD\",\"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-editor__editable .ck-list-bogus-paragraph {\\n\\tdisplay: block;\\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-list-properties.ck-list-properties_without-styles{padding:var(--ck-spacing-large)}.ck.ck-list-properties.ck-list-properties_without-styles>*{min-width:14em}.ck.ck-list-properties.ck-list-properties_without-styles>*+*{margin-top:var(--ck-spacing-standard)}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-list-styles-list{grid-template-columns:repeat(4,auto)}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-collapsible{border-top:1px solid var(--ck-color-base-border)}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-collapsible>.ck-collapsible__children>*{width:100%}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-collapsible>.ck-collapsible__children>*+*{margin-top:var(--ck-spacing-standard)}.ck.ck-list-properties .ck.ck-numbered-list-properties__start-index .ck-input{min-width:auto;width:100%}.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order{background:transparent;margin-bottom:calc(var(--ck-spacing-tiny)*-1);padding-left:0;padding-right:0}.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order:active,.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order:hover{background:none;border-color:transparent;box-shadow:none}\", \"\",{\"version\":3,\"sources\":[\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-list/listproperties.css\"],\"names\":[],\"mappings\":\"AAOC,yDACC,+BASD,CAPC,2DACC,cAKD,CAHC,6DACC,qCACD,CASD,wFACC,oCACD,CAGA,mFACC,gDAWD,CARE,+GACC,UAKD,CAHC,iHACC,qCACD,CAMJ,8EACC,cAAe,CACf,UACD,CAEA,uEACC,sBAAuB,CAGvB,6CAAgD,CAFhD,cAAe,CACf,eAQD,CALC,2JAGC,eAAgB,CADhB,wBAAyB,CADzB,eAGD\",\"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-list-properties {\\n\\t/* When there are no list styles and there is no collapsible. */\\n\\t&.ck-list-properties_without-styles {\\n\\t\\tpadding: var(--ck-spacing-large);\\n\\n\\t\\t& > * {\\n\\t\\t\\tmin-width: 14em;\\n\\n\\t\\t\\t& + * {\\n\\t\\t\\t\\tmargin-top: var(--ck-spacing-standard);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t/*\\n\\t * When the numbered list property fields (start at, reversed) should be displayed,\\n\\t * more horizontal space is needed. Reconfigure the style grid to create that space.\\n\\t */\\n\\t&.ck-list-properties_with-numbered-properties {\\n\\t\\t& > .ck-list-styles-list {\\n\\t\\t\\tgrid-template-columns: repeat( 4, auto );\\n\\t\\t}\\n\\n\\t\\t/* When list styles are rendered and property fields are in a collapsible. */\\n\\t\\t& > .ck-collapsible {\\n\\t\\t\\tborder-top: 1px solid var(--ck-color-base-border);\\n\\n\\t\\t\\t& > .ck-collapsible__children {\\n\\t\\t\\t\\t& > * {\\n\\t\\t\\t\\t\\twidth: 100%;\\n\\n\\t\\t\\t\\t\\t& + * {\\n\\t\\t\\t\\t\\t\\tmargin-top: var(--ck-spacing-standard);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t& .ck.ck-numbered-list-properties__start-index .ck-input {\\n\\t\\tmin-width: auto;\\n\\t\\twidth: 100%;\\n\\t}\\n\\n\\t& .ck.ck-numbered-list-properties__reversed-order {\\n\\t\\tbackground: transparent;\\n\\t\\tpadding-left: 0;\\n\\t\\tpadding-right: 0;\\n\\t\\tmargin-bottom: calc(-1 * var(--ck-spacing-tiny));\\n\\n\\t\\t&:active, &:hover {\\n\\t\\t\\tbox-shadow: none;\\n\\t\\t\\tborder-color: transparent;\\n\\t\\t\\tbackground: none;\\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-list-styles-list{display:grid}:root{--ck-list-style-button-size:44px}.ck.ck-list-styles-list{column-gap:var(--ck-spacing-medium);grid-template-columns:repeat(3,auto);padding:var(--ck-spacing-large);row-gap:var(--ck-spacing-medium)}.ck.ck-list-styles-list .ck-button{box-sizing:content-box;margin:0;padding:0}.ck.ck-list-styles-list .ck-button,.ck.ck-list-styles-list .ck-button .ck-icon{height:var(--ck-list-style-button-size);width:var(--ck-list-style-button-size)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/liststyles.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-list/liststyles.css\"],\"names\":[],\"mappings\":\"AAKA,wBACC,YACD,CCFA,MACC,gCACD,CAEA,wBAGC,mCAAoC,CAFpC,oCAAwC,CAGxC,+BAAgC,CAFhC,gCA4BD,CAxBC,mCAiBC,sBAAuB,CAPvB,QAAS,CANT,SAmBD,CAJC,+EAhBA,uCAAwC,CADxC,sCAoBA\",\"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-list-styles-list {\\n\\tdisplay: grid;\\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-list-style-button-size: 44px;\\n}\\n\\n.ck.ck-list-styles-list {\\n\\tgrid-template-columns: repeat( 3, auto );\\n\\trow-gap: var(--ck-spacing-medium);\\n\\tcolumn-gap: var(--ck-spacing-medium);\\n\\tpadding: var(--ck-spacing-large);\\n\\n\\t& .ck-button {\\n\\t\\t/* Make the button look like a thumbnail (the icon \\\"takes it all\\\"). */\\n\\t\\twidth: var(--ck-list-style-button-size);\\n\\t\\theight: var(--ck-list-style-button-size);\\n\\t\\tpadding: 0;\\n\\n\\t\\t/*\\n\\t\\t * Buttons are aligned by the grid so disable default button margins to not collide with the\\n\\t\\t * gaps in the grid.\\n\\t\\t */\\n\\t\\tmargin: 0;\\n\\n\\t\\t/*\\n\\t\\t * Make sure the button border (which is displayed on focus, BTW) does not steal pixels\\n\\t\\t * from the button dimensions and, as a result, decrease the size of the icon\\n\\t\\t * (which becomes blurry as it scales down).\\n\\t\\t */\\n\\t\\tbox-sizing: content-box;\\n\\n\\t\\t& .ck-icon {\\n\\t\\t\\twidth: var(--ck-list-style-button-size);\\n\\t\\t\\theight: var(--ck-list-style-button-size);\\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-todo-list-checkmark-size:16px}.ck-content .todo-list{list-style:none}.ck-content .todo-list li{margin-bottom:5px}.ck-content .todo-list li .todo-list{margin-top:5px}.ck-content .todo-list .todo-list__label>input{-webkit-appearance:none;border:0;display:inline-block;height:var(--ck-todo-list-checkmark-size);left:-25px;margin-left:0;margin-right:-15px;position:relative;right:0;vertical-align:middle;width:var(--ck-todo-list-checkmark-size)}.ck-content .todo-list .todo-list__label>input:before{border:1px solid #333;border-radius:2px;box-sizing:border-box;content:\\\"\\\";display:block;height:100%;position:absolute;transition:box-shadow .25s ease-in-out,background .25s ease-in-out,border .25s ease-in-out;width:100%}.ck-content .todo-list .todo-list__label>input:after{border-color:transparent;border-style:solid;border-width:0 calc(var(--ck-todo-list-checkmark-size)/8) calc(var(--ck-todo-list-checkmark-size)/8) 0;box-sizing:content-box;content:\\\"\\\";display:block;height:calc(var(--ck-todo-list-checkmark-size)/2.6);left:calc(var(--ck-todo-list-checkmark-size)/3);pointer-events:none;position:absolute;top:calc(var(--ck-todo-list-checkmark-size)/5.3);transform:rotate(45deg);width:calc(var(--ck-todo-list-checkmark-size)/5.3)}.ck-content .todo-list .todo-list__label>input[checked]:before{background:#26ab33;border-color:#26ab33}.ck-content .todo-list .todo-list__label>input[checked]:after{border-color:#fff}.ck-content .todo-list .todo-list__label .todo-list__label__description{vertical-align:middle}[dir=rtl] .todo-list .todo-list__label>input{left:0;margin-left:-15px;margin-right:0;right:-25px}.ck-editor__editable .todo-list .todo-list__label>input{cursor:pointer}.ck-editor__editable .todo-list .todo-list__label>input:hover:before{box-shadow:0 0 0 5px rgba(0,0,0,.1)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/todolist.css\"],\"names\":[],\"mappings\":\"AAKA,MACC,kCACD,CAEA,uBACC,eA0ED,CAxEC,0BACC,iBAKD,CAHC,qCACC,cACD,CAIA,+CACC,uBAAwB,CAQxB,QAAS,CAPT,oBAAqB,CAGrB,yCAA0C,CAO1C,UAAW,CAGX,aAAc,CAFd,kBAAmB,CAVnB,iBAAkB,CAWlB,OAAQ,CARR,qBAAsB,CAFtB,wCAqDD,CAxCC,sDAOC,qBAAiC,CACjC,iBAAkB,CALlB,qBAAsB,CACtB,UAAW,CAHX,aAAc,CAKd,WAAY,CAJZ,iBAAkB,CAOlB,0FAAgG,CAJhG,UAKD,CAEA,qDAaC,wBAAyB,CADzB,kBAAmB,CAEnB,sGAA+G,CAX/G,sBAAuB,CAEvB,UAAW,CAJX,aAAc,CAUd,mDAAwD,CAHxD,+CAAoD,CAJpD,mBAAoB,CAFpB,iBAAkB,CAOlB,gDAAqD,CAMrD,uBAAwB,CALxB,kDAMD,CAGC,+DACC,kBAA8B,CAC9B,oBACD,CAEA,8DACC,iBACD,CAIF,wEACC,qBACD,CAKF,6CACC,MAAO,CAGP,iBAAkB,CAFlB,cAAe,CACf,WAED,CAMA,wDACC,cAKD,CAHC,qEACC,mCACD\",\"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-todo-list-checkmark-size: 16px;\\n}\\n\\n.ck-content .todo-list {\\n\\tlist-style: none;\\n\\n\\t& li {\\n\\t\\tmargin-bottom: 5px;\\n\\n\\t\\t& .todo-list {\\n\\t\\t\\tmargin-top: 5px;\\n\\t\\t}\\n\\t}\\n\\n\\t& .todo-list__label {\\n\\t\\t& > input {\\n\\t\\t\\t-webkit-appearance: none;\\n\\t\\t\\tdisplay: inline-block;\\n\\t\\t\\tposition: relative;\\n\\t\\t\\twidth: var(--ck-todo-list-checkmark-size);\\n\\t\\t\\theight: var(--ck-todo-list-checkmark-size);\\n\\t\\t\\tvertical-align: middle;\\n\\n\\t\\t\\t/* Needed on iOS */\\n\\t\\t\\tborder: 0;\\n\\n\\t\\t\\t/* LTR styles */\\n\\t\\t\\tleft: -25px;\\n\\t\\t\\tmargin-right: -15px;\\n\\t\\t\\tright: 0;\\n\\t\\t\\tmargin-left: 0;\\n\\n\\t\\t\\t&::before {\\n\\t\\t\\t\\tdisplay: block;\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tbox-sizing: border-box;\\n\\t\\t\\t\\tcontent: '';\\n\\t\\t\\t\\twidth: 100%;\\n\\t\\t\\t\\theight: 100%;\\n\\t\\t\\t\\tborder: 1px solid hsl(0, 0%, 20%);\\n\\t\\t\\t\\tborder-radius: 2px;\\n\\t\\t\\t\\ttransition: 250ms ease-in-out box-shadow, 250ms ease-in-out background, 250ms ease-in-out border;\\n\\t\\t\\t}\\n\\n\\t\\t\\t&::after {\\n\\t\\t\\t\\tdisplay: block;\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tbox-sizing: content-box;\\n\\t\\t\\t\\tpointer-events: none;\\n\\t\\t\\t\\tcontent: '';\\n\\n\\t\\t\\t\\t/* Calculate tick position, size and border-width proportional to the checkmark size. */\\n\\t\\t\\t\\tleft: calc( var(--ck-todo-list-checkmark-size) / 3 );\\n\\t\\t\\t\\ttop: calc( var(--ck-todo-list-checkmark-size) / 5.3 );\\n\\t\\t\\t\\twidth: calc( var(--ck-todo-list-checkmark-size) / 5.3 );\\n\\t\\t\\t\\theight: calc( var(--ck-todo-list-checkmark-size) / 2.6 );\\n\\t\\t\\t\\tborder-style: solid;\\n\\t\\t\\t\\tborder-color: transparent;\\n\\t\\t\\t\\tborder-width: 0 calc( var(--ck-todo-list-checkmark-size) / 8 ) calc( var(--ck-todo-list-checkmark-size) / 8 ) 0;\\n\\t\\t\\t\\ttransform: rotate(45deg);\\n\\t\\t\\t}\\n\\n\\t\\t\\t&[checked] {\\n\\t\\t\\t\\t&::before {\\n\\t\\t\\t\\t\\tbackground: hsl(126, 64%, 41%);\\n\\t\\t\\t\\t\\tborder-color: hsl(126, 64%, 41%);\\n\\t\\t\\t\\t}\\n\\n\\t\\t\\t\\t&::after {\\n\\t\\t\\t\\t\\tborder-color: hsl(0, 0%, 100%);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\t& .todo-list__label__description {\\n\\t\\t\\tvertical-align: middle;\\n\\t\\t}\\n\\t}\\n}\\n\\n/* RTL styles */\\n[dir=\\\"rtl\\\"] .todo-list .todo-list__label > input {\\n\\tleft: 0;\\n\\tmargin-right: 0;\\n\\tright: -25px;\\n\\tmargin-left: -15px;\\n}\\n\\n/*\\n * To-do list should be interactive only during the editing\\n * (https://github.com/ckeditor/ckeditor5/issues/2090).\\n */\\n.ck-editor__editable .todo-list .todo-list__label > input {\\n\\tcursor: pointer;\\n\\n\\t&:hover::before {\\n\\t\\tbox-shadow: 0 0 0 5px hsla(0, 0%, 0%, 0.1);\\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=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0C1 4.784 1.777 4 2.75 4c.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75C1.784 7.5 1 6.723 1 5.75zm6 9c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0c0-.966.777-1.75 1.75-1.75.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75-.966 0-1.75-.777-1.75-1.75z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11 27a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0-10a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0-10a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M10.29 15V8.531H9.286c-.14.393-.4.736-.778 1.03-.378.295-.728.495-1.05.6v1.121a4.257 4.257 0 0 0 1.595-.936V15h1.235zm3.343 0v-1.235h-1.235V15h1.235zM11.3 24v-1.147H8.848c.064-.111.148-.226.252-.343.104-.117.351-.354.74-.712.39-.357.66-.631.81-.821.225-.288.39-.562.494-.824.104-.263.156-.539.156-.829 0-.51-.182-.936-.545-1.279-.363-.342-.863-.514-1.499-.514-.58 0-1.063.148-1.45.444-.387.296-.617.784-.69 1.463l1.23.124c.024-.36.112-.619.264-.774.153-.155.358-.233.616-.233.26 0 .465.074.613.222.148.148.222.36.222.635 0 .25-.085.501-.255.756-.126.185-.468.536-1.024 1.055-.692.641-1.155 1.156-1.389 1.544-.234.389-.375.8-.422 1.233H11.3zm2.333 0v-1.235h-1.235V24h1.235zM9.204 34.11c.615 0 1.129-.2 1.542-.598.413-.398.62-.88.62-1.446 0-.39-.11-.722-.332-.997a1.5 1.5 0 0 0-.886-.532c.619-.337.928-.788.928-1.353 0-.399-.151-.756-.453-1.073-.366-.386-.852-.58-1.459-.58a2.25 2.25 0 0 0-.96.2 1.617 1.617 0 0 0-.668.55c-.16.232-.28.544-.358.933l1.138.194c.032-.282.123-.495.272-.642.15-.146.33-.22.54-.22.215 0 .386.065.515.194s.193.302.193.518c0 .255-.087.46-.263.613-.176.154-.43.227-.765.218l-.136 1.006c.22-.061.409-.092.567-.092.24 0 .444.09.61.272.168.182.251.428.251.739 0 .328-.087.589-.261.782a.833.833 0 0 1-.644.29.841.841 0 0 1-.607-.242c-.167-.16-.27-.394-.307-.698l-1.196.145c.062.542.285.98.668 1.316.384.335.868.503 1.45.503zm4.43-.11v-1.235h-1.236V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M5.714 15.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm6.078.914V8.531H10.79c-.14.393-.4.736-.778 1.03-.378.295-.728.495-1.05.6v1.121a4.257 4.257 0 0 0 1.595-.936V15h1.235zm3.344 0v-1.235h-1.235V15h1.235zm-9.422 9.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm7.088.914v-1.147H10.35c.065-.111.149-.226.253-.343.104-.117.35-.354.74-.712.39-.357.66-.631.81-.821.225-.288.39-.562.493-.824.104-.263.156-.539.156-.829 0-.51-.181-.936-.544-1.279-.364-.342-.863-.514-1.499-.514-.58 0-1.063.148-1.45.444-.387.296-.617.784-.69 1.463l1.23.124c.024-.36.112-.619.264-.774.152-.155.357-.233.615-.233.261 0 .465.074.613.222.148.148.222.36.222.635 0 .25-.085.501-.255.756-.126.185-.467.536-1.024 1.055-.691.641-1.154 1.156-1.388 1.544-.235.389-.375.8-.422 1.233h4.328zm2.334 0v-1.235h-1.235V24h1.235zM5.714 34.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm4.992 1.024c.616 0 1.13-.2 1.543-.598.413-.398.62-.88.62-1.446 0-.39-.111-.722-.332-.997a1.5 1.5 0 0 0-.886-.532c.618-.337.927-.788.927-1.353 0-.399-.15-.756-.452-1.073-.366-.386-.853-.58-1.46-.58a2.25 2.25 0 0 0-.96.2 1.617 1.617 0 0 0-.667.55c-.16.232-.28.544-.359.933l1.139.194c.032-.282.123-.495.272-.642.15-.146.33-.22.54-.22.214 0 .386.065.515.194s.193.302.193.518c0 .255-.088.46-.264.613-.175.154-.43.227-.764.218l-.136 1.006c.22-.061.408-.092.566-.092.24 0 .444.09.611.272.167.182.25.428.25.739 0 .328-.086.589-.26.782a.833.833 0 0 1-.644.29.841.841 0 0 1-.607-.242c-.167-.16-.27-.394-.308-.698l-1.195.145c.062.542.284.98.668 1.316.384.335.867.503 1.45.503zm4.43-.11v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11 27a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0-9a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0-9a3 3 0 1 1 0 6 3 3 0 0 1 0-6z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M9.62 14.105c.272 0 .528-.05.768-.153s.466-.257.677-.462c.009.024.023.072.044.145.047.161.086.283.119.365h1.221a2.649 2.649 0 0 1-.222-.626c-.04-.195-.059-.498-.059-.908l.013-1.441c0-.536-.055-.905-.165-1.105-.11-.201-.3-.367-.569-.497-.27-.13-.68-.195-1.23-.195-.607 0-1.064.108-1.371.325-.308.217-.525.55-.65 1.002l1.12.202c.076-.217.176-.369.299-.455.123-.086.294-.13.514-.13.325 0 .546.05.663.152.118.101.176.27.176.508v.123c-.222.093-.622.194-1.2.303-.427.082-.755.178-.982.288-.227.11-.403.268-.53.474a1.327 1.327 0 0 0-.188.706c0 .398.138.728.415.988.277.261.656.391 1.136.391zm.368-.87a.675.675 0 0 1-.492-.189.606.606 0 0 1-.193-.448c0-.176.08-.32.241-.435.106-.07.33-.142.673-.215a7.19 7.19 0 0 0 .751-.19v.247c0 .296-.016.496-.048.602a.773.773 0 0 1-.295.409 1.07 1.07 0 0 1-.637.22zm4.645.765v-1.235h-1.235V14h1.235zM10.2 25.105c.542 0 1.003-.215 1.382-.646.38-.43.57-1.044.57-1.84 0-.771-.187-1.362-.559-1.774a1.82 1.82 0 0 0-1.41-.617c-.522 0-.973.216-1.354.65v-2.32H7.594V25h1.147v-.686a1.9 1.9 0 0 0 .67.592c.26.133.523.2.79.2zm-.299-.975c-.354 0-.638-.164-.852-.492-.153-.232-.229-.59-.229-1.073 0-.468.098-.818.295-1.048a.93.93 0 0 1 .738-.345c.302 0 .55.118.743.354.193.236.29.62.29 1.154 0 .5-.096.868-.288 1.1-.192.233-.424.35-.697.35zm4.478.87v-1.235h-1.234V25h1.234zm-4.017 9.105c.6 0 1.08-.142 1.437-.426.357-.284.599-.704.725-1.261l-1.213-.207c-.061.326-.167.555-.316.688a.832.832 0 0 1-.576.2.916.916 0 0 1-.75-.343c-.185-.228-.278-.62-.278-1.173 0-.498.091-.853.274-1.066.183-.212.429-.318.736-.318.232 0 .42.061.565.184.145.123.238.306.28.55l1.216-.22c-.146-.501-.387-.874-.722-1.119-.336-.244-.788-.366-1.356-.366-.695 0-1.245.214-1.653.643-.407.43-.61 1.03-.61 1.8 0 .762.202 1.358.608 1.788.406.431.95.646 1.633.646zM14.633 34v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11.88 8.7V7.558h-1.234V8.7h1.234zm0 5.3V9.333h-1.234V14h1.234zm2.5 0v-1.235h-1.234V14h1.235zm-4.75 4.7v-1.142H8.395V18.7H9.63zm0 5.3v-4.667H8.395V24H9.63zm2.5-5.3v-1.142h-1.234V18.7h1.235zm0 5.3v-4.667h-1.234V24h1.235zm2.501 0v-1.235h-1.235V24h1.235zM7.38 28.7v-1.142H6.145V28.7H7.38zm0 5.3v-4.667H6.145V34H7.38zm2.5-5.3v-1.142H8.646V28.7H9.88zm0 5.3v-4.667H8.646V34H9.88zm2.5-5.3v-1.142h-1.234V28.7h1.235zm0 5.3v-4.667h-1.234V34h1.235zm2.501 0v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M14 27v6H8v-6h6zm0-9v6H8v-6h6zm0-9v6H8V9h6z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"m7.88 15 .532-1.463h2.575L11.549 15h1.415l-2.58-6.442H9.01L6.5 15h1.38zm2.69-2.549H8.811l.87-2.39.887 2.39zM14.88 15v-1.235h-1.234V15h1.234zM9.352 25c.83-.006 1.352-.02 1.569-.044.346-.038.636-.14.872-.305.236-.166.422-.387.558-.664.137-.277.205-.562.205-.855 0-.372-.106-.695-.317-.97-.21-.276-.512-.471-.905-.585a1.51 1.51 0 0 0 .661-.567 1.5 1.5 0 0 0 .244-.83c0-.28-.066-.53-.197-.754a1.654 1.654 0 0 0-.495-.539 1.676 1.676 0 0 0-.672-.266c-.25-.042-.63-.063-1.14-.063H7.158V25h2.193zm.142-3.88H8.46v-1.49h.747c.612 0 .983.007 1.112.022.217.026.38.102.49.226.11.125.165.287.165.486a.68.68 0 0 1-.192.503.86.86 0 0 1-.525.23 11.47 11.47 0 0 1-.944.023h.18zm.17 2.795H8.46v-1.723h1.05c.592 0 .977.03 1.154.092.177.062.313.16.406.295a.84.84 0 0 1 .14.492c0 .228-.06.41-.181.547a.806.806 0 0 1-.473.257c-.126.026-.423.04-.892.04zM14.88 25v-1.235h-1.234V25h1.234zm-5.018 9.11c.691 0 1.262-.17 1.711-.512.45-.341.772-.864.965-1.567l-1.261-.4c-.109.472-.287.818-.536 1.037-.25.22-.547.33-.892.33-.47 0-.85-.173-1.143-.519-.293-.345-.44-.925-.44-1.74 0-.767.15-1.322.447-1.665.297-.343.684-.514 1.162-.514.346 0 .64.096.881.29.242.193.4.457.477.79l1.288-.307c-.147-.516-.367-.911-.66-1.187-.492-.465-1.132-.698-1.92-.698-.902 0-1.63.296-2.184.89-.554.593-.83 1.426-.83 2.498 0 1.014.275 1.813.825 2.397.551.585 1.254.877 2.11.877zM14.88 34v-1.235h-1.234V34h1.234z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11.916 15V8.558h-1.301V15h1.3zm2.465 0v-1.235h-1.235V15h1.235zM9.665 25v-6.442h-1.3V25h1.3zm2.5 0v-6.442h-1.3V25h1.3zm2.466 0v-1.235h-1.235V25h1.235zm-7.216 9v-6.442h-1.3V34h1.3zm2.5 0v-6.442h-1.3V34h1.3zm2.501 0v-6.442h-1.3V34h1.3zm2.465 0v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM3.5 3v5H2V3.7H1v-1h2.5V3zM.343 17.857l2.59-3.257H2.92a.6.6 0 1 0-1.04 0H.302a2 2 0 1 1 3.995 0h-.001c-.048.405-.16.734-.333.988-.175.254-.59.692-1.244 1.312H4.3v1h-4l.043-.043zM7 14.75a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m2.315 14.705 2.224-2.24a.689.689 0 0 1 .963 0 .664.664 0 0 1 0 .949L2.865 16.07a.682.682 0 0 1-.112.089.647.647 0 0 1-.852-.051L.688 14.886a.635.635 0 0 1 0-.903.647.647 0 0 1 .91 0l.717.722zm5.185.045a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75zM2.329 5.745l2.21-2.226a.689.689 0 0 1 .963 0 .664.664 0 0 1 0 .95L2.865 7.125a.685.685 0 0 1-.496.196.644.644 0 0 1-.468-.187L.688 5.912a.635.635 0 0 1 0-.903.647.647 0 0 1 .91 0l.73.736zM7.5 5.75A.75.75 0 0 1 8.25 5h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 10 10\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M.941 4.523a.75.75 0 1 1 1.06-1.06l3.006 3.005 3.005-3.005a.75.75 0 1 1 1.06 1.06l-3.549 3.55a.75.75 0 0 1-1.168-.136L.941 4.523z\\\"/></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]!./collapsible.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]!./documentlist.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]!./listproperties.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]!./liststyles.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]!./todolist.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 list/documentlist\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport DocumentListEditing from './documentlist/documentlistediting';\nimport ListUI from './list/listui';\n\n/**\n * The document list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/documentlist/documentlistediting~DocumentListEditing document list\n * editing feature} and {@link module:list/list/listui~ListUI list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ DocumentListEditing, ListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentList';\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 list/documentlist/converters\n */\n\nimport {\n\tgetAllListItemBlocks,\n\tgetListItemBlocks,\n\tisListItemBlock,\n\tListItemUid\n} from './utils/model';\nimport {\n\tcreateListElement,\n\tcreateListItemElement,\n\tgetIndent,\n\tisListView,\n\tisListItemView\n} from './utils/view';\nimport ListWalker, { iterateSiblingListBlocks } from './utils/listwalker';\nimport { findAndAddListHeadToMap } from './utils/postfixers';\n\nimport { UpcastWriter } from 'ckeditor5/src/engine';\n\n/**\n * Returns the upcast converter for list items. It's supposed to work after the block converters (content inside list items) is converted.\n *\n * @protected\n * @returns {Function}\n */\nexport function listItemUpcastConverter() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema } = conversionApi;\n\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst items = Array.from( data.modelRange.getItems( { shallow: true } ) )\n\t\t\t.filter( item => schema.checkAttribute( item, 'listItemId' ) );\n\n\t\tif ( !items.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst attributes = {\n\t\t\tlistItemId: ListItemUid.next(),\n\t\t\tlistIndent: getIndent( data.viewItem ),\n\t\t\tlistType: data.viewItem.parent && data.viewItem.parent.name == 'ol' ? 'numbered' : 'bulleted'\n\t\t};\n\n\t\tfor ( const item of items ) {\n\t\t\t// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n\t\t\tif ( !isListItemBlock( item ) ) {\n\t\t\t\twriter.setAttributes( attributes, item );\n\t\t\t}\n\t\t}\n\n\t\tif ( items.length > 1 ) {\n\t\t\t// Make sure that list item that contain only nested list will preserve paragraph for itself:\n\t\t\t//\t<ul>\n\t\t\t//\t\t<li>\n\t\t\t//\t\t\t<p></p> <-- this one must be kept\n\t\t\t//\t\t\t<ul>\n\t\t\t//\t\t\t\t<li></li>\n\t\t\t//\t\t\t</ul>\n\t\t\t//\t\t</li>\n\t\t\t//\t</ul>\n\t\t\tif ( items[ 1 ].getAttribute( 'listItemId' ) != attributes.listItemId ) {\n\t\t\t\tconversionApi.keepEmptyElement( items[ 0 ] );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns the upcast converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @protected\n * @returns {Function}\n */\nexport function listUpcastCleanList() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = new UpcastWriter( data.viewItem.document );\n\n\t\tfor ( const child of Array.from( data.viewItem.getChildren() ) ) {\n\t\t\tif ( !isListItemView( child ) && !isListView( child ) ) {\n\t\t\t\tviewWriter.remove( child );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns a model document change:data event listener that triggers conversion of related items if needed.\n *\n * @protected\n * @param {module:engine/model/model~Model} model The editor model.\n * @param {module:engine/controller/editingcontroller~EditingController} editing The editing controller.\n * @param {Array.<String>} attributeNames The list of all model list attributes (including registered strategies).\n * @param {module:list/documentlist/documentlistediting~DocumentListEditing} documentListEditing The document list editing plugin.\n * @return {Function}\n */\nexport function reconvertItemsOnDataChange( model, editing, attributeNames, documentListEditing ) {\n\treturn () => {\n\t\tconst changes = model.document.differ.getChanges();\n\t\tconst itemsToRefresh = [];\n\t\tconst itemToListHead = new Map();\n\t\tconst changedItems = new Set();\n\n\t\tfor ( const entry of changes ) {\n\t\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\n\t\t\t\t// Insert of a non-list item.\n\t\t\t\tif ( !entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( entry.position.getShiftedBy( entry.length ), itemToListHead );\n\t\t\t\t} else {\n\t\t\t\t\tchangedItems.add( entry.position.nodeAfter );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Removed list item.\n\t\t\telse if ( entry.type == 'remove' && entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\t\t\t}\n\t\t\t// Changed list attribute.\n\t\t\telse if ( entry.type == 'attribute' ) {\n\t\t\t\tconst item = entry.range.start.nodeAfter;\n\n\t\t\t\tif ( attributeNames.includes( entry.attributeKey ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( entry.range.start, itemToListHead );\n\n\t\t\t\t\tif ( entry.attributeNewValue === null ) {\n\t\t\t\t\t\tfindAndAddListHeadToMap( entry.range.start.getShiftedBy( 1 ), itemToListHead );\n\n\t\t\t\t\t\t// Check if paragraph should be converted from bogus to plain paragraph.\n\t\t\t\t\t\tif ( doesItemParagraphRequiresRefresh( item ) ) {\n\t\t\t\t\t\t\titemsToRefresh.push( item );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchangedItems.add( item );\n\t\t\t\t\t}\n\t\t\t\t} else if ( isListItemBlock( item ) ) {\n\t\t\t\t\t// Some other attribute was changed on the list item,\n\t\t\t\t\t// check if paragraph does not need to be converted to bogus or back.\n\t\t\t\t\tif ( doesItemParagraphRequiresRefresh( item ) ) {\n\t\t\t\t\t\titemsToRefresh.push( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const listHead of itemToListHead.values() ) {\n\t\t\titemsToRefresh.push( ...collectListItemsToRefresh( listHead, changedItems ) );\n\t\t}\n\n\t\tfor ( const item of new Set( itemsToRefresh ) ) {\n\t\t\tediting.reconvertItem( item );\n\t\t}\n\t};\n\n\tfunction collectListItemsToRefresh( listHead, changedItems ) {\n\t\tconst itemsToRefresh = [];\n\t\tconst visited = new Set();\n\t\tconst stack = [];\n\n\t\tfor ( const { node, previous } of iterateSiblingListBlocks( listHead, 'forward' ) ) {\n\t\t\tif ( visited.has( node ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst itemIndent = node.getAttribute( 'listIndent' );\n\n\t\t\t// Current node is at the lower indent so trim the stack.\n\t\t\tif ( previous && itemIndent < previous.getAttribute( 'listIndent' ) ) {\n\t\t\t\tstack.length = itemIndent + 1;\n\t\t\t}\n\n\t\t\t// Update the stack for the current indent level.\n\t\t\tstack[ itemIndent ] = Object.fromEntries(\n\t\t\t\tArray.from( node.getAttributes() )\n\t\t\t\t\t.filter( ( [ key ] ) => attributeNames.includes( key ) )\n\t\t\t);\n\n\t\t\t// Find all blocks of the current node.\n\t\t\tconst blocks = getListItemBlocks( node, { direction: 'forward' } );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tvisited.add( block );\n\n\t\t\t\t// Check if bogus vs plain paragraph needs refresh.\n\t\t\t\tif ( doesItemParagraphRequiresRefresh( block, blocks ) ) {\n\t\t\t\t\titemsToRefresh.push( block );\n\t\t\t\t}\n\t\t\t\t// Check if wrapping with UL, OL, LIs needs refresh.\n\t\t\t\telse if ( doesItemWrappingRequiresRefresh( block, stack, changedItems ) ) {\n\t\t\t\t\titemsToRefresh.push( block );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn itemsToRefresh;\n\t}\n\n\tfunction doesItemParagraphRequiresRefresh( item, blocks ) {\n\t\tif ( !item.is( 'element', 'paragraph' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewElement = editing.mapper.toViewElement( item );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst useBogus = shouldUseBogusParagraph( item, attributeNames, blocks );\n\n\t\tif ( useBogus && viewElement.is( 'element', 'p' ) ) {\n\t\t\treturn true;\n\t\t} else if ( !useBogus && viewElement.is( 'element', 'span' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction doesItemWrappingRequiresRefresh( item, stack, changedItems ) {\n\t\t// Items directly affected by some \"change\" don't need a refresh, they will be converted by their own changes.\n\t\tif ( changedItems.has( item ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewElement = editing.mapper.toViewElement( item );\n\t\tlet indent = stack.length - 1;\n\n\t\t// Traverse down the stack to the root to verify if all ULs, OLs, and LIs are as expected.\n\t\tfor (\n\t\t\tlet element = viewElement.parent;\n\t\t\t!element.is( 'editableElement' );\n\t\t\telement = element.parent\n\t\t) {\n\t\t\tconst isListItemElement = isListItemView( element );\n\t\t\tconst isListElement = isListView( element );\n\n\t\t\tif ( !isListElement && !isListItemElement ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired on changes detected on the model list element to verify if the view representation of a list element\n\t\t\t * is representing those attributes.\n\t\t\t *\n\t\t\t * It allows triggering a re-wrapping of a list item.\n\t\t\t *\n\t\t\t * **Note**: For convenience this event is namespaced and could be captured as `checkAttributes:list` or `checkAttributes:item`.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event module:list/documentlist/documentlistediting~DocumentListEditing#event:checkAttributes\n\t\t\t * @param {module:engine/view/element~Element} viewElement\n\t\t\t * @param {Object} modelAttributes\n\t\t\t */\n\t\t\tconst eventName = `checkAttributes:${ isListItemElement ? 'item' : 'list' }`;\n\t\t\tconst needsRefresh = documentListEditing.fire( eventName, {\n\t\t\t\tviewElement: element,\n\t\t\t\tmodelAttributes: stack[ indent ]\n\t\t\t} );\n\n\t\t\tif ( needsRefresh ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ( isListElement ) {\n\t\t\t\tindent--;\n\n\t\t\t\t// Don't need to iterate further if we already know that the item is wrapped appropriately.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Returns the list item downcast converter.\n *\n * @protected\n * @param {Array.<String>} attributeNames A list of attribute names that should be converted if are set.\n * @param {Array.<module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy>} strategies The strategies.\n * @param {module:engine/model/model~Model} model The model.\n * @returns {Function}\n */\nexport function listItemDowncastConverter( attributeNames, strategies, model ) {\n\tconst consumer = createAttributesConsumer( attributeNames );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, mapper, consumable } = conversionApi;\n\n\t\tconst listItem = data.item;\n\n\t\tif ( !attributeNames.includes( data.attributeKey ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Test if attributes on the converted items are not consumed.\n\t\tif ( !consumer( listItem, consumable ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Use positions mapping instead of mapper.toViewElement( listItem ) to find outermost view element.\n\t\t// This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n\t\tconst viewElement = findMappedViewElement( listItem, mapper, model );\n\n\t\t// Unwrap element from current list wrappers.\n\t\tunwrapListItemBlock( viewElement, writer );\n\n\t\t// Then wrap them with the new list wrappers.\n\t\twrapListItemBlock( listItem, writer.createRangeOn( viewElement ), strategies, writer );\n\t};\n}\n\n/**\n * Returns the bogus paragraph view element creator. A bogus paragraph is used if a list item contains only a single block or nested list.\n *\n * @protected\n * @param {Array.<String>} attributeNames The list of all model list attributes (including registered strategies).\n * @param {Object} [options]\n * @param {Boolean} [options.dataPipeline=false]\n * @returns {Function}\n */\nexport function bogusParagraphCreator( attributeNames, { dataPipeline } = {} ) {\n\treturn ( modelElement, { writer } ) => {\n\t\t// Convert only if a bogus paragraph should be used.\n\t\tif ( !shouldUseBogusParagraph( modelElement, attributeNames ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = writer.createContainerElement( 'span', { class: 'ck-list-bogus-paragraph' } );\n\n\t\tif ( dataPipeline ) {\n\t\t\twriter.setCustomProperty( 'dataPipeline:transparentRendering', true, viewElement );\n\t\t}\n\n\t\treturn viewElement;\n\t};\n}\n\n/**\n * Helper for mapping mode to view elements. It's using positions mapping instead of mapper.toViewElement( element )\n * to find outermost view element. This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n *\n * @protected\n * @param {module:engine/model/element~Element} element The model element.\n * @param {module:engine/conversion/mapper~Mapper} mapper The mapper instance.\n * @param {module:engine/model/model~Model} model The model.\n * @returns {module:engine/view/element~Element|null}\n */\nexport function findMappedViewElement( element, mapper, model ) {\n\tconst modelRange = model.createRangeOn( element );\n\tconst viewRange = mapper.toViewRange( modelRange ).getTrimmed();\n\n\treturn viewRange.getContainedElement();\n}\n\n// Unwraps all ol, ul, and li attribute elements that are wrapping the provided view element.\nfunction unwrapListItemBlock( viewElement, viewWriter ) {\n\tlet attributeElement = viewElement.parent;\n\n\twhile ( attributeElement.is( 'attributeElement' ) && [ 'ul', 'ol', 'li' ].includes( attributeElement.name ) ) {\n\t\tconst parentElement = attributeElement.parent;\n\n\t\tviewWriter.unwrap( viewWriter.createRangeOn( viewElement ), attributeElement );\n\n\t\tattributeElement = parentElement;\n\t}\n}\n\n// Wraps the given list item with appropriate attribute elements for ul, ol, and li.\nfunction wrapListItemBlock( listItem, viewRange, strategies, writer ) {\n\tif ( !listItem.hasAttribute( 'listIndent' ) ) {\n\t\treturn;\n\t}\n\n\tconst listItemIndent = listItem.getAttribute( 'listIndent' );\n\tlet currentListItem = listItem;\n\n\tfor ( let indent = listItemIndent; indent >= 0; indent-- ) {\n\t\tconst listItemViewElement = createListItemElement( writer, indent, currentListItem.getAttribute( 'listItemId' ) );\n\t\tconst listViewElement = createListElement( writer, indent, currentListItem.getAttribute( 'listType' ) );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tif ( currentListItem.hasAttribute( strategy.attributeName ) ) {\n\t\t\t\tstrategy.setAttributeOnDowncast(\n\t\t\t\t\twriter,\n\t\t\t\t\tcurrentListItem.getAttribute( strategy.attributeName ),\n\t\t\t\t\tstrategy.scope == 'list' ? listViewElement : listItemViewElement\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tviewRange = writer.wrap( viewRange, listItemViewElement );\n\t\tviewRange = writer.wrap( viewRange, listViewElement );\n\n\t\tif ( indent == 0 ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurrentListItem = ListWalker.first( currentListItem, { lowerIndent: true } );\n\n\t\t// There is no list item with lower indent, this means this is a document fragment containing\n\t\t// only a part of nested list (like copy to clipboard) so we don't need to try to wrap it further.\n\t\tif ( !currentListItem ) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n// Returns the function that is responsible for consuming attributes that are set on the model node.\nfunction createAttributesConsumer( attributeNames ) {\n\treturn ( node, consumable ) => {\n\t\tconst events = [];\n\n\t\t// Collect all set attributes that are triggering conversion.\n\t\tfor ( const attributeName of attributeNames ) {\n\t\t\tif ( node.hasAttribute( attributeName ) ) {\n\t\t\t\tevents.push( `attribute:${ attributeName }` );\n\t\t\t}\n\t\t}\n\n\t\tif ( !events.every( event => consumable.test( node, event ) !== false ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tevents.forEach( event => consumable.consume( node, event ) );\n\n\t\treturn true;\n\t};\n}\n\n// Whether the given item should be rendered as a bogus paragraph.\nfunction shouldUseBogusParagraph( item, attributeNames, blocks = getAllListItemBlocks( item ) ) {\n\tif ( !isListItemBlock( item ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( const attributeKey of item.getAttributeKeys() ) {\n\t\t// Ignore selection attributes stored on block elements.\n\t\tif ( attributeKey.startsWith( 'selection:' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Don't use bogus paragraph if there are attributes from other features.\n\t\tif ( !attributeNames.includes( attributeKey ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn blocks.length < 2;\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 list/documentlist/documentlistcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\tsplitListItemBefore,\n\texpandListBlocksToCompleteItems,\n\tgetListItemBlocks,\n\tgetListItems,\n\tremoveListAttributes,\n\toutdentFollowingItems,\n\tListItemUid,\n\tsortBlocks,\n\tgetSelectedBlockObject,\n\tisListItemBlock\n} from './utils/model';\n\n/**\n * The list command. It is used by the {@link module:list/documentlist~DocumentList document list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'numbered'|'bulleted'} type List type that will be handled by this command.\n\t */\n\tconstructor( editor, type ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The type of the list created by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'numbered'|'bulleted'}\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => model.schema.checkAttribute( block, 'listType' ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( turnOff ) {\n\t\t\t\tconst lastBlock = blocks[ blocks.length - 1 ];\n\n\t\t\t\t// Split the first block from the list item.\n\t\t\t\tconst itemBlocks = getListItemBlocks( lastBlock, { direction: 'forward' } );\n\t\t\t\tconst changedBlocks = [];\n\n\t\t\t\tif ( itemBlocks.length > 1 ) {\n\t\t\t\t\tchangedBlocks.push( ...splitListItemBefore( itemBlocks[ 1 ], writer ) );\n\t\t\t\t}\n\n\t\t\t\t// Convert list blocks to plain blocks.\n\t\t\t\tchangedBlocks.push( ...removeListAttributes( blocks, writer ) );\n\n\t\t\t\t// Outdent items following the selected list item.\n\t\t\t\tchangedBlocks.push( ...outdentFollowingItems( lastBlock, writer ) );\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t\t// Turning on the list items for a collapsed selection inside a list item.\n\t\t\telse if ( ( selectedBlockObject || document.selection.isCollapsed ) && isListItemBlock( blocks[ 0 ] ) ) {\n\t\t\t\tconst changedBlocks = getListItems( selectedBlockObject || blocks[ 0 ] );\n\n\t\t\t\tfor ( const block of changedBlocks ) {\n\t\t\t\t\twriter.setAttribute( 'listType', this.type, block );\n\t\t\t\t}\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t\t// Turning on the list items for a non-collapsed selection.\n\t\t\telse {\n\t\t\t\tconst changedBlocks = [];\n\n\t\t\t\tfor ( const block of blocks ) {\n\t\t\t\t\t// Promote the given block to the list item.\n\t\t\t\t\tif ( !block.hasAttribute( 'listType' ) ) {\n\t\t\t\t\t\twriter.setAttributes( {\n\t\t\t\t\t\t\tlistIndent: 0,\n\t\t\t\t\t\t\tlistItemId: ListItemUid.next(),\n\t\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t\t}, block );\n\n\t\t\t\t\t\tchangedBlocks.push( block );\n\t\t\t\t\t}\n\t\t\t\t\t// Change the type of list item.\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor ( const node of expandListBlocksToCompleteItems( block, { withNested: false } ) ) {\n\t\t\t\t\t\t\tif ( node.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t\t\t\twriter.setAttribute( 'listType', this.type, node );\n\t\t\t\t\t\t\t\tchangedBlocks.push( node );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tif ( !blocks.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const block of blocks ) {\n\t\t\tif ( block.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tif ( !blocks.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tfor ( const block of blocks ) {\n\t\t\tif ( schema.checkAttribute( block, 'listType' ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\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 list/documentlist/documentlistediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Enter } from 'ckeditor5/src/enter';\nimport { Delete } from 'ckeditor5/src/typing';\nimport { CKEditorError } from 'ckeditor5/src/utils';\n\nimport DocumentListIndentCommand from './documentlistindentcommand';\nimport DocumentListCommand from './documentlistcommand';\nimport DocumentListMergeCommand from './documentlistmergecommand';\nimport DocumentListSplitCommand from './documentlistsplitcommand';\nimport {\n\tbogusParagraphCreator,\n\tlistItemDowncastConverter,\n\tlistItemUpcastConverter,\n\tlistUpcastCleanList,\n\treconvertItemsOnDataChange\n} from './converters';\nimport {\n\tfindAndAddListHeadToMap,\n\tfixListIndents,\n\tfixListItemIds\n} from './utils/postfixers';\nimport {\n\tgetAllListItemBlocks,\n\tisFirstBlockOfListItem,\n\tisLastBlockOfListItem,\n\tisSingleListItem,\n\tgetSelectedBlockObject,\n\tisListItemBlock,\n\tremoveListAttributes\n} from './utils/model';\nimport {\n\tgetViewElementIdForListType,\n\tgetViewElementNameForListType\n} from './utils/view';\nimport ListWalker, {\n\titerateSiblingListBlocks,\n\tListBlocksIterable\n} from './utils/listwalker';\n\nimport '../../theme/documentlist.css';\n\n/**\n * A list of base list model attributes.\n *\n * @private\n */\nconst LIST_BASE_ATTRIBUTES = [ 'listType', 'listIndent', 'listItemId' ];\n\n/**\n * The editing part of the document-list feature. It handles creating, editing and removing lists and list items.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentListEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Enter, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The list of registered downcast strategies.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<module:list/documentlist/documentlistediting~DowncastStrategy>}\n\t\t */\n\t\tthis._downcastStrategies = [];\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\tif ( editor.plugins.has( 'ListEditing' ) ) {\n\t\t\t/**\n\t\t\t * The `DocumentList` feature can not be loaded together with the `List` plugin.\n\t\t\t *\n\t\t\t * @error document-list-feature-conflict\n\t\t\t * @param {String} conflictPlugin Name of the plugin.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'document-list-feature-conflict', this, { conflictPlugin: 'ListEditing' } );\n\t\t}\n\n\t\tmodel.schema.extend( '$container', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\t\tmodel.schema.extend( '$block', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\t\tmodel.schema.extend( '$blockObject', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\n\t\tfor ( const attribute of LIST_BASE_ATTRIBUTES ) {\n\t\t\tmodel.schema.setAttributeProperties( attribute, {\n\t\t\t\tcopyOnReplace: true\n\t\t\t} );\n\t\t}\n\n\t\t// Register commands.\n\t\teditor.commands.add( 'numberedList', new DocumentListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new DocumentListCommand( editor, 'bulleted' ) );\n\n\t\teditor.commands.add( 'indentList', new DocumentListIndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new DocumentListIndentCommand( editor, 'backward' ) );\n\n\t\teditor.commands.add( 'mergeListItemBackward', new DocumentListMergeCommand( editor, 'backward' ) );\n\t\teditor.commands.add( 'mergeListItemForward', new DocumentListMergeCommand( editor, 'forward' ) );\n\n\t\teditor.commands.add( 'splitListItemBefore', new DocumentListSplitCommand( editor, 'before' ) );\n\t\teditor.commands.add( 'splitListItemAfter', new DocumentListSplitCommand( editor, 'after' ) );\n\n\t\tthis._setupDeleteIntegration();\n\t\tthis._setupEnterIntegration();\n\t\tthis._setupTabIntegration();\n\t\tthis._setupClipboardIntegration();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst commands = editor.commands;\n\t\tconst indent = commands.get( 'indent' );\n\t\tconst outdent = commands.get( 'outdent' );\n\n\t\tif ( indent ) {\n\t\t\t// Priority is high due to integration with `IndentBlock` plugin. We want to indent list first and if it's not possible\n\t\t\t// user can indent content with `IndentBlock` plugin.\n\t\t\tindent.registerChildCommand( commands.get( 'indentList' ), { priority: 'high' } );\n\t\t}\n\n\t\tif ( outdent ) {\n\t\t\t// Priority is lowest due to integration with `IndentBlock` and `IndentCode` plugins.\n\t\t\t// First we want to allow user to outdent all indendations from other features then he can oudent list item.\n\t\t\toutdent.registerChildCommand( commands.get( 'outdentList' ), { priority: 'lowest' } );\n\t\t}\n\n\t\t// Register conversion and model post-fixer after other plugins had a chance to register their attribute strategies.\n\t\tthis._setupModelPostFixing();\n\t\tthis._setupConversion();\n\t}\n\n\t/**\n\t * Registers a downcast strategy.\n\t *\n\t * **Note**: Strategies must be registered in the `Plugin#init()` phase so that it can be applied\n\t * in the `DocumentListEditing#afterInit()`.\n\t *\n\t * @param {module:list/documentlist/documentlistediting~DowncastStrategy} strategy The downcast strategy to register.\n\t */\n\tregisterDowncastStrategy( strategy ) {\n\t\tthis._downcastStrategies.push( strategy );\n\t}\n\n\t/**\n\t * Returns list of model attribute names that should affect downcast conversion.\n\t *\n\t * @private\n\t */\n\t_getListAttributeNames() {\n\t\treturn [\n\t\t\t...LIST_BASE_ATTRIBUTES,\n\t\t\t...this._downcastStrategies.map( strategy => strategy.attributeName )\n\t\t];\n\t}\n\n\t/**\n\t * Attaches the listener to the {@link module:engine/view/document~Document#event:delete} event and handles backspace/delete\n\t * keys in and around document lists.\n\t *\n\t * @private\n\t */\n\t_setupDeleteIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst mergeBackwardCommand = editor.commands.get( 'mergeListItemBackward' );\n\t\tconst mergeForwardCommand = editor.commands.get( 'mergeListItemForward' );\n\n\t\tthis.listenTo( editor.editing.view.document, 'delete', ( evt, data ) => {\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\t// Let the Widget plugin take care of block widgets while deleting (https://github.com/ckeditor/ckeditor5/issues/11346).\n\t\t\tif ( getSelectedBlockObject( editor.model ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.model.change( () => {\n\t\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\t\tif ( selection.isCollapsed && data.direction == 'backward' ) {\n\t\t\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\t\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst previousBlock = ListWalker.first( positionParent, {\n\t\t\t\t\t\tsameAttributes: 'listType',\n\t\t\t\t\t\tsameIndent: true\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Outdent the first block of a first list item.\n\t\t\t\t\tif ( !previousBlock && positionParent.getAttribute( 'listIndent' ) === 0 ) {\n\t\t\t\t\t\tif ( !isLastBlockOfListItem( positionParent ) ) {\n\t\t\t\t\t\t\teditor.execute( 'splitListItemAfter' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\teditor.execute( 'outdentList' );\n\t\t\t\t\t}\n\t\t\t\t\t// Merge block with previous one (on the block level or on the content level).\n\t\t\t\t\telse {\n\t\t\t\t\t\tif ( !mergeBackwardCommand.isEnabled ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmergeBackwardCommand.execute( {\n\t\t\t\t\t\t\tshouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel( editor.model, 'backward' )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// Non-collapsed selection or forward delete.\n\t\t\t\telse {\n\t\t\t\t\t// Collapsed selection should trigger forward merging only if at the end of a block.\n\t\t\t\t\tif ( selection.isCollapsed && !selection.getLastPosition().isAtEnd ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !mergeForwardCommand.isEnabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tmergeForwardCommand.execute( {\n\t\t\t\t\t\tshouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel( editor.model, 'forward' )\n\t\t\t\t\t} );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t} );\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:enter} event and handles enter key press\n\t * in document lists.\n\t *\n\t * @private\n\t */\n\t_setupEnterIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst commands = editor.commands;\n\t\tconst enterCommand = commands.get( 'enter' );\n\n\t\t// Overwrite the default Enter key behavior: outdent or split the list in certain cases.\n\t\tthis.listenTo( editor.editing.view.document, 'enter', ( evt, data ) => {\n\t\t\tconst doc = model.document;\n\t\t\tconst positionParent = doc.selection.getFirstPosition().parent;\n\n\t\t\tif (\n\t\t\t\tdoc.selection.isCollapsed &&\n\t\t\t\tisListItemBlock( positionParent ) &&\n\t\t\t\tpositionParent.isEmpty &&\n\t\t\t\t!data.isSoft\n\t\t\t) {\n\t\t\t\tconst isFirstBlock = isFirstBlockOfListItem( positionParent );\n\t\t\t\tconst isLastBlock = isLastBlockOfListItem( positionParent );\n\n\t\t\t\t// * a → * a\n\t\t\t\t// * [] → []\n\t\t\t\tif ( isFirstBlock && isLastBlock ) {\n\t\t\t\t\teditor.execute( 'outdentList' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// * [] → * []\n\t\t\t\t// a → * a\n\t\t\t\telse if ( isFirstBlock && !isLastBlock ) {\n\t\t\t\t\teditor.execute( 'splitListItemAfter' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// * a → * a\n\t\t\t\t// [] → * []\n\t\t\t\telse if ( isLastBlock ) {\n\t\t\t\t\teditor.execute( 'splitListItemBefore' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { context: 'li' } );\n\n\t\t// In some cases, after the default block splitting, we want to modify the new block to become a new list item\n\t\t// instead of an additional block in the same list item.\n\t\tthis.listenTo( enterCommand, 'afterExecute', () => {\n\t\t\tconst splitCommand = commands.get( 'splitListItemBefore' );\n\n\t\t\t// The command has not refreshed because the change block related to EnterCommand#execute() is not over yet.\n\t\t\t// Let's keep it up to date and take advantage of DocumentListSplitCommand#isEnabled.\n\t\t\tsplitCommand.refresh();\n\n\t\t\tif ( !splitCommand.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst doc = editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\t\t\tconst listItemBlocks = getAllListItemBlocks( positionParent );\n\n\t\t\t// Keep in mind this split happens after the default enter handler was executed. For instance:\n\t\t\t//\n\t\t\t// │ Initial state │ After default enter │ Here in #afterExecute │\n\t\t\t// ├───────────────────────────┼───────────────────────────┼───────────────────────────┤\n\t\t\t// │ * a[] │ * a │ * a │\n\t\t\t// │ │ [] │ * [] │\n\t\t\tif ( listItemBlocks.length === 2 ) {\n\t\t\t\tsplitCommand.execute();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:tab} event and handles tab key and tab+shift keys\n\t * presses in document lists.\n\t *\n\t * @private\n\t */\n\t_setupTabIntegration() {\n\t\tconst editor = this.editor;\n\n\t\tthis.listenTo( editor.editing.view.document, 'tab', ( evt, data ) => {\n\t\t\tconst commandName = data.shiftKey ? 'outdentList' : 'indentList';\n\t\t\tconst command = this.editor.commands.get( commandName );\n\n\t\t\tif ( command.isEnabled ) {\n\t\t\t\teditor.execute( commandName );\n\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * Registers the conversion helpers for the document-list feature.\n\t * @private\n\t */\n\t_setupConversion() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst attributeNames = this._getListAttributeNames();\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.elementToElement( { view: 'li', model: 'paragraph' } )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'element:li', listItemUpcastConverter() );\n\t\t\t\tdispatcher.on( 'element:ul', listUpcastCleanList(), { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:ol', listUpcastCleanList(), { priority: 'high' } );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'paragraph',\n\t\t\t\tview: bogusParagraphCreator( attributeNames ),\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'paragraph',\n\t\t\t\tview: bogusParagraphCreator( attributeNames, { dataPipeline: true } ),\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} );\n\n\t\teditor.conversion.for( 'downcast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'attribute', listItemDowncastConverter( attributeNames, this._downcastStrategies, model ) );\n\t\t\t} );\n\n\t\tthis.listenTo( model.document, 'change:data', reconvertItemsOnDataChange( model, editor.editing, attributeNames, this ) );\n\n\t\t// For LI verify if an ID of the attribute element is correct.\n\t\tthis.on( 'checkAttributes:item', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tif ( viewElement.id != modelAttributes.listItemId ) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// For UL and OL check if the name and ID of element is correct.\n\t\tthis.on( 'checkAttributes:list', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tif (\n\t\t\t\tviewElement.name != getViewElementNameForListType( modelAttributes.listType ) ||\n\t\t\t\tviewElement.id != getViewElementIdForListType( modelAttributes.listType, modelAttributes.listIndent )\n\t\t\t) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Registers model post-fixers.\n\t *\n\t * @private\n\t */\n\t_setupModelPostFixing() {\n\t\tconst model = this.editor.model;\n\t\tconst attributeNames = this._getListAttributeNames();\n\n\t\t// Register list fixing.\n\t\t// First the low level handler.\n\t\tmodel.document.registerPostFixer( writer => modelChangePostFixer( model, writer, attributeNames, this ) );\n\n\t\t// Then the callbacks for the specific lists.\n\t\t// The indentation fixing must be the first one...\n\t\tthis.on( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tevt.return = fixListIndents( listNodes, writer ) || evt.return;\n\t\t}, { priority: 'high' } );\n\n\t\t// ...then the item ids... and after that other fixers that rely on the correct indentation and ids.\n\t\tthis.on( 'postFixer', ( evt, { listNodes, writer, seenIds } ) => {\n\t\t\tevt.return = fixListItemIds( listNodes, seenIds, writer ) || evt.return;\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Integrates the feature with the clipboard via {@link module:engine/model/model~Model#insertContent} and\n\t * {@link module:engine/model/model~Model#getSelectedContent}.\n\t *\n\t * @private\n\t */\n\t_setupClipboardIntegration() {\n\t\tconst model = this.editor.model;\n\n\t\tthis.listenTo( model, 'insertContent', createModelIndentPasteFixer( model ), { priority: 'high' } );\n\n\t\t// To enhance the UX, the editor should not copy list attributes to the clipboard if the selection\n\t\t// started and ended in the same list item.\n\t\t//\n\t\t// If the selection was enclosed in a single list item, there is a good chance the user did not want it\n\t\t// copied as a list item but plain blocks.\n\t\t//\n\t\t// This avoids pasting orphaned list items instead of paragraphs, for instance, straight into the root.\n\t\t//\n\t\t//\t ┌─────────────────────┬───────────────────┐\n\t\t//\t │ Selection │ Clipboard content │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ [* <Widget />] │ <Widget /> │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ [* Foo] │ Foo │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ * Foo [bar] baz │ bar │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ * Fo[o │ o │\n\t\t//\t │ ba]r │ ba │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ * Fo[o │ * o │\n\t\t//\t │ * ba]r │ * ba │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ [* Foo │ * Foo │\n\t\t//\t │ * bar] │ * bar │\n\t\t//\t └─────────────────────┴───────────────────┘\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/11608.\n\t\tthis.listenTo( model, 'getSelectedContent', ( evt, [ selection ] ) => {\n\t\t\tconst isSingleListItemSelected = isSingleListItem( Array.from( selection.getSelectedBlocks() ) );\n\n\t\t\tif ( isSingleListItemSelected ) {\n\t\t\t\tmodel.change( writer => removeListAttributes( Array.from( evt.return.getChildren() ), writer ) );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * @typedef {Object} module:list/documentlist/documentlistediting~DowncastStrategy\n * @property {'list'|'item'} scope The scope of the downcast (whether it applies to LI or OL/UL).\n * @property {String} attributeName The model attribute name.\n * @property {Function} setAttributeOnDowncast Sets the property on the view element.\n */\n\n// Post-fixer that reacts to changes on document and fixes incorrect model states (invalid `listItemId` and `listIndent` values).\n//\n// In the example below, there is a correct list structure.\n// Then the middle element is removed so the list structure will become incorrect:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>Item 2</paragraph> <--- this is removed.\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n//\n// The list structure after the middle element is removed:\n//\n// \t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n//\n// Should become:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=1>Item 3</paragraph> <--- note that indent got post-fixed.\n//\n// @param {module:engine/model/model~Model} model The data model.\n// @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n// @param {Array.<String>} attributeNames The list of all model list attributes (including registered strategies).\n// @param {module:list/documentlist/documentlistediting~DocumentListEditing} documentListEditing The document list editing plugin.\n// @returns {Boolean} `true` if any change has been applied, `false` otherwise.\nfunction modelChangePostFixer( model, writer, attributeNames, documentListEditing ) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map();\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\tconst item = entry.position.nodeAfter;\n\n\t\t\t// Remove attributes in case of renamed element.\n\t\t\tif ( !model.schema.checkAttribute( item, 'listItemId' ) ) {\n\t\t\t\tfor ( const attributeName of Array.from( item.getAttributeKeys() ) ) {\n\t\t\t\t\tif ( attributeNames.includes( attributeName ) ) {\n\t\t\t\t\t\twriter.removeAttribute( attributeName, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\n\t\t\t// Insert of a non-list item - check if there is a list after it.\n\t\t\tif ( !entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position.getShiftedBy( entry.length ), itemToListHead );\n\t\t\t}\n\n\t\t\t// Check if there is no nested list.\n\t\t\tfor ( const { item: innerItem, previousPosition } of model.createRangeIn( item ) ) {\n\t\t\t\tif ( isListItemBlock( innerItem ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( previousPosition, itemToListHead );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Removed list item or block adjacent to a list.\n\t\telse if ( entry.type == 'remove' ) {\n\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\t\t}\n\t\t// Changed list item indent or type.\n\t\telse if ( entry.type == 'attribute' && attributeNames.includes( entry.attributeKey ) ) {\n\t\t\tfindAndAddListHeadToMap( entry.range.start, itemToListHead );\n\n\t\t\tif ( entry.attributeNewValue === null ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.range.start.getShiftedBy( 1 ), itemToListHead );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Make sure that IDs are not shared by split list.\n\tconst seenIds = new Set();\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\t/**\n\t\t * Event fired on changes detected on the model list element to verify if the view representation of a list element\n\t\t * is representing those attributes.\n\t\t *\n\t\t * It allows triggering a re-wrapping of a list item.\n\t\t *\n\t\t * **Note**: For convenience this event is namespaced and could be captured as `checkAttributes:list` or `checkAttributes:item`.\n\t\t *\n\t\t * @protected\n\t\t * @event module:list/documentlist/documentlistediting~DocumentListEditing#event:postFixer\n\t\t * @param {module:engine/model/element~Element} listHead The head element of a list.\n\t\t * @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n\t\t * @param {Set.<String>} seenIds The set of already known IDs.\n\t\t * @param {Object} modelAttributes\n\t\t * @returns {Boolean} If a post-fixer made a change of the model tree, it should return `true`.\n\t\t */\n\t\tapplied = documentListEditing.fire( 'postFixer', {\n\t\t\tlistNodes: new ListBlocksIterable( listHead ),\n\t\t\tlistHead,\n\t\t\twriter,\n\t\t\tseenIds\n\t\t} ) || applied;\n\t}\n\n\treturn applied;\n}\n\n// A fixer for pasted content that includes list items.\n//\n// It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n//\n// Example:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>A</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>B^</paragraph>\n//\t\t// At ^ paste: <paragraph listType=\"bulleted\" listItemId=\"x\" listIndent=4>X</paragraph>\n//\t\t// <paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=5>Y</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>C</paragraph>\n//\n// Should become:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>A</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>BX</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=2>Y/paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>C</paragraph>\n//\nfunction createModelIndentPasteFixer( model ) {\n\treturn ( evt, [ content, selectable ] ) => {\n\t\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t\t// that list will be broken.\n\t\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t\t// would create incorrect model.\n\t\tconst item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\t\tif ( !isListItemBlock( item ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet selection;\n\n\t\tif ( !selectable ) {\n\t\t\tselection = model.document.selection;\n\t\t} else {\n\t\t\tselection = model.createSelection( selectable );\n\t\t}\n\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\n\t\tif ( isListItemBlock( pos.parent ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( isListItemBlock( pos.nodeBefore ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( !refItem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t// Indent of all those items has to be adjusted to reference item.\n\t\tconst indentChange = refItem.getAttribute( 'listIndent' ) - item.getAttribute( 'listIndent' );\n\n\t\t// Fix only if there is anything to fix.\n\t\tif ( indentChange <= 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\tfor ( const { node } of iterateSiblingListBlocks( item, 'forward' ) ) {\n\t\t\t\twriter.setAttribute( 'listIndent', node.getAttribute( 'listIndent' ) + indentChange, node );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// Decides whether the merge should be accompanied by the model's `deleteContent()`, for instance, to get rid of the inline\n// content in the selection or take advantage of the heuristics in `deleteContent()` that helps convert lists into paragraphs\n// in certain cases.\n//\n// @param {module:engine/model/model~Model} model\n// @param {'backward'|'forward'} direction\n// @returns {Boolean}\nfunction shouldMergeOnBlocksContentLevel( model, direction ) {\n\tconst selection = model.document.selection;\n\n\tif ( !selection.isCollapsed ) {\n\t\treturn !getSelectedBlockObject( model );\n\t}\n\n\tif ( direction === 'forward' ) {\n\t\treturn true;\n\t}\n\n\tconst firstPosition = selection.getFirstPosition();\n\tconst positionParent = firstPosition.parent;\n\tconst previousSibling = positionParent.previousSibling;\n\n\tif ( model.schema.isObject( previousSibling ) ) {\n\t\treturn false;\n\t}\n\n\tif ( previousSibling.isEmpty ) {\n\t\treturn true;\n\t}\n\n\treturn isSingleListItem( [ positionParent, previousSibling ] );\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 list/documentlist/documentlistindentcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\texpandListBlocksToCompleteItems,\n\tindentBlocks,\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tisSingleListItem,\n\toutdentBlocksWithMerge,\n\tsortBlocks,\n\tsplitListItemBefore\n} from './utils/model';\nimport ListWalker from './utils/listwalker';\n\n/**\n * The document list indent command. It is used by the {@link module:list/documentlist~DocumentList list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListIndentCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'forward'|'backward'} indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor, indentDirection ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Determines by how much the command will change the list item's indent attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {'forward'|'backward'}\n\t\t */\n\t\tthis._direction = indentDirection;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst blocks = getSelectedListBlocks( model.document.selection );\n\n\t\tmodel.change( writer => {\n\t\t\tconst changedBlocks = [];\n\n\t\t\t// Handle selection contained in the single list item and starting in the following blocks.\n\t\t\tif ( isSingleListItem( blocks ) && !isFirstBlockOfListItem( blocks[ 0 ] ) ) {\n\t\t\t\t// Allow increasing indent of following list item blocks.\n\t\t\t\tif ( this._direction == 'forward' ) {\n\t\t\t\t\tchangedBlocks.push( ...indentBlocks( blocks, writer ) );\n\t\t\t\t}\n\n\t\t\t\t// For indent make sure that indented blocks have a new ID.\n\t\t\t\t// For outdent just split blocks from the list item (give them a new IDs).\n\t\t\t\tchangedBlocks.push( ...splitListItemBefore( blocks[ 0 ], writer ) );\n\t\t\t}\n\t\t\t// More than a single list item is selected, or the first block of list item is selected.\n\t\t\telse {\n\t\t\t\t// Now just update the attributes of blocks.\n\t\t\t\tif ( this._direction == 'forward' ) {\n\t\t\t\t\tchangedBlocks.push( ...indentBlocks( blocks, writer, { expand: true } ) );\n\t\t\t\t} else {\n\t\t\t\t\tchangedBlocks.push( ...outdentBlocksWithMerge( blocks, writer ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Align the list item type to match the previous list item (from the same list).\n\t\t\tfor ( const block of changedBlocks ) {\n\t\t\t\t// This block become a plain block (for example a paragraph).\n\t\t\t\tif ( !block.hasAttribute( 'listType' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst previousItemBlock = ListWalker.first( block, { sameIndent: true } );\n\n\t\t\t\tif ( previousItemBlock ) {\n\t\t\t\t\twriter.setAttribute( 'listType', previousItemBlock.getAttribute( 'listType' ), block );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListIndentCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tlet blocks = getSelectedListBlocks( this.editor.model.document.selection );\n\t\tlet firstBlock = blocks[ 0 ];\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\tif ( this._direction == 'backward' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// A single block of a list item is selected, so it could be indented as a sublist.\n\t\tif ( isSingleListItem( blocks ) && !isFirstBlockOfListItem( blocks[ 0 ] ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tblocks = expandListBlocksToCompleteItems( blocks );\n\t\tfirstBlock = blocks[ 0 ];\n\n\t\t// Check if there is any list item before selected items that could become a parent of selected items.\n\t\tconst siblingItem = ListWalker.first( firstBlock, { sameIndent: true } );\n\n\t\tif ( !siblingItem ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( siblingItem.getAttribute( 'listType' ) == firstBlock.getAttribute( 'listType' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n// Returns an array of selected blocks truncated to the first non list block element.\nfunction getSelectedListBlocks( selection ) {\n\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\tconst firstNonListBlockIndex = blocks.findIndex( block => !isListItemBlock( block ) );\n\n\tif ( firstNonListBlockIndex != -1 ) {\n\t\tblocks.length = firstNonListBlockIndex;\n\t}\n\n\treturn blocks;\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 list/documentlist/documentlistmergecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\tgetNestedListBlocks,\n\tindentBlocks,\n\tsortBlocks,\n\tisFirstBlockOfListItem,\n\tmergeListItemBefore,\n\tisSingleListItem,\n\tgetSelectedBlockObject,\n\tisListItemBlock\n} from './utils/model';\nimport ListWalker from './utils/listwalker';\n\n/**\n * The document list merge command. It is used by the {@link module:list/documentlist~DocumentList list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListMergeCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'backward'|'forward'} direction Whether list item should be merged before or after the selected block.\n\t */\n\tconstructor( editor, direction ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Whether list item should be merged before or after the selected block.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {'backward'|'forward'}\n\t\t */\n\t\tthis._direction = direction;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Merges list blocks together (depending on the {@link #constructor}'s `direction` parameter).\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param {Object} [options] Command options.\n\t * @param {String|Boolean} [options.shouldMergeOnBlocksContentLevel=false] When set `true`, merging will be performed together\n\t * with {@link module:engine/model/model~Model#deleteContent} to get rid of the inline content in the selection or take advantage\n\t * of the heuristics in `deleteContent()` that helps convert lists into paragraphs in certain cases.\n\t */\n\texecute( { shouldMergeOnBlocksContentLevel = false } = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst changedBlocks = [];\n\n\t\tmodel.change( writer => {\n\t\t\tconst { firstElement, lastElement } = this._getMergeSubjectElements( selection, shouldMergeOnBlocksContentLevel );\n\n\t\t\tconst firstIndent = firstElement.getAttribute( 'listIndent' ) || 0;\n\t\t\tconst lastIndent = lastElement.getAttribute( 'listIndent' );\n\t\t\tconst lastElementId = lastElement.getAttribute( 'listItemId' );\n\n\t\t\tif ( firstIndent != lastIndent ) {\n\t\t\t\tconst nestedLastElementBlocks = getNestedListBlocks( lastElement );\n\n\t\t\t\tchangedBlocks.push( ...indentBlocks( [ lastElement, ...nestedLastElementBlocks ], writer, {\n\t\t\t\t\tindentBy: firstIndent - lastIndent,\n\n\t\t\t\t\t// If outdenting, the entire sub-tree that follows must be included.\n\t\t\t\t\texpand: firstIndent < lastIndent\n\t\t\t\t} ) );\n\t\t\t}\n\n\t\t\tif ( shouldMergeOnBlocksContentLevel ) {\n\t\t\t\tlet sel = selection;\n\n\t\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\t\tsel = writer.createSelection( writer.createRange(\n\t\t\t\t\t\twriter.createPositionAt( firstElement, 'end' ),\n\t\t\t\t\t\twriter.createPositionAt( lastElement, 0 )\n\t\t\t\t\t) );\n\t\t\t\t}\n\n\t\t\t\t// Delete selected content. Replace entire content only for non-collapsed selection.\n\t\t\t\tmodel.deleteContent( sel, { doNotResetEntireContent: selection.isCollapsed } );\n\n\t\t\t\t// Get the last \"touched\" element after deleteContent call (can't use the lastElement because\n\t\t\t\t// it could get merged into the firstElement while deleting content).\n\t\t\t\tconst lastElementAfterDelete = sel.getLastPosition().parent;\n\n\t\t\t\t// Check if the element after it was in the same list item and adjust it if needed.\n\t\t\t\tconst nextSibling = lastElementAfterDelete.nextSibling;\n\n\t\t\t\tchangedBlocks.push( lastElementAfterDelete );\n\n\t\t\t\tif ( nextSibling && nextSibling !== lastElement && nextSibling.getAttribute( 'listItemId' ) == lastElementId ) {\n\t\t\t\t\tchangedBlocks.push( ...mergeListItemBefore( nextSibling, lastElementAfterDelete, writer ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tchangedBlocks.push( ...mergeListItemBefore( lastElement, firstElement, writer ) );\n\t\t\t}\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListMergeCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\n\t\tif ( selection.isCollapsed || selectedBlockObject ) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n\n\t\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst siblingNode = this._direction == 'backward' ?\n\t\t\t\tpositionParent.previousSibling :\n\t\t\t\tpositionParent.nextSibling;\n\n\t\t\tif ( !siblingNode ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( isSingleListItem( [ positionParent, siblingNode ] ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tconst lastPosition = selection.getLastPosition();\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\t// If deleting within a single block of a list item, there's no need to merge anything.\n\t\t\t// The default delete should be executed instead.\n\t\t\tif ( lastPosition.parent === firstPosition.parent ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( !isListItemBlock( lastPosition.parent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the boundary elements the merge should be executed for. These are not necessarily selection's first\n\t * and last position parents but sometimes sibling or even further blocks depending on the context.\n\t *\n\t * @param {module:engine/model/selection~Selection} selection The selection the merge is executed for.\n\t * @param {Boolean} shouldMergeOnBlocksContentLevel When `true`, merge is performed together with\n\t * {@link module:engine/model/model~Model#deleteContent} to remove the inline content within the selection.\n\t * @returns {Object} elements\n\t * @returns {module:engine/model/element~Element} elements.firstElement\n\t * @returns {module:engine/model/element~Element} elements.lastElement\n\t */\n\t_getMergeSubjectElements( selection, shouldMergeOnBlocksContentLevel ) {\n\t\tconst model = this.editor.model;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\t\tlet firstElement, lastElement;\n\n\t\tif ( selection.isCollapsed || selectedBlockObject ) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n\t\t\tconst isFirstBlock = isFirstBlockOfListItem( positionParent );\n\n\t\t\tif ( this._direction == 'backward' ) {\n\t\t\t\tlastElement = positionParent;\n\n\t\t\t\tif ( isFirstBlock && !shouldMergeOnBlocksContentLevel ) {\n\t\t\t\t\t// For the \"c\" as an anchorElement:\n\t\t\t\t\t// * a\n\t\t\t\t\t// * b\n\t\t\t\t\t// * [c] <-- this block should be merged with \"a\"\n\t\t\t\t\t// It should find \"a\" element to merge with:\n\t\t\t\t\t// * a\n\t\t\t\t\t// * b\n\t\t\t\t\t// c\n\t\t\t\t\tfirstElement = ListWalker.first( positionParent, { sameIndent: true, lowerIndent: true } );\n\t\t\t\t} else {\n\t\t\t\t\tfirstElement = positionParent.previousSibling;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// In case of the forward merge there is no case as above, just merge with next sibling.\n\t\t\t\tfirstElement = positionParent;\n\t\t\t\tlastElement = positionParent.nextSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tfirstElement = selection.getFirstPosition().parent;\n\t\t\tlastElement = selection.getLastPosition().parent;\n\t\t}\n\n\t\treturn { firstElement, lastElement };\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 list/documentlist/documentlistsplitcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tsortBlocks,\n\tsplitListItemBefore\n} from './utils/model';\n\n/**\n * The document list split command that splits the list item at the selection.\n *\n * It is used by the {@link module:list/documentlist~DocumentList document list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListSplitCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'before'|'after'} direction Whether list item should be split before or after the selected block.\n\t */\n\tconstructor( editor, direction ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Whether list item should be split before or after the selected block.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {'before'|'after'}\n\t\t */\n\t\tthis._direction = direction;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Splits the list item at the selection.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */\n\texecute() {\n\t\tconst editor = this.editor;\n\n\t\teditor.model.change( writer => {\n\t\t\tconst changedBlocks = splitListItemBefore( this._getStartBlock(), writer );\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListSplitCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst block = this._getStartBlock();\n\n\t\treturn selection.isCollapsed &&\n\t\t\tisListItemBlock( block ) &&\n\t\t\t!isFirstBlockOfListItem( block );\n\t}\n\n\t/**\n\t * Returns the model element that is the main focus of the command (according to the current selection and command direction).\n\t *\n\t * @private\n\t * @returns {module:engine/model/element~Element}\n\t */\n\t_getStartBlock() {\n\t\tconst doc = this.editor.model.document;\n\t\tconst positionParent = doc.selection.getFirstPosition().parent;\n\n\t\treturn this._direction == 'before' ? positionParent : positionParent.nextSibling;\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 list/documentlist/utils/listwalker\n */\n\nimport { first, toArray } from 'ckeditor5/src/utils';\nimport { isListItemBlock } from './model';\n\n/**\n * Document list blocks iterator.\n */\nexport default class ListWalker {\n\t/**\n\t * Creates a document list iterator.\n\t *\n\t * @param {module:engine/model/element~Element} startElement The start list item block element.\n\t * @param {Object} options\n\t * @param {'forward'|'backward'} [options.direction='backward'] The iterating direction.\n\t * @param {Boolean} [options.includeSelf=false] Whether start block should be included in the result (if it's matching other criteria).\n\t * @param {Array.<String>|String} [options.sameAttributes=[]] Additional attributes that must be the same for each block.\n\t * @param {Boolean} [options.sameIndent=false] Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.lowerIndent=false] Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t */\n\tconstructor( startElement, options ) {\n\t\t/**\n\t\t * The start list item block element.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/element~Element}\n\t\t */\n\t\tthis._startElement = startElement;\n\n\t\t/**\n\t\t * The reference indent. Initialized by the indent of the start block.\n\t\t *\n\t\t * @private\n\t\t * @type {Number}\n\t\t */\n\t\tthis._referenceIndent = startElement.getAttribute( 'listIndent' );\n\n\t\t/**\n\t\t * The iterating direction.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._isForward = options.direction == 'forward';\n\n\t\t/**\n\t\t * Whether start block should be included in the result (if it's matching other criteria).\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._includeSelf = !!options.includeSelf;\n\n\t\t/**\n\t\t * Additional attributes that must be the same for each block.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<String>}\n\t\t */\n\t\tthis._sameAttributes = toArray( options.sameAttributes || [] );\n\n\t\t/**\n\t\t * Whether blocks with the same indent level as the start block should be included in the result.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._sameIndent = !!options.sameIndent;\n\n\t\t/**\n\t\t * Whether blocks with a lower indent level than the start block should be included in the result.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._lowerIndent = !!options.lowerIndent;\n\n\t\t/**\n\t\t * Whether blocks with a higher indent level than the start block should be included in the result.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._higherIndent = !!options.higherIndent;\n\t}\n\n\t/**\n\t * Performs only first step of iteration and returns the result.\n\t *\n\t * @param {module:engine/model/element~Element} startElement The start list item block element.\n\t * @param {Object} options\n\t * @param {'forward'|'backward'} [options.direction='backward'] The iterating direction.\n\t * @param {Boolean} [options.includeSelf=false] Whether start block should be included in the result (if it's matching other criteria).\n\t * @param {Array.<String>|String} [options.sameAttributes=[]] Additional attributes that must be the same for each block.\n\t * @param {Boolean} [options.sameIndent=false] Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.lowerIndent=false] Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\tstatic first( startElement, options ) {\n\t\tconst walker = new this( startElement, options );\n\t\tconst iterator = walker[ Symbol.iterator ]();\n\n\t\treturn first( iterator );\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:engine/model/element~Element>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tconst nestedItems = [];\n\n\t\tfor ( const { node } of iterateSiblingListBlocks( this._getStartNode(), this._isForward ? 'forward' : 'backward' ) ) {\n\t\t\tconst indent = node.getAttribute( 'listIndent' );\n\n\t\t\t// Leaving a nested list.\n\t\t\tif ( indent < this._referenceIndent ) {\n\t\t\t\t// Abort searching blocks.\n\t\t\t\tif ( !this._lowerIndent ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// While searching for lower indents, update the reference indent to find another parent in the next step.\n\t\t\t\tthis._referenceIndent = indent;\n\t\t\t}\n\t\t\t// Entering a nested list.\n\t\t\telse if ( indent > this._referenceIndent ) {\n\t\t\t\t// Ignore nested blocks.\n\t\t\t\tif ( !this._higherIndent ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Collect nested blocks to verify if they are really nested, or it's a different item.\n\t\t\t\tif ( !this._isForward ) {\n\t\t\t\t\tnestedItems.push( node );\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Same indent level block.\n\t\t\telse {\n\t\t\t\t// Ignore same indent block.\n\t\t\t\tif ( !this._sameIndent ) {\n\t\t\t\t\t// While looking for nested blocks, stop iterating while encountering first same indent block.\n\t\t\t\t\tif ( this._higherIndent ) {\n\t\t\t\t\t\t// No more nested blocks so yield nested items.\n\t\t\t\t\t\tif ( nestedItems.length ) {\n\t\t\t\t\t\t\tyield* nestedItems;\n\t\t\t\t\t\t\tnestedItems.length = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Abort if item has any additionally specified attribute different.\n\t\t\t\tif ( this._sameAttributes.some( attr => node.getAttribute( attr ) !== this._startElement.getAttribute( attr ) ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// There is another block for the same list item so the nested items were in the same list item.\n\t\t\tif ( nestedItems.length ) {\n\t\t\t\tyield* nestedItems;\n\t\t\t\tnestedItems.length = 0;\n\t\t\t}\n\n\t\t\tyield node;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the model element to start iterating.\n\t *\n\t * @private\n\t * @returns {module:engine/model/element~Element}\n\t */\n\t_getStartNode() {\n\t\tif ( this._includeSelf ) {\n\t\t\treturn this._startElement;\n\t\t}\n\n\t\treturn this._isForward ?\n\t\t\tthis._startElement.nextSibling :\n\t\t\tthis._startElement.previousSibling;\n\t}\n}\n\n/**\n * Iterates sibling list blocks starting from the given node.\n *\n * @protected\n * @param {module:engine/model/node~Node} node The model node.\n * @param {'backward'|'forward'} [direction='forward'] Iteration direction.\n * @returns {Iterator.<module:list/documentlist/utils/listwalker~ListIteratorValue>} The object with `node` and `previous`\n * {@link module:engine/model/element~Element blocks}.\n */\nexport function* iterateSiblingListBlocks( node, direction = 'forward' ) {\n\tconst isForward = direction == 'forward';\n\tlet previous = null;\n\n\twhile ( isListItemBlock( node ) ) {\n\t\tyield { node, previous };\n\n\t\tprevious = node;\n\t\tnode = isForward ? node.nextSibling : node.previousSibling;\n\t}\n}\n\n/**\n * The iterable protocol over the list elements.\n *\n * @protected\n */\nexport class ListBlocksIterable {\n\t/**\n\t * @param {module:engine/model/element~Element} listHead The head element of a list.\n\t */\n\tconstructor( listHead ) {\n\t\tthis._listHead = listHead;\n\t}\n\n\t/**\n\t * List blocks iterator.\n\t *\n\t * Iterates over all blocks of a list.\n\t *\n\t * @returns {Iterator.<module:list/documentlist/utils/listwalker~ListIteratorValue>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn iterateSiblingListBlocks( this._listHead, 'forward' );\n\t}\n}\n\n/**\n * Object returned by `iterateSiblingListBlocks()` when traversing a list.\n *\n * @protected\n * @typedef {Object} module:list/documentlist/utils/listwalker~ListIteratorValue\n * @property {module:engine/model/node~Node} node The current list node.\n * @property {module:engine/model/node~Node} previous The previous list node.\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 list/documentlist/utils/model\n */\n\nimport { uid, toArray } from 'ckeditor5/src/utils';\nimport ListWalker, { iterateSiblingListBlocks } from './listwalker';\n\n/**\n * The list item ID generator.\n *\n * @protected\n */\nexport class ListItemUid {\n\t/**\n\t * Returns the next ID.\n\t *\n\t * @protected\n\t * @returns {String}\n\t */\n\t/* istanbul ignore next: static function definition */\n\tstatic next() {\n\t\treturn uid();\n\t}\n}\n\n/**\n * Returns true if the given model node is a list item block.\n *\n * @protected\n * @param {module:engine/model/node~Node} node A model node.\n * @returns {Boolean}\n */\nexport function isListItemBlock( node ) {\n\treturn !!node && node.is( 'element' ) && node.hasAttribute( 'listItemId' );\n}\n\n/**\n * Returns an array with all elements that represents the same list item.\n *\n * It means that values for `listIndent`, and `listItemId` for all items are equal.\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @param {Object} [options]\n * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n * in the result.\n * @return {Array.<module:engine/model/element~Element>}\n */\nexport function getAllListItemBlocks( listItem, options = {} ) {\n\treturn [\n\t\t...getListItemBlocks( listItem, { ...options, direction: 'backward' } ),\n\t\t...getListItemBlocks( listItem, { ...options, direction: 'forward' } )\n\t];\n}\n\n/**\n * Returns an array with elements that represents the same list item in the specified direction.\n *\n * It means that values for `listIndent` and `listItemId` for all items are equal.\n *\n * **Note**: For backward search the provided item is not included, but for forward search it is included in the result.\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @param {Object} [options]\n * @param {'forward'|'backward'} [options.direction='backward'] Walking direction.\n * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n * in the result.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getListItemBlocks( listItem, options = {} ) {\n\tconst isForward = options.direction == 'forward';\n\n\tconst items = Array.from( new ListWalker( listItem, {\n\t\t...options,\n\t\tincludeSelf: isForward,\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} ) );\n\n\treturn isForward ? items : items.reverse();\n}\n\n/**\n * Returns a list items nested inside the given list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getNestedListBlocks( listItem ) {\n\treturn Array.from( new ListWalker( listItem, {\n\t\tdirection: 'forward',\n\t\thigherIndent: true\n\t} ) );\n}\n\n/**\n * Returns array of all blocks/items of the same list as given block (same indent, same type and properties).\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getListItems( listItem ) {\n\tconst backwardBlocks = new ListWalker( listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listType'\n\t} );\n\n\tconst forwardBlocks = new ListWalker( listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listType',\n\t\tincludeSelf: true,\n\t\tdirection: 'forward'\n\t} );\n\n\treturn [\n\t\t...Array.from( backwardBlocks ).reverse(),\n\t\t...forwardBlocks\n\t];\n}\n\n/**\n * Check if the given block is the first in the list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @returns {Boolean}\n */\nexport function isFirstBlockOfListItem( listBlock ) {\n\tconst previousSibling = ListWalker.first( listBlock, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} );\n\n\tif ( !previousSibling ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if the given block is the last in the list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @returns {Boolean}\n */\nexport function isLastBlockOfListItem( listBlock ) {\n\tconst nextSibling = ListWalker.first( listBlock, {\n\t\tdirection: 'forward',\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} );\n\n\tif ( !nextSibling ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n *\n * @protected\n * @param {module:engine/model/element~Element|Array.<module:engine/model/element~Element>} blocks The list of selected blocks.\n * @param {Object} [options]\n * @param {Boolean} [options.withNested=true] Whether should include nested list items.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function expandListBlocksToCompleteItems( blocks, options = {} ) {\n\tblocks = toArray( blocks );\n\n\tconst higherIndent = options.withNested !== false;\n\tconst allBlocks = new Set();\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const itemBlock of getAllListItemBlocks( block, { higherIndent } ) ) {\n\t\t\tallBlocks.add( itemBlock );\n\t\t}\n\t}\n\n\treturn sortBlocks( allBlocks );\n}\n\n/**\n * Expands the given list of selected blocks to include all the items of the lists they're in.\n *\n * @protected\n * @param {module:engine/model/element~Element|Array.<module:engine/model/element~Element>} blocks The list of selected blocks.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function expandListBlocksToCompleteList( blocks ) {\n\tblocks = toArray( blocks );\n\n\tconst allBlocks = new Set();\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const itemBlock of getListItems( block ) ) {\n\t\t\tallBlocks.add( itemBlock );\n\t\t}\n\t}\n\n\treturn sortBlocks( allBlocks );\n}\n\n/**\n * Splits the list item just before the provided list block.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} The array of updated blocks.\n */\nexport function splitListItemBefore( listBlock, writer ) {\n\tconst blocks = getListItemBlocks( listBlock, { direction: 'forward' } );\n\tconst id = ListItemUid.next();\n\n\tfor ( const block of blocks ) {\n\t\twriter.setAttribute( 'listItemId', id, block );\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Merges the list item with the parent list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @param {module:engine/model/element~Element} parentBlock The list block element to merge with.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} The array of updated blocks.\n */\nexport function mergeListItemBefore( listBlock, parentBlock, writer ) {\n\tconst attributes = {};\n\n\tfor ( const [ key, value ] of parentBlock.getAttributes() ) {\n\t\tif ( key.startsWith( 'list' ) ) {\n\t\t\tattributes[ key ] = value;\n\t\t}\n\t}\n\n\tconst blocks = getListItemBlocks( listBlock, { direction: 'forward' } );\n\n\tfor ( const block of blocks ) {\n\t\twriter.setAttributes( attributes, block );\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Increases indentation of given list blocks.\n *\n * @protected\n * @param {module:engine/model/element~Element|Iterable.<module:engine/model/element~Element>} blocks The block or iterable of blocks.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @param {Object} [options]\n * @param {Boolean} [options.expand=false] Whether should expand the list of blocks to include complete list items.\n * @param {Number} [options.indentBy=1] The number of levels the indentation should change (could be negative).\n */\nexport function indentBlocks( blocks, writer, { expand, indentBy = 1 } = {} ) {\n\tblocks = toArray( blocks );\n\n\t// Expand the selected blocks to contain the whole list items.\n\tconst allBlocks = expand ? expandListBlocksToCompleteItems( blocks ) : blocks;\n\n\tfor ( const block of allBlocks ) {\n\t\tconst blockIndent = block.getAttribute( 'listIndent' ) + indentBy;\n\n\t\tif ( blockIndent < 0 ) {\n\t\t\tremoveListAttributes( block, writer );\n\t\t} else {\n\t\t\twriter.setAttribute( 'listIndent', blockIndent, block );\n\t\t}\n\t}\n\n\treturn allBlocks;\n}\n\n/**\n * Decreases indentation of given list of blocks. If the indentation of some blocks matches the indentation\n * of surrounding blocks, they get merged together.\n *\n * @protected\n * @param {module:engine/model/element~Element|Iterable.<module:engine/model/element~Element>} blocks The block or iterable of blocks.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n */\nexport function outdentBlocksWithMerge( blocks, writer ) {\n\tblocks = toArray( blocks );\n\n\t// Expand the selected blocks to contain the whole list items.\n\tconst allBlocks = expandListBlocksToCompleteItems( blocks );\n\tconst visited = new Set();\n\n\tconst referenceIndent = Math.min( ...allBlocks.map( block => block.getAttribute( 'listIndent' ) ) );\n\tconst parentBlocks = new Map();\n\n\t// Collect parent blocks before the list structure gets altered.\n\tfor ( const block of allBlocks ) {\n\t\tparentBlocks.set( block, ListWalker.first( block, { lowerIndent: true } ) );\n\t}\n\n\tfor ( const block of allBlocks ) {\n\t\tif ( visited.has( block ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvisited.add( block );\n\n\t\tconst blockIndent = block.getAttribute( 'listIndent' ) - 1;\n\n\t\tif ( blockIndent < 0 ) {\n\t\t\tremoveListAttributes( block, writer );\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Merge with parent list item while outdenting and indent matches reference indent.\n\t\tif ( block.getAttribute( 'listIndent' ) == referenceIndent ) {\n\t\t\tconst mergedBlocks = mergeListItemIfNotLast( block, parentBlocks.get( block ), writer );\n\n\t\t\t// All list item blocks are updated while merging so add those to visited set.\n\t\t\tfor ( const mergedBlock of mergedBlocks ) {\n\t\t\t\tvisited.add( mergedBlock );\n\t\t\t}\n\n\t\t\t// The indent level was updated while merging so continue to next block.\n\t\t\tif ( mergedBlocks.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\twriter.setAttribute( 'listIndent', blockIndent, block );\n\t}\n\n\treturn sortBlocks( visited );\n}\n\n/**\n * Removes all list attributes from the given blocks.\n *\n * @protected\n * @param {module:engine/model/element~Element|Iterable.<module:engine/model/element~Element>} blocks The block or iterable of blocks.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} Array of altered blocks.\n */\nexport function removeListAttributes( blocks, writer ) {\n\tblocks = toArray( blocks );\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const attributeKey of block.getAttributeKeys() ) {\n\t\t\tif ( attributeKey.startsWith( 'list' ) ) {\n\t\t\t\twriter.removeAttribute( attributeKey, block );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Checks whether the given blocks are related to a single list item.\n *\n * @protected\n * @param {Array.<module:engine/model/element~Element>} blocks The list block elements.\n * @returns {Boolean}\n */\nexport function isSingleListItem( blocks ) {\n\tif ( !blocks.length ) {\n\t\treturn false;\n\t}\n\n\tconst firstItemId = blocks[ 0 ].getAttribute( 'listItemId' );\n\n\tif ( !firstItemId ) {\n\t\treturn false;\n\t}\n\n\treturn !blocks.some( item => item.getAttribute( 'listItemId' ) != firstItemId );\n}\n\n/**\n * Modifies the indents of list blocks following the given list block so the indentation is valid after\n * the given block is no longer a list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} lastBlock The last list block that has become a non-list element.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} Array of altered blocks.\n */\nexport function outdentFollowingItems( lastBlock, writer ) {\n\tconst changedBlocks = [];\n\n\t// Start from the model item that is just after the last turned-off item.\n\tlet currentIndent = Number.POSITIVE_INFINITY;\n\n\t// Correct indent of all items after the last turned off item.\n\t// Rules that should be followed:\n\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t// will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t// should not end up as a child of any of list items that they were not children of before.\n\t// 3. All other items should have their indent changed relatively to it's parent.\n\t//\n\t// For example:\n\t// 1 * --------\n\t// 2 * --------\n\t// 3 * --------\t\t\t<-- this is turned off.\n\t// 4 * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t// 5 * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t// 6 * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t// 7 * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t// 8 * --------\t\t\t\t<-- this has to become indent = 0.\n\t// 9 * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t// 10 * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t// 11 * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t// 13 * --------\n\t// 14 * --------\n\t//\n\t// After turning off 3 the list becomes:\n\t//\n\t// 1 * --------\n\t// 2 * --------\n\t//\n\t// 3 --------\n\t//\n\t// 4 * --------\n\t// 5 * --------\n\t// 6 * --------\n\t// 7 * --------\n\t// 8 * --------\n\t// 9 * --------\n\t// 10 * --------\n\t// 11 * --------\n\t// 12 * --------\n\t// 13 * --------\n\t// 14 * --------\n\t//\n\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t// less conversion (faster).\n\tfor ( const { node } of iterateSiblingListBlocks( lastBlock.nextSibling, 'forward' ) ) {\n\t\t// Check each next list item, as long as its indent is higher than 0.\n\t\tconst indent = node.getAttribute( 'listIndent' );\n\n\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\tif ( indent == 0 ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// We check if that's item indent is lower than current relative indent.\n\t\tif ( indent < currentIndent ) {\n\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\tcurrentIndent = indent;\n\t\t}\n\n\t\t// Fix indent relatively to current relative indent.\n\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\tconst newIndent = indent - currentIndent;\n\n\t\twriter.setAttribute( 'listIndent', newIndent, node );\n\t\tchangedBlocks.push( node );\n\t}\n\n\treturn changedBlocks;\n}\n\n/**\n * Returns the array of given blocks sorted by model indexes (document order).\n *\n * @protected\n * @param {Iterable.<module:engine/model/element~Element>} blocks The array of blocks.\n * @returns {Array.<module:engine/model/element~Element>} The sorted array of blocks.\n */\nexport function sortBlocks( blocks ) {\n\treturn Array.from( blocks )\n\t\t.filter( block => block.root.rootName !== '$graveyard' )\n\t\t.sort( ( a, b ) => a.index - b.index );\n}\n\n/**\n * Returns a selected block object. If a selected object is inline or when there is no selected\n * object, `null` is returned.\n *\n * @protected\n * @param {module:engine/model/model~Model} model The instance of editor model.\n * @returns {module:engine/model/element~Element|null} Selected block object or `null`.\n */\nexport function getSelectedBlockObject( model ) {\n\tconst selectedElement = model.document.selection.getSelectedElement();\n\n\tif ( !selectedElement ) {\n\t\treturn null;\n\t}\n\n\tif ( model.schema.isObject( selectedElement ) && model.schema.isBlock( selectedElement ) ) {\n\t\treturn selectedElement;\n\t}\n\n\treturn null;\n}\n\n// Merges a given block to the given parent block if parent is a list item and there is no more blocks in the same item.\nfunction mergeListItemIfNotLast( block, parentBlock, writer ) {\n\tconst parentItemBlocks = getListItemBlocks( parentBlock, { direction: 'forward' } );\n\n\t// Merge with parent only if outdented item wasn't the last one in its parent.\n\t// Merge:\n\t// * a\t\t\t->\t\t* a\n\t// * [b]\t\t->\t\t b\n\t// c\t\t\t->\t\t c\n\t// Don't merge:\n\t// * a\t\t\t->\t\t* a\n\t// * [b]\t\t-> \t\t* b\n\t// * c\t\t\t->\t\t* c\n\tif ( parentItemBlocks.pop().index > block.index ) {\n\t\treturn mergeListItemBefore( block, parentBlock, writer );\n\t}\n\n\treturn [];\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 list/documentlist/utils/postfixers\n */\n\nimport { iterateSiblingListBlocks } from './listwalker';\nimport { getListItemBlocks, isListItemBlock, ListItemUid } from './model';\n\n/**\n * Based on the provided positions looks for the list head and stores it in the provided map.\n *\n * @protected\n * @param {module:engine/model/position~Position} position The search starting position.\n * @param {Map.<module:engine/model/element~Element,module:engine/model/element~Element>} itemToListHead The map from list item element\n * to the list head element.\n */\nexport function findAndAddListHeadToMap( position, itemToListHead ) {\n\tconst previousNode = position.nodeBefore;\n\n\tif ( !isListItemBlock( previousNode ) ) {\n\t\tconst item = position.nodeAfter;\n\n\t\tif ( isListItemBlock( item ) ) {\n\t\t\titemToListHead.set( item, item );\n\t\t}\n\t} else {\n\t\tlet listHead = previousNode;\n\n\t\tfor ( { node: listHead } of iterateSiblingListBlocks( listHead, 'backward' ) ) {\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\titemToListHead.set( previousNode, listHead );\n\t}\n}\n\n/**\n * Scans the list starting from the given list head element and fixes items' indentation.\n *\n * @protected\n * @param {Iterable.<module:list/documentlist/utils/listwalker~ListIteratorValue>} listNodes The iterable of list nodes.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Boolean} Whether the model was modified.\n */\nexport function fixListIndents( listNodes, writer ) {\n\tlet maxIndent = 0; // Guards local sublist max indents that need fixing.\n\tlet prevIndent = -1; // Previous item indent.\n\tlet fixBy = null;\n\tlet applied = false;\n\n\tfor ( const { node } of listNodes ) {\n\t\tconst itemIndent = node.getAttribute( 'listIndent' );\n\n\t\tif ( itemIndent > maxIndent ) {\n\t\t\tlet newIndent;\n\n\t\t\tif ( fixBy === null ) {\n\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\tnewIndent = maxIndent;\n\t\t\t} else {\n\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t}\n\n\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t}\n\n\t\t\tif ( newIndent > prevIndent + 1 ) {\n\t\t\t\tnewIndent = prevIndent + 1;\n\t\t\t}\n\n\t\t\twriter.setAttribute( 'listIndent', newIndent, node );\n\n\t\t\tapplied = true;\n\t\t\tprevIndent = newIndent;\n\t\t} else {\n\t\t\tfixBy = null;\n\t\t\tmaxIndent = itemIndent + 1;\n\t\t\tprevIndent = itemIndent;\n\t\t}\n\t}\n\n\treturn applied;\n}\n\n/**\n * Scans the list starting from the given list head element and fixes items' types.\n *\n * @protected\n * @param {Iterable.<module:list/documentlist/utils/listwalker~ListIteratorValue>} listNodes The iterable of list nodes.\n * @param {Set.<String>} seenIds The set of already known IDs.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Boolean} Whether the model was modified.\n */\nexport function fixListItemIds( listNodes, seenIds, writer ) {\n\tconst visited = new Set();\n\tlet applied = false;\n\n\tfor ( const { node } of listNodes ) {\n\t\tif ( visited.has( node ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet listType = node.getAttribute( 'listType' );\n\t\tlet listItemId = node.getAttribute( 'listItemId' );\n\n\t\t// Use a new ID if this one was spot earlier (even in other list).\n\t\tif ( seenIds.has( listItemId ) ) {\n\t\t\tlistItemId = ListItemUid.next();\n\t\t}\n\n\t\tseenIds.add( listItemId );\n\n\t\tfor ( const block of getListItemBlocks( node, { direction: 'forward' } ) ) {\n\t\t\tvisited.add( block );\n\n\t\t\t// Use a new ID if a block of a bigger list item has different type.\n\t\t\tif ( block.getAttribute( 'listType' ) != listType ) {\n\t\t\t\tlistItemId = ListItemUid.next();\n\t\t\t\tlistType = block.getAttribute( 'listType' );\n\t\t\t}\n\n\t\t\tif ( block.getAttribute( 'listItemId' ) != listItemId ) {\n\t\t\t\twriter.setAttribute( 'listItemId', listItemId, block );\n\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn applied;\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 list/documentlist/utils/view\n */\n\n/**\n * Checks if view element is a list type (ul or ol).\n *\n * @protected\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isListView( viewElement ) {\n\treturn viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );\n}\n\n/**\n * Checks if view element is a list item (li).\n *\n * @protected\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isListItemView( viewElement ) {\n\treturn viewElement.is( 'element', 'li' );\n}\n\n/**\n * Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n *\n * Also, fixes non HTML compliant lists indents:\n *\n * \t\tbefore: fixed list:\n * \t\tOL OL\n * \t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n * \t\t |-> OL |-> OL\n * \t\t |-> OL |\n * \t\t | |-> OL |\n * \t\t | |-> OL |\n * \t\t | |-> LI (parent LIs: 1) |-> LI (indent: 1)\n * \t\t |-> LI (parent LIs: 1) |-> LI (indent: 1)\n *\n * \t\tbefore: fixed list:\n * \t\tOL OL\n * \t\t|-> OL |\n * \t\t |-> OL |\n * \t\t |-> OL |\n * \t\t |-> LI (parent LIs: 0) |-> LI (indent: 0)\n *\n * \t\tbefore: fixed list:\n * \t\tOL OL\n * \t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n * \t\t|-> OL |-> OL\n * \t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n *\n * @protected\n * @param {module:engine/view/element~Element} listItem\n * @returns {Number}\n */\nexport function getIndent( listItem ) {\n\tlet indent = 0;\n\tlet parent = listItem.parent;\n\n\twhile ( parent ) {\n\t\t// Each LI in the tree will result in an increased indent for HTML compliant lists.\n\t\tif ( isListItemView( parent ) ) {\n\t\t\tindent++;\n\t\t} else {\n\t\t\t// If however the list is nested in other list we should check previous sibling of any of the list elements...\n\t\t\tconst previousSibling = parent.previousSibling;\n\n\t\t\t// ...because the we might need increase its indent:\n\t\t\t//\t\tbefore: fixed list:\n\t\t\t//\t\tOL OL\n\t\t\t//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n\t\t\t//\t\t|-> OL |-> OL\n\t\t\t//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n\t\t\tif ( previousSibling && isListItemView( previousSibling ) ) {\n\t\t\t\tindent++;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn indent;\n}\n\n/**\n * Creates a list attribute element (ol or ul).\n *\n * @protected\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The downcast writer.\n * @param {Number} indent The list item indent.\n * @param {'bulleted'|'numbered'} type The list type.\n * @returns {module:engine/view/attributeelement~AttributeElement}\n */\nexport function createListElement( writer, indent, type, id = getViewElementIdForListType( type, indent ) ) {\n\t// Negative priorities so that restricted editing attribute won't wrap lists.\n\treturn writer.createAttributeElement( getViewElementNameForListType( type ), null, {\n\t\tpriority: 2 * indent / 100 - 100,\n\t\tid\n\t} );\n}\n\n/**\n * Creates a list item attribute element (li).\n *\n * @protected\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The downcast writer.\n * @param {Number} indent The list item indent.\n * @param {String} id The list item ID.\n * @returns {module:engine/view/attributeelement~AttributeElement}\n */\nexport function createListItemElement( writer, indent, id ) {\n\t// Negative priorities so that restricted editing attribute won't wrap list items.\n\treturn writer.createAttributeElement( 'li', null, {\n\t\tpriority: ( 2 * indent + 1 ) / 100 - 100,\n\t\tid\n\t} );\n}\n\n/**\n * Returns a view element name for the given list type.\n *\n * @protected\n * @param {'bulleted'|'numbered'} type The list type.\n * @returns {String}\n */\nexport function getViewElementNameForListType( type ) {\n\treturn type == 'numbered' ? 'ol' : 'ul';\n}\n\n/**\n * Returns a view element ID for the given list type and indent.\n *\n * @protected\n * @param {'bulleted'|'numbered'} type The list type.\n * @param {Number} indent The list indent level.\n * @returns {String}\n */\nexport function getViewElementIdForListType( type, indent ) {\n\treturn `list-${ type }-${ indent }`;\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 list/documentlistproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport DocumentListPropertiesEditing from './documentlistproperties/documentlistpropertiesediting';\nimport ListPropertiesUI from './listproperties/listpropertiesui';\n\n/**\n * The document list properties feature.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:list/documentlistproperties/documentlistpropertiesediting~DocumentListPropertiesEditing document list properties\n * editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ DocumentListPropertiesEditing, ListPropertiesUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentListProperties';\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 list/documentlistproperties/converters\n */\n\n/**\n * Returns a converter that consumes the `style`, `reversed`, and `start` attributes.\n * In `style`, it searches for the `list-style-type` definition.\n * If not found, the `\"default\"` value will be used.\n *\n * @protected\n * @param {module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy} strategy\n * @returns {Function}\n */\nexport function listPropertiesUpcastConverter( strategy ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema, consumable } = conversionApi;\n\n\t\t// If there is no view consumable to consume, set the default attribute value to be able to reconvert nested lists on parent change.\n\t\t// So abort converting if attribute was directly consumed.\n\t\tif ( consumable.test( data.viewItem, strategy.viewConsumables ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !data.modelRange ) {\n\t\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\tlet applied = false;\n\n\t\tfor ( const item of data.modelRange.getItems( { shallow: true } ) ) {\n\t\t\tif ( !schema.checkAttribute( item, strategy.attributeName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !strategy.appliesToListItem( item ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n\t\t\tif ( item.hasAttribute( strategy.attributeName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\twriter.setAttribute( strategy.attributeName, strategy.getAttributeOnUpcast( data.viewItem ), item );\n\t\t\tapplied = true;\n\t\t}\n\n\t\tif ( applied ) {\n\t\t\tconsumable.consume( data.viewItem, strategy.viewConsumables );\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 list/documentlistproperties/documentlistpropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport DocumentListEditing from '../documentlist/documentlistediting';\nimport DocumentListStartCommand from './documentliststartcommand';\nimport DocumentListStyleCommand from './documentliststylecommand';\nimport DocumentListReversedCommand from './documentlistreversedcommand';\nimport { listPropertiesUpcastConverter } from './converters';\nimport {\n\tgetAllSupportedStyleTypes,\n\tgetListTypeFromListStyleType,\n\tgetListStyleTypeFromTypeAttribute,\n\tgetTypeAttributeFromListStyleType\n} from './utils/style';\n\nconst DEFAULT_LIST_TYPE = 'default';\n\n/**\n * The document list properties engine feature.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listproperties~ListPropertiesConfig}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentListPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ DocumentListEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentListPropertiesEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list', {\n\t\t\tproperties: {\n\t\t\t\tstyles: true,\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t}\n\t\t} );\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 documentListEditing = editor.plugins.get( DocumentListEditing );\n\n\t\tconst enabledProperties = editor.config.get( 'list.properties' );\n\t\tconst strategies = createAttributeStrategies( enabledProperties );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tstrategy.addCommand( editor );\n\n\t\t\tmodel.schema.extend( '$container', { allowAttributes: strategy.attributeName } );\n\t\t\tmodel.schema.extend( '$block', { allowAttributes: strategy.attributeName } );\n\t\t\tmodel.schema.extend( '$blockObject', { allowAttributes: strategy.attributeName } );\n\n\t\t\t// Register downcast strategy.\n\t\t\tdocumentListEditing.registerDowncastStrategy( {\n\t\t\t\tscope: 'list',\n\t\t\t\tattributeName: strategy.attributeName,\n\n\t\t\t\tsetAttributeOnDowncast( writer, attributeValue, viewElement ) {\n\t\t\t\t\tstrategy.setAttributeOnDowncast( writer, attributeValue, viewElement );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Set up conversion.\n\t\teditor.conversion.for( 'upcast' ).add( dispatcher => {\n\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\tdispatcher.on( 'element:ol', listPropertiesUpcastConverter( strategy ) );\n\t\t\t\tdispatcher.on( 'element:ul', listPropertiesUpcastConverter( strategy ) );\n\t\t\t}\n\t\t} );\n\n\t\t// Verify if the list view element (ul or ol) requires refreshing.\n\t\tdocumentListEditing.on( 'checkAttributes:list', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\tif ( strategy.getAttributeOnUpcast( viewElement ) != modelAttributes[ strategy.attributeName ] ) {\n\t\t\t\t\tevt.return = true;\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Reset list properties after indenting list items.\n\t\tthis.listenTo( editor.commands.get( 'indentList' ), 'afterExecute', ( evt, changedBlocks ) => {\n\t\t\tmodel.change( writer => {\n\t\t\t\tfor ( const node of changedBlocks ) {\n\t\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\t\tif ( strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\t\t// Just reset the attribute.\n\t\t\t\t\t\t\t// If there is a previous indented list that this node should be merged into,\n\t\t\t\t\t\t\t// the postfixer will unify all the attributes of both sub-lists.\n\t\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, strategy.defaultValue, node );\n\t\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\t\t// Add or remove list properties attributes depending on the list type.\n\t\tdocumentListEditing.on( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tfor ( const { node } of listNodes ) {\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\t// Check if attribute is valid.\n\t\t\t\t\tif ( strategy.hasValidAttribute( node ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add missing default property attributes...\n\t\t\t\t\tif ( strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, strategy.defaultValue, node );\n\t\t\t\t\t}\n\t\t\t\t\t// ...or remove invalid property attributes.\n\t\t\t\t\telse {\n\t\t\t\t\t\twriter.removeAttribute( strategy.attributeName, node );\n\t\t\t\t\t}\n\n\t\t\t\t\tevt.return = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Make sure that all items in a single list (items at the same level & listType) have the same properties.\n\t\tdocumentListEditing.on( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tconst previousNodesByIndent = []; // Last seen nodes of lower indented lists.\n\n\t\t\tfor ( const { node, previous } of listNodes ) {\n\t\t\t\t// For the first list block there is nothing to compare with.\n\t\t\t\tif ( !previous ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst nodeIndent = node.getAttribute( 'listIndent' );\n\t\t\t\tconst previousNodeIndent = previous.getAttribute( 'listIndent' );\n\n\t\t\t\tlet previousNodeInList = null; // It's like `previous` but has the same indent as current node.\n\n\t\t\t\t// Let's find previous node for the same indent.\n\t\t\t\t// We're going to need that when we get back to previous indent.\n\t\t\t\tif ( nodeIndent > previousNodeIndent ) {\n\t\t\t\t\tpreviousNodesByIndent[ previousNodeIndent ] = previous;\n\t\t\t\t}\n\t\t\t\t// Restore the one for given indent.\n\t\t\t\telse if ( nodeIndent < previousNodeIndent ) {\n\t\t\t\t\tpreviousNodeInList = previousNodesByIndent[ nodeIndent ];\n\t\t\t\t\tpreviousNodesByIndent.length = nodeIndent;\n\t\t\t\t}\n\t\t\t\t// Same indent.\n\t\t\t\telse {\n\t\t\t\t\tpreviousNodeInList = previous;\n\t\t\t\t}\n\n\t\t\t\t// This is a first item of a nested list.\n\t\t\t\tif ( !previousNodeInList ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// This is a first block of a list of a different type.\n\t\t\t\tif ( previousNodeInList.getAttribute( 'listType' ) != node.getAttribute( 'listType' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Copy properties from the previous one.\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\tconst { attributeName } = strategy;\n\n\t\t\t\t\tif ( !strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = previousNodeInList.getAttribute( attributeName );\n\n\t\t\t\t\tif ( node.getAttribute( attributeName ) != value ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, value, node );\n\t\t\t\t\t\tevt.return = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Strategy for dealing with `listItem` attributes supported by this plugin.\n *\n * @typedef {Object} module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy\n * @protected\n * @property {String} attributeName The model attribute name.\n * @property {*} defaultValue The model attribute default value.\n * @property {Object} viewConsumables The view consumable as expected by\n * {@link module:engine/conversion/viewconsumable~ViewConsumable#consume `ViewConsumable`}.\n * @property {Function} addCommand Registers an editor command.\n * @property {Function} appliesToListItem Verifies whether the strategy is applicable for the specified model element.\n * @property {Function} hasValidAttribute Verifies whether the model attribute value is valid.\n * @property {Function} setAttributeOnDowncast Sets the property on the view element.\n * @property {Function} getAttributeOnUpcast Retrieves the property value from the view element.\n */\n\n// Creates an array of strategies for dealing with enabled listItem attributes.\n//\n// @param {Object} enabledProperties\n// @param {Boolean|Object} enabledProperties.styles\n// @param {Boolean} [enabledProperties.styles.useAttribute]\n// @param {Boolean} enabledProperties.reversed\n// @param {Boolean} enabledProperties.startIndex\n// @returns {Array.<module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy>}\nfunction createAttributeStrategies( enabledProperties ) {\n\tconst strategies = [];\n\n\tif ( enabledProperties.styles ) {\n\t\tconst useAttribute = typeof enabledProperties.styles == 'object' && enabledProperties.styles.useAttribute;\n\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStyle',\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\t\t\tviewConsumables: { styles: 'list-style-type' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\tlet supportedTypes = getAllSupportedStyleTypes();\n\n\t\t\t\tif ( useAttribute ) {\n\t\t\t\t\tsupportedTypes = supportedTypes.filter( styleType => !!getTypeAttributeFromListStyleType( styleType ) );\n\t\t\t\t}\n\n\t\t\t\teditor.commands.add( 'listStyle', new DocumentListStyleCommand( editor, DEFAULT_LIST_TYPE, supportedTypes ) );\n\t\t\t},\n\n\t\t\tappliesToListItem() {\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\tif ( !item.hasAttribute( 'listStyle' ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst value = item.getAttribute( 'listStyle' );\n\n\t\t\t\tif ( value == DEFAULT_LIST_TYPE ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn getListTypeFromListStyleType( value ) == item.getAttribute( 'listType' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStyle, element ) {\n\t\t\t\tif ( listStyle && listStyle !== DEFAULT_LIST_TYPE ) {\n\t\t\t\t\tif ( useAttribute ) {\n\t\t\t\t\t\tconst value = getTypeAttributeFromListStyleType( listStyle );\n\n\t\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\t\twriter.setAttribute( 'type', value, element );\n\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.setStyle( 'list-style-type', listStyle, element );\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twriter.removeStyle( 'list-style-type', element );\n\t\t\t\twriter.removeAttribute( 'type', element );\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\tconst style = listParent.getStyle( 'list-style-type' );\n\n\t\t\t\tif ( style ) {\n\t\t\t\t\treturn style;\n\t\t\t\t}\n\n\t\t\t\tconst attribute = listParent.getAttribute( 'type' );\n\n\t\t\t\tif ( attribute ) {\n\t\t\t\t\treturn getListStyleTypeFromTypeAttribute( attribute );\n\t\t\t\t}\n\n\t\t\t\treturn DEFAULT_LIST_TYPE;\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listReversed',\n\t\t\tdefaultValue: false,\n\t\t\tviewConsumables: { attributes: 'reversed' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listReversed', new DocumentListReversedCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\treturn this.appliesToListItem( item ) == item.hasAttribute( 'listReversed' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listReversed, element ) {\n\t\t\t\tif ( listReversed ) {\n\t\t\t\t\twriter.setAttribute( 'reversed', 'reversed', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'reversed', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.hasAttribute( 'reversed' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStart',\n\t\t\tdefaultValue: 1,\n\t\t\tviewConsumables: { attributes: 'start' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStart', new DocumentListStartCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\treturn this.appliesToListItem( item ) == item.hasAttribute( 'listStart' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStart, element ) {\n\t\t\t\tif ( listStart && listStart > 1 ) {\n\t\t\t\t\twriter.setAttribute( 'start', listStart, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'start', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getAttribute( 'start' ) || 1;\n\t\t\t}\n\t\t} );\n\t}\n\n\treturn strategies;\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 list/documentlistproperties/documentlistreversedcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../documentlist/utils/model';\n\n/**\n * The list reversed command. It changes the `listReversed` attribute of the selected list items,\n * letting the user to choose the order of an ordered list.\n * It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListReversedCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.reversed=false] Whether the list should be reversed.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listReversed', !!options.reversed, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tif ( isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn block.getAttribute( 'listReversed' );\n\t\t}\n\n\t\treturn null;\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 list/documentlistproperties/documentliststartcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../documentlist/utils/model';\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items,\n * letting the user to choose the starting point of an ordered list.\n * It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListStartCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {Number} [options.startIndex=1] The list start index.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listStart', options.startIndex || 1, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Number|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tif ( block && isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn block.getAttribute( 'listStart' );\n\t\t}\n\n\t\treturn null;\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 list/documentlistproperties/documentliststylecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../documentlist/utils/model';\nimport { getListTypeFromListStyleType } from './utils/style';\n\n/**\n * The list style command. It changes `listStyle` attribute of the selected list items,\n * letting the user choose styles for the list item markers.\n * It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListStyleCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {String} defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t * @param {Array.<String>} [supportedTypes] The list of supported style types by this command.\n\t */\n\tconstructor( editor, defaultType, supportedTypes ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The default type of the list style.\n\t\t *\n\t\t * @protected\n\t\t * @member {String}\n\t\t */\n\t\tthis._defaultType = defaultType;\n\n\t\t/**\n\t\t * The list of supported style types by this command.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<String>|undefined}\n\t\t */\n\t\tthis._supportedTypes = supportedTypes;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tthis._tryToConvertItemsToList( options );\n\n\t\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t\t.filter( block => block.hasAttribute( 'listType' ) );\n\n\t\t\tif ( !blocks.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listStyle', options.type || this._defaultType, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if the given style type is supported by this plugin.\n\t *\n\t * @param {String} value\n\t * @returns {Boolean}\n\t */\n\tisStyleTypeSupported( value ) {\n\t\tif ( !this._supportedTypes ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn this._supportedTypes.includes( value );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {String|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\tif ( isListItemBlock( listItem ) ) {\n\t\t\treturn listItem.getAttribute( 'listStyle' );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst editor = this.editor;\n\n\t\tconst numberedList = editor.commands.get( 'numberedList' );\n\t\tconst bulletedList = editor.commands.get( 'bulletedList' );\n\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\n\t/**\n\t * Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t *\n\t * @private\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style. If `null` is specified, the function does nothing.\n\t*/\n\t_tryToConvertItemsToList( options ) {\n\t\tif ( !options.type ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listType = getListTypeFromListStyleType( options.type );\n\n\t\tif ( !listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst commandName = listType + 'List';\n\t\tconst command = editor.commands.get( commandName );\n\n\t\tif ( !command.value ) {\n\t\t\teditor.execute( commandName );\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 list/documentlistproperties/utils/style\n*/\n\nconst LIST_STYLE_TO_LIST_TYPE = {};\nconst LIST_STYLE_TO_TYPE_ATTRIBUTE = {};\nconst TYPE_ATTRIBUTE_TO_LIST_STYLE = {};\n\nconst LIST_STYLE_TYPES = [\n\t{ listStyle: 'disc', typeAttribute: 'disc', listType: 'bulleted' },\n\t{ listStyle: 'circle', typeAttribute: 'circle', listType: 'bulleted' },\n\t{ listStyle: 'square', typeAttribute: 'square', listType: 'bulleted' },\n\t{ listStyle: 'decimal', typeAttribute: '1', listType: 'numbered' },\n\t{ listStyle: 'decimal-leading-zero', typeAttribute: null, listType: 'numbered' },\n\t{ listStyle: 'lower-roman', typeAttribute: 'i', listType: 'numbered' },\n\t{ listStyle: 'upper-roman', typeAttribute: 'I', listType: 'numbered' },\n\t{ listStyle: 'lower-alpha', typeAttribute: 'a', listType: 'numbered' },\n\t{ listStyle: 'upper-alpha', typeAttribute: 'A', listType: 'numbered' },\n\t{ listStyle: 'lower-latin', typeAttribute: 'a', listType: 'numbered' },\n\t{ listStyle: 'upper-latin', typeAttribute: 'A', listType: 'numbered' }\n];\n\nfor ( const { listStyle, typeAttribute, listType } of LIST_STYLE_TYPES ) {\n\tLIST_STYLE_TO_LIST_TYPE[ listStyle ] = listType;\n\tLIST_STYLE_TO_TYPE_ATTRIBUTE[ listStyle ] = typeAttribute;\n\n\tif ( typeAttribute ) {\n\t\tTYPE_ATTRIBUTE_TO_LIST_STYLE[ typeAttribute ] = listStyle;\n\t}\n}\n\n/**\n * Gets all the style types supported by given list type.\n *\n * @returns {Array.<String>}\n */\nexport function getAllSupportedStyleTypes() {\n\treturn LIST_STYLE_TYPES.map( x => x.listStyle );\n}\n\n/**\n* Checks whether the given list-style-type is supported by numbered or bulleted list.\n*\n* @param {String} listStyleType\n* @returns {'bulleted'|'numbered'|null}\n*/\nexport function getListTypeFromListStyleType( listStyleType ) {\n\treturn LIST_STYLE_TO_LIST_TYPE[ listStyleType ] || null;\n}\n\n/**\n * Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n *\n * @param {String} value\n * @returns {String|null}\n */\nexport function getListStyleTypeFromTypeAttribute( value ) {\n\treturn TYPE_ATTRIBUTE_TO_LIST_STYLE[ value ] || null;\n}\n\n/**\n * Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n *\n * @param {String} value\n * @returns {String|null}\n */\nexport function getTypeAttributeFromListStyleType( value ) {\n\treturn LIST_STYLE_TO_TYPE_ATTRIBUTE[ value ] || null;\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 list/list\n */\n\nimport ListEditing from './list/listediting';\nimport ListUI from './list/listui';\n\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/list/listediting~ListEditing list editing feature}\n * and {@link module:list/list/listui~ListUI list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class List extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing, ListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'List';\n\t}\n}\n\n/**\n * The configuration of the {@link module:list/list~List list} feature\n * and the {@link module:list/documentlist~DocumentList document list} feature.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tlist: ... // The list feature configuration.\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 ListConfig\n */\n\n/**\n * The configuration of the {@link module:list/list~List} feature and the {@link module:list/documentlist~DocumentList} feature.\n *\n * Read more in {@link module:list/list~ListConfig}.\n *\n * @member {module:module:list/list~ListConfig} module:core/editor/editorconfig~EditorConfig#list\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 list/list/converters\n */\n\nimport { TreeWalker } from 'ckeditor5/src/engine';\n\nimport {\n\tgenerateLiInUl,\n\tinjectViewList,\n\tmergeViewLists,\n\tgetSiblingListItem,\n\tpositionAfterUiElements\n} from './utils';\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n * position, and merges the list with surrounding lists (if available).\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewInsertion( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconsumable.consume( data.item, 'insert' );\n\t\tconsumable.consume( data.item, 'attribute:listType' );\n\t\tconsumable.consume( data.item, 'attribute:listIndent' );\n\n\t\tconst modelItem = data.item;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for the `listItem` model element removal.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewRemove( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\t\tconst viewStart = viewPosition.getLastMatchingPosition( value => !value.item.is( 'element', 'li' ) );\n\t\tconst viewItem = viewStart.nodeAfter;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item - the one to remove.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Remove the list with the item to remove.\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tconst removed = viewWriter.remove( removeRange );\n\n\t\t// 3. Merge the whole created by breaking and removing the list.\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 4. Bring back nested list that was in the removed <li>.\n\t\tconst modelItem = conversionApi.mapper.toModelElement( viewItem );\n\n\t\thoistNestedLists( modelItem.getAttribute( 'listIndent' ) + 1, data.position, removeRange.start, viewItem, conversionApi, model );\n\n\t\t// 5. Unbind removed view item and all children.\n\t\tfor ( const child of viewWriter.createRangeIn( removed ).getItems() ) {\n\t\t\tconversionApi.mapper.unbindViewElement( child );\n\t\t}\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * A model-to-view converter for the `type` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n * by breaking view elements and changing their name. The next {@link module:list/list/converters~modelViewMergeAfterChangeType}\n * converter will attempt to merge split nodes.\n *\n * Splitting this conversion into 2 steps makes it possible to add an additional conversion in the middle.\n * Check {@link module:list/todolist/todolistconverters~modelViewChangeType} to see an example of it.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewChangeType( evt, data, conversionApi ) {\n\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\treturn;\n\t}\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\tconst viewWriter = conversionApi.writer;\n\n\t// Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t// Change name of the view list that holds the changed view item.\n\t// We cannot just change name property, because that would not render properly.\n\tconst viewList = viewItem.parent;\n\tconst listName = data.attributeNewValue == 'numbered' ? 'ol' : 'ul';\n\n\tviewWriter.rename( listName, viewList );\n}\n\n/**\n * A model-to-view converter that attempts to merge nodes split by {@link module:list/list/converters~modelViewChangeType}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewMergeAfterChangeType( evt, data, conversionApi ) {\n\tconversionApi.consumable.consume( data.item, evt.name );\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\tconst viewList = viewItem.parent;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Merge the changed view list with other lists, if possible.\n\tmergeViewLists( viewWriter, viewList, viewList.nextSibling );\n\tmergeViewLists( viewWriter, viewList.previousSibling, viewList );\n}\n\n/**\n * A model-to-view converter for the `listIndent` attribute change on the `listItem` model element.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeIndent( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:listIndent' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item -- the one that changed type.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Extract view list with changed view list item and merge \"hole\" possibly created by breaking and removing elements.\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tviewWriter.remove( removeRange );\n\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 3. Bring back nested list that was in the removed <li>.\n\t\thoistNestedLists( data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi, model );\n\n\t\t// 4. Inject view list like it is newly inserted.\n\t\tinjectViewList( data.item, viewItem, conversionApi, model );\n\n\t\t// 5. Consume insertion of children inside the item. They are already handled by re-building the item in view.\n\t\tfor ( const child of data.item.getChildren() ) {\n\t\t\tconversionApi.consumable.consume( child, 'insert' );\n\t\t}\n\t};\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter is fired for\n * insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n * model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n * list so the model element is inserted to the view parent element corresponding to its model parent element.\n *\n * The converter prevents such situations:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n *\t\t<paragraph>xxx</paragraph> // Instead of this wrong view state:\n *\t\t<listItem>bar</listItem> <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewSplitOnInsert( evt, data, conversionApi ) {\n\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\treturn;\n\t}\n\n\tif ( data.item.name != 'listItem' ) {\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst lists = [];\n\n\t\t// Break multiple ULs/OLs if there are.\n\t\t//\n\t\t// Imagine following list:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// Insert paragraph after item 1.1.1:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// In this case 1.1.2 has to become beginning of a new list.\n\t\t// We need to break list before 1.1.2 (obvious), then we need to break list also before 1.2.\n\t\t// Then we need to move those broken pieces one after another and merge:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\twhile ( viewPosition.parent.name == 'ul' || viewPosition.parent.name == 'ol' ) {\n\t\t\tviewPosition = viewWriter.breakContainer( viewPosition );\n\n\t\t\tif ( viewPosition.parent.name != 'li' ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Remove lists that are after inserted element.\n\t\t\t// They will be brought back later, below the inserted element.\n\t\t\tconst removeStart = viewPosition;\n\t\t\tconst removeEnd = viewWriter.createPositionAt( viewPosition.parent, 'end' );\n\n\t\t\t// Don't remove if there is nothing to remove.\n\t\t\tif ( !removeStart.isEqual( removeEnd ) ) {\n\t\t\t\tconst removed = viewWriter.remove( viewWriter.createRange( removeStart, removeEnd ) );\n\t\t\t\tlists.push( removed );\n\t\t\t}\n\n\t\t\tviewPosition = viewWriter.createPositionAfter( viewPosition.parent );\n\t\t}\n\n\t\t// Bring back removed lists.\n\t\tif ( lists.length > 0 ) {\n\t\t\tfor ( let i = 0; i < lists.length; i++ ) {\n\t\t\t\tconst previousList = viewPosition.nodeBefore;\n\t\t\t\tconst insertedRange = viewWriter.insert( viewPosition, lists[ i ] );\n\t\t\t\tviewPosition = insertedRange.end;\n\n\t\t\t\t// Don't merge first list! We want a split in that place (this is why this converter is introduced).\n\t\t\t\tif ( i > 0 ) {\n\t\t\t\t\tconst mergePos = mergeViewLists( viewWriter, previousList, previousList.nextSibling );\n\n\t\t\t\t\t// If `mergePos` is in `previousList` it means that the lists got merged.\n\t\t\t\t\t// In this case, we need to fix insert position.\n\t\t\t\t\tif ( mergePos && mergePos.parent == previousList ) {\n\t\t\t\t\t\tviewPosition.offset--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge last inserted list with element after it.\n\t\t\tmergeViewLists( viewWriter, viewPosition.nodeBefore, viewPosition.nodeAfter );\n\t\t}\n\t}\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter takes care of\n * merging view lists after something is removed or moved from near them.\n *\n * Example:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul>\n *\t\t<paragraph>xxx</paragraph> <p>xxx</p>\n *\t\t<listItem>bar</listItem> <ul><li>bar</li></ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewMergeAfter( evt, data, conversionApi ) {\n\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\tconst viewItemPrev = viewPosition.nodeBefore;\n\tconst viewItemNext = viewPosition.nodeAfter;\n\n\t// Merge lists if something (remove, move) was done from inside of list.\n\t// Merging will be done only if both items are view lists of the same type.\n\t// The check is done inside the helper function.\n\tmergeViewLists( conversionApi.writer, viewItemPrev, viewItemNext );\n}\n\n/**\n * A view-to-model converter that converts the `<li>` view elements into the `listItem` model elements.\n *\n * To set correct values of the `listType` and `listIndent` attributes the converter:\n * * checks `<li>`'s parent,\n * * stores and increases the `conversionApi.store.indent` value when `<li>`'s sub-items are converted.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function viewModelConverter( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.consume( data.viewItem, { name: true } ) ) {\n\t\tconst writer = conversionApi.writer;\n\n\t\t// 1. Create `listItem` model element.\n\t\tconst listItem = writer.createElement( 'listItem' );\n\n\t\t// 2. Handle `listItem` model element attributes.\n\t\tconst indent = getIndent( data.viewItem );\n\n\t\twriter.setAttribute( 'listIndent', indent, listItem );\n\n\t\t// Set 'bulleted' as default. If this item is pasted into a context,\n\t\tconst type = data.viewItem.parent && data.viewItem.parent.name == 'ol' ? 'numbered' : 'bulleted';\n\t\twriter.setAttribute( 'listType', type, listItem );\n\n\t\tif ( !conversionApi.safeInsert( listItem, data.modelCursor ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextPosition = viewToModelListItemChildrenConverter( listItem, data.viewItem.getChildren(), conversionApi );\n\n\t\t// Result range starts before the first item and ends after the last.\n\t\tdata.modelRange = writer.createRange( data.modelCursor, nextPosition );\n\n\t\tconversionApi.updateConversionResult( listItem, data );\n\t}\n}\n\n/**\n * A view-to-model converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function cleanList( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t// Caching children because when we start removing them iterating fails.\n\t\tconst children = Array.from( data.viewItem.getChildren() );\n\n\t\tfor ( const child of children ) {\n\t\t\tconst isWrongElement = !( child.is( 'element', 'li' ) || isList( child ) );\n\n\t\t\tif ( isWrongElement ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A view-to-model converter for the `<li>` elements that cleans whitespace formatting from the input view.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function cleanListItem( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\tif ( data.viewItem.childCount === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst children = [ ...data.viewItem.getChildren() ];\n\n\t\tlet foundList = false;\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( foundList && !isList( child ) ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\n\t\t\tif ( isList( child ) ) {\n\t\t\t\t// If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.\n\t\t\t\tfoundList = true;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Returns a callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `listItem` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:modelToViewPosition\n * @param {module:engine/view/view~View} view A view instance.\n * @returns {Function}\n */\nexport function modelToViewPosition( view ) {\n\treturn ( evt, data ) => {\n\t\tif ( data.isPhantom ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.modelPosition.nodeBefore;\n\n\t\tif ( modelItem && modelItem.is( 'element', 'listItem' ) ) {\n\t\t\tconst viewItem = data.mapper.toViewElement( modelItem );\n\t\t\tconst topmostViewList = viewItem.getAncestors().find( isList );\n\t\t\tconst walker = view.createPositionAt( viewItem, 0 ).getWalker();\n\n\t\t\tfor ( const value of walker ) {\n\t\t\t\tif ( value.type == 'elementStart' && value.item.is( 'element', 'li' ) ) {\n\t\t\t\t\tdata.viewPosition = value.previousPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ( value.type == 'elementEnd' && value.item == topmostViewList ) {\n\t\t\t\t\tdata.viewPosition = value.nextPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `<li>` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function viewToModelPosition( model ) {\n\treturn ( evt, data ) => {\n\t\tconst viewPos = data.viewPosition;\n\t\tconst viewParent = viewPos.parent;\n\t\tconst mapper = data.mapper;\n\n\t\tif ( viewParent.name == 'ul' || viewParent.name == 'ol' ) {\n\t\t\t// Position is directly in <ul> or <ol>.\n\t\t\tif ( !viewPos.isAtEnd ) {\n\t\t\t\t// If position is not at the end, it must be before <li>.\n\t\t\t\t// Get that <li>, map it to `listItem` and set model position before that `listItem`.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeAfter );\n\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode );\n\t\t\t} else {\n\t\t\t\t// Position is at the end of <ul> or <ol>, so there is no <li> after it to be mapped.\n\t\t\t\t// There is <li> before the position, but we cannot just map it to `listItem` and set model position after it,\n\t\t\t\t// because that <li> may contain nested items.\n\t\t\t\t// We will check \"model length\" of that <li>, in other words - how many `listItem`s are in that <li>.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeBefore );\n\t\t\t\tconst modelLength = mapper.getModelLength( viewPos.nodeBefore );\n\n\t\t\t\t// Then we get model position before mapped `listItem` and shift it accordingly.\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode ).getShiftedBy( modelLength );\n\t\t\t}\n\n\t\t\tevt.stop();\n\t\t} else if (\n\t\t\tviewParent.name == 'li' &&\n\t\t\tviewPos.nodeBefore &&\n\t\t\t( viewPos.nodeBefore.name == 'ul' || viewPos.nodeBefore.name == 'ol' )\n\t\t) {\n\t\t\t// In most cases when view position is in <li> it is in text and this is a correct position.\n\t\t\t// However, if position is after <ul> or <ol> we have to fix it -- because in model <ul>/<ol> are not in the `listItem`.\n\t\t\tconst modelNode = mapper.toModelElement( viewParent );\n\n\t\t\t// Check all <ul>s and <ol>s that are in the <li> but before mapped position.\n\t\t\t// Get model length of those elements and then add it to the offset of `listItem` mapped to the original <li>.\n\t\t\tlet modelLength = 1; // Starts from 1 because the original <li> has to be counted in too.\n\t\t\tlet viewList = viewPos.nodeBefore;\n\n\t\t\twhile ( viewList && isList( viewList ) ) {\n\t\t\t\tmodelLength += mapper.getModelLength( viewList );\n\n\t\t\t\tviewList = viewList.previousSibling;\n\t\t\t}\n\n\t\t\tdata.modelPosition = model.createPositionBefore( modelNode ).getShiftedBy( modelLength );\n\n\t\t\tevt.stop();\n\t\t}\n\t};\n}\n\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states.\n *\n * In the example below, there is a correct list structure.\n * Then the middle element is removed so the list structure will become incorrect:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>Item 2</listItem> <--- this is removed.\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n *\n * The list structure after the middle element is removed:\n *\n * \t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n *\n * Should become:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>Item 3</listItem> <--- note that indent got post-fixed.\n *\n * @param {module:engine/model/model~Model} model The data model.\n * @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n * @returns {Boolean} `true` if any change has been applied, `false` otherwise.\n */\nexport function modelChangePostFixer( model, writer ) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map();\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'insert' && entry.name != 'listItem' ) {\n\t\t\tif ( entry.name != '$text' ) {\n\t\t\t\t// In case of renamed element.\n\t\t\t\tconst item = entry.position.nodeAfter;\n\n\t\t\t\tif ( item.hasAttribute( 'listIndent' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listIndent', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listType' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listType', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listStyle' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listStyle', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listReversed' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listReversed', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listStart' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listStart', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tfor ( const innerItem of Array.from( model.createRangeIn( item ) ).filter( e => e.item.is( 'element', 'listItem' ) ) ) {\n\t\t\t\t\t_addListToFix( innerItem.previousPosition );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst posAfter = entry.position.getShiftedBy( entry.length );\n\n\t\t\t_addListToFix( posAfter );\n\t\t} else if ( entry.type == 'remove' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listIndent' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listType' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t}\n\t}\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\t_fixListIndents( listHead );\n\t\t_fixListTypes( listHead );\n\t}\n\n\treturn applied;\n\n\tfunction _addListToFix( position ) {\n\t\tconst previousNode = position.nodeBefore;\n\n\t\tif ( !previousNode || !previousNode.is( 'element', 'listItem' ) ) {\n\t\t\tconst item = position.nodeAfter;\n\n\t\t\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\t\titemToListHead.set( item, item );\n\t\t\t}\n\t\t} else {\n\t\t\tlet listHead = previousNode;\n\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (\n\t\t\t\t// Cache previousSibling and reuse for performance reasons. See #6581.\n\t\t\t\tlet previousSibling = listHead.previousSibling;\n\t\t\t\tpreviousSibling && previousSibling.is( 'element', 'listItem' );\n\t\t\t\tpreviousSibling = listHead.previousSibling\n\t\t\t) {\n\t\t\t\tlistHead = previousSibling;\n\n\t\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titemToListHead.set( previousNode, listHead );\n\t\t}\n\t}\n\n\tfunction _fixListIndents( item ) {\n\t\tlet maxIndent = 0;\n\t\tlet fixBy = null;\n\n\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\t\tif ( itemIndent > maxIndent ) {\n\t\t\t\tlet newIndent;\n\n\t\t\t\tif ( fixBy === null ) {\n\t\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\t\tnewIndent = maxIndent;\n\t\t\t\t} else {\n\t\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t\t}\n\n\t\t\t\twriter.setAttribute( 'listIndent', newIndent, item );\n\n\t\t\t\tapplied = true;\n\t\t\t} else {\n\t\t\t\tfixBy = null;\n\t\t\t\tmaxIndent = item.getAttribute( 'listIndent' ) + 1;\n\t\t\t}\n\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n\n\tfunction _fixListTypes( item ) {\n\t\tlet typesStack = [];\n\t\tlet prev = null;\n\n\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\t\tif ( prev && prev.getAttribute( 'listIndent' ) > itemIndent ) {\n\t\t\t\ttypesStack = typesStack.slice( 0, itemIndent + 1 );\n\t\t\t}\n\n\t\t\tif ( itemIndent != 0 ) {\n\t\t\t\tif ( typesStack[ itemIndent ] ) {\n\t\t\t\t\tconst type = typesStack[ itemIndent ];\n\n\t\t\t\t\tif ( item.getAttribute( 'listType' ) != type ) {\n\t\t\t\t\t\twriter.setAttribute( 'listType', type, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttypesStack[ itemIndent ] = item.getAttribute( 'listType' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprev = item;\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n}\n\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>A</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>B^</listItem>\n *\t\t// At ^ paste: <listItem listType=\"bulleted\" listIndent=4>X</listItem>\n *\t\t// <listItem listType=\"bulleted\" listIndent=5>Y</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>C</listItem>\n *\n * Should become:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>A</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>BX</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Y/listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>C</listItem>\n *\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Array} args Arguments of {@link module:engine/model/model~Model#insertContent}.\n */\nexport function modelIndentPasteFixer( evt, [ content, selectable ] ) {\n\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t// that list will be broken.\n\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t// would create incorrect model.\n\tlet item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\tlet selection;\n\n\tif ( !selectable ) {\n\t\tselection = this.document.selection;\n\t} else {\n\t\tselection = this.createSelection( selectable );\n\t}\n\n\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\n\t\tif ( pos.parent.is( 'element', 'listItem' ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( pos.nodeBefore && pos.nodeBefore.is( 'element', 'listItem' ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( refItem ) {\n\t\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t\t// Indent of all those items has to be adjusted to reference item.\n\t\t\tconst indentChange = refItem.getAttribute( 'listIndent' );\n\n\t\t\t// Fix only if there is anything to fix.\n\t\t\tif ( indentChange > 0 ) {\n\t\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\t\t\titem._setAttribute( 'listIndent', item.getAttribute( 'listIndent' ) + indentChange );\n\n\t\t\t\t\titem = item.nextSibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Helper function that converts children of a given `<li>` view element into corresponding model elements.\n// The function maintains proper order of elements if model `listItem` is split during the conversion\n// due to block children conversion.\n//\n// @param {module:engine/model/element~Element} listItemModel List item model element to which converted children will be inserted.\n// @param {Iterable.<module:engine/view/node~Node>} viewChildren View elements which will be converted.\n// @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n// @returns {module:engine/model/position~Position} Position on which next elements should be inserted after children conversion.\nfunction viewToModelListItemChildrenConverter( listItemModel, viewChildren, conversionApi ) {\n\tconst { writer, schema } = conversionApi;\n\n\t// A position after the last inserted `listItem`.\n\tlet nextPosition = writer.createPositionAfter( listItemModel );\n\n\t// Check all children of the converted `<li>`. At this point we assume there are no \"whitespace\" view text nodes\n\t// in view list, between view list items. This should be handled by `<ul>` and `<ol>` converters.\n\tfor ( const child of viewChildren ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\t// If the children is a list, we will insert its conversion result after currently handled `listItem`.\n\t\t\t// Then, next insertion position will be set after all the new list items (and maybe other elements if\n\t\t\t// something split list item).\n\t\t\t//\n\t\t\t// If this is a list, we expect that some `listItem`s and possibly other blocks will be inserted, however `.modelCursor`\n\t\t\t// should be set after last `listItem` (or block). This is why it feels safe to use it as `nextPosition`\n\t\t\tnextPosition = conversionApi.convertItem( child, nextPosition ).modelCursor;\n\t\t} else {\n\t\t\t// If this is not a list, try inserting content at the end of the currently handled `listItem`.\n\t\t\tconst result = conversionApi.convertItem( child, writer.createPositionAt( listItemModel, 'end' ) );\n\n\t\t\t// It may end up that the current `listItem` becomes split (if that content cannot be inside `listItem`). For example:\n\t\t\t//\n\t\t\t// <li><p>Foo</p></li>\n\t\t\t//\n\t\t\t// will be converted to:\n\t\t\t//\n\t\t\t// <listItem></listItem><paragraph>Foo</paragraph><listItem></listItem>\n\t\t\t//\n\t\t\tconst convertedChild = result.modelRange.start.nodeAfter;\n\t\t\tconst wasSplit = convertedChild && convertedChild.is( 'element' ) && !schema.checkChild( listItemModel, convertedChild.name );\n\n\t\t\tif ( wasSplit ) {\n\t\t\t\t// As `lastListItem` got split, we need to update it to the second part of the split `listItem` element.\n\t\t\t\t//\n\t\t\t\t// `modelCursor` should be set to a position where the conversion should continue. There are multiple possible scenarios\n\t\t\t\t// that may happen. Usually, `modelCursor` (marked as `#` below) would point to the second list item after conversion:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><p>Foo</p></li>` -> `<listItem></listItem><paragraph>Foo</paragraph><listItem>#</listItem>`\n\t\t\t\t//\n\t\t\t\t// However, in some cases, like auto-paragraphing, the position is placed at the end of the block element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div>Foo</div></li>` -> `<listItem></listItem><paragraph>Foo#</paragraph><listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// or after an element if another element broken auto-paragraphed element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div><h2>Foo</h2></div></li>` -> `<listItem></listItem><heading1>Foo</heading1>#<listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// We need to check for such cases and use proper list item and position based on it.\n\t\t\t\t//\n\t\t\t\tif ( result.modelCursor.parent.is( 'element', 'listItem' ) ) {\n\t\t\t\t\t// (1).\n\t\t\t\t\tlistItemModel = result.modelCursor.parent;\n\t\t\t\t} else {\n\t\t\t\t\t// (2), (3).\n\t\t\t\t\tlistItemModel = findNextListItem( result.modelCursor );\n\t\t\t\t}\n\n\t\t\t\tnextPosition = writer.createPositionAfter( listItemModel );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nextPosition;\n}\n\n// Helper function that seeks for a next list item starting from given `startPosition`.\nfunction findNextListItem( startPosition ) {\n\tconst treeWalker = new TreeWalker( { startPosition } );\n\n\tlet value;\n\n\tdo {\n\t\tvalue = treeWalker.next();\n\t} while ( !value.value.item.is( 'element', 'listItem' ) );\n\n\treturn value.value.item;\n}\n\n// Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n// to other given parameters.\nfunction hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, conversionApi, model ) {\n\t// Find correct previous model list item element.\n\t// The element has to have either same or smaller indent than given reference indent.\n\t// This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).\n\t// Keep in mind that such element might not be found, if removed item was the first item.\n\tconst prevModelItem = getSiblingListItem( modelRemoveStartPosition.nodeBefore, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: nextIndent,\n\t\tfoo: 'b'\n\t} );\n\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Indent of found element or `null` if the element has not been found.\n\tconst prevIndent = prevModelItem ? prevModelItem.getAttribute( 'listIndent' ) : null;\n\n\tlet insertPosition;\n\n\tif ( !prevModelItem ) {\n\t\t// If element has not been found, simply insert lists at the position where the removed item was:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1 -------- <--- this is removed, no previous list item, put nested items in place of removed item.\n\t\t// 1.1 -------- <--- this is reference indent.\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\tinsertPosition = viewRemoveStartPosition;\n\t} else if ( prevIndent == nextIndent ) {\n\t\t// If element has been found and has same indent as reference indent it means that nested items should\n\t\t// become siblings of found element:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 -------- <--- this is `prevModelItem`.\n\t\t// 2 -------- <--- this is removed, previous list item has indent same as reference indent.\n\t\t// 2.1 -------- <--- this is reference indent, this and 2.2 should become siblings of 1.2.\n\t\t// 2.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 --------\n\t\t// 2.1 --------\n\t\t// 2.2 --------\n\t\tconst prevViewList = mapper.toViewElement( prevModelItem ).parent;\n\t\tinsertPosition = viewWriter.createPositionAfter( prevViewList );\n\t} else {\n\t\t// If element has been found and has smaller indent as reference indent it means that nested items\n\t\t// should become nested items of found item:\n\t\t//\n\t\t// 1 -------- <--- this is `prevModelItem`.\n\t\t// 1.1 -------- <--- this is removed, previous list item has indent smaller than reference indent.\n\t\t// 1.1.1 -------- <--- this is reference indent, this and 1.1.1 should become nested items of 1.\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Note: in this case 1.1.1 have indent 2 while 1 have indent 0. In model that should not be possible,\n\t\t// because following item may have indent bigger only by one. But this is fixed by postfixer.\n\t\tconst modelPosition = model.createPositionAt( prevModelItem, 'end' );\n\t\tinsertPosition = mapper.toViewPosition( modelPosition );\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Handle multiple lists. This happens if list item has nested numbered and bulleted lists. Following lists\n\t// are inserted after the first list (no need to recalculate insertion position for them).\n\tfor ( const child of [ ...viewRemovedItem.getChildren() ] ) {\n\t\tif ( isList( child ) ) {\n\t\t\tinsertPosition = viewWriter.move( viewWriter.createRangeOn( child ), insertPosition ).end;\n\n\t\t\tmergeViewLists( viewWriter, child, child.nextSibling );\n\t\t\tmergeViewLists( viewWriter, child.previousSibling, child );\n\t\t}\n\t}\n}\n\n// Checks if view element is a list type (ul or ol).\n//\n// @param {module:engine/view/element~Element} viewElement\n// @returns {Boolean}\nfunction isList( viewElement ) {\n\treturn viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );\n}\n\n// Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n//\n// Also, fixes non HTML compliant lists indents:\n//\n//\t\tbefore: fixed list:\n//\t\tOL OL\n//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n//\t\t |-> OL |-> OL\n//\t\t |-> OL |\n//\t\t | |-> OL |\n//\t\t | |-> OL |\n//\t\t | |-> LI (parent LIs: 1) |-> LI (indent: 1)\n//\t\t |-> LI (parent LIs: 1) |-> LI (indent: 1)\n//\n//\t\tbefore: fixed list:\n//\t\tOL OL\n//\t\t|-> OL |\n//\t\t |-> OL |\n//\t\t |-> OL |\n//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 0)\n//\n//\t\tbefore: fixed list:\n//\t\tOL OL\n//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n//\t\t|-> OL |-> OL\n//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n//\n// @param {module:engine/view/element~Element} listItem\n// @param {Object} conversionStore\n// @returns {Number}\nfunction getIndent( listItem ) {\n\tlet indent = 0;\n\n\tlet parent = listItem.parent;\n\n\twhile ( parent ) {\n\t\t// Each LI in the tree will result in an increased indent for HTML compliant lists.\n\t\tif ( parent.is( 'element', 'li' ) ) {\n\t\t\tindent++;\n\t\t} else {\n\t\t\t// If however the list is nested in other list we should check previous sibling of any of the list elements...\n\t\t\tconst previousSibling = parent.previousSibling;\n\n\t\t\t// ...because the we might need increase its indent:\n\t\t\t//\t\tbefore: fixed list:\n\t\t\t//\t\tOL OL\n\t\t\t//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n\t\t\t//\t\t|-> OL |-> OL\n\t\t\t//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n\t\t\tif ( previousSibling && previousSibling.is( 'element', 'li' ) ) {\n\t\t\t\tindent++;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn indent;\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 list/list/indentcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\n\n/**\n * The list indent command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class IndentCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'forward'|'backward'} indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor, indentDirection ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Determines by how much the command will change the list item's indent attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {Number}\n\t\t */\n\t\tthis._indentBy = indentDirection == 'forward' ? 1 : -1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t * @fires _executeCleanup\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tlet itemsToChange = Array.from( doc.selection.getSelectedBlocks() );\n\n\t\tmodel.change( writer => {\n\t\t\tconst lastItem = itemsToChange[ itemsToChange.length - 1 ];\n\n\t\t\t// Indenting a list item should also indent all the items that are already sub-items of indented item.\n\t\t\tlet next = lastItem.nextSibling;\n\n\t\t\t// Check all items after last indented item, as long as their indent is bigger than indent of that item.\n\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) > lastItem.getAttribute( 'listIndent' ) ) {\n\t\t\t\titemsToChange.push( next );\n\n\t\t\t\tnext = next.nextSibling;\n\t\t\t}\n\n\t\t\t// We need to be sure to keep model in correct state after each small change, because converters\n\t\t\t// bases on that state and assumes that model is correct.\n\t\t\t// Because of that, if the command outdents items, we will outdent them starting from the last item, as\n\t\t\t// it is safer.\n\t\t\tif ( this._indentBy < 0 ) {\n\t\t\t\titemsToChange = itemsToChange.reverse();\n\t\t\t}\n\n\t\t\tfor ( const item of itemsToChange ) {\n\t\t\t\tconst indent = item.getAttribute( 'listIndent' ) + this._indentBy;\n\n\t\t\t\t// If indent is lower than 0, it means that the item got outdented when it was not indented.\n\t\t\t\t// This means that we need to convert that list item to paragraph.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\t// To keep the model as correct as possible, first rename listItem, then remove attributes,\n\t\t\t\t\t// as listItem without attributes is very incorrect and will cause problems in converters.\n\t\t\t\t\t// No need to remove attributes, will be removed by post fixer.\n\t\t\t\t\twriter.rename( item, 'paragraph' );\n\t\t\t\t}\n\t\t\t\t// If indent is >= 0, change the attribute value.\n\t\t\t\telse {\n\t\t\t\t\twriter.setAttribute( 'listIndent', indent, item );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired by the {@link #execute} method.\n\t\t\t *\n\t\t\t * It allows to execute an action after executing the {@link ~IndentCommand#execute} method, for example adjusting\n\t\t\t * attributes of changed list items.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event _executeCleanup\n\t\t\t */\n\t\t\tthis.fire( '_executeCleanup', itemsToChange );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !listItem || !listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this._indentBy > 0 ) {\n\t\t\t// Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.\n\t\t\t// To be in the same list, the item has to have same attributes and cannot be \"split\" by an item with lower indent.\n\t\t\tconst indent = listItem.getAttribute( 'listIndent' );\n\t\t\tconst type = listItem.getAttribute( 'listType' );\n\n\t\t\tlet prev = listItem.previousSibling;\n\n\t\t\twhile ( prev && prev.is( 'element', 'listItem' ) && prev.getAttribute( 'listIndent' ) >= indent ) {\n\t\t\t\tif ( prev.getAttribute( 'listIndent' ) == indent ) {\n\t\t\t\t\t// The item is on the same level.\n\t\t\t\t\t// If it has same type, it means that we found a preceding sibling from the same list.\n\t\t\t\t\t// If it does not have same type, it means that `listItem` is on different list (this can happen only\n\t\t\t\t\t// on top level lists, though).\n\t\t\t\t\treturn prev.getAttribute( 'listType' ) == type;\n\t\t\t\t}\n\n\t\t\t\tprev = prev.previousSibling;\n\t\t\t}\n\n\t\t\t// Could not find similar list item, this means that `listItem` is first in its list.\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\treturn true;\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 list/list/listcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\n\n/**\n * The list command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'numbered'|'bulleted'} type List type that will be handled by this command.\n\t */\n\tconstructor( editor, type ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The type of the list created by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'numbered'|'bulleted'|'todo'}\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false`, it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => checkCanBecomeListItem( block, model.schema ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n\n\t\t// If we are turning off items, we are going to rename them to paragraphs.\n\n\t\tmodel.change( writer => {\n\t\t\t// If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.\n\t\t\t// To be sure that model is all the time in a good state, we first fix items below turned-off item.\n\t\t\tif ( turnOff ) {\n\t\t\t\t// Start from the model item that is just after the last turned-off item.\n\t\t\t\tlet next = blocks[ blocks.length - 1 ].nextSibling;\n\t\t\t\tlet currentIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tlet changes = [];\n\n\t\t\t\t// Correct indent of all items after the last turned off item.\n\t\t\t\t// Rules that should be followed:\n\t\t\t\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t\t\t\t// will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t\t\t\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t\t\t\t// should not end up as a child of any of list items that they were not children of before.\n\t\t\t\t// 3. All other items should have their indent changed relatively to it's parent.\n\t\t\t\t//\n\t\t\t\t// For example:\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t// 3 * --------\t\t\t<-- this is turned off.\n\t\t\t\t// 4 * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t\t\t\t// 5 * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 6 * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t\t\t\t// 7 * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 8 * --------\t\t\t\t<-- this has to become indent = 0.\n\t\t\t\t// 9 * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t\t\t\t// 10 * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t\t\t\t// 11 * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t\t\t\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// After turning off 3 the list becomes:\n\t\t\t\t//\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t//\n\t\t\t\t// 3 --------\n\t\t\t\t//\n\t\t\t\t// 4 * --------\n\t\t\t\t// 5 * --------\n\t\t\t\t// 6 * --------\n\t\t\t\t// 7 * --------\n\t\t\t\t// 8 * --------\n\t\t\t\t// 9 * --------\n\t\t\t\t// 10 * --------\n\t\t\t\t// 11 * --------\n\t\t\t\t// 12 * --------\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t\t\t\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t\t\t\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t\t\t\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t\t\t\t// less conversion (faster).\n\t\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) !== 0 ) {\n\t\t\t\t\t// Check each next list item, as long as its indent is bigger than 0.\n\t\t\t\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\t\t\t\tconst indent = next.getAttribute( 'listIndent' );\n\n\t\t\t\t\t// We check if that's item indent is lower as current relative indent.\n\t\t\t\t\tif ( indent < currentIndent ) {\n\t\t\t\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\t\t\t\tcurrentIndent = indent;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fix indent relatively to current relative indent.\n\t\t\t\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\t\t\t\tconst newIndent = indent - currentIndent;\n\n\t\t\t\t\t// Save the entry in changes array. We do not apply it at the moment, because we will need to\n\t\t\t\t\t// reverse the changes so the last item is changed first.\n\t\t\t\t\t// This is to keep model in correct state all the time.\n\t\t\t\t\tchanges.push( { element: next, listIndent: newIndent } );\n\n\t\t\t\t\t// Find next item.\n\t\t\t\t\tnext = next.nextSibling;\n\t\t\t\t}\n\n\t\t\t\tchanges = changes.reverse();\n\n\t\t\t\tfor ( const item of changes ) {\n\t\t\t\t\twriter.setAttribute( 'listIndent', item.listIndent, item.element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are turning on, we might change some items that are already `listItem`s but with different type.\n\t\t\t// Changing one nested list item to other type should also trigger changing all its siblings so the\n\t\t\t// whole nested list is of the same type.\n\t\t\t// Example (assume changing to numbered list):\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ---[--\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t\t<-- already in selection, but does not cause other list items to change because is top-level\n\t\t\t// * ---]--\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- fix, because preceding list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\tif ( !turnOff ) {\n\t\t\t\t// Find lowest indent among selected items. This will be indicator what is the indent of\n\t\t\t\t// top-most list affected by the command.\n\t\t\t\tlet lowestIndent = Number.POSITIVE_INFINITY;\n\n\t\t\t\tfor ( const item of blocks ) {\n\t\t\t\t\tif ( item.is( 'element', 'listItem' ) && item.getAttribute( 'listIndent' ) < lowestIndent ) {\n\t\t\t\t\t\tlowestIndent = item.getAttribute( 'listIndent' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Do not execute the fix for top-level lists.\n\t\t\t\tlowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n\n\t\t\t\t// Fix types of list items that are \"before\" the selected blocks.\n\t\t\t\t_fixType( blocks, true, lowestIndent );\n\n\t\t\t\t// Fix types of list items that are \"after\" the selected blocks.\n\t\t\t\t_fixType( blocks, false, lowestIndent );\n\t\t\t}\n\n\t\t\t// Phew! Now it will be easier :).\n\t\t\t// For each block element that was in the selection, we will either: turn it to list item,\n\t\t\t// turn it to paragraph, or change it's type. Or leave it as it is.\n\t\t\t// Do it in reverse as there might be multiple blocks (same as with changing indents).\n\t\t\tfor ( const element of blocks.reverse() ) {\n\t\t\t\tif ( turnOff && element.name == 'listItem' ) {\n\t\t\t\t\t// We are turning off and the element is a `listItem` - it should be converted to `paragraph`.\n\t\t\t\t\t// List item specific attributes are removed by post fixer.\n\t\t\t\t\twriter.rename( element, 'paragraph' );\n\t\t\t\t} else if ( !turnOff && element.name != 'listItem' ) {\n\t\t\t\t\t// We are turning on and the element is not a `listItem` - it should be converted to `listItem`.\n\t\t\t\t\t// The order of operations is important to keep model in correct state.\n\t\t\t\t\twriter.setAttributes( { listType: this.type, listIndent: 0 }, element );\n\t\t\t\t\twriter.rename( element, 'listItem' );\n\t\t\t\t} else if ( !turnOff && element.name == 'listItem' && element.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t// We are turning on and the element is a `listItem` but has different type - change it's type and\n\t\t\t\t\t// type of it's all siblings that have same indent.\n\t\t\t\t\twriter.setAttribute( 'listType', this.type, element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired by the {@link #execute} method.\n\t\t\t *\n\t\t\t * It allows to execute an action after executing the {@link ~ListCommand#execute} method, for example adjusting\n\t\t\t * attributes of changed blocks.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event _executeCleanup\n\t\t\t */\n\t\t\tthis.fire( '_executeCleanup', blocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\t// Check whether closest `listItem` ancestor of the position has a correct type.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\treturn !!listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == this.type;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Otherwise, check if list item can be inserted at the position start.\n\t\treturn checkCanBecomeListItem( firstBlock, schema );\n\t}\n}\n\n// Helper function used when one or more list item have their type changed. Fixes type of other list items\n// that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n// not to duplicated code, as same fix has to be performed before and after selection.\n//\n// @param {Array.<module:engine/model/node~Node>} blocks Blocks that are in selection.\n// @param {Boolean} isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n// or blocks after last selected block (`false`).\n// @param {Number} lowestIndent Lowest indent among selected blocks.\nfunction _fixType( blocks, isBackward, lowestIndent ) {\n\t// We need to check previous sibling of first changed item and next siblings of last changed item.\n\tconst startingItem = isBackward ? blocks[ 0 ] : blocks[ blocks.length - 1 ];\n\n\tif ( startingItem.is( 'element', 'listItem' ) ) {\n\t\tlet item = startingItem[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t// During processing items, keeps the lowest indent of already processed items.\n\t\t// This saves us from changing too many items.\n\t\t// Following example is for going forward as it is easier to read, however same applies to going backward.\n\t\t// * ------\n\t\t// * ------\n\t\t// * --[---\n\t\t// * ------\t\t<-- `lowestIndent` should be 1\n\t\t// * --]---\t\t<-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1\n\t\t// * ------\t\t<-- should be fixed, `indent` == 2 == `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t<-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t\t<-- break loop (`indent` < `lowestIndent`)\n\t\tlet currentIndent = startingItem.getAttribute( 'listIndent' );\n\n\t\t// Look back until a list item with indent lower than reference `lowestIndent`.\n\t\t// That would be the parent of nested sublist which contains item having `lowestIndent`.\n\t\twhile ( item && item.is( 'element', 'listItem' ) && item.getAttribute( 'listIndent' ) >= lowestIndent ) {\n\t\t\tif ( currentIndent > item.getAttribute( 'listIndent' ) ) {\n\t\t\t\tcurrentIndent = item.getAttribute( 'listIndent' );\n\t\t\t}\n\n\t\t\t// Found an item that is in the same nested sublist.\n\t\t\tif ( item.getAttribute( 'listIndent' ) == currentIndent ) {\n\t\t\t\t// Just add the item to selected blocks like it was selected by the user.\n\t\t\t\tblocks[ isBackward ? 'unshift' : 'push' ]( item );\n\t\t\t}\n\n\t\t\titem = item[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t}\n\t}\n}\n\n// Checks whether the given block can be replaced by a listItem.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeListItem( block, schema ) {\n\treturn schema.checkChild( block.parent, 'listItem' ) && !schema.isObject( block );\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 list/list/listediting\n */\n\nimport ListCommand from './listcommand';\nimport IndentCommand from './indentcommand';\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Enter } from 'ckeditor5/src/enter';\nimport { Delete } from 'ckeditor5/src/typing';\n\nimport {\n\tcleanList,\n\tcleanListItem,\n\tmodelViewInsertion,\n\tmodelViewChangeType,\n\tmodelViewMergeAfterChangeType,\n\tmodelViewMergeAfter,\n\tmodelViewRemove,\n\tmodelViewSplitOnInsert,\n\tmodelViewChangeIndent,\n\tmodelChangePostFixer,\n\tmodelIndentPasteFixer,\n\tviewModelConverter,\n\tmodelToViewPosition,\n\tviewToModelPosition\n} from './converters';\n\n/**\n * The engine of the list feature. It handles creating, editing and removing lists and list items.\n *\n * It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Enter, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Schema.\n\t\t// Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature\n\t\t// uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.\n\t\t// If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.\n\t\teditor.model.schema.register( 'listItem', {\n\t\t\tinheritAllFrom: '$block',\n\t\t\tallowAttributes: [ 'listType', 'listIndent' ]\n\t\t} );\n\n\t\t// Converters.\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\teditor.model.document.registerPostFixer( writer => modelChangePostFixer( editor.model, writer ) );\n\n\t\tediting.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t\tdata.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\n\t\tediting.mapper.on( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\t\tediting.mapper.on( 'viewToModelPosition', viewToModelPosition( editor.model ) );\n\t\tdata.mapper.on( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\t\t\tdispatcher.on( 'attribute:listType:listItem', modelViewChangeType, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'attribute:listType:listItem', modelViewMergeAfterChangeType, { priority: 'low' } );\n\t\t\t\tdispatcher.on( 'attribute:listIndent:listItem', modelViewChangeIndent( editor.model ) );\n\t\t\t\tdispatcher.on( 'remove:listItem', modelViewRemove( editor.model ) );\n\t\t\t\tdispatcher.on( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'element:ul', cleanList, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:ol', cleanList, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:li', cleanListItem, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:li', viewModelConverter );\n\t\t\t} );\n\n\t\t// Fix indentation of pasted items.\n\t\teditor.model.on( 'insertContent', modelIndentPasteFixer, { priority: 'high' } );\n\n\t\t// Register commands for numbered and bulleted list.\n\t\teditor.commands.add( 'numberedList', new ListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new ListCommand( editor, 'bulleted' ) );\n\n\t\t// Register commands for indenting.\n\t\teditor.commands.add( 'indentList', new IndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new IndentCommand( editor, 'backward' ) );\n\n\t\tconst viewDocument = editing.view.document;\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.\n\t\tthis.listenTo( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tconst doc = this.editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\n\t\t\tif ( doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty ) {\n\t\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\n\t\t// Overwrite default Backspace key behavior.\n\t\t// If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\t// Check conditions from those that require less computations like those immediately available.\n\t\t\tif ( data.direction !== 'backward' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = this.editor.model.document.selection;\n\n\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\tif ( positionParent.name !== 'listItem' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst previousIsAListItem = positionParent.previousSibling && positionParent.previousSibling.name === 'listItem';\n\n\t\t\tif ( previousIsAListItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\tdata.preventDefault();\n\t\t\tevt.stop();\n\t\t}, { context: 'li' } );\n\n\t\tthis.listenTo( editor.editing.view.document, 'tab', ( evt, data ) => {\n\t\t\tconst commandName = data.shiftKey ? 'outdentList' : 'indentList';\n\t\t\tconst command = this.editor.commands.get( commandName );\n\n\t\t\tif ( command.isEnabled ) {\n\t\t\t\teditor.execute( commandName );\n\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst commands = this.editor.commands;\n\n\t\tconst indent = commands.get( 'indent' );\n\t\tconst outdent = commands.get( 'outdent' );\n\n\t\tif ( indent ) {\n\t\t\tindent.registerChildCommand( commands.get( 'indentList' ) );\n\t\t}\n\n\t\tif ( outdent ) {\n\t\t\toutdent.registerChildCommand( commands.get( 'outdentList' ) );\n\t\t}\n\t}\n}\n\nfunction getViewListItemLength( element ) {\n\tlet length = 1;\n\n\tfor ( const child of element.getChildren() ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\tfor ( const item of child.getChildren() ) {\n\t\t\t\tlength += getViewListItemLength( item );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 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 list/list/listui\n */\n\nimport { createUIComponent } from './utils';\n\nimport numberedListIcon from '../../theme/icons/numberedlist.svg';\nimport bulletedListIcon from '../../theme/icons/bulletedlist.svg';\n\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The list UI feature. It introduces the `'numberedList'` and `'bulletedList'` buttons that\n * allow to convert paragraphs to and from list items and indent or outdent them.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst t = this.editor.t;\n\n\t\t// Create two buttons and link them with numberedList and bulletedList commands.\n\t\tcreateUIComponent( this.editor, 'numberedList', t( 'Numbered List' ), numberedListIcon );\n\t\tcreateUIComponent( this.editor, 'bulletedList', t( 'Bulleted List' ), bulletedListIcon );\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 list/list/utils\n */\n\nimport { TreeWalker, getFillerOffset } from 'ckeditor5/src/engine';\nimport { ButtonView } from 'ckeditor5/src/ui';\n\n/**\n * Creates a list item {@link module:engine/view/containerelement~ContainerElement}.\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The writer instance.\n * @returns {module:engine/view/containerelement~ContainerElement}\n */\nexport function createViewListItemElement( writer ) {\n\tconst viewItem = writer.createContainerElement( 'li' );\n\n\tviewItem.getFillerOffset = getListItemFillerOffset;\n\n\treturn viewItem;\n}\n\n/**\n * Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of the given `modelItem` model `listItem` element.\n * Then, it binds the created view list item (`<li>`) with the model `listItem` element.\n * The function then returns the created view list item (`<li>`).\n *\n * @param {module:engine/model/item~Item} modelItem Model list item.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface.\n * @returns {module:engine/view/containerelement~ContainerElement} View list element.\n */\nexport function generateLiInUl( modelItem, conversionApi ) {\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tconst listType = modelItem.getAttribute( 'listType' ) == 'numbered' ? 'ol' : 'ul';\n\tconst viewItem = createViewListItemElement( viewWriter );\n\n\tconst viewList = viewWriter.createContainerElement( listType, null );\n\n\tviewWriter.insert( viewWriter.createPositionAt( viewList, 0 ), viewItem );\n\n\tmapper.bindElements( modelItem, viewItem );\n\n\treturn viewItem;\n}\n\n/**\n * Helper function that inserts a view list at a correct place and merges it with its siblings.\n * It takes a model list item element (`modelItem`) and a corresponding view list item element (`injectedItem`). The view list item\n * should be in a view list element (`<ul>` or `<ol>`) and should be its only child.\n * See comments below to better understand the algorithm.\n *\n * @param {module:engine/view/item~Item} modelItem Model list item.\n * @param {module:engine/view/containerelement~ContainerElement} injectedItem\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface.\n * @param {module:engine/model/model~Model} model The model instance.\n */\nexport function injectViewList( modelItem, injectedItem, conversionApi, model ) {\n\tconst injectedList = injectedItem.parent;\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// The position where the view list will be inserted.\n\tlet insertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\n\t// 1. Find the previous list item that has the same or smaller indent. Basically we are looking for the first model item\n\t// that is a \"parent\" or \"sibling\" of the injected model item.\n\t// If there is no such list item, it means that the injected list item is the first item in \"its list\".\n\tconst refItem = getSiblingListItem( modelItem.previousSibling, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: modelItem.getAttribute( 'listIndent' )\n\t} );\n\tconst prevItem = modelItem.previousSibling;\n\n\tif ( refItem && refItem.getAttribute( 'listIndent' ) == modelItem.getAttribute( 'listIndent' ) ) {\n\t\t// There is a list item with the same indent - we found the same-level sibling.\n\t\t// Break the list after it. The inserted view item will be added in the broken space.\n\t\tconst viewItem = mapper.toViewElement( refItem );\n\t\tinsertPosition = viewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\t} else {\n\t\t// There is no list item with the same indent. Check the previous model item.\n\t\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\t\t// If it is a list item, it has to have a lower indent.\n\t\t\t// It means that the inserted item should be added to it as its nested item.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionAt( prevItem, 'end' ) );\n\n\t\t\t// There could be some not mapped elements (eg. span in to-do list) but we need to insert\n\t\t\t// a nested list directly inside the li element.\n\t\t\tconst mappedViewAncestor = mapper.findMappedViewAncestor( insertPosition );\n\t\t\tconst nestedList = findNestedList( mappedViewAncestor );\n\n\t\t\t// If there already is some nested list, then use it's position.\n\t\t\tif ( nestedList ) {\n\t\t\t\tinsertPosition = viewWriter.createPositionBefore( nestedList );\n\t\t\t} else {\n\t\t\t\t// Else just put new list on the end of list item content.\n\t\t\t\tinsertPosition = viewWriter.createPositionAt( mappedViewAncestor, 'end' );\n\t\t\t}\n\t\t} else {\n\t\t\t// The previous item is not a list item (or does not exist at all).\n\t\t\t// Just map the position and insert the view item at the mapped position.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\t\t}\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Insert the view item.\n\tviewWriter.insert( insertPosition, injectedList );\n\n\t// 2. Handle possible children of the injected model item.\n\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\tconst prevView = mapper.toViewElement( prevItem );\n\n\t\tconst walkerBoundaries = viewWriter.createRange( viewWriter.createPositionAt( prevView, 0 ), insertPosition );\n\t\tconst walker = walkerBoundaries.getWalker( { ignoreElementEnd: true } );\n\n\t\tfor ( const value of walker ) {\n\t\t\tif ( value.item.is( 'element', 'li' ) ) {\n\t\t\t\tconst breakPosition = viewWriter.breakContainer( viewWriter.createPositionBefore( value.item ) );\n\t\t\t\tconst viewList = value.item.parent;\n\n\t\t\t\tconst targetPosition = viewWriter.createPositionAt( injectedItem, 'end' );\n\t\t\t\tmergeViewLists( viewWriter, targetPosition.nodeBefore, targetPosition.nodeAfter );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( viewList ), targetPosition );\n\n\t\t\t\twalker.position = breakPosition;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst nextViewList = injectedList.nextSibling;\n\n\t\tif ( nextViewList && ( nextViewList.is( 'element', 'ul' ) || nextViewList.is( 'element', 'ol' ) ) ) {\n\t\t\tlet lastSubChild = null;\n\n\t\t\tfor ( const child of nextViewList.getChildren() ) {\n\t\t\t\tconst modelChild = mapper.toModelElement( child );\n\n\t\t\t\tif ( modelChild && modelChild.getAttribute( 'listIndent' ) > modelItem.getAttribute( 'listIndent' ) ) {\n\t\t\t\t\tlastSubChild = child;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( lastSubChild ) {\n\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( lastSubChild ) );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( lastSubChild.parent ), viewWriter.createPositionAt( injectedItem, 'end' ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge the inserted view list with its possible neighbor lists.\n\tmergeViewLists( viewWriter, injectedList, injectedList.nextSibling );\n\tmergeViewLists( viewWriter, injectedList.previousSibling, injectedList );\n}\n\n/**\n * Helper function that takes two parameters that are expected to be view list elements, and merges them.\n * The merge happens only if both parameters are list elements of the same type (the same element name and the same class attributes).\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter The writer instance.\n * @param {module:engine/view/item~Item} firstList The first element to compare.\n * @param {module:engine/view/item~Item} secondList The second element to compare.\n * @returns {module:engine/view/position~Position|null} The position after merge or `null` when there was no merge.\n */\nexport function mergeViewLists( viewWriter, firstList, secondList ) {\n\t// Check if two lists are going to be merged.\n\tif ( !firstList || !secondList || ( firstList.name != 'ul' && firstList.name != 'ol' ) ) {\n\t\treturn null;\n\t}\n\n\t// Both parameters are list elements, so compare types now.\n\tif ( firstList.name != secondList.name || firstList.getAttribute( 'class' ) !== secondList.getAttribute( 'class' ) ) {\n\t\treturn null;\n\t}\n\n\treturn viewWriter.mergeContainers( viewWriter.createPositionAfter( firstList ) );\n}\n\n/**\n * Helper function that for a given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n * are after the given position.\n *\n * For example:\n * `<container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</container:p>`\n * For position ^, the position before \"bar\" will be returned.\n *\n * @param {module:engine/view/position~Position} viewPosition\n * @returns {module:engine/view/position~Position}\n */\nexport function positionAfterUiElements( viewPosition ) {\n\treturn viewPosition.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n}\n\n/**\n * Helper function that searches for a previous list item sibling of a given model item that meets the given criteria\n * passed by the options object.\n *\n * @param {module:engine/model/item~Item} modelItem\n * @param {Object} options Search criteria.\n * @param {Boolean} [options.sameIndent=false] Whether the sought sibling should have the same indentation.\n * @param {Boolean} [options.smallerIndent=false] Whether the sought sibling should have a smaller indentation.\n * @param {Number} [options.listIndent] The reference indentation.\n * @param {'forward'|'backward'} [options.direction='backward'] Walking direction.\n * @returns {module:engine/model/item~Item|null}\n */\nexport function getSiblingListItem( modelItem, options ) {\n\tconst sameIndent = !!options.sameIndent;\n\tconst smallerIndent = !!options.smallerIndent;\n\tconst indent = options.listIndent;\n\n\tlet item = modelItem;\n\n\twhile ( item && item.name == 'listItem' ) {\n\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\tif ( ( sameIndent && indent == itemIndent ) || ( smallerIndent && indent > itemIndent ) ) {\n\t\t\treturn item;\n\t\t}\n\n\t\tif ( options.direction === 'forward' ) {\n\t\t\titem = item.nextSibling;\n\t\t} else {\n\t\t\titem = item.previousSibling;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Helper method for creating a UI button and linking it with an appropriate command.\n *\n * @private\n * @param {module:core/editor/editor~Editor} editor The editor instance to which the UI component will be added.\n * @param {String} commandName The name of the command.\n * @param {String} label The button label.\n * @param {String} icon The source of the icon.\n */\nexport function createUIComponent( editor, commandName, label, icon ) {\n\teditor.ui.componentFactory.add( commandName, locale => {\n\t\tconst command = editor.commands.get( commandName );\n\t\tconst buttonView = new ButtonView( locale );\n\n\t\tbuttonView.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\t// Bind button model to command.\n\t\tbuttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\n\t\t// Execute command.\n\t\tbuttonView.on( 'execute', () => {\n\t\t\teditor.execute( commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn buttonView;\n\t} );\n}\n\n/**\n * Returns a first list view element that is direct child of the given view element.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @return {module:engine/view/element~Element|null}\n */\nexport function findNestedList( viewElement ) {\n\tfor ( const node of viewElement.getChildren() ) {\n\t\tif ( node.name == 'ul' || node.name == 'ol' ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns an array with all `listItem` elements that represent the same list.\n *\n * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n *\n * Additionally, if the `position` is inside a list item, that list item will be returned as well.\n *\n * @param {module:engine/model/position~Position} position Starting position.\n * @param {'forward'|'backward'} direction Walking direction.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getSiblingNodes( position, direction ) {\n\tconst items = [];\n\tconst listItem = position.parent;\n\tconst walkerOptions = {\n\t\tignoreElementEnd: false,\n\t\tstartPosition: position,\n\t\tshallow: true,\n\t\tdirection\n\t};\n\tconst limitIndent = listItem.getAttribute( 'listIndent' );\n\tconst nodes = [ ...new TreeWalker( walkerOptions ) ]\n\t\t.filter( value => value.item.is( 'element' ) )\n\t\t.map( value => value.item );\n\n\tfor ( const element of nodes ) {\n\t\t// If found something else than `listItem`, we're out of the list scope.\n\t\tif ( !element.is( 'element', 'listItem' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// If current parsed item has lower indent that element that the element that was a starting point,\n\t\t// it means we left a nested list. Abort searching items.\n\t\t//\n\t\t// ■ List item 1. [listIndent=0]\n\t\t// ○ List item 2.[] [listIndent=1], limitIndent = 1,\n\t\t// ○ List item 3. [listIndent=1]\n\t\t// ■ List item 4. [listIndent=0]\n\t\t//\n\t\t// Abort searching when leave nested list.\n\t\tif ( element.getAttribute( 'listIndent' ) < limitIndent ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ■ List item 1.[] [listIndent=0] limitIndent = 0,\n\t\t// ○ List item 2. [listIndent=1]\n\t\t// ○ List item 3. [listIndent=1]\n\t\t// ■ List item 4. [listIndent=0]\n\t\t//\n\t\t// Ignore nested lists.\n\t\tif ( element.getAttribute( 'listIndent' ) > limitIndent ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// ■ List item 1.[] [listType=bulleted]\n\t\t// 1. List item 2. [listType=numbered]\n\t\t// 2.List item 3. [listType=numbered]\n\t\t//\n\t\t// Abort searching when found a different kind of a list.\n\t\tif ( element.getAttribute( 'listType' ) !== listItem.getAttribute( 'listType' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ■ List item 1.[] [listType=bulleted]\n\t\t// ■ List item 2. [listType=bulleted]\n\t\t// ○ List item 3. [listType=bulleted]\n\t\t// ○ List item 4. [listType=bulleted]\n\t\t//\n\t\t// Abort searching when found a different list style,\n\t\tif ( element.getAttribute( 'listStyle' ) !== listItem.getAttribute( 'listStyle' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ... different direction\n\t\tif ( element.getAttribute( 'listReversed' ) !== listItem.getAttribute( 'listReversed' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ... and different start index\n\t\tif ( element.getAttribute( 'listStart' ) !== listItem.getAttribute( 'listStart' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif ( direction === 'backward' ) {\n\t\t\titems.unshift( element );\n\t\t} else {\n\t\t\titems.push( element );\n\t\t}\n\t}\n\n\treturn items;\n}\n\n/**\n * Returns an array with all `listItem` elements in the model selection.\n *\n * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n * If no list is selected, it returns an empty array.\n * The order of the elements is not specified.\n *\n * @protected\n * @param {module:engine/model/model~Model} model\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getSelectedListItems( model ) {\n\tconst document = model.document;\n\n\t// For all selected blocks find all list items that are being selected\n\t// and update the `listStyle` attribute in those lists.\n\tlet listItems = [ ...document.selection.getSelectedBlocks() ]\n\t\t.filter( element => element.is( 'element', 'listItem' ) )\n\t\t.map( element => {\n\t\t\tconst position = model.change( writer => writer.createPositionAt( element, 0 ) );\n\n\t\t\treturn [\n\t\t\t\t...getSiblingNodes( position, 'backward' ),\n\t\t\t\t...getSiblingNodes( position, 'forward' )\n\t\t\t];\n\t\t} )\n\t\t.flat();\n\n\t// Since `getSelectedBlocks()` can return items that belong to the same list, and\n\t// `getSiblingNodes()` returns the entire list, we need to remove duplicated items.\n\tlistItems = [ ...new Set( listItems ) ];\n\n\treturn listItems;\n}\n\nconst BULLETED_LIST_STYLE_TYPES = [ 'disc', 'circle', 'square' ];\n\n// There's a lot of them (https://www.w3.org/TR/css-counter-styles-3/#typedef-counter-style).\n// Let's support only those that can be selected by ListPropertiesUI.\nconst NUMBERED_LIST_STYLE_TYPES = [\n\t'decimal',\n\t'decimal-leading-zero',\n\t'lower-roman',\n\t'upper-roman',\n\t'lower-latin',\n\t'upper-latin'\n];\n\n/**\n * Checks whether the given list-style-type is supported by numbered or bulleted list.\n *\n * @param {String} listStyleType\n * @returns {'bulleted'|'numbered'|null}\n */\nexport function getListTypeFromListStyleType( listStyleType ) {\n\tif ( BULLETED_LIST_STYLE_TYPES.includes( listStyleType ) ) {\n\t\treturn 'bulleted';\n\t}\n\n\tif ( NUMBERED_LIST_STYLE_TYPES.includes( listStyleType ) ) {\n\t\treturn 'numbered';\n\t}\n\n\treturn null;\n}\n\n// Implementation of getFillerOffset for view list item element.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getListItemFillerOffset() {\n\tconst hasOnlyLists = !this.isEmpty && ( this.getChild( 0 ).name == 'ul' || this.getChild( 0 ).name == 'ol' );\n\n\tif ( this.isEmpty || hasOnlyLists ) {\n\t\treturn 0;\n\t}\n\n\treturn getFillerOffset.call( this );\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 list/listproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ListPropertiesEditing from './listproperties/listpropertiesediting';\nimport ListPropertiesUI from './listproperties/listpropertiesui';\n\n/**\n * The list properties feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/listproperties/listpropertiesediting~ListPropertiesEditing list properties\n * editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListPropertiesEditing, ListPropertiesUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListProperties';\n\t}\n}\n\n/**\n * The configuration of the {@link module:list/listproperties~ListProperties list properties} feature and the\n * {@link module:list/documentlistproperties~DocumentListProperties document list properties} feature.\n *\n * This configuration controls the individual list properties. For instance, it enables or disables specific editor commands\n * operating on lists ({@link module:list/listproperties/liststylecommand~ListStyleCommand `'listStyle'`},\n * {@link module:list/listproperties/liststartcommand~ListStartCommand `'listStart'`},\n * {@link module:list/listproperties/listreversedcommand~ListReversedCommand `'listReversed'`}, or on the document lists\n * {@link module:list/documentlistproperties/documentliststylecommand~DocumentListStyleCommand `'listStyle'`},\n * {@link module:list/documentlistproperties/documentliststartcommand~DocumentListStartCommand `'listStart'`},\n * {@link module:list/documentlistproperties/documentlistreversedcommand~DocumentListReversedCommand `'listReversed'`}), the look of the UI\n * (`'numberedList'` and `'bulletedList'` dropdowns), and the editor data pipeline (allowed HTML attributes).\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tlist: {\n *\t\t\t\t\tproperties: {\n *\t\t\t\t\t\tstyles: true,\n *\t\t\t\t\t\tstartIndex: true,\n *\t\t\t\t\t\treversed: true\n *\t\t\t\t\t}\n *\t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * @interface ListPropertiesConfig\n */\n\n/**\n * When set, the list style feature will be enabled. It allows changing the `list-style-type` style or the `type` HTML attribute of a list.\n *\n * **Note**: Styling using the `type` HTML attribute is only available in\n * {@link module:list/documentlistproperties~DocumentListProperties document list properties}\n * ({@link module:list/listproperties~ListPropertiesStyleConfig learn more}).\n *\n * @default true\n * @member {Boolean|module:list/listproperties~ListPropertiesStyleConfig} module:list/listproperties~ListPropertiesConfig#styles\n */\n\n/**\n * When set, the list start index feature will be enabled. It allows changing the `start` HTML attribute of the numbered lists. As a\n * result, it will be possible to specify the start value of the first item in an ordered list.\n *\n * **Note**: This configuration does not affect bulleted and to-do lists.\n *\n * @default false\n * @member {Boolean} module:list/listproperties~ListPropertiesConfig#startIndex\n */\n\n/**\n * When set, the reversed list feature will be enabled. It allows changing the `reversed` HTML attribute of the numbered lists. As a\n * result, it will be possible to make the list order descending instead of ascending.\n *\n * **Note**: This configuration does not affect bulleted and to-do lists.\n *\n * @default false\n * @member {Boolean} module:list/listproperties~ListPropertiesConfig#reversed\n */\n\n/**\n * The configuration of the {@link module:list/listproperties~ListProperties} feature and the\n * {@link module:list/documentlistproperties~DocumentListProperties document list properties} feature.\n *\n * Read more in {@link module:list/listproperties~ListPropertiesConfig}.\n *\n * @member {module:list/listproperties~ListPropertiesConfig} module:list/list~ListConfig#properties\n */\n\n/**\n * @interface ListPropertiesStyleConfig\n */\n\n/**\n * When set `true`, the list style feature will use the `type` attribute of `<ul>` and `<ol>` elements instead of the `list-style-type`\n * style.\n *\n *\t\t{\n *\t\t\tlist: {\n *\t\t\t\tproperties: {\n *\t\t\t\t\tstyles: {\n *\t\t\t\t\t\tuseAttribute: true\n *\t\t\t\t\t},\n *\n *\t\t\t\t\t// ...\n *\t\t\t\t}\n *\t\t\t},\n *\n *\t\t\t// ...\n *\t\t}\n *\n * **Note**: Due to limitations of HTML, the \"Decimal with leading zero\" style is impossible to set using the `type` attribute.\n *\n * **Note**: This configuration works only with {@link module:list/documentlistproperties~DocumentListProperties document list properties}.\n *\n * @default false\n * @member {Boolean} module:list/listproperties~ListPropertiesStyleConfig#useAttribute\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 list/listproperties/listpropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ListEditing from '../list/listediting';\nimport ListStyleCommand from './liststylecommand';\nimport ListReversedCommand from './listreversedcommand';\nimport ListStartCommand from './liststartcommand';\nimport { getSiblingListItem, getSiblingNodes } from '../list/utils';\n\nconst DEFAULT_LIST_TYPE = 'default';\n\n/**\n * The engine of the list properties feature.\n *\n * It sets the value for the `listItem` attribute of the {@link module:list/list~List `<listItem>`} element that\n * allows modifying the list style type.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listproperties~ListPropertiesConfig}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListPropertiesEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list', {\n\t\t\tproperties: {\n\t\t\t\tstyles: true,\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t}\n\t\t} );\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\tconst enabledProperties = editor.config.get( 'list.properties' );\n\t\tconst strategies = createAttributeStrategies( enabledProperties );\n\n\t\t// Extend schema.\n\t\tmodel.schema.extend( 'listItem', {\n\t\t\tallowAttributes: strategies.map( s => s.attributeName )\n\t\t} );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tstrategy.addCommand( editor );\n\t\t}\n\n\t\t// Fix list attributes when modifying their nesting levels (the `listIndent` attribute).\n\t\tthis.listenTo( editor.commands.get( 'indentList' ), '_executeCleanup', fixListAfterIndentListCommand( editor, strategies ) );\n\t\tthis.listenTo( editor.commands.get( 'outdentList' ), '_executeCleanup', fixListAfterOutdentListCommand( editor, strategies ) );\n\n\t\tthis.listenTo( editor.commands.get( 'bulletedList' ), '_executeCleanup', restoreDefaultListStyle( editor ) );\n\t\tthis.listenTo( editor.commands.get( 'numberedList' ), '_executeCleanup', restoreDefaultListStyle( editor ) );\n\n\t\t// Register a post-fixer that ensures that the attributes is specified in each `listItem` element.\n\t\tmodel.document.registerPostFixer( fixListAttributesOnListItemElements( editor, strategies ) );\n\n\t\t// Set up conversion.\n\t\teditor.conversion.for( 'upcast' ).add( upcastListItemAttributes( strategies ) );\n\t\teditor.conversion.for( 'downcast' ).add( downcastListItemAttributes( strategies ) );\n\n\t\t// Handle merging two separated lists into the single one.\n\t\tthis._mergeListAttributesWhileMergingLists( strategies );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\n\t\t// Enable post-fixer that removes the attributes from to-do list items only if the \"TodoList\" plugin is on.\n\t\t// We need to registry the hook here since the `TodoList` plugin can be added after the `ListPropertiesEditing`.\n\t\tif ( editor.commands.get( 'todoList' ) ) {\n\t\t\teditor.model.document.registerPostFixer( removeListItemAttributesFromTodoList( editor ) );\n\t\t}\n\t}\n\n\t/**\n\t * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether two lists will be merged into a single\n\t * one after deleting the content.\n\t *\n\t * The purpose of this action is to adjust the `listStyle`, `listReversed` and `listStart` values\n\t * for the list that was merged.\n\t *\n\t * Consider the following model's content:\n\t *\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <paragraph>[A paragraph.]</paragraph>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t *\n\t * After removing the paragraph element, the second list will be merged into the first one.\n\t * We want to inherit the `listStyle` attribute for the second list from the first one.\n\t *\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/7879.\n\t *\n\t * @private\n\t * @param {Array.<module:list/listproperties/listpropertiesediting~AttributeStrategy>} attributeStrategies Strategies for the\n\t * enabled attributes.\n\t */\n\t_mergeListAttributesWhileMergingLists( attributeStrategies ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\t// First the outer-most`listItem` in the first list reference.\n\t\t// If found, the lists should be merged and this `listItem` provides the attributes\n\t\t// and it is also a starting point when searching for items in the second list.\n\t\tlet firstMostOuterItem;\n\n\t\t// Check whether the removed content is between two lists.\n\t\tthis.listenTo( model, 'deleteContent', ( evt, [ selection ] ) => {\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\tconst lastPosition = selection.getLastPosition();\n\n\t\t\t// Typing or removing content in a single item. Aborting.\n\t\t\tif ( firstPosition.parent === lastPosition.parent ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// An element before the content that will be removed is not a list.\n\t\t\tif ( !firstPosition.parent.is( 'element', 'listItem' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nextSibling = lastPosition.parent.nextSibling;\n\n\t\t\t// An element after the content that will be removed is not a list.\n\t\t\tif ( !nextSibling || !nextSibling.is( 'element', 'listItem' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Find the outermost list item based on the `listIndent` attribute. We can't assume that `listIndent=0`\n\t\t\t// because the selection can be hooked in nested lists.\n\t\t\t//\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List [item 1.1</listItem>\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1.</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"circle\">UL List ]item 1.1</listItem>\n\t\t\t//\n\t\t\t// After deleting the content, we would like to inherit the \"square\" attribute for the last element:\n\t\t\t//\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List []item 1.1</listItem>\n\t\t\tconst mostOuterItemList = getSiblingListItem( firstPosition.parent, {\n\t\t\t\tsameIndent: true,\n\t\t\t\tlistIndent: nextSibling.getAttribute( 'listIndent' )\n\t\t\t} );\n\n\t\t\t// The outermost list item may not exist while removing elements between lists with different value\n\t\t\t// of the `listIndent` attribute. In such a case we don't want to update anything. See: #8073.\n\t\t\tif ( !mostOuterItemList ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( mostOuterItemList.getAttribute( 'listType' ) === nextSibling.getAttribute( 'listType' ) ) {\n\t\t\t\tfirstMostOuterItem = mostOuterItemList;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// If so, update the `listStyle` attribute for the second list.\n\t\tthis.listenTo( model, 'deleteContent', () => {\n\t\t\tif ( !firstMostOuterItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.change( writer => {\n\t\t\t\t// Find the first most-outer item list in the merged list.\n\t\t\t\t// A case when the first list item in the second list was merged into the last item in the first list.\n\t\t\t\t//\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t\t\t\tconst secondListMostOuterItem = getSiblingListItem( firstMostOuterItem.nextSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: firstMostOuterItem.getAttribute( 'listIndent' ),\n\t\t\t\t\tdirection: 'forward'\n\t\t\t\t} );\n\n\t\t\t\t// If the selection ends in a non-list element, there are no <listItem>s that would require adjustments.\n\t\t\t\t// See: #8642.\n\t\t\t\tif ( !secondListMostOuterItem ) {\n\t\t\t\t\tfirstMostOuterItem = null;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst items = [\n\t\t\t\t\tsecondListMostOuterItem,\n\t\t\t\t\t...getSiblingNodes( writer.createPositionAt( secondListMostOuterItem, 0 ), 'forward' )\n\t\t\t\t];\n\n\t\t\t\tfor ( const listItem of items ) {\n\t\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\t\tif ( strategy.appliesToListItem( listItem ) ) {\n\t\t\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\t\t\tconst value = firstMostOuterItem.getAttribute( attributeName );\n\n\t\t\t\t\t\t\twriter.setAttribute( attributeName, value, listItem );\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\tfirstMostOuterItem = null;\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n/**\n * Strategy for dealing with `listItem` attributes supported by this plugin.\n *\n * @typedef {Object} AttributeStrategy\n * @private\n * @property {String} #attributeName\n * @property {*} #defaultValue\n * @property {Function} #addCommand\n * @property {Function} #appliesToListItem\n * @property {Function} #setAttributeOnDowncast\n * @property {Function} #getAttributeOnUpcast\n*/\n\n// Creates an array of strategies for dealing with enabled listItem attributes.\n//\n// @param {Object} enabledProperties\n// @param {Boolean} enabledProperties.styles\n// @param {Boolean} enabledProperties.reversed\n// @param {Boolean} enabledProperties.startIndex\n// @returns {Array.<module:list/listpropertiesediting~AttributeStrategy>}\nfunction createAttributeStrategies( enabledProperties ) {\n\tconst strategies = [];\n\n\tif ( enabledProperties.styles ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStyle',\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStyle', new ListStyleCommand( editor, DEFAULT_LIST_TYPE ) );\n\t\t\t},\n\n\t\t\tappliesToListItem() {\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStyle, element ) {\n\t\t\t\tif ( listStyle && listStyle !== DEFAULT_LIST_TYPE ) {\n\t\t\t\t\twriter.setStyle( 'list-style-type', listStyle, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeStyle( 'list-style-type', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getStyle( 'list-style-type' ) || DEFAULT_LIST_TYPE;\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listReversed',\n\t\t\tdefaultValue: false,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listReversed', new ListReversedCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listReversed, element ) {\n\t\t\t\tif ( listReversed ) {\n\t\t\t\t\twriter.setAttribute( 'reversed', 'reversed', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'reversed', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.hasAttribute( 'reversed' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStart',\n\t\t\tdefaultValue: 1,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStart', new ListStartCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStart, element ) {\n\t\t\t\tif ( listStart != 1 ) {\n\t\t\t\t\twriter.setAttribute( 'start', listStart, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'start', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getAttribute( 'start' ) || 1;\n\t\t\t}\n\t\t} );\n\t}\n\n\treturn strategies;\n}\n\n// Returns a converter consumes the `style`, `reversed` and `start` attribute.\n// In `style` it searches for the `list-style-type` definition.\n// If not found, the `\"default\"` value will be used.\n//\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction upcastListItemAttributes( attributeStrategies ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:li', ( evt, data, conversionApi ) => {\n\t\t\tconst listParent = data.viewItem.parent;\n\n\t\t\t// It may happen that the native spell checker fixes a word inside a list item.\n\t\t\t// When the children mutation is fired, the `<li>` does not have the parent element. See: #9325.\n\t\t\tif ( !listParent ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst listItem = data.modelRange.start.nodeAfter || data.modelRange.end.nodeBefore;\n\n\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\tif ( strategy.appliesToListItem( listItem ) ) {\n\t\t\t\t\tconst listStyle = strategy.getAttributeOnUpcast( listParent );\n\t\t\t\t\tconversionApi.writer.setAttribute( strategy.attributeName, listStyle, listItem );\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t};\n}\n\n// Returns a converter that adds `reversed`, `start` attributes and adds `list-style-type` definition as a value for the `style` attribute.\n// The `\"default\"` values are removed and not present in the view/data.\n//\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction downcastListItemAttributes( attributeStrategies ) {\n\treturn dispatcher => {\n\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\tdispatcher.on( `attribute:${ strategy.attributeName }:listItem`, ( evt, data, conversionApi ) => {\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst currentElement = data.item;\n\n\t\t\t\tconst previousElement = getSiblingListItem( currentElement.previousSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: currentElement.getAttribute( 'listIndent' ),\n\t\t\t\t\tdirection: 'backward'\n\t\t\t\t} );\n\n\t\t\t\tconst viewItem = conversionApi.mapper.toViewElement( currentElement );\n\n\t\t\t\t// A case when elements represent different lists. We need to separate their container.\n\t\t\t\tif ( !areRepresentingSameList( currentElement, previousElement ) ) {\n\t\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\t\t\t}\n\t\t\t\tstrategy.setAttributeOnDowncast( viewWriter, data.attributeNewValue, viewItem.parent );\n\t\t\t}, { priority: 'low' } );\n\t\t}\n\t};\n\n\t// Checks whether specified list items belong to the same list.\n\t//\n\t// @param {module:engine/model/element~Element} `listItem1` The first list item to check.\n\t// @param {module:engine/model/element~Element|null} `listItem2` The second list item to check.\n\t// @returns {Boolean}\n\tfunction areRepresentingSameList( listItem1, listItem2 ) {\n\t\treturn listItem2 &&\n\t\t\tlistItem1.getAttribute( 'listType' ) === listItem2.getAttribute( 'listType' ) &&\n\t\t\tlistItem1.getAttribute( 'listIndent' ) === listItem2.getAttribute( 'listIndent' ) &&\n\t\t\tlistItem1.getAttribute( 'listStyle' ) === listItem2.getAttribute( 'listStyle' ) &&\n\t\t\tlistItem1.getAttribute( 'listReversed' ) === listItem2.getAttribute( 'listReversed' ) &&\n\t\t\tlistItem1.getAttribute( 'listStart' ) === listItem2.getAttribute( 'listStart' );\n\t}\n}\n\n// When indenting list, nested list should clear its value for the attributes or inherit from nested lists.\n//\n// ■ List item 1.\n// ■ List item 2.[]\n// ■ List item 3.\n// editor.execute( 'indentList' );\n//\n// ■ List item 1.\n// ○ List item 2.[]\n// ■ List item 3.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction fixListAfterIndentListCommand( editor, attributeStrategies ) {\n\treturn ( evt, changedItems ) => {\n\t\tconst root = changedItems[ 0 ];\n\t\tconst rootIndent = root.getAttribute( 'listIndent' );\n\n\t\tconst itemsToUpdate = changedItems.filter( item => item.getAttribute( 'listIndent' ) === rootIndent );\n\n\t\t// A case where a few list items are indented must be checked separately\n\t\t// since `getSiblingListItem()` returns the first changed element.\n\t\t// ■ List item 1.\n\t\t// ○ [List item 2.\n\t\t// ○ List item 3.]\n\t\t// ■ List item 4.\n\t\t//\n\t\t// List items: `2` and `3` should be adjusted.\n\t\tlet previousSibling = null;\n\n\t\tif ( root.previousSibling.getAttribute( 'listIndent' ) + 1 !== rootIndent ) {\n\t\t\tpreviousSibling = getSiblingListItem( root.previousSibling, {\n\t\t\t\tsameIndent: true, direction: 'backward', listIndent: rootIndent\n\t\t\t} );\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\tfor ( const item of itemsToUpdate ) {\n\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\tif ( strategy.appliesToListItem( item ) ) {\n\t\t\t\t\t\tconst valueToSet = previousSibling == null ?\n\t\t\t\t\t\t\tstrategy.defaultValue :\n\t\t\t\t\t\t\tpreviousSibling.getAttribute( strategy.attributeName );\n\n\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, valueToSet, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// When outdenting a list, a nested list should copy attribute values\n// from the previous sibling list item including the same value for the `listIndent` value.\n//\n// ■ List item 1.\n// ○ List item 2.[]\n// ■ List item 3.\n//\n// editor.execute( 'outdentList' );\n//\n// ■ List item 1.\n// ■ List item 2.[]\n// ■ List item 3.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction fixListAfterOutdentListCommand( editor, attributeStrategies ) {\n\treturn ( evt, changedItems ) => {\n\t\tchangedItems = changedItems.reverse().filter( item => item.is( 'element', 'listItem' ) );\n\n\t\tif ( !changedItems.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst indent = changedItems[ 0 ].getAttribute( 'listIndent' );\n\t\tconst listType = changedItems[ 0 ].getAttribute( 'listType' );\n\t\tlet listItem = changedItems[ 0 ].previousSibling;\n\n\t\t// ■ List item 1.\n\t\t// ○ List item 2.\n\t\t// ○ List item 3.[]\n\t\t// ■ List item 4.\n\t\t//\n\t\t// After outdenting a list, `List item 3` should inherit the `listStyle` attribute from `List item 1`.\n\t\t//\n\t\t// ■ List item 1.\n\t\t// ○ List item 2.\n\t\t// ■ List item 3.[]\n\t\t// ■ List item 4.\n\t\tif ( listItem.is( 'element', 'listItem' ) ) {\n\t\t\twhile ( listItem.getAttribute( 'listIndent' ) !== indent ) {\n\t\t\t\tlistItem = listItem.previousSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tlistItem = null;\n\t\t}\n\n\t\t// Outdenting such a list should restore values based on `List item 4`.\n\t\t// ■ List item 1.[]\n\t\t// ○ List item 2.\n\t\t// ○ List item 3.\n\t\t// ■ List item 4.\n\t\tif ( !listItem ) {\n\t\t\tlistItem = changedItems[ changedItems.length - 1 ].nextSibling;\n\t\t}\n\n\t\t// And such a list should not modify anything.\n\t\t// However, `listItem` can indicate a node below the list. Be sure that we have the `listItem` element.\n\t\t// ■ List item 1.[]\n\t\t// ○ List item 2.\n\t\t// ○ List item 3.\n\t\t// <paragraph>The later if check.</paragraph>\n\t\tif ( !listItem || !listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not modify the list if found `listItem` represents other type of list than outdented list items.\n\t\tif ( listItem.getAttribute( 'listType' ) !== listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\tconst itemsToUpdate = changedItems.filter( item => item.getAttribute( 'listIndent' ) === indent );\n\n\t\t\tfor ( const item of itemsToUpdate ) {\n\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\tif ( strategy.appliesToListItem( item ) ) {\n\t\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\t\tconst valueToSet = listItem.getAttribute( attributeName );\n\n\t\t\t\t\t\twriter.setAttribute( attributeName, valueToSet, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// Each `listItem` element must have specified the `listStyle`, `listReversed` and `listStart` attributes\n// if they are enabled and supported by its `listType`.\n// This post-fixer checks whether inserted elements `listItem` elements should inherit the attribute values from\n// their sibling nodes or should use the default values.\n//\n// Paragraph[]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2. // ...\n// ■ List item 3. // ...\n//\n// editor.execute( 'bulletedList' )\n//\n// ■ Paragraph[] // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2.\n// ■ List item 3.\n//\n// It also covers a such change:\n//\n// [Paragraph 1\n// Paragraph 2]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2. // ...\n// ■ List item 3. // ...\n//\n// editor.execute( 'numberedList' )\n//\n// 1. [Paragraph 1 // [listStyle=\"default\", listType=\"numbered\"]\n// 2. Paragraph 2] // [listStyle=\"default\", listType=\"numbered\"]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2. // ...\n// ■ List item 3. // ...\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction fixListAttributesOnListItemElements( editor, attributeStrategies ) {\n\treturn writer => {\n\t\tlet wasFixed = false;\n\n\t\tconst insertedListItems = getChangedListItems( editor.model.document.differ.getChanges() )\n\t\t\t.filter( item => {\n\t\t\t\t// Don't touch todo lists. They are handled in another post-fixer.\n\t\t\t\treturn item.getAttribute( 'listType' ) !== 'todo';\n\t\t\t} );\n\n\t\tif ( !insertedListItems.length ) {\n\t\t\treturn wasFixed;\n\t\t}\n\n\t\t// Check whether the last inserted element is next to the `listItem` element.\n\t\t//\n\t\t// ■ Paragraph[] // <-- The inserted item.\n\t\t// ■ List item 1.\n\t\tlet existingListItem = insertedListItems[ insertedListItems.length - 1 ].nextSibling;\n\n\t\t// If it doesn't, maybe the `listItem` was inserted at the end of the list.\n\t\t//\n\t\t// ■ List item 1.\n\t\t// ■ Paragraph[] // <-- The inserted item.\n\t\tif ( !existingListItem || !existingListItem.is( 'element', 'listItem' ) ) {\n\t\t\texistingListItem = insertedListItems[ 0 ].previousSibling;\n\n\t\t\tif ( existingListItem ) {\n\t\t\t\tconst indent = insertedListItems[ 0 ].getAttribute( 'listIndent' );\n\n\t\t\t\t// But we need to find a `listItem` with the `listIndent=0` attribute.\n\t\t\t\t// If doesn't, maybe the `listItem` was inserted at the end of the list.\n\t\t\t\t//\n\t\t\t\t// ■ List item 1.\n\t\t\t\t// ○ List item 2.\n\t\t\t\t// ■ Paragraph[] // <-- The inserted item.\n\t\t\t\twhile ( existingListItem.is( 'element', 'listItem' ) && existingListItem.getAttribute( 'listIndent' ) !== indent ) {\n\t\t\t\t\texistingListItem = existingListItem.previousSibling;\n\n\t\t\t\t\t// If the item does not exist, most probably there is no other content in the editor. See: #8072.\n\t\t\t\t\tif ( !existingListItem ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\tconst attributeName = strategy.attributeName;\n\n\t\t\tfor ( const item of insertedListItems ) {\n\t\t\t\tif ( !strategy.appliesToListItem( item ) ) {\n\t\t\t\t\twriter.removeAttribute( attributeName, item );\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( !item.hasAttribute( attributeName ) ) {\n\t\t\t\t\tif ( shouldInheritListType( existingListItem, item, strategy ) ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, existingListItem.getAttribute( attributeName ), item );\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.setAttribute( attributeName, strategy.defaultValue, item );\n\t\t\t\t\t}\n\t\t\t\t\twasFixed = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Adjust the `listStyle`, `listReversed` and `listStart`\n\t\t\t\t\t// attributes for inserted (pasted) items. See #8160.\n\t\t\t\t\t//\n\t\t\t\t\t// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ [] (selection is here)\n\t\t\t\t\t//\n\t\t\t\t\t// Then, pasting a list with different attributes (listStyle, listType):\n\t\t\t\t\t//\n\t\t\t\t\t// 1. First. // [listStyle=\"decimal\", listType=\"numbered\"]\n\t\t\t\t\t// 2. Second // [listStyle=\"decimal\", listType=\"numbered\"]\n\t\t\t\t\t//\n\t\t\t\t\t// The `listType` attribute will be corrected by the `ListEditing` converters.\n\t\t\t\t\t// We need to adjust the `listStyle` attribute. Expected structure:\n\t\t\t\t\t//\n\t\t\t\t\t// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ First. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ Second // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\tconst previousSibling = item.previousSibling;\n\n\t\t\t\t\tif ( shouldInheritListTypeFromPreviousItem( previousSibling, item, strategy.attributeName ) ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, previousSibling.getAttribute( attributeName ), item );\n\n\t\t\t\t\t\twasFixed = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn wasFixed;\n\t};\n}\n\n// Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n// should be copied from the `baseItem` element.\n//\n// The attribute should be copied if the inserted element does not have defined it and\n// the value for the element is other than default in the base element.\n//\n// @param {module:engine/model/element~Element|null} baseItem\n// @param {module:engine/model/element~Element} itemToChange\n// @param {module:list/listpropertiesediting~AttributeStrategy} attributeStrategy\n// @returns {Boolean}\nfunction shouldInheritListType( baseItem, itemToChange, attributeStrategy ) {\n\tif ( !baseItem ) {\n\t\treturn false;\n\t}\n\n\tconst baseListAttribute = baseItem.getAttribute( attributeStrategy.attributeName );\n\n\tif ( !baseListAttribute ) {\n\t\treturn false;\n\t}\n\n\tif ( baseListAttribute == attributeStrategy.defaultValue ) {\n\t\treturn false;\n\t}\n\n\tif ( baseItem.getAttribute( 'listType' ) !== itemToChange.getAttribute( 'listType' ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n// Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n// should be copied from previous list item.\n//\n// The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list.\n// Top-level lists are not normalized as we allow side-by-side list of different types.\n//\n// @param {module:engine/model/element~Element|null} previousItem\n// @param {module:engine/model/element~Element} itemToChange\n// @returns {Boolean}\nfunction shouldInheritListTypeFromPreviousItem( previousItem, itemToChange, attributeName ) {\n\tif ( !previousItem || !previousItem.is( 'element', 'listItem' ) ) {\n\t\treturn false;\n\t}\n\n\tif ( itemToChange.getAttribute( 'listType' ) !== previousItem.getAttribute( 'listType' ) ) {\n\t\treturn false;\n\t}\n\n\tconst previousItemIndent = previousItem.getAttribute( 'listIndent' );\n\n\tif ( previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute( 'listIndent' ) ) {\n\t\treturn false;\n\t}\n\n\tconst previousItemListAttribute = previousItem.getAttribute( attributeName );\n\n\tif ( !previousItemListAttribute || previousItemListAttribute === itemToChange.getAttribute( attributeName ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n// Removes the `listStyle`, `listReversed` and `listStart` attributes from \"todo\" list items.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @returns {Function}\nfunction removeListItemAttributesFromTodoList( editor ) {\n\treturn writer => {\n\t\tconst todoListItems = getChangedListItems( editor.model.document.differ.getChanges() )\n\t\t\t.filter( item => {\n\t\t\t\t// Handle the todo lists only. The rest is handled in another post-fixer.\n\t\t\t\treturn item.getAttribute( 'listType' ) === 'todo' && (\n\t\t\t\t\titem.hasAttribute( 'listStyle' ) ||\n\t\t\t\t\titem.hasAttribute( 'listReversed' ) ||\n\t\t\t\t\titem.hasAttribute( 'listStart' )\n\t\t\t\t);\n\t\t\t} );\n\n\t\tif ( !todoListItems.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const item of todoListItems ) {\n\t\t\twriter.removeAttribute( 'listStyle', item );\n\t\t\twriter.removeAttribute( 'listReversed', item );\n\t\t\twriter.removeAttribute( 'listStart', item );\n\t\t}\n\n\t\treturn true;\n\t};\n}\n\n// Restores the `listStyle` attribute after changing the list type.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @returns {Function}\nfunction restoreDefaultListStyle( editor ) {\n\treturn ( evt, changedItems ) => {\n\t\tchangedItems = changedItems.filter( item => item.is( 'element', 'listItem' ) );\n\n\t\teditor.model.change( writer => {\n\t\t\tfor ( const item of changedItems ) {\n\t\t\t\t// Remove the attribute. Post-fixer will restore the proper value.\n\t\t\t\twriter.removeAttribute( 'listStyle', item );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// Returns the `listItem` that was inserted or changed.\n//\n// @param {Array.<Object>} changes The changes list returned by the differ.\n// @returns {Array.<module:engine/model/element~Element>}\nfunction getChangedListItems( changes ) {\n\tconst items = [];\n\n\tfor ( const change of changes ) {\n\t\tconst item = getItemFromChange( change );\n\n\t\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\treturn items;\n}\n\nfunction getItemFromChange( change ) {\n\tif ( change.type === 'attribute' ) {\n\t\treturn change.range.start.nodeAfter;\n\t}\n\n\tif ( change.type === 'insert' ) {\n\t\treturn change.position.nodeAfter;\n\t}\n\n\treturn null;\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 list/listproperties/listpropertiesui\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { ButtonView, SplitButtonView, createDropdown, focusChildOnDropdownOpen } from 'ckeditor5/src/ui';\n\nimport ListPropertiesView from './ui/listpropertiesview';\n\nimport bulletedListIcon from '../../theme/icons/bulletedlist.svg';\nimport numberedListIcon from '../../theme/icons/numberedlist.svg';\n\nimport listStyleDiscIcon from '../../theme/icons/liststyledisc.svg';\nimport listStyleCircleIcon from '../../theme/icons/liststylecircle.svg';\nimport listStyleSquareIcon from '../../theme/icons/liststylesquare.svg';\nimport listStyleDecimalIcon from '../../theme/icons/liststyledecimal.svg';\nimport listStyleDecimalWithLeadingZeroIcon from '../../theme/icons/liststyledecimalleadingzero.svg';\nimport listStyleLowerRomanIcon from '../../theme/icons/liststylelowerroman.svg';\nimport listStyleUpperRomanIcon from '../../theme/icons/liststyleupperroman.svg';\nimport listStyleLowerLatinIcon from '../../theme/icons/liststylelowerlatin.svg';\nimport listStyleUpperLatinIcon from '../../theme/icons/liststyleupperlatin.svg';\n\nimport '../../theme/liststyles.css';\n\n/**\n * The list properties UI plugin. It introduces the extended `'bulletedList'` and `'numberedList'` toolbar\n * buttons that allow users to control such aspects of list as the marker, start index or order.\n *\n * **Note**: Buttons introduced by this plugin override implementations from the {@link module:list/list/listui~ListUI}\n * (because they share the same names).\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListPropertiesUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListPropertiesUI';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst enabledProperties = editor.config.get( 'list.properties' );\n\n\t\t// Note: When this plugin does not register the \"bulletedList\" dropdown due to properties configuration,\n\t\t// a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n\t\t// in most editor configuration because the List plugin automatically requires ListUI.\n\t\tif ( enabledProperties.styles ) {\n\t\t\teditor.ui.componentFactory.add( 'bulletedList', getDropdownViewCreator( {\n\t\t\t\teditor,\n\t\t\t\tparentCommandName: 'bulletedList',\n\t\t\t\tbuttonLabel: t( 'Bulleted List' ),\n\t\t\t\tbuttonIcon: bulletedListIcon,\n\t\t\t\tstyleGridAriaLabel: t( 'Bulleted list styles toolbar' ),\n\t\t\t\tstyleDefinitions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the disc list style' ),\n\t\t\t\t\t\ttooltip: t( 'Disc' ),\n\t\t\t\t\t\ttype: 'disc',\n\t\t\t\t\t\ticon: listStyleDiscIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the circle list style' ),\n\t\t\t\t\t\ttooltip: t( 'Circle' ),\n\t\t\t\t\t\ttype: 'circle',\n\t\t\t\t\t\ticon: listStyleCircleIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the square list style' ),\n\t\t\t\t\t\ttooltip: t( 'Square' ),\n\t\t\t\t\t\ttype: 'square',\n\t\t\t\t\t\ticon: listStyleSquareIcon\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t} ) );\n\t\t}\n\n\t\t// Note: When this plugin does not register the \"numberedList\" dropdown due to properties configuration,\n\t\t// a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n\t\t// in most editor configuration because the List plugin automatically requires ListUI.\n\t\tif ( enabledProperties.styles || enabledProperties.startIndex || enabledProperties.reversed ) {\n\t\t\teditor.ui.componentFactory.add( 'numberedList', getDropdownViewCreator( {\n\t\t\t\teditor,\n\t\t\t\tparentCommandName: 'numberedList',\n\t\t\t\tbuttonLabel: t( 'Numbered List' ),\n\t\t\t\tbuttonIcon: numberedListIcon,\n\t\t\t\tstyleGridAriaLabel: t( 'Numbered list styles toolbar' ),\n\t\t\t\tstyleDefinitions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the decimal list style' ),\n\t\t\t\t\t\ttooltip: t( 'Decimal' ),\n\t\t\t\t\t\ttype: 'decimal',\n\t\t\t\t\t\ticon: listStyleDecimalIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the decimal with leading zero list style' ),\n\t\t\t\t\t\ttooltip: t( 'Decimal with leading zero' ),\n\t\t\t\t\t\ttype: 'decimal-leading-zero',\n\t\t\t\t\t\ticon: listStyleDecimalWithLeadingZeroIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the lower–roman list style' ),\n\t\t\t\t\t\ttooltip: t( 'Lower–roman' ),\n\t\t\t\t\t\ttype: 'lower-roman',\n\t\t\t\t\t\ticon: listStyleLowerRomanIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the upper–roman list style' ),\n\t\t\t\t\t\ttooltip: t( 'Upper-roman' ),\n\t\t\t\t\t\ttype: 'upper-roman',\n\t\t\t\t\t\ticon: listStyleUpperRomanIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the lower–latin list style' ),\n\t\t\t\t\t\ttooltip: t( 'Lower-latin' ),\n\t\t\t\t\t\ttype: 'lower-latin',\n\t\t\t\t\t\ticon: listStyleLowerLatinIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the upper–latin list style' ),\n\t\t\t\t\t\ttooltip: t( 'Upper-latin' ),\n\t\t\t\t\t\ttype: 'upper-latin',\n\t\t\t\t\t\ticon: listStyleUpperLatinIcon\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t} ) );\n\t\t}\n\t}\n}\n\n// A helper that returns a function that creates a split button with a toolbar in the dropdown,\n// which in turn contains buttons allowing users to change list styles in the context of the current selection.\n//\n// @param {Object} options\n// @param {module:core/editor/editor~Editor} options.editor\n// @param {'bulletedList'|'numberedList'} options.parentCommandName The name of the higher-order editor command associated with\n// the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n// @param {String} options.buttonLabel Label of the main part of the split button.\n// @param {String} options.buttonIcon The SVG string of an icon for the main part of the split button.\n// @param {String} options.styleGridAriaLabel The ARIA label for the styles grid in the split button dropdown.\n// @param {Object} options.styleDefinitions Definitions of the style buttons.\n// @returns {Function} A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\nfunction getDropdownViewCreator( { editor, parentCommandName, buttonLabel, buttonIcon, styleGridAriaLabel, styleDefinitions } ) {\n\tconst parentCommand = editor.commands.get( parentCommandName );\n\n\t// @param {module:utils/locale~Locale} locale\n\t// @returns {module:ui/dropdown/dropdownview~DropdownView}\n\treturn locale => {\n\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\tconst mainButtonView = dropdownView.buttonView;\n\n\t\tdropdownView.bind( 'isEnabled' ).to( parentCommand );\n\t\tdropdownView.class = 'ck-list-styles-dropdown';\n\n\t\t// Main button was clicked.\n\t\tmainButtonView.on( 'execute', () => {\n\t\t\teditor.execute( parentCommandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\tmainButtonView.set( {\n\t\t\tlabel: buttonLabel,\n\t\t\ticon: buttonIcon,\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tmainButtonView.bind( 'isOn' ).to( parentCommand, 'value', value => !!value );\n\n\t\tconst listPropertiesView = createListPropertiesView( {\n\t\t\teditor,\n\t\t\tdropdownView,\n\t\t\tparentCommandName,\n\t\t\tstyleGridAriaLabel,\n\t\t\tstyleDefinitions\n\t\t} );\n\n\t\tdropdownView.panelView.children.add( listPropertiesView );\n\n\t\t// Focus the editable after executing the command.\n\t\t// Overrides a default behaviour where the focus is moved to the dropdown button (#12125).\n\t\tdropdownView.on( 'execute', () => {\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn dropdownView;\n\t};\n}\n\n// A helper that returns a function (factory) that creates individual buttons used by users to change styles\n// of lists.\n//\n// @param {Object} options\n// @param {module:core/editor/editor~Editor} options.editor\n// @param {module:list/liststylecommand~ListStylesCommand} options.listStyleCommand The instance of the `ListStylesCommand` class.\n// @param {'bulletedList'|'numberedList'} options.parentCommandName The name of the higher-order command associated with a\n// particular list style (e.g. \"bulletedList\" is associated with \"square\" and \"numberedList\" is associated with \"roman\").\n// @returns {Function} A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\nfunction getStyleButtonCreator( { editor, listStyleCommand, parentCommandName } ) {\n\tconst locale = editor.locale;\n\tconst parentCommand = editor.commands.get( parentCommandName );\n\n\t// @param {String} label The label of the style button.\n\t// @param {String} type The type of the style button (e.g. \"roman\" or \"circle\").\n\t// @param {String} icon The SVG string of an icon of the style button.\n\t// @param {String} tooltip The tooltip text of the button (shorter than verbose label).\n\t// @returns {module:ui/button/buttonview~ButtonView}\n\treturn ( { label, type, icon, tooltip } ) => {\n\t\tconst button = new ButtonView( locale );\n\n\t\tbutton.set( { label, icon, tooltip } );\n\n\t\tlistStyleCommand.on( 'change:value', () => {\n\t\t\tbutton.isOn = listStyleCommand.value === type;\n\t\t} );\n\n\t\tbutton.on( 'execute', () => {\n\t\t\t// If the content the selection is anchored to is a list, let's change its style.\n\t\t\tif ( parentCommand.value ) {\n\t\t\t\t// If the current list style is not set in the model or the style is different than the\n\t\t\t\t// one to be applied, simply apply the new style.\n\t\t\t\tif ( listStyleCommand.value !== type ) {\n\t\t\t\t\teditor.execute( 'listStyle', { type } );\n\t\t\t\t}\n\t\t\t\t// If the style was the same, remove it (the button works as an off toggle).\n\t\t\t\telse {\n\t\t\t\t\teditor.execute( 'listStyle', { type: listStyleCommand._defaultType } );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise, leave the creation of the styled list to the `ListStyleCommand`.\n\t\t\telse {\n\t\t\t\teditor.model.change( () => {\n\t\t\t\t\teditor.execute( 'listStyle', { type } );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\treturn button;\n\t};\n}\n\n// A helper that creates the properties view for the individual style dropdown.\n//\n// @param {Object} options\n// @param {module:core/editor/editor~Editor} options.editor Editor instance.\n// @param {module:ui/dropdown/dropdownview~DropdownView} options.dropdownView Styles dropdown view that hosts the properties view.\n// @param {'bulletedList'|'numberedList'} options.parentCommandName The name of the higher-order editor command associated with\n// the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n// @param {Object} options.styleDefinitions Definitions of the style buttons.\n// @param {String} options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n// @returns {module:list/ui/listpropertiesview~ListPropertiesView}\nfunction createListPropertiesView( {\n\teditor,\n\tdropdownView,\n\tparentCommandName,\n\tstyleDefinitions,\n\tstyleGridAriaLabel\n} ) {\n\tconst locale = editor.locale;\n\tconst enabledProperties = editor.config.get( 'list.properties' );\n\tlet styleButtonViews;\n\n\tif ( parentCommandName != 'numberedList' ) {\n\t\tenabledProperties.startIndex = false;\n\t\tenabledProperties.reversed = false;\n\t}\n\n\tif ( enabledProperties.styles ) {\n\t\tconst listStyleCommand = editor.commands.get( 'listStyle' );\n\n\t\tconst styleButtonCreator = getStyleButtonCreator( {\n\t\t\teditor,\n\t\t\tparentCommandName,\n\t\t\tlistStyleCommand\n\t\t} );\n\n\t\t// The command can be ListStyleCommand or DocumentListStyleCommand.\n\t\tconst isStyleTypeSupported = typeof listStyleCommand.isStyleTypeSupported == 'function' ?\n\t\t\tstyleDefinition => listStyleCommand.isStyleTypeSupported( styleDefinition.type ) :\n\t\t\t() => true;\n\n\t\tstyleButtonViews = styleDefinitions.filter( isStyleTypeSupported ).map( styleButtonCreator );\n\t}\n\n\tconst listPropertiesView = new ListPropertiesView( locale, {\n\t\tstyleGridAriaLabel,\n\t\tenabledProperties,\n\t\tstyleButtonViews\n\t} );\n\n\tif ( enabledProperties.styles ) {\n\t\t// Accessibility: focus the first active style when opening the dropdown.\n\t\tfocusChildOnDropdownOpen( dropdownView, () => {\n\t\t\treturn listPropertiesView.stylesView.children.find( child => child.isOn );\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tconst listStartCommand = editor.commands.get( 'listStart' );\n\n\t\tlistPropertiesView.startIndexFieldView.bind( 'isEnabled' ).to( listStartCommand );\n\t\tlistPropertiesView.startIndexFieldView.fieldView.bind( 'value' ).to( listStartCommand );\n\t\tlistPropertiesView.on( 'listStart', ( evt, data ) => editor.execute( 'listStart', data ) );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tconst listReversedCommand = editor.commands.get( 'listReversed' );\n\n\t\tlistPropertiesView.reversedSwitchButtonView.bind( 'isEnabled' ).to( listReversedCommand );\n\t\tlistPropertiesView.reversedSwitchButtonView.bind( 'isOn' ).to( listReversedCommand, 'value' );\n\t\tlistPropertiesView.on( 'listReversed', () => {\n\t\t\tconst isReversed = listReversedCommand.value;\n\n\t\t\teditor.execute( 'listReversed', { reversed: !isReversed } );\n\t\t} );\n\t}\n\n\t// Make sure applying styles closes the dropdown.\n\tlistPropertiesView.delegate( 'execute' ).to( dropdownView );\n\n\treturn listPropertiesView;\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 list/listproperties/listreversedcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getSelectedListItems } from '../list/utils';\n\n/**\n * The reversed list command. It changes the `listReversed` attribute of the selected list items. As a result, the list order will be\n * reversed.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListReversedCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {Boolean} [options.reversed=false] Whether the list should be reversed.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model )\n\t\t\t.filter( item => item.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listReversed', !!options.reversed, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn listItem.getAttribute( 'listReversed' );\n\t\t}\n\n\t\treturn null;\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 list/listproperties/liststartcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getSelectedListItems } from '../list/utils';\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListStartCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {Number} [options.startIndex=1] The list start index.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model )\n\t\t\t.filter( item => item.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listStart', options.startIndex || 1, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn listItem.getAttribute( 'listStart' );\n\t\t}\n\n\t\treturn null;\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 list/listproperties/liststylecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getListTypeFromListStyleType, getSelectedListItems } from '../list/utils';\n\n/**\n * The list style command. It changes the `listStyle` attribute of the selected list items.\n *\n * If the list type (numbered or bulleted) can be inferred from the passed style type,\n * the command tries to convert selected items to a list of that type.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListStyleCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {String} defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t */\n\tconstructor( editor, defaultType ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The default type of the list style.\n\t\t *\n\t\t * @protected\n\t\t * @member {String}\n\t\t */\n\t\tthis._defaultType = defaultType;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */\n\texecute( options = {} ) {\n\t\tthis._tryToConvertItemsToList( options );\n\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model );\n\n\t\tif ( !listItems.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listStyle', options.type || this._defaultType, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {String|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn listItem.getAttribute( 'listStyle' );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst editor = this.editor;\n\n\t\tconst numberedList = editor.commands.get( 'numberedList' );\n\t\tconst bulletedList = editor.commands.get( 'bulletedList' );\n\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\n\t/**\n\t * Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t *\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style. If `null` is specified, the function does nothing.\n\t * @private\n\t*/\n\t_tryToConvertItemsToList( options ) {\n\t\tif ( !options.type ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listType = getListTypeFromListStyleType( options.type );\n\n\t\tif ( !listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst commandName = listType + 'List';\n\t\tconst command = editor.commands.get( commandName );\n\n\t\tif ( !command.value ) {\n\t\t\teditor.execute( commandName );\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 list/ui/collapsibleview\n */\n\nimport { View, ButtonView } from 'ckeditor5/src/ui';\n\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport dropdownArrowIcon from '@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg';\n\nimport '../../../theme/collapsible.css';\n\n/**\n * A collapsible UI component. Consists of a labeled button and a container which can be collapsed\n * by clicking the button. The collapsible container can be a host to other UI views.\n *\n * @protected\n * @extends module:ui/view~View\n */\nexport default class CollapsibleView extends View {\n\t/**\n\t * Creates an instance of the collapsible view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param {Array.<module:ui/view~View>} [childViews] An optional array of initial child views to be inserted\n\t * into the collapsible.\n\t */\n\tconstructor( locale, childViews ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * `true` when the container with {@link #children} is collapsed. `false` otherwise.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isCollapsed\n\t\t */\n\t\tthis.set( 'isCollapsed', false );\n\n\t\t/**\n\t\t * The text label of the {@link #buttonView}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t * @default 'Show more'\n\t\t */\n\t\tthis.set( 'label', '' );\n\n\t\t/**\n\t\t * The main button that, when clicked, collapses or expands the container with {@link #children}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/button/buttonview~ButtonView} #buttonView\n\t\t */\n\t\tthis.buttonView = this._createButtonView();\n\n\t\t/**\n\t\t * A collection of the child views that can be collapsed by clicking the {@link #buttonView}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection} #children\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\t/**\n\t\t * The ID of the label inside the {@link #buttonView} that describes the collapsible\n\t\t * container for assistive technologies. Set after the button was {@link #render rendered}.\n\t\t *\n\t\t * @private\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {String} #_collapsibleAriaLabelUid\n\t\t */\n\t\tthis.set( '_collapsibleAriaLabelUid' );\n\n\t\tif ( childViews ) {\n\t\t\tthis.children.addMany( childViews );\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-collapsible',\n\t\t\t\t\tbind.if( 'isCollapsed', 'ck-collapsible_collapsed' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView,\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: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-collapsible__children'\n\t\t\t\t\t\t],\n\t\t\t\t\t\trole: 'region',\n\t\t\t\t\t\thidden: bind.if( 'isCollapsed', 'hidden' ),\n\t\t\t\t\t\t'aria-labelledby': bind.to( '_collapsibleAriaLabelUid' )\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.children\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis._collapsibleAriaLabelUid = this.buttonView.labelView.element.id;\n\t}\n\n\t/**\n\t * Creates the main {@link #buttonView} of the collapsible.\n\t *\n\t * @private\n\t * @returns {module:ui/button/buttonview~ButtonView}\n\t */\n\t_createButtonView() {\n\t\tconst buttonView = new ButtonView( this.locale );\n\t\tconst bind = buttonView.bindTemplate;\n\n\t\tbuttonView.set( {\n\t\t\twithText: true,\n\t\t\ticon: dropdownArrowIcon\n\t\t} );\n\n\t\tbuttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\t'aria-expanded': bind.to( 'isOn', value => String( value ) )\n\t\t\t}\n\t\t} );\n\n\t\tbuttonView.bind( 'label' ).to( this );\n\t\tbuttonView.bind( 'isOn' ).to( this, 'isCollapsed', isCollapsed => !isCollapsed );\n\n\t\tbuttonView.on( 'execute', () => {\n\t\t\tthis.isCollapsed = !this.isCollapsed;\n\t\t} );\n\n\t\treturn buttonView;\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 list/ui/listpropertiesview\n */\n\nimport {\n\tView,\n\tViewCollection,\n\tFocusCycler,\n\tSwitchButtonView,\n\tLabeledFieldView,\n\tcreateLabeledInputNumber,\n\taddKeyboardHandlingForGrid\n} from 'ckeditor5/src/ui';\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\tglobal\n} from 'ckeditor5/src/utils';\n\nimport CollapsibleView from './collapsibleview';\n\nimport '../../../theme/listproperties.css';\n\n/**\n * The list properties view to be displayed in the list dropdown.\n *\n * Contains a grid of available list styles and, for numbered list, also the list start index and reversed fields.\n *\n * @extends module:ui/view~View\n */\nexport default class ListPropertiesView extends View {\n\t/**\n\t * Creates an instance of the list properties 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 Options of the view.\n\t * @param {Object.<String,Boolean>} options.enabledProperties An object containing the configuration of enabled list property names.\n\t * Allows conditional rendering the sub-components of the properties view.\n\t * @param {Array.<module:ui/button/buttonview~ButtonView>|null} options.styleButtonViews A list of style buttons to be rendered\n\t * inside the styles grid. The grid will not be rendered when `enabledProperties` does not include the `'styles'` key.\n\t * @param {String} options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n\t */\n\tconstructor( locale, { enabledProperties, styleButtonViews, styleGridAriaLabel } ) {\n\t\tsuper( locale );\n\n\t\tconst elementCssClasses = [\n\t\t\t'ck',\n\t\t\t'ck-list-properties'\n\t\t];\n\n\t\t/**\n\t\t * A collection of the child views.\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\t/**\n\t\t * A view that renders the grid of list styles.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/view~View|null}\n\t\t */\n\t\tthis.stylesView = null;\n\n\t\t/**\n\t\t * A collapsible view that hosts additional list property fields ({@link #startIndexFieldView} and\n\t\t * {@link #reversedSwitchButtonView}) to visually separate them from the {@link #stylesView grid of styles}.\n\t\t *\n\t\t * **Note**: Only present when:\n\t\t * * the view represents **numbered** list properties,\n\t\t * * and the {@link #stylesView} is rendered,\n\t\t * * and either {@link #startIndexFieldView} or {@link #reversedSwitchButtonView} is rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:list/ui/collapsibleview~CollapsibleView|null}\n\t\t */\n\t\tthis.additionalPropertiesCollapsibleView = null;\n\n\t\t/**\n\t\t * A labeled number field allowing the user to set the start index of the list.\n\t\t *\n\t\t * **Note**: Only present when the view represents **numbered** list properties.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView|null}\n\t\t */\n\t\tthis.startIndexFieldView = null;\n\n\t\t/**\n\t\t * A switch button allowing the user to make the edited list reversed.\n\t\t *\n\t\t * **Note**: Only present when the view represents **numbered** list properties.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/button/switchbuttonview~SwitchButtonView|null}\n\t\t */\n\t\tthis.reversedSwitchButtonView = null;\n\n\t\t/**\n\t\t * Tracks information about the DOM focus in the view.\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 views that can be focused in the properties view.\n\t\t *\n\t\t * @readonly\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 view.\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 #children backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate #children forwards using the <kbd>Tab</kbd> key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// The rendering of the styles grid is conditional. When there is no styles grid, the view will render without collapsible\n\t\t// for numbered list properties, hence simplifying the layout.\n\t\tif ( enabledProperties.styles ) {\n\t\t\tthis.stylesView = this._createStylesView( styleButtonViews, styleGridAriaLabel );\n\t\t\tthis.children.add( this.stylesView );\n\t\t} else {\n\t\t\telementCssClasses.push( 'ck-list-properties_without-styles' );\n\t\t}\n\n\t\t// The rendering of the numbered list property views is also conditional. It only makes sense for the numbered list\n\t\t// dropdown. The unordered list does not have such properties.\n\t\tif ( enabledProperties.startIndex || enabledProperties.reversed ) {\n\t\t\tthis._addNumberedListPropertyViews( enabledProperties, styleButtonViews );\n\n\t\t\telementCssClasses.push( 'ck-list-properties_with-numbered-properties' );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: elementCssClasses\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\tif ( this.stylesView ) {\n\t\t\tthis.focusables.add( this.stylesView );\n\t\t\tthis.focusTracker.add( this.stylesView.element );\n\n\t\t\t// Register the collapsible toggle button to the focus system.\n\t\t\tif ( this.startIndexFieldView || this.reversedSwitchButtonView ) {\n\t\t\t\tthis.focusables.add( this.children.last.buttonView );\n\t\t\t\tthis.focusTracker.add( this.children.last.buttonView.element );\n\t\t\t}\n\n\t\t\tfor ( const item of this.stylesView.children ) {\n\t\t\t\tthis.stylesView.focusTracker.add( item.element );\n\t\t\t}\n\n\t\t\taddKeyboardHandlingForGrid( {\n\t\t\t\tkeystrokeHandler: this.stylesView.keystrokes,\n\t\t\t\tfocusTracker: this.stylesView.focusTracker,\n\t\t\t\tgridItems: this.stylesView.children,\n\t\t\t\t// Note: The styles view has a different number of columns depending on whether the other properties\n\t\t\t\t// are enabled in the dropdown or not (https://github.com/ckeditor/ckeditor5/issues/12340)\n\t\t\t\tnumberOfColumns: () => global.window\n\t\t\t\t\t.getComputedStyle( this.stylesView.element )\n\t\t\t\t\t.getPropertyValue( 'grid-template-columns' )\n\t\t\t\t\t.split( ' ' )\n\t\t\t\t\t.length\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.startIndexFieldView ) {\n\t\t\tthis.focusables.add( this.startIndexFieldView );\n\t\t\tthis.focusTracker.add( this.startIndexFieldView.element );\n\n\t\t\t// Intercept the `selectstart` event, which is blocked by default because of the default behavior\n\t\t\t// of the DropdownView#panelView.\n\t\t\t// TODO: blocking `selectstart` in the #panelView should be configurable per–drop–down instance.\n\t\t\tthis.listenTo( this.startIndexFieldView.element, 'selectstart', ( evt, domEvt ) => {\n\t\t\t\tdomEvt.stopPropagation();\n\t\t\t}, { priority: 'high' } );\n\n\t\t\tconst stopPropagation = data => data.stopPropagation();\n\n\t\t\t// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n\t\t\t// keystroke handler would take over the key management in the input. We need to prevent\n\t\t\t// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n\t\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\t\t}\n\n\t\tif ( this.reversedSwitchButtonView ) {\n\t\t\tthis.focusables.add( this.reversedSwitchButtonView );\n\t\t\tthis.focusTracker.add( this.reversedSwitchButtonView.element );\n\t\t}\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocus() {\n\t\tthis.focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocusLast() {\n\t\tthis.focusCycler.focusLast();\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 * Creates the list styles grid.\n\t *\n\t * @protected\n\t * @param {Array.<module:ui/button/buttonview~ButtonView>} styleButtons Buttons to be placed in the grid.\n\t * @param {String} styleGridAriaLabel The assistive technology label of the grid.\n\t * @returns {module:ui/view~View}\n\t */\n\t_createStylesView( styleButtons, styleGridAriaLabel ) {\n\t\tconst stylesView = new View( this.locale );\n\n\t\tstylesView.children = stylesView.createCollection( this.locale );\n\t\tstylesView.children.addMany( styleButtons );\n\n\t\tstylesView.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\t'aria-label': styleGridAriaLabel,\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list-styles-list'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: stylesView.children\n\t\t} );\n\n\t\tstylesView.children.delegate( 'execute' ).to( this );\n\n\t\tstylesView.focus = function() {\n\t\t\tthis.children.first.focus();\n\t\t};\n\n\t\tstylesView.focusTracker = new FocusTracker();\n\t\tstylesView.keystrokes = new KeystrokeHandler();\n\n\t\tstylesView.render();\n\n\t\tstylesView.keystrokes.listenTo( stylesView.element );\n\n\t\treturn stylesView;\n\t}\n\n\t/**\n\t * Renders {@link #startIndexFieldView} and/or {@link #reversedSwitchButtonView} depending on the configuration of the properties view.\n\t *\n\t * @private\n\t * @param {Object.<String,Boolean>} options.enabledProperties An object containing the configuration of enabled list property names\n\t * (see {@link #constructor}).\n\t */\n\t_addNumberedListPropertyViews( enabledProperties ) {\n\t\tconst t = this.locale.t;\n\t\tconst numberedPropertyViews = [];\n\n\t\tif ( enabledProperties.startIndex ) {\n\t\t\tthis.startIndexFieldView = this._createStartIndexField();\n\t\t\tnumberedPropertyViews.push( this.startIndexFieldView );\n\t\t}\n\n\t\tif ( enabledProperties.reversed ) {\n\t\t\tthis.reversedSwitchButtonView = this._createReversedSwitchButton();\n\t\t\tnumberedPropertyViews.push( this.reversedSwitchButtonView );\n\t\t}\n\n\t\t// When there are some style buttons, pack the numbered list properties into a collapsible to separate them.\n\t\tif ( enabledProperties.styles ) {\n\t\t\tthis.additionalPropertiesCollapsibleView = new CollapsibleView( this.locale, numberedPropertyViews );\n\n\t\t\tthis.additionalPropertiesCollapsibleView.set( {\n\t\t\t\tlabel: t( 'List properties' ),\n\t\t\t\tisCollapsed: true\n\t\t\t} );\n\n\t\t\t// Don't enable the collapsible view unless either start index or reversed field is enabled (e.g. when no list is selected).\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.bind( 'isEnabled' ).toMany(\n\t\t\t\tnumberedPropertyViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) );\n\n\t\t\t// Automatically collapse the additional properties collapsible when either start index or reversed field gets disabled.\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.on( 'change:isEnabled', ( evt, data, isEnabled ) => {\n\t\t\t\tif ( !isEnabled ) {\n\t\t\t\t\tthis.additionalPropertiesCollapsibleView.isCollapsed = true;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthis.children.add( this.additionalPropertiesCollapsibleView );\n\t\t} else {\n\t\t\tthis.children.addMany( numberedPropertyViews );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the list start index labeled field.\n\t *\n\t * @private\n\t * @protected\n\t * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n\t */\n\t_createStartIndexField() {\n\t\tconst t = this.locale.t;\n\t\tconst startIndexFieldView = new LabeledFieldView( this.locale, createLabeledInputNumber );\n\n\t\tstartIndexFieldView.set( {\n\t\t\tlabel: t( 'Start at' ),\n\t\t\tclass: 'ck-numbered-list-properties__start-index'\n\t\t} );\n\n\t\tstartIndexFieldView.fieldView.set( {\n\t\t\tmin: 1,\n\t\t\tstep: 1,\n\t\t\tvalue: 1,\n\t\t\tinputMode: 'numeric'\n\t\t} );\n\n\t\tstartIndexFieldView.fieldView.on( 'input', () => {\n\t\t\tconst inputElement = startIndexFieldView.fieldView.element;\n\t\t\tconst startIndex = inputElement.valueAsNumber;\n\n\t\t\tif ( Number.isNaN( startIndex ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !inputElement.checkValidity() ) {\n\t\t\t\tstartIndexFieldView.errorText = t( 'Start index must be greater than 0.' );\n\t\t\t} else {\n\t\t\t\tthis.fire( 'listStart', { startIndex } );\n\t\t\t}\n\t\t} );\n\n\t\treturn startIndexFieldView;\n\t}\n\n\t/**\n\t * Creates the reversed list switch button.\n\t *\n\t * @private\n\t * @protected\n\t * @returns {module:ui/button/switchbuttonview~SwitchButtonView}\n\t */\n\t_createReversedSwitchButton() {\n\t\tconst t = this.locale.t;\n\t\tconst reversedButtonView = new SwitchButtonView( this.locale );\n\n\t\treversedButtonView.set( {\n\t\t\twithText: true,\n\t\t\tlabel: t( 'Reversed order' ),\n\t\t\tclass: 'ck-numbered-list-properties__reversed-order'\n\t\t} );\n\n\t\treversedButtonView.delegate( 'execute' ).to( this, 'listReversed' );\n\n\t\treturn reversedButtonView;\n\t}\n\n\t/**\n\t * Fired when the list start index value has changed via {@link #startIndexFieldView}.\n\t *\n\t * @event listStart\n\t * @param {Object} data\n\t * @param {Number} data.startIndex The new start index of the list.\n\t */\n\n\t/**\n\t * Fired when the list order has changed (reversed) via {@link #reversedSwitchButtonView}.\n\t *\n\t * @event listReversed\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 list/todolist\n */\n\nimport TodoListEditing from './todolist/todolistediting';\nimport TodoListUI from './todolist/todolistui';\nimport { Plugin } from 'ckeditor5/src/core';\nimport '../theme/todolist.css';\n\n/**\n * The to-do list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/todolist/todolistediting~TodoListEditing to-do list editing feature}\n * and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TodoList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TodoListEditing, TodoListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TodoList';\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 list/todolist/checktodolistcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nconst attributeKey = 'todoListChecked';\n\n/**\n * The check to-do command.\n *\n * The command is registered by the {@link module:list/todolist/todolistediting~TodoListEditing} as\n * the `checkTodoList` editor command and it is also available via aliased `todoListCheck` name.\n *\n * @extends module:core/command~Command\n */\nexport default class CheckTodoListCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * A flag indicating whether the command is active. The command is active when at least one of\n\t\t * {@link module:engine/model/selection~Selection selected} elements is a to-do list item.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\n\t\t/**\n\t\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Array.<module:engine/model/element~Element>} #value\n\t\t */\n\n\t\t/**\n\t\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t\t *\n\t\t * @protected\n\t\t * @type {Array.<module:engine/model/element~Element>}\n\t\t */\n\t\tthis._selectedElements = [];\n\n\t\t// Refresh command before executing to be sure all values are up to date.\n\t\t// It is needed when selection has changed before command execution, in the same change block.\n\t\tthis.on( 'execute', () => {\n\t\t\tthis.refresh();\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t */\n\trefresh() {\n\t\tthis._selectedElements = this._getSelectedItems();\n\t\tthis.value = this._selectedElements.every( element => !!element.getAttribute( 'todoListChecked' ) );\n\t\tthis.isEnabled = !!this._selectedElements.length;\n\t}\n\n\t/**\n\t * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t *\n\t * @private\n\t * @returns {Array.<module:engine/model/element~Element>}\n\t */\n\t_getSelectedItems() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\n\t\tconst selectionRange = model.document.selection.getFirstRange();\n\t\tconst startElement = selectionRange.start.parent;\n\t\tconst elements = [];\n\n\t\tif ( schema.checkAttribute( startElement, attributeKey ) ) {\n\t\t\telements.push( startElement );\n\t\t}\n\n\t\tfor ( const item of selectionRange.getItems() ) {\n\t\t\tif ( schema.checkAttribute( item, attributeKey ) && !elements.includes( item ) ) {\n\t\t\t\telements.push( item );\n\t\t\t}\n\t\t}\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply\n\t * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t * value to decide what it should do.\n\t */\n\texecute( options = {} ) {\n\t\tthis.editor.model.change( writer => {\n\t\t\tfor ( const element of this._selectedElements ) {\n\t\t\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\t\t\tif ( value ) {\n\t\t\t\t\twriter.setAttribute( attributeKey, true, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( attributeKey, element );\n\t\t\t\t}\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 list/todolist/todolistconverters\n */\n\n/* global document */\n\nimport { createElement } from 'ckeditor5/src/utils';\n\nimport { generateLiInUl, injectViewList, positionAfterUiElements, findNestedList } from '../list/utils';\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It converts the `listItem` model element to an unordered list with a {@link module:engine/view/uielement~UIElement checkbox element}\n * at the beginning of each list item. It also merges the list with surrounding lists (if available).\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @param {Function} onCheckboxChecked Callback function.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewInsertion( model, onCheckboxChecked ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.item;\n\n\t\tconsumable.consume( modelItem, 'insert' );\n\t\tconsumable.consume( modelItem, 'attribute:listType' );\n\t\tconsumable.consume( modelItem, 'attribute:listIndent' );\n\t\tconsumable.consume( modelItem, 'attribute:todoListChecked' );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tconst isChecked = !!modelItem.getAttribute( 'todoListChecked' );\n\t\tconst checkmarkElement = createCheckmarkElement( modelItem, viewWriter, isChecked, onCheckboxChecked );\n\n\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\tclass: 'todo-list__label__description'\n\t\t} );\n\n\t\tviewWriter.addClass( 'todo-list', viewItem.parent );\n\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );\n\t\tviewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function dataModelViewInsertion( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.item;\n\n\t\tconsumable.consume( modelItem, 'insert' );\n\t\tconsumable.consume( modelItem, 'attribute:listType' );\n\t\tconsumable.consume( modelItem, 'attribute:listIndent' );\n\t\tconsumable.consume( modelItem, 'attribute:todoListChecked' );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tviewWriter.addClass( 'todo-list', viewItem.parent );\n\n\t\tconst label = viewWriter.createContainerElement( 'label', {\n\t\t\tclass: 'todo-list__label'\n\t\t} );\n\n\t\tconst checkbox = viewWriter.createEmptyElement( 'input', {\n\t\t\ttype: 'checkbox',\n\t\t\tdisabled: 'disabled'\n\t\t} );\n\n\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\tclass: 'todo-list__label__description'\n\t\t} );\n\n\t\tif ( modelItem.getAttribute( 'todoListChecked' ) ) {\n\t\t\tviewWriter.setAttribute( 'checked', 'checked', checkbox );\n\t\t}\n\n\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), label );\n\t\tviewWriter.insert( viewWriter.createPositionAt( label, 0 ), checkbox );\n\t\tviewWriter.insert( viewWriter.createPositionAfter( checkbox ), span );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A view-to-model converter for the checkbox element inside a view list item.\n *\n * It changes the `listType` of the model `listItem` to a `todo` value.\n * When a view checkbox element is marked as checked, an additional `todoListChecked=\"true\"` attribute is added to the model item.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input, a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function dataViewModelCheckmarkInsertion( evt, data, conversionApi ) {\n\tconst modelCursor = data.modelCursor;\n\tconst modelItem = modelCursor.parent;\n\tconst viewItem = data.viewItem;\n\n\tif ( viewItem.getAttribute( 'type' ) != 'checkbox' || modelItem.name != 'listItem' || !modelCursor.isAtStart ) {\n\t\treturn;\n\t}\n\n\tif ( !conversionApi.consumable.consume( viewItem, { name: true } ) ) {\n\t\treturn;\n\t}\n\n\tconst writer = conversionApi.writer;\n\n\twriter.setAttribute( 'listType', 'todo', modelItem );\n\n\tif ( data.viewItem.hasAttribute( 'checked' ) ) {\n\t\twriter.setAttribute( 'todoListChecked', true, modelItem );\n\t}\n\n\tdata.modelRange = writer.createRange( modelCursor );\n}\n\n/**\n * A model-to-view converter for the `listType` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes to `<ul class=\"todo-list\">` and a\n * {@link module:engine/view/uielement~UIElement checkbox UI element} is added at the beginning\n * of the list item element (or vice versa).\n *\n * This converter is preceded by {@link module:list/list/converters~modelViewChangeType} and followed by\n * {@link module:list/list/converters~modelViewMergeAfterChangeType} to handle splitting and merging surrounding lists of the same type.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {Function} onCheckedChange Callback fired after clicking the checkbox UI element.\n * @param {module:engine/view/view~View} view Editing view controller.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeType( onCheckedChange, view ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tconst labelElement = findLabel( viewItem, view );\n\n\t\tif ( data.attributeNewValue == 'todo' ) {\n\t\t\tconst isChecked = !!data.item.getAttribute( 'todoListChecked' );\n\t\t\tconst checkmarkElement = createCheckmarkElement( data.item, viewWriter, isChecked, onCheckedChange );\n\n\t\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\t\tclass: 'todo-list__label__description'\n\t\t\t} );\n\n\t\t\tconst itemRange = viewWriter.createRangeIn( viewItem );\n\t\t\tconst nestedList = findNestedList( viewItem );\n\n\t\t\tconst descriptionStart = positionAfterUiElements( itemRange.start );\n\t\t\tconst descriptionEnd = nestedList ? viewWriter.createPositionBefore( nestedList ) : itemRange.end;\n\t\t\tconst descriptionRange = viewWriter.createRange( descriptionStart, descriptionEnd );\n\n\t\t\tviewWriter.addClass( 'todo-list', viewItem.parent );\n\t\t\tviewWriter.move( descriptionRange, viewWriter.createPositionAt( span, 0 ) );\n\t\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );\n\t\t\tviewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );\n\t\t} else if ( data.attributeOldValue == 'todo' ) {\n\t\t\tconst descriptionSpan = findDescription( viewItem, view );\n\n\t\t\tviewWriter.removeClass( 'todo-list', viewItem.parent );\n\t\t\tviewWriter.remove( labelElement );\n\t\t\tviewWriter.move( viewWriter.createRangeIn( descriptionSpan ), viewWriter.createPositionBefore( descriptionSpan ) );\n\t\t\tviewWriter.remove( descriptionSpan );\n\t\t}\n\t};\n}\n\n/**\n * A model-to-view converter for the `todoListChecked` attribute change on the `listItem` model element.\n *\n * It marks the {@link module:engine/view/uielement~UIElement checkbox UI element} as checked.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {Function} onCheckedChange Callback fired after clicking the checkbox UI element.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeChecked( onCheckedChange ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Do not convert `todoListChecked` attribute when to-do list item has changed to other list item.\n\t\t// This attribute will be removed by the model post fixer.\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:todoListChecked' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { mapper, writer: viewWriter } = conversionApi;\n\t\tconst isChecked = !!data.item.getAttribute( 'todoListChecked' );\n\t\tconst viewItem = mapper.toViewElement( data.item );\n\t\t// Because of m -> v position mapper we can be sure checkbox is always at the beginning.\n\t\tconst oldCheckmarkElement = viewItem.getChild( 0 );\n\t\tconst newCheckmarkElement = createCheckmarkElement( data.item, viewWriter, isChecked, onCheckedChange );\n\n\t\tviewWriter.insert( viewWriter.createPositionAfter( oldCheckmarkElement ), newCheckmarkElement );\n\t\tviewWriter.remove( oldCheckmarkElement );\n\t};\n}\n\n/**\n * A model-to-view position at zero offset mapper.\n *\n * This helper ensures that position inside todo-list in the view is mapped after the checkbox.\n *\n * It only handles the position at the beginning of a list item as other positions are properly mapped be the default mapper.\n *\n * @param {module:engine/view/view~View} view\n * @return {Function}\n */\nexport function mapModelToViewPosition( view ) {\n\treturn ( evt, data ) => {\n\t\tconst modelPosition = data.modelPosition;\n\t\tconst parent = modelPosition.parent;\n\n\t\tif ( !parent.is( 'element', 'listItem' ) || parent.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewLi = data.mapper.toViewElement( parent );\n\t\tconst descSpan = findDescription( viewLi, view );\n\n\t\tif ( descSpan ) {\n\t\t\tdata.viewPosition = data.mapper.findPositionIn( descSpan, modelPosition.offset );\n\t\t}\n\t};\n}\n\n// Creates a checkbox UI element.\n//\n// @private\n// @param {module:engine/model/item~Item} modelItem\n// @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n// @param {Boolean} isChecked\n// @param {Function} onChange\n// @returns {module:view/uielement~UIElement}\nfunction createCheckmarkElement( modelItem, viewWriter, isChecked, onChange ) {\n\tconst uiElement = viewWriter.createUIElement(\n\t\t'label',\n\t\t{\n\t\t\tclass: 'todo-list__label',\n\t\t\tcontenteditable: false\n\t\t},\n\t\tfunction( domDocument ) {\n\t\t\tconst checkbox = createElement( document, 'input', { type: 'checkbox' } );\n\n\t\t\tif ( isChecked ) {\n\t\t\t\tcheckbox.setAttribute( 'checked', 'checked' );\n\t\t\t}\n\n\t\t\tcheckbox.addEventListener( 'change', () => onChange( modelItem ) );\n\n\t\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t\tdomElement.appendChild( checkbox );\n\n\t\t\treturn domElement;\n\t\t}\n\t);\n\n\treturn uiElement;\n}\n\n// Helper method to find label element inside li.\nfunction findLabel( viewItem, view ) {\n\tconst range = view.createRangeIn( viewItem );\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'uiElement', 'label' ) ) {\n\t\t\treturn value.item;\n\t\t}\n\t}\n}\n\nfunction findDescription( viewItem, view ) {\n\tconst range = view.createRangeIn( viewItem );\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'containerElement', 'span' ) && value.item.hasClass( 'todo-list__label__description' ) ) {\n\t\t\treturn value.item;\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 list/todolist/todolistediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport {\n\tgetCode,\n\tparseKeystroke,\n\tgetLocalizedArrowKeyCodeDirection\n} from 'ckeditor5/src/utils';\n\nimport ListCommand from '../list/listcommand';\nimport ListEditing from '../list/listediting';\nimport CheckTodoListCommand from './checktodolistcommand';\nimport {\n\tdataModelViewInsertion,\n\tdataViewModelCheckmarkInsertion,\n\tmapModelToViewPosition,\n\tmodelViewChangeChecked,\n\tmodelViewChangeType,\n\tmodelViewInsertion\n} from './todolistconverters';\n\nconst ITEM_TOGGLE_KEYSTROKE = parseKeystroke( 'Ctrl+Enter' );\n\n/**\n * The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n *\n * It registers the entire functionality of the {@link module:list/list/listediting~ListEditing list editing plugin} and extends\n * it with the commands:\n *\n * - `'todoList'`,\n * - `'checkTodoList'`,\n * - `'todoListCheck'` as an alias for `checkTodoList` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TodoListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TodoListEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst { editing, data, model } = editor;\n\n\t\t// Extend schema.\n\t\tmodel.schema.extend( 'listItem', {\n\t\t\tallowAttributes: [ 'todoListChecked' ]\n\t\t} );\n\n\t\t// Disallow todoListChecked attribute on other nodes than listItem with to-do listType.\n\t\tmodel.schema.addAttributeCheck( ( context, attributeName ) => {\n\t\t\tconst item = context.last;\n\n\t\t\tif ( attributeName == 'todoListChecked' && item.name == 'listItem' && item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\n\t\t// Register `todoList` command.\n\t\teditor.commands.add( 'todoList', new ListCommand( editor, 'todo' ) );\n\n\t\tconst checkTodoListCommand = new CheckTodoListCommand( editor );\n\n\t\t// Register `checkTodoList` command and add `todoListCheck` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'checkTodoList', checkTodoListCommand );\n\t\teditor.commands.add( 'todoListCheck', checkTodoListCommand );\n\n\t\t// Define converters.\n\t\tdata.downcastDispatcher.on( 'insert:listItem', dataModelViewInsertion( model ), { priority: 'high' } );\n\t\tdata.upcastDispatcher.on( 'element:input', dataViewModelCheckmarkInsertion, { priority: 'high' } );\n\n\t\tediting.downcastDispatcher.on(\n\t\t\t'insert:listItem',\n\t\t\tmodelViewInsertion( model, listItem => this._handleCheckmarkChange( listItem ) ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\t\tediting.downcastDispatcher.on(\n\t\t\t'attribute:listType:listItem',\n\t\t\tmodelViewChangeType( listItem => this._handleCheckmarkChange( listItem ), editing.view )\n\t\t);\n\t\tediting.downcastDispatcher.on(\n\t\t\t'attribute:todoListChecked:listItem',\n\t\t\tmodelViewChangeChecked( listItem => this._handleCheckmarkChange( listItem ) )\n\t\t);\n\n\t\tediting.mapper.on( 'modelToViewPosition', mapModelToViewPosition( editing.view ) );\n\t\tdata.mapper.on( 'modelToViewPosition', mapModelToViewPosition( editing.view ) );\n\n\t\t// Jump at the end of the previous node on left arrow key press, when selection is after the checkbox.\n\t\t//\n\t\t// <blockquote><p>Foo</p></blockquote>\n\t\t// <ul><li><checkbox/>{}Bar</li></ul>\n\t\t//\n\t\t// press: `<-`\n\t\t//\n\t\t// <blockquote><p>Foo{}</p></blockquote>\n\t\t// <ul><li><checkbox/>Bar</li></ul>\n\t\t//\n\t\tthis.listenTo( editing.view.document, 'arrowKey', jumpOverCheckmarkOnSideArrowKeyPress( model, editor.locale ), { context: 'li' } );\n\n\t\t// Toggle check state of selected to-do list items on keystroke.\n\t\tthis.listenTo( editing.view.document, 'keydown', ( evt, data ) => {\n\t\t\tif ( getCode( data ) === ITEM_TOGGLE_KEYSTROKE ) {\n\t\t\t\teditor.execute( 'checkTodoList' );\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// Remove `todoListChecked` attribute when a host element is no longer a to-do list item.\n\t\tconst listItemsToFix = new Set();\n\n\t\tthis.listenTo( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.type == 'rename' && operation.oldName == 'listItem' ) {\n\t\t\t\tconst item = operation.position.nodeAfter;\n\n\t\t\t\tif ( item.hasAttribute( 'todoListChecked' ) ) {\n\t\t\t\t\tlistItemsToFix.add( item );\n\t\t\t\t}\n\t\t\t} else if ( operation.type == 'changeAttribute' && operation.key == 'listType' && operation.oldValue === 'todo' ) {\n\t\t\t\tfor ( const item of operation.range.getItems() ) {\n\t\t\t\t\tif ( item.hasAttribute( 'todoListChecked' ) && item.getAttribute( 'listType' ) !== 'todo' ) {\n\t\t\t\t\t\tlistItemsToFix.add( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tmodel.document.registerPostFixer( writer => {\n\t\t\tlet hasChanged = false;\n\n\t\t\tfor ( const listItem of listItemsToFix ) {\n\t\t\t\twriter.removeAttribute( 'todoListChecked', listItem );\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tlistItemsToFix.clear();\n\n\t\t\treturn hasChanged;\n\t\t} );\n\t}\n\n\t/**\n\t * Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t * to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t *\n\t * Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t * is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t * See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} listItem\n\t */\n\t_handleCheckmarkChange( listItem ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst previousSelectionRanges = Array.from( model.document.selection.getRanges() );\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( listItem, 'end' );\n\t\t\teditor.execute( 'checkTodoList' );\n\t\t\twriter.setSelection( previousSelectionRanges );\n\t\t} );\n\t}\n}\n\n// Handles the left/right (LTR/RTL content) arrow key and moves the selection at the end of the previous block element\n// if the selection is just after the checkbox element. In other words, it jumps over the checkbox element when\n// moving the selection to the left/right (LTR/RTL).\n//\n// @private\n// @param {module:engine/model/model~Model} model\n// @param {module:utils/locale~Locale} locale\n// @returns {Function} Callback for 'keydown' events.\nfunction jumpOverCheckmarkOnSideArrowKeyPress( model, locale ) {\n\treturn ( eventInfo, domEventData ) => {\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( domEventData.keyCode, locale.contentLanguageDirection );\n\n\t\tif ( direction != 'left' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = selection.getFirstPosition();\n\t\tconst parent = position.parent;\n\n\t\tif ( parent.name === 'listItem' && parent.getAttribute( 'listType' ) == 'todo' && position.isAtStart ) {\n\t\t\tconst newRange = schema.getNearestSelectionRange( model.createPositionBefore( parent ), 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodel.change( writer => writer.setSelection( newRange ) );\n\t\t\t}\n\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\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 list/todolist/todolistui\n */\n\nimport { createUIComponent } from '../list/utils';\nimport todoListIcon from '../../theme/icons/todolist.svg';\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The to-do list UI feature. It introduces the `'todoList'` button that\n * allows to convert elements to and from to-do list items and to indent or outdent them.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TodoListUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TodoListUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst t = this.editor.t;\n\n\t\tcreateUIComponent( this.editor, 'todoList', t( 'To-do List' ), todoListIcon );\n\t}\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/enter.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/typing.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 = CKEditor5.dll;","// 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};","__webpack_require__.nc = undefined;","/**\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 list\n */\n\nexport { default as DocumentList } from './documentlist';\nexport { default as DocumentListEditing } from './documentlist/documentlistediting';\nexport { default as DocumentListProperties } from './documentlistproperties';\nexport { default as DocumentListPropertiesEditing } from './documentlistproperties/documentlistpropertiesediting';\nexport { default as List } from './list';\nexport { default as ListEditing } from './list/listediting';\nexport { default as ListUI } from './list/listui';\nexport { default as ListProperties } from './listproperties';\nexport { default as ListPropertiesEditing } from './listproperties/listpropertiesediting';\nexport { default as ListPropertiesUI } from './listproperties/listpropertiesui';\nexport { default as TodoList } from './todolist';\nexport { default as TodoListEditing } from './todolist/todolistediting';\nexport { default as TodoListUI } from './todolist/todolistui';\n"],"sourceRoot":""}
1
+ {"version":3,"sources":["webpack://CKEditor5.list/./theme/collapsible.css","webpack://CKEditor5.list/./theme/documentlist.css","webpack://CKEditor5.list/./theme/listproperties.css","webpack://CKEditor5.list/./theme/liststyles.css","webpack://CKEditor5.list/./theme/todolist.css","webpack://CKEditor5.list/../node_modules/css-loader/dist/runtime/api.js","webpack://CKEditor5.list/../node_modules/css-loader/dist/runtime/cssWithMappingToString.js","webpack://CKEditor5.list/./theme/icons/bulletedlist.svg","webpack://CKEditor5.list/./theme/icons/liststylecircle.svg","webpack://CKEditor5.list/./theme/icons/liststyledecimal.svg","webpack://CKEditor5.list/./theme/icons/liststyledecimalleadingzero.svg","webpack://CKEditor5.list/./theme/icons/liststyledisc.svg","webpack://CKEditor5.list/./theme/icons/liststylelowerlatin.svg","webpack://CKEditor5.list/./theme/icons/liststylelowerroman.svg","webpack://CKEditor5.list/./theme/icons/liststylesquare.svg","webpack://CKEditor5.list/./theme/icons/liststyleupperlatin.svg","webpack://CKEditor5.list/./theme/icons/liststyleupperroman.svg","webpack://CKEditor5.list/./theme/icons/numberedlist.svg","webpack://CKEditor5.list/./theme/icons/todolist.svg","webpack://CKEditor5.list/../ckeditor5-ui/theme/icons/dropdown-arrow.svg","webpack://CKEditor5.list/./theme/collapsible.css?56dc","webpack://CKEditor5.list/./theme/documentlist.css?7eef","webpack://CKEditor5.list/./theme/listproperties.css?da79","webpack://CKEditor5.list/./theme/liststyles.css?bcba","webpack://CKEditor5.list/./theme/todolist.css?40fa","webpack://CKEditor5.list/../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack://CKEditor5.list/./src/documentlist.js","webpack://CKEditor5.list/./src/documentlist/converters.js","webpack://CKEditor5.list/./src/documentlist/documentlistcommand.js","webpack://CKEditor5.list/./src/documentlist/documentlistediting.js","webpack://CKEditor5.list/./src/documentlist/documentlistindentcommand.js","webpack://CKEditor5.list/./src/documentlist/documentlistmergecommand.js","webpack://CKEditor5.list/./src/documentlist/documentlistsplitcommand.js","webpack://CKEditor5.list/./src/documentlist/utils/listwalker.js","webpack://CKEditor5.list/./src/documentlist/utils/model.js","webpack://CKEditor5.list/./src/documentlist/utils/postfixers.js","webpack://CKEditor5.list/./src/documentlist/utils/view.js","webpack://CKEditor5.list/./src/documentlistproperties.js","webpack://CKEditor5.list/./src/documentlistproperties/converters.js","webpack://CKEditor5.list/./src/documentlistproperties/documentlistpropertiesediting.js","webpack://CKEditor5.list/./src/documentlistproperties/documentlistreversedcommand.js","webpack://CKEditor5.list/./src/documentlistproperties/documentliststartcommand.js","webpack://CKEditor5.list/./src/documentlistproperties/documentliststylecommand.js","webpack://CKEditor5.list/./src/documentlistproperties/utils/style.js","webpack://CKEditor5.list/./src/list.js","webpack://CKEditor5.list/./src/list/converters.js","webpack://CKEditor5.list/./src/list/indentcommand.js","webpack://CKEditor5.list/./src/list/listcommand.js","webpack://CKEditor5.list/./src/list/listediting.js","webpack://CKEditor5.list/./src/list/listui.js","webpack://CKEditor5.list/./src/list/utils.js","webpack://CKEditor5.list/./src/listproperties.js","webpack://CKEditor5.list/./src/listproperties/listpropertiesediting.js","webpack://CKEditor5.list/./src/listproperties/listpropertiesui.js","webpack://CKEditor5.list/./src/listproperties/listreversedcommand.js","webpack://CKEditor5.list/./src/listproperties/liststartcommand.js","webpack://CKEditor5.list/./src/listproperties/liststylecommand.js","webpack://CKEditor5.list/./src/listproperties/ui/collapsibleview.js","webpack://CKEditor5.list/./src/listproperties/ui/listpropertiesview.js","webpack://CKEditor5.list/./src/todolist.js","webpack://CKEditor5.list/./src/todolist/checktodolistcommand.js","webpack://CKEditor5.list/./src/todolist/todolistconverters.js","webpack://CKEditor5.list/./src/todolist/todolistediting.js","webpack://CKEditor5.list/./src/todolist/todolistui.js","webpack://CKEditor5.list/delegated \"./src/core.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/engine.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/enter.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/typing.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/ui.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/delegated \"./src/utils.js\" from dll-reference CKEditor5.dll","webpack://CKEditor5.list/external var \"CKEditor5.dll\"","webpack://CKEditor5.list/webpack/bootstrap","webpack://CKEditor5.list/webpack/runtime/compat get default export","webpack://CKEditor5.list/webpack/runtime/define property getters","webpack://CKEditor5.list/webpack/runtime/hasOwnProperty shorthand","webpack://CKEditor5.list/webpack/runtime/make namespace object","webpack://CKEditor5.list/webpack/runtime/nonce","webpack://CKEditor5.list/./src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gHAAgH,aAAa,MAAM,0DAA0D,iCAAiC,gBAAgB,cAAc,gBAAgB,yDAAyD,WAAW,uCAAuC,uBAAuB,wIAAwI,uBAAuB,yBAAyB,gBAAgB,0CAA0C,sCAAsC,uCAAuC,6CAA6C,0DAA0D,mEAAmE,yBAAyB,OAAO,wmBAAwmB,mCAAmC,oBAAoB,KAAK,GAAG,0LAA0L,iEAAiE,GAAG,wBAAwB,uBAAuB,kBAAkB,wBAAwB,gEAAgE,uBAAuB,qBAAqB,iBAAiB,gCAAgC,OAAO,sDAAsD,gCAAgC,kCAAkC,yBAAyB,OAAO,sBAAsB,+CAA+C,gDAAgD,OAAO,KAAK,qCAAqC,iEAAiE,KAAK,kCAAkC,kCAAkC,kCAAkC,OAAO,KAAK,GAAG,qBAAqB;AACvkF;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,wFAAwF,cAAc,OAAO,qVAAqV,mBAAmB,GAAG,qBAAqB;AAC7e;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,mGAAmG,gCAAgC,2DAA2D,eAAe,6DAA6D,sCAAsC,wFAAwF,qCAAqC,mFAAmF,iDAAiD,+GAA+G,WAAW,iHAAiH,sCAAsC,8EAA8E,eAAe,WAAW,uEAAuE,uBAAuB,8CAA8C,eAAe,gBAAgB,2JAA2J,gBAAgB,yBAAyB,gBAAgB,OAAO,mkBAAmkB,6GAA6G,uCAAuC,eAAe,wBAAwB,iBAAiB,iDAAiD,SAAS,OAAO,KAAK,iPAAiP,gCAAgC,iDAAiD,OAAO,gHAAgH,0DAA0D,yCAAyC,iBAAiB,wBAAwB,qBAAqB,qDAAqD,aAAa,WAAW,SAAS,OAAO,KAAK,gEAAgE,sBAAsB,kBAAkB,KAAK,yDAAyD,8BAA8B,sBAAsB,uBAAuB,uDAAuD,2BAA2B,yBAAyB,kCAAkC,yBAAyB,OAAO,KAAK,GAAG,qBAAqB;AAC5vG;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,kEAAkE,aAAa,eAAe,wBAAwB,kBAAkB,4BAA4B,qBAAqB,4BAA4B,wBAAwB,4BAA4B,2BAA2B,4BAA4B,eAAe,uBAAuB,kBAAkB,qBAAqB,6CAA6C,uBAAuB,MAAM,iCAAiC,wBAAwB,oCAAoC,qCAAqC,gCAAgC,iCAAiC,mCAAmC,uBAAuB,SAAS,UAAU,+EAA+E,wCAAwC,uCAAuC,OAAO,kqBAAkqB,kBAAkB,GAAG,oBAAoB,6BAA6B,YAAY,mCAAmC,cAAc,qCAAqC,gBAAgB,uCAAuC,kBAAkB,yCAAyC,WAAW,SAAS,OAAO,KAAK,GAAG,oBAAoB,4BAA4B,YAAY,4BAA4B,cAAc,gCAAgC,gBAAgB,kCAAkC,SAAS,OAAO,KAAK,GAAG,0LAA0L,sCAAsC,GAAG,6BAA6B,6CAA6C,sCAAsC,yCAAyC,qCAAqC,oBAAoB,4HAA4H,+CAA+C,iBAAiB,+JAA+J,mRAAmR,oBAAoB,gDAAgD,iDAAiD,OAAO,KAAK,GAAG,qBAAqB;AACvvG;AACA,iEAAe,uBAAuB,EAAC;;;;;;;;;;;;;;;;;;;;ACPvC;AAC4H;AAC7B;AAC/F,8BAA8B,mFAA2B,CAAC,wGAAqC;AAC/F;AACA,gDAAgD,mCAAmC,uBAAuB,gBAAgB,0BAA0B,kBAAkB,qCAAqC,eAAe,+CAA+C,wBAAwB,SAAS,qBAAqB,0CAA0C,WAAW,cAAc,mBAAmB,kBAAkB,QAAQ,sBAAsB,yCAAyC,sDAAsD,sBAAsB,kBAAkB,sBAAsB,aAAa,cAAc,YAAY,kBAAkB,2FAA2F,WAAW,qDAAqD,yBAAyB,mBAAmB,uGAAuG,uBAAuB,aAAa,cAAc,oDAAoD,gDAAgD,oBAAoB,kBAAkB,iDAAiD,wBAAwB,mDAAmD,+DAA+D,mBAAmB,qBAAqB,8DAA8D,kBAAkB,wEAAwE,sBAAsB,6CAA6C,OAAO,kBAAkB,eAAe,YAAY,wDAAwD,eAAe,qEAAqE,oCAAoC,OAAO,64BAA64B,wCAAwC,GAAG,4BAA4B,qBAAqB,YAAY,yBAAyB,sBAAsB,wBAAwB,OAAO,KAAK,2BAA2B,iBAAiB,iCAAiC,8BAA8B,2BAA2B,kDAAkD,mDAAmD,+BAA+B,+CAA+C,8CAA8C,4BAA4B,iBAAiB,uBAAuB,qBAAqB,yBAAyB,6BAA6B,iCAAiC,sBAAsB,sBAAsB,uBAAuB,4CAA4C,6BAA6B,2GAA2G,SAAS,oBAAoB,yBAAyB,6BAA6B,kCAAkC,+BAA+B,sBAAsB,mKAAmK,gEAAgE,kEAAkE,mEAAmE,8BAA8B,oCAAoC,0HAA0H,mCAAmC,SAAS,sBAAsB,qBAAqB,2CAA2C,6CAA6C,WAAW,sBAAsB,2CAA2C,WAAW,SAAS,OAAO,0CAA0C,+BAA+B,OAAO,KAAK,GAAG,0EAA0E,YAAY,oBAAoB,iBAAiB,uBAAuB,GAAG,8LAA8L,oBAAoB,uBAAuB,iDAAiD,KAAK,GAAG,qBAAqB;AAC5oK;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,qcAAqc;;;;;;;;;;;;;;;ACApd,iEAAe,8hBAA8hB;;;;;;;;;;;;;;;ACA7iB,iEAAe,mrDAAmrD;;;;;;;;;;;;;;;ACAlsD,iEAAe,4xGAA4xG;;;;;;;;;;;;;;;ACA3yG,iEAAe,ybAAyb;;;;;;;;;;;;;;;ACAxc,iEAAe,ykEAAykE;;;;;;;;;;;;;;;ACAxlE,iEAAe,yyBAAyyB;;;;;;;;;;;;;;;ACAxzB,iEAAe,+XAA+X;;;;;;;;;;;;;;;ACA9Y,iEAAe,oqDAAoqD;;;;;;;;;;;;;;;ACAnrD,iEAAe,6lBAA6lB;;;;;;;;;;;;;;;ACA5mB,iEAAe,kaAAka;;;;;;;;;;;;;;;ACAjb,iEAAe,knBAAknB;;;;;;;;;;;;;;;ACAjoB,iEAAe,uNAAuN;;;;;;;;;;;;;;;;;;ACAvI;AAC/F,YAAgL;;AAEhL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,4JAAO;;;;AAIxB,iEAAe,mKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAiL;;AAEjL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,6JAAO;;;;AAIxB,iEAAe,oKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAAmL;;AAEnL,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,+JAAO;;;;AAIxB,iEAAe,sKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA+K;;AAE/K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,2JAAO;;;;AAIxB,iEAAe,kKAAc,MAAM;;;;;;;;;;;;;;;;;;ACZ4D;AAC/F,YAA6K;;AAE7K,eAAe,+CAA+C;;AAE9D;AACA;;AAEA,aAAa,0GAAG,CAAC,yJAAO;;;;AAIxB,iEAAe,gKAAc,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;;AAE4C;AACyB;AAClC;;AAEnC;AACA;AACA;AACA,2CAA2C;AAC3C,oBAAoB,KAAK,qDAAqD;AAC9E;AACA;AACA;AACe,2BAA2B,sDAAM;AAChD;AACA;AACA;AACA;AACA,WAAW,yEAAmB,EAAE,oDAAM;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;ACnCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAOuB;AAOD;AACoD;AACb;;AAET;;AAEpD;AACA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA,UAAU,iBAAiB;;AAE3B;AACA;AACA;;AAEA,wDAAwD,gBAAgB;AACxE;;AAEA;AACA;AACA;;AAEA;AACA,eAAe,0DAAgB;AAC/B,eAAe,sDAAS;AACxB;AACA;;AAEA;AACA;AACA,SAAS,6DAAe;AACxB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA,wDAAwD,aAAa;AACrE;AACA;;AAEA,yBAAyB,8DAAY;;AAErC;AACA,SAAS,2DAAc,cAAc,uDAAU;AAC/C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,8DAA8D;AACzE,WAAW,gBAAgB;AAC3B,WAAW,kEAAkE;AAC7E,YAAY;AACZ;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,0EAAuB;;AAE3B;AACA;AACA,KAAK,0EAAuB;AAC5B,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,IAAI,0EAAuB;AAC3B;AACA;AACA;AACA;;AAEA;AACA,KAAK,0EAAuB;;AAE5B;AACA,MAAM,0EAAuB;;AAE7B;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA,MAAM,UAAU,6DAAe;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,gBAAgB,iBAAiB,GAAG,2EAAwB;AAC5D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,kBAAkB,+DAAiB,UAAU,uBAAuB;;AAEpE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,2DAAc;AAC3C,yBAAyB,uDAAU;;AAEnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,oCAAoC;AAClD,cAAc,QAAQ;AACtB;AACA,yCAAyC,qCAAqC;AAC9E;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,4FAA4F;AACvG,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;;AAEA;AACA,UAAU,6BAA6B;;AAEvC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,gBAAgB;AAC3B,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO,kDAAkD,eAAe,KAAK;AAC7E,0BAA0B,SAAS;AACnC;AACA;AACA;AACA;;AAEA,+DAA+D,mCAAmC;;AAElG;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,wCAAwC;AACnD,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,oCAAoC,aAAa;AACjD,8BAA8B,kEAAqB;AACnD,0BAA0B,8DAAiB;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,oBAAoB,+DAAgB,qBAAqB,oBAAoB;;AAE7E;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,+BAA+B,eAAe;AAC9C;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA,iEAAiE,kEAAoB;AACrF,OAAO,6DAAe;AACtB;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACrdA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAYtB;;AAEvB;AACA,wCAAwC,kEAAkE;AAC1G;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,uBAAuB;AACnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA,8BAA8B,oEAAsB;;AAEpD;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,uBAAuB,+DAAiB,eAAe,uBAAuB;AAC9E;;AAEA;AACA,4BAA4B,iEAAmB;AAC/C;;AAEA;AACA,2BAA2B,kEAAoB;;AAE/C;AACA,2BAA2B,mEAAqB;;AAEhD;AACA;AACA;AACA,0EAA0E,6DAAe;AACzF,0BAA0B,0DAAY;;AAEtC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,mBAAmB,0DAAgB;AACnC;AACA,OAAO;;AAEP;AACA;AACA;AACA;AACA,0BAA0B,6EAA+B,WAAW,oBAAoB;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,oCAAoC;AAC7F;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvNA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACA;AACE;AACM;;AAEgB;AACZ;AACU;AACA;AAO5C;AAKM;AASL;AAID;AAIM;;AAEU;;AAEtC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACe,kCAAkC,sDAAM;AACvD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,sDAAK,EAAE,wDAAM;AACxB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA,aAAa,8DAAa,4CAA4C,gCAAgC;AACtG;;AAEA,uCAAuC,wCAAwC;AAC/E,mCAAmC,wCAAwC;AAC3E,yCAAyC,wCAAwC;;AAEjF;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA,2CAA2C,4DAAmB;AAC9D,2CAA2C,4DAAmB;;AAE9D,yCAAyC,kEAAyB;AAClE,0CAA0C,kEAAyB;;AAEnE,oDAAoD,iEAAwB;AAC5E,mDAAmD,iEAAwB;;AAE3E,kDAAkD,iEAAwB;AAC1E,iDAAiD,iEAAwB;;AAEzE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,gEAAgE,mBAAmB;AACnF;;AAEA;AACA;AACA;AACA,kEAAkE,qBAAqB;AACvF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAA+D;AAC3E;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC,yDAAyD;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,QAAQ,qEAAsB;AAC9B;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA,WAAW,8DAAe;AAC1B;AACA;;AAEA,2BAA2B,gEAAgB;AAC3C;AACA;AACA,OAAO;;AAEP;AACA;AACA,YAAY,oEAAqB;AACjC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ;AACR;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,KAAK;AACL,GAAG,IAAI,gBAAgB;AACvB;;AAEA;AACA,gCAAgC,wDAAwD;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI,8DAAe;AACnB;AACA;AACA;AACA,yBAAyB,qEAAsB;AAC/C,wBAAwB,oEAAqB;;AAE7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;;AAEvB;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B,mEAAoB;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,gCAAgC,sDAAsD;AACtF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wBAAwB,iCAAiC;AACzD;AACA,iCAAiC,oEAAuB;AACxD,iCAAiC,gEAAmB,MAAM,mBAAmB;AAC7E,iCAAiC,gEAAmB,MAAM,mBAAmB;AAC7E,KAAK;;AAEL;AACA;AACA;AACA,UAAU,kEAAqB;AAC/B;AACA,KAAK;;AAEL;AACA;AACA;AACA,UAAU,kEAAqB,oBAAoB,qBAAqB;AACxE;AACA,KAAK;;AAEL;AACA;AACA,gCAAgC,sEAAyB;AACzD,KAAK;;AAEL,gDAAgD,uEAA0B;;AAE1E;AACA,4CAA4C,+BAA+B;AAC3E;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,4CAA4C,+BAA+B;AAC3E;AACA,wBAAwB,2EAA6B;AACrD,sBAAsB,yEAA2B;AACjD;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,iCAAiC,oBAAoB;AACrD,gBAAgB,iEAAc;AAC9B,GAAG,IAAI,mBAAmB;;AAE1B;AACA,iCAAiC,6BAA6B;AAC9D,gBAAgB,iEAAc;AAC9B,GAAG,IAAI,mBAAmB;AAC1B;;AAEA;AACA,mDAAmD,qDAAqD;AACxG,KAAK,yDAAyD;AAC9D;AACA;AACA;AACA;AACA;;AAEA,iFAAiF,mBAAmB;;AAEpG;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,oCAAoC,+DAAgB;;AAEpD;AACA,4BAA4B,mEAAoB;AAChD;AACA,IAAI;AACJ;AACA;;AAEA;AACA,aAAa,QAAQ;AACrB,cAAc,eAAe;AAC7B,cAAc,QAAQ;AACtB,cAAc,UAAU;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,mCAAmC;AAC9C,WAAW,gBAAgB;AAC3B,WAAW,kEAAkE;AAC7E,aAAa,SAAS;AACtB;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,GAAG,0EAAuB;;AAE1B;AACA;AACA,IAAI,0EAAuB;AAC3B;;AAEA;AACA,iBAAiB,oCAAoC;AACrD,SAAS,8DAAe;AACxB,KAAK,0EAAuB;AAC5B;AACA;AACA;AACA;AACA;AACA,GAAG,0EAAuB;AAC1B;AACA;AACA;AACA,GAAG,0EAAuB;;AAE1B;AACA,IAAI,0EAAuB;AAC3B;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,qCAAqC;AAClD,aAAa,mCAAmC;AAChD,aAAa,cAAc;AAC3B,aAAa,QAAQ;AACrB,eAAe,SAAS;AACxB;AACA;AACA,kBAAkB,kEAAkB;AACpC;AACA;AACA;AACA,IAAI;AACJ;;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;;AAEA,QAAQ,8DAAe;AACvB;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;;AAEA,OAAO,8DAAe;AACtB;AACA,IAAI,UAAU,8DAAe;AAC7B;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,iBAAiB,OAAO,GAAG,4EAAwB;AACnD;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,sBAAsB;AACjC,aAAa;AACb;AACA;;AAEA;AACA,UAAU,qEAAsB;AAChC;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,QAAQ,+DAAgB;AACxB;;;;;;;;;;;;;;;;;;;ACntBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAUtB;AACqB;;AAE5C;AACA,wDAAwD,yDAAyD;AACjH;AACA;AACA;AACe,wCAAwC,uDAAO;AAC9D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,sBAAsB;AAClC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C,mBAAmB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,QAAQ,8DAAgB,eAAe,oEAAsB;AAC7D;AACA;AACA,4BAA4B,0DAAY;AACxC;;AAEA;AACA;AACA,2BAA2B,iEAAmB;AAC9C;AACA;AACA;AACA;AACA;AACA,4BAA4B,0DAAY,oBAAoB,eAAe;AAC3E,MAAM;AACN,4BAA4B,oEAAsB;AAClD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,8BAA8B,+DAAgB,WAAW,mBAAmB;;AAE5E;AACA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,0CAA0C;AACnG;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,OAAO,8DAAgB,eAAe,oEAAsB;AAC5D;AACA;;AAEA,WAAW,6EAA+B;AAC1C;;AAEA;AACA,sBAAsB,+DAAgB,gBAAgB,mBAAmB;;AAEzE;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,4DAA4D,6DAAe;;AAE3E;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACpLA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAUtB;AACqB;;AAE5C;AACA,uDAAuD,yDAAyD;AAChH;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,sBAAsB;AAClC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,mDAAmD,mBAAmB;AACtE;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,gBAAgB;AAC5B,UAAU,qDAAqD;AAC/D;AACA;AACA,YAAY,0CAA0C,KAAK;AAC3D;AACA;AACA;;AAEA;AACA,WAAW,4BAA4B;;AAEvC;AACA;AACA;;AAEA;AACA,oCAAoC,iEAAmB;;AAEvD,2BAA2B,0DAAY;AACvC;;AAEA;AACA;AACA,MAAM;AACN;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,gCAAgC,iDAAiD;;AAEjF;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,4BAA4B,iEAAmB;AAC/C;AACA,KAAK;AACL,2BAA2B,iEAAmB;AAC9C;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,yCAAyC;AAClG;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA,8BAA8B,oEAAsB;;AAEpD;AACA;;AAEA,SAAS,6DAAe;AACxB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,QAAQ,8DAAgB;AACxB;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,SAAS,6DAAe;AACxB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,yCAAyC;AACrD,YAAY,SAAS;AACrB,KAAK,qDAAqD;AAC1D,cAAc,QAAQ;AACtB,cAAc,qCAAqC;AACnD,cAAc,qCAAqC;AACnD;AACA;AACA;AACA,8BAA8B,oEAAsB;AACpD;;AAEA;AACA;AACA,wBAAwB,oEAAsB;;AAE9C;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAgB,oBAAoB,sCAAsC;AAC9F,MAAM;AACN;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA,WAAW;AACX;AACA;;;;;;;;;;;;;;;;;;AC1OA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AAMtB;;AAEvB;AACA;AACA;AACA,sBAAsB,kEAAkE;AACxF;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,kBAAkB;AAC9B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB,iEAAmB;;AAE5C;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,YAAY,6CAA6C;AACzD;AACA;AACA;AACA,yBAAyB,gBAAgB;AACzC;AACA,yDAAyD,yCAAyC;AAClG;AACA;AACA;AACA;AACA;AACA,6BAA6B,wDAAU;AACvC;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;;AAEA;AACA,GAAG,6DAAe;AAClB,IAAI,oEAAsB;AAC1B;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACjHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEqD;AACX;;AAE1C;AACA;AACA;AACe;AACf;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,sBAAsB;AAClC,YAAY,SAAS;AACrB,YAAY,uBAAuB;AACnC,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,yBAAyB,4DAAO;;AAEhC;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,QAAQ;AACpB,YAAY,sBAAsB;AAClC,YAAY,SAAS;AACrB,YAAY,uBAAuB;AACnC,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA,YAAY,SAAS;AACrB;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA,SAAS,0DAAK;AACd;;AAEA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA,gBAAgB,OAAO;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,sBAAsB;AACjC,aAAa,wEAAwE;AACrF,IAAI,iDAAiD;AACrD;AACO;AACP;AACA;;AAEA,SAAS,uDAAe;AACxB,UAAU;;AAEV;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACO;AACP;AACA,YAAY,qCAAqC;AACjD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,cAAc,+BAA+B;AAC7C,cAAc,+BAA+B;AAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnQA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEmD;AACiB;;AAEpE;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS,wDAAG;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,YAAY;AACZ;AACO,sDAAsD;AAC7D;AACA,oCAAoC,oCAAoC;AACxE,oCAAoC,mCAAmC;AACvE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,QAAQ;AACnB,WAAW,sBAAsB;AACjC,WAAW,SAAS;AACpB;AACA,aAAa;AACb;AACO,mDAAmD;AAC1D;;AAEA,+BAA+B,mDAAU;AACzC;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,wBAAwB,mDAAU;AAClC;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,4BAA4B,mDAAU;AACtC;AACA;AACA,GAAG;;AAEH,2BAA2B,mDAAU;AACrC;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,yBAAyB,yDAAgB;AACzC;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,aAAa;AACb;AACO;AACP,qBAAqB,yDAAgB;AACrC;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iFAAiF;AAC5F,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,aAAa;AACb;AACO,+DAA+D;AACtE,UAAU,4DAAO;;AAEjB;AACA;;AAEA;AACA,0DAA0D,eAAe;AACzE;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iFAAiF;AAC5F,aAAa;AACb;AACO;AACP,UAAU,4DAAO;;AAEjB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP,gDAAgD,uBAAuB;AACvE;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP;;AAEA;AACA;AACA;AACA;AACA;;AAEA,gDAAgD,uBAAuB;;AAEvE;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,WAAW,mCAAmC;AAC9C,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB;AACO,yCAAyC,uBAAuB,KAAK;AAC5E,UAAU,4DAAO;;AAEjB;AACA;;AAEA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,WAAW,mCAAmC;AAC9C;AACO;AACP,UAAU,4DAAO;;AAEjB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,2BAA2B,yDAAgB,WAAW,oBAAoB;AAC1E;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP,UAAU,4DAAO;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,6CAA6C;AACxD,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa,6CAA6C;AAC1D;AACO;AACP;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,GAAG,qEAAwB;AACjD;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,gDAAgD;AAC3D,aAAa,6CAA6C;AAC1D;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,0CAA0C;AACvD;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,4DAA4D,uBAAuB;;AAEnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;ACrhBA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwD;AACkB;;AAE1E;AACA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,WAAW,+EAA+E;AAC1F;AACA;AACO;AACP;;AAEA,OAAO,uDAAe;AACtB;;AAEA,OAAO,uDAAe;AACtB;AACA;AACA,GAAG;AACH;;AAEA,UAAU,iBAAiB,GAAG,qEAAwB;AACtD;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,wEAAwE;AACnF,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACO;AACP,oBAAoB;AACpB,sBAAsB;AACtB;AACA;;AAEA,eAAe,OAAO;AACtB;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,wEAAwE;AACnF,WAAW,cAAc;AACzB,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACO;AACP;AACA;;AAEA,eAAe,OAAO;AACtB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,gBAAgB,oDAAgB;AAChC;;AAEA;;AAEA,uBAAuB,yDAAiB,UAAU,uBAAuB;AACzE;;AAEA;AACA;AACA,iBAAiB,oDAAgB;AACjC;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;ACzIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;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,WAAW,oCAAoC;AAC/C,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,QAAQ;AACnB,WAAW,uBAAuB;AAClC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA,WAAW,uBAAuB;AAClC,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uBAAuB;AAClC,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP,iBAAiB,MAAM,IAAI,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;ACnJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACuD;AAClC;;AAEjE;AACA;AACA;AACA;AACA,IAAI;AACJ,oBAAoB,SAAS,8FAA8F;AAC3H;AACA;AACA;AACe,qCAAqC,sDAAM;AAC1D;AACA;AACA;AACA;AACA,WAAW,6FAA6B,EAAE,wEAAgB;AAC1D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oFAAoF;AAC/F,aAAa;AACb;AACO;AACP;AACA,UAAU,6BAA6B;;AAEvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA,kDAAkD,gBAAgB;AAClE;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;ACxDA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAE0B;AACJ;AACA;AACM;AACX;AAMtC;;AAEvB;;AAEA;AACA;AACA;AACA;AACA,iBAAiB,sDAAsD;AACvE;AACA;AACA;AACe,4CAA4C,sDAAM;AACjE;AACA;AACA;AACA;AACA,WAAW,yEAAmB;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,yEAAmB;;AAErE;AACA;;AAEA;AACA;;AAEA,wCAAwC,0CAA0C;AAClF,oCAAoC,0CAA0C;AAC9E,0CAA0C,0CAA0C;;AAEpF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA,iCAAiC,0EAA6B;AAC9D,iCAAiC,0EAA6B;AAC9D;AACA,IAAI;;AAEJ;AACA,2DAA2D,+BAA+B;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,IAAI;;AAEJ;AACA,gDAAgD,oBAAoB;AACpE,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,gDAAgD,oBAAoB;AACpE,qCAAqC;;AAErC,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;;AAEA;AACA;;AAEA,mCAAmC;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,gBAAgB;;AAE7B;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,cAAc,QAAQ;AACtB,cAAc,GAAG;AACjB,cAAc,QAAQ;AACtB,IAAI,sFAAsF;AAC1F,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,gBAAgB;AAC3B,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa;AACb;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,sBAAsB,2BAA2B;;AAEjD;AACA,yBAAyB,uEAAyB;;AAElD;AACA,4DAA4D,+EAAiC;AAC7F;;AAEA,0CAA0C,iEAAwB;AAClE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA,WAAW,0EAA4B;AACvC,IAAI;;AAEJ;AACA;AACA;AACA,oBAAoB,+EAAiC;;AAErD;AACA;;AAEA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,YAAY,+EAAiC;AAC7C;;AAEA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,sBAAsB,wBAAwB;;AAE9C;AACA,6CAA6C,oEAA2B;AACxE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,sBAAsB,qBAAqB;;AAE3C;AACA,0CAA0C,iEAAwB;AAClE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;;;;;;;;;;;;;;;;;;ACxXA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;AAIP;;AAErC;AACA;AACA;AACA,sBAAsB,wFAAwF;AAC9G;AACA;AACA;AACe,0CAA0C,uDAAO;AAChE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA,uBAAuB;AACvB;AACA;;AAEA;AACA,qBAAqB,0EAAe;;AAEpC,WAAW,yFAA8B;;AAEzC;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,cAAc;AAC5B;AACA;AACA;AACA;;AAEA,gBAAgB,0DAAK;;AAErB,OAAO,0EAAe;AACtB;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;AAIP;;AAErC;AACA;AACA;AACA,sBAAsB,wFAAwF;AAC9G;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,uBAAuB;AACvB;AACA;;AAEA;AACA,qBAAqB,0EAAe;;AAEpC,WAAW,yFAA8B;;AAEzC;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA;AACA;;AAEA,gBAAgB,0DAAK;;AAErB,gBAAgB,0EAAe;AAC/B;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC3EA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;AAIP;AACwB;;AAE7D;AACA;AACA;AACA,sBAAsB,wFAAwF;AAC9G;AACA;AACA;AACe,uCAAuC,uDAAO;AAC7D;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA,uBAAuB;AACvB;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA,YAAY,yFAA8B;;AAE1C;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA,mBAAmB,0DAAK;;AAExB,OAAO,0EAAe;AACtB;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;;AAEA,mBAAmB,0EAA4B;;AAE/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;AClKA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,GAAG,gEAAgE;AACnE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,gEAAgE;AACnE,GAAG,8EAA8E;AACjF,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG,oEAAoE;AACvE,GAAG;AACH;;AAEA,cAAc,qCAAqC;AACnD;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,YAAY;AACZ;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;;;;;;;;;;;;;;;;;;;ACzEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACV;;AAES;;AAE5C;AACA;AACA;AACA,2CAA2C;AAC3C,QAAQ,qDAAqD;AAC7D;AACA;AACA;AACe,mBAAmB,sDAAM;AACxC;AACA;AACA;AACA;AACA,WAAW,yDAAW,EAAE,oDAAM;AAC9B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,kCAAkC;AAC/D,YAAY,2DAA2D;AACvE;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,QAAQ,sEAAsE;AAC9E;AACA;AACA;;AAEA;AACA,6BAA6B,6BAA6B,iBAAiB,6CAA6C;AACxH;AACA,iBAAiB,kCAAkC;AACnD;AACA,YAAY,oCAAoC;AAChD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkD;;AAQjC;;AAEjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,mBAAmB,sDAAc;;AAEjC,EAAE,sDAAc;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,GAAG,sDAAc;AACjB;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,gEAAgE;AAChE;AACA;AACA;AACA,UAAU,mEAAmE;AAC7E;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,oEAAoE,sDAAsD;AAC1H;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;;AAEA;AACA;AACA;;AAEA;AACA,CAAC,sDAAc;AACf,CAAC,sDAAc;AACf;;AAEA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG,sDAAc;AACjB;;AAEA;AACA;;AAEA;AACA,EAAE,sDAAc;;AAEhB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,wDAAwD,yCAAyC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;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;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;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;;AAEA;AACA;AACA,sBAAsB,sDAAc;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,GAAG,sDAAc;AACjB;AACA;AACA;;AAEA;AACA,wDAAwD,yCAAyC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,mEAAmE;AAC9E;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA,CAAC,sDAAc;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP,yDAAyD,aAAa;AACtE;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP,sDAAsD,aAAa;AACnE;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP,sDAAsD,aAAa;AACnE;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,uEAAuE,6CAA6C;AACpH;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,MAAM;AACN;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iEAAiE,6CAA6C;AAC9G;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,wBAAwB;AACxB;;AAEA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,mCAAmC;AAC9C,aAAa,SAAS;AACtB;AACO;AACP;AACA;;AAEA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,OAAO,mBAAmB,oDAAoD;AACzF;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG;AACH;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,yCAAyC;AACpD,WAAW,+DAA+D;AAC1E,aAAa,uCAAuC;AACpD;AACA,SAAS,iBAAiB;;AAE1B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;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;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,wBAAwB,4DAAU,IAAI,gBAAgB;;AAEtD;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0DAAkB;AACzC;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,kBAAkB,+DAAuB;;AAEzC;AACA;AACA;AACA;AACA;;AAEA,GAAG,sDAAc;AACjB,GAAG,sDAAc;AACjB;AACA;AACA;;AAEA;AACA;AACA,WAAW,oCAAoC;AAC/C,aAAa;AACb;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;AACA;AACA,WAAW,oCAAoC;AAC/C,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACriCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;;AAE5C;AACA,+CAA+C,yCAAyC;AACxF;AACA;AACA;AACe,4BAA4B,uDAAO;AAClD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,sBAAsB;AAClC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C,mBAAmB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,gBAAgB;AAC1C;AACA,0DAA0D,8BAA8B;AACxF;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA,mBAAmB,0DAAK;;AAExB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACrJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACD;;AAE5C;AACA,wCAAwC,yCAAyC;AACjF;AACA;AACA;AACe,0BAA0B,uDAAO;AAChD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,uBAAuB;AACnC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;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;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;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,qBAAqB,uCAAuC;;AAE5D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,6BAA6B,oCAAoC;AACjE;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;;AAEA;AACA,0BAA0B,gBAAgB;AAC1C;AACA,0DAA0D,4BAA4B;AACtF;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA,mBAAmB,0DAAK;;AAExB;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,qBAAqB,0DAAK;;AAE1B;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,WAAW,SAAS;AACpB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,qCAAqC;AAChD,WAAW,mCAAmC;AAC9C,aAAa;AACb;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACtUA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEwC;AACI;;AAEA;AACA;AACE;;AAiBxB;;AAEtB;AACA;AACA;AACA;AACA;AACA;AACA;AACe,0BAA0B,sDAAM;AAC/C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,sDAAK,EAAE,wDAAM;AACxB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA,qDAAqD,iEAAoB;;AAEzE;AACA;;AAEA,4CAA4C,gEAAmB;AAC/D,4CAA4C,gEAAmB;AAC/D,yCAAyC,gEAAmB;;AAE5D;AACA;AACA,6BAA6B,+DAAsB,IAAI,mBAAmB;AAC1E,sCAAsC,+DAAkB;AACxD,kDAAkD,4DAAmB,IAAI,mBAAmB;AAC5F,kDAAkD,sEAA6B,IAAI,kBAAkB;AACrG,oDAAoD,kEAAqB;AACzE,sCAAsC,4DAAe;AACrD,6BAA6B,4DAAmB,IAAI,kBAAkB;AACtE,KAAK;;AAEL;AACA;AACA,6BAA6B,+DAAsB,IAAI,mBAAmB;AAC1E,sCAAsC,+DAAkB;AACxD,KAAK;;AAEL;AACA;AACA,iCAAiC,kDAAS,IAAI,mBAAmB;AACjE,iCAAiC,kDAAS,IAAI,mBAAmB;AACjE,iCAAiC,sDAAa,IAAI,mBAAmB;AACrE,iCAAiC,2DAAkB;AACnD,KAAK;;AAEL;AACA,oCAAoC,8DAAqB,IAAI,mBAAmB;;AAEhF;AACA,2CAA2C,oDAAW;AACtD,2CAA2C,oDAAW;;AAEtD;AACA,yCAAyC,sDAAa;AACtD,0CAA0C,sDAAa;;AAEvD;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;;AAEvB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA,GAAG,IAAI,gBAAgB;;AAEvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,gBAAgB;AACvB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;AC1NA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;;AAEsB;AACA;;AAEtB;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACe,qBAAqB,sDAAM;AAC1C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,EAAE,yDAAiB,qDAAqD,qEAAgB;AACxF,EAAE,yDAAiB,qDAAqD,qEAAgB;AACxF;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEmE;AACrB;;AAE9C;AACA,wBAAwB,2DAA2D;AACnF;AACA,WAAW,kDAAkD;AAC7D,aAAa;AACb;AACO;AACP;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,+DAA+D;AAC1E,aAAa,sDAAsD;AACnE;AACO;AACP;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,WAAW,sDAAsD;AACjE,WAAW,+DAA+D;AAC1E,WAAW,iCAAiC;AAC5C;AACO;AACP;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,+CAA+C,yBAAyB;;AAExE;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kDAAkD;AAC7D,WAAW,8BAA8B;AACzC,WAAW,8BAA8B;AACzC,aAAa,2CAA2C;AACxD;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,sCAAsC;AACjD,aAAa;AACb;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,QAAQ;AACnB,WAAW,sBAAsB;AACjC,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACO;AACP;AACA;AACA,yBAAyB,wDAAU;;AAEnC;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,YAAY;AACZ;AACO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,uCAAuC;AAClD,WAAW,sBAAsB;AACjC,aAAa;AACb;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4DAAU;AAClC;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa;AACb;AACO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa;AACb;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,aAAa,aAAa;AAC1B;AACA;;AAEA;AACA;AACA;;AAEA,QAAQ,sEAAoB;AAC5B;;;;;;;;;;;;;;;;;;;ACxcA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC+B;AACV;;AAEjE;AACA;AACA;AACA,2CAA2C;AAC3C,oBAAoB,SAAS,8FAA8F;AAC3H;AACA;AACA;AACe,6BAA6B,sDAAM;AAClD;AACA;AACA;AACA;AACA,WAAW,6EAAqB,EAAE,wEAAgB;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,6BAA6B,iEAAiE;AAC9F,IAAI,0FAA0F;AAC9F;AACA;AACA,wBAAwB,iFAAiF;AACzG,IAAI,iFAAiF;AACrF,IAAI,0FAA0F;AAC9F,IAAI,yGAAyG;AAC7G,IAAI,yGAAyG;AAC7G,IAAI,kHAAkH;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ,KAAK,sEAAsE;AAC3E;AACA;AACA,YAAY,8DAA8D;AAC1E;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;;AAEA;AACA,6BAA6B,iDAAiD;AAC9E,IAAI,0FAA0F;AAC9F;AACA,iBAAiB,sDAAsD;AACvE;AACA,YAAY,iDAAiD;AAC7D;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,yFAAyF;AAC1I;AACA;AACA,YAAY,SAAS;AACrB;;;;;;;;;;;;;;;;;;;;;;ACtIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AACE;AACI;AACM;AACN;AACkB;;AAEpE;;AAEA;AACA;AACA;AACA,0DAA0D,0CAA0C;AACpG;AACA;AACA;AACA,iBAAiB,sDAAsD;AACvE;AACA;AACA;AACe,oCAAoC,sDAAM;AACzD;AACA;AACA;AACA;AACA,WAAW,yDAAW;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,yBAAyB,qDAAqD;AAC9E;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,4EAA4E;AACxF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,+DAAkB;AAC/C;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAG,IAAI,mBAAmB;;AAE1B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,+DAAkB;AACtD;AACA;AACA;AACA,MAAM;;AAEN;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,QAAQ,4DAAe;AACvB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,GAAG,IAAI,kBAAkB;AACzB;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA,cAAc,QAAQ;AACtB,cAAc,GAAG;AACjB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB,cAAc,UAAU;AACxB;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB,aAAa;AACb;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C,yDAAgB;AAC1D,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA,6CAA6C,4DAAmB;AAChE,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;;AAEA;AACA,0CAA0C,yDAAgB;AAC1D,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG,IAAI,kBAAkB;AACzB;AACA;;AAEA;AACA;AACA;AACA,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;AACA,gCAAgC,wBAAwB;AACxD;AACA;;AAEA,4BAA4B,+DAAkB;AAC9C;AACA;AACA;AACA,MAAM;;AAEN;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,IAAI,kBAAkB;AAC1B;AACA;;AAEA;AACA;AACA,YAAY,qCAAqC;AACjD,YAAY,0CAA0C;AACtD,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,+DAAkB;AACvC;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;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;AACA,WAAW,kCAAkC;AAC7C,WAAW,6DAA6D;AACxE,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,0CAA0C;AACrD,WAAW,qCAAqC;AAChD,WAAW,qDAAqD;AAChE,aAAa;AACb;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,0CAA0C;AACrD,WAAW,qCAAqC;AAChD,aAAa;AACb;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,WAAW,kCAAkC;AAC7C,aAAa;AACb;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA,WAAW,gBAAgB;AAC3B,aAAa;AACb;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC10BA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAC6D;;AAEhD;;AAES;AACA;;AAEE;AACI;AACA;AACE;AAC0B;AACpB;AACA;AACA;AACA;;AAE5C;;AAEpC;AACA;AACA;AACA;AACA,kFAAkF;AAClF;AACA;AACA;AACA;AACe,+BAA+B,sDAAM;AACpD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qEAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,sEAAiB;AAC7B,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,wEAAmB;AAC/B,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,wEAAmB;AAC/B;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qEAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yEAAoB;AAChC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,oFAAmC;AAC/C,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,6EAAuB;AACnC;AACA;AACA,KAAK;AACL;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,kCAAkC;AAC7C,WAAW,+BAA+B;AAC1C;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,UAAU,6CAA6C,sDAAsD;AAC1H,mCAAmC,2FAA2F;AAC9H;;AAEA,YAAY,4BAA4B;AACxC,cAAc;AACd;AACA,uBAAuB,gEAAc,UAAU,6DAAe;AAC9D;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,kCAAkC;AAC7C,WAAW,gDAAgD;AAC3D,WAAW,+BAA+B;AAC1C;AACA,aAAa,UAAU,6CAA6C,sDAAsD;AAC1H,kCAAkC,8CAA8C;AAChF;AACA;;AAEA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB,cAAc;AACd,YAAY,6BAA6B;AACzC,qBAAqB,wDAAU;;AAE/B,gBAAgB,uBAAuB;;AAEvC;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA,oCAAoC,sCAAsC;AAC1E;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C,MAAM;AACN;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,kCAAkC;AAC7C,WAAW,8CAA8C;AACzD,WAAW,+BAA+B;AAC1C;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;;AAEA;AACA;;AAEA,gCAAgC,8DAAkB;AAClD;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA,EAAE,0EAAwB;AAC1B;AACA,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,qCAAqC,wBAAwB;AAC7D,IAAI;AACJ;;AAEA;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;;;ACxUA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACQ;;AAErD;AACA;AACA;AACA,sBAAsB,wEAAwE;AAC9F;AACA;AACA;AACe,kCAAkC,uDAAO;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA,uBAAuB;AACvB;AACA,oBAAoB,iEAAoB;AACxC;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,cAAc;AAC5B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC/DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACQ;;AAErD;AACA;AACA,sBAAsB,wEAAwE;AAC9F;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;AACA,uBAAuB;AACvB;AACA,oBAAoB,iEAAoB;AACxC;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,cAAc;AAC5B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;;;;;;;;;;;AC9DA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;AACsC;;AAEnF;AACA;AACA;AACA;AACA;AACA,sBAAsB,wEAAwE;AAC9F;AACA;AACA;AACe,+BAA+B,uDAAO;AACrD;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C,YAAY,QAAQ;AACpB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA,uBAAuB;AACvB;;AAEA;AACA,oBAAoB,iEAAoB;;AAExC;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA,0BAA0B,aAAa;AACvC;AACA;AACA,cAAc,aAAa;AAC3B;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc,SAAS;AACvB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,aAAa;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA,mBAAmB,yEAA4B;;AAE/C;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACnIA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEoD;;AAEpD;AACsF;;AAE9C;;AAExC;AACA;AACA;AACA;AACA;AACA;AACA;AACe,8BAA8B,kDAAI;AACjD;AACA;AACA;AACA,YAAY,4BAA4B,YAAY,+CAA+C;AACnG,YAAY,6BAA6B;AACzC;AACA;AACA;AACA;;AAEA;;AAEA;AACA,qCAAqC,iBAAiB;AACtD;AACA;AACA,cAAc,SAAS;AACvB;AACA;;AAEA;AACA,4BAA4B,kBAAkB;AAC9C;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;;AAEA;AACA,kFAAkF,gBAAgB;AAClG;AACA;AACA,cAAc,wCAAwC;AACtD;AACA;;AAEA;AACA,4EAA4E,kBAAkB;AAC9F;AACA;AACA,cAAc,yCAAyC;AACvD;AACA;;AAEA;AACA,qCAAqC,mBAAmB;AACxD,qEAAqE,uBAAuB;AAC5F;AACA;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,sBAAsB,mBAAmB;AACzC;AACA;AACA,cAAc;AACd;AACA;AACA,yBAAyB,wDAAU;AACnC;;AAEA;AACA;AACA,SAAS,6FAAiB;AAC1B,IAAI;;AAEJ;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;;;;;;;;;;;;;;;;;;;ACvJA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAU0B;AAKG;;AAEmB;;AAEL;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACe,iCAAiC,kDAAI;AACpD;AACA;AACA;AACA,YAAY,4BAA4B,YAAY,+CAA+C;AACnG,YAAY,QAAQ;AACpB,YAAY,yBAAyB;AACrC;AACA,YAAY,qDAAqD;AACjE;AACA,YAAY,QAAQ;AACpB;AACA,wBAAwB,0DAA0D;AAClF;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA,qEAAqE,4BAA4B;AACjG,MAAM,gCAAgC,sCAAsC,iCAAiC;AAC7G;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC,mBAAmB,4BAA4B,IAAI,iCAAiC;AACpF;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;;AAEA;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,cAAc;AACd;AACA,wBAAwB,4DAAc;;AAEtC;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA,cAAc;AACd;AACA,yBAAyB,yDAAW;AACpC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,GAAG,4EAA0B;AAC7B;AACA;AACA;AACA;AACA;AACA,2BAA2B,+EACL;AACtB;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,IAAI,IAAI,mBAAmB;;AAE3B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,gDAAgD;AAC5D,YAAY,QAAQ;AACpB,cAAc;AACd;AACA;AACA,yBAAyB,kDAAI;;AAE7B;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,IAAI;;AAEJ;;AAEA;AACA;AACA;;AAEA,gCAAgC,6DAAY;AAC5C,8BAA8B,iEAAgB;;AAE9C;;AAEA;;AAEA;AACA;;AAEA;AACA,aAAa,4BAA4B,QAAQ,iCAAiC;AAClF;AACA;AACA,YAAY,yBAAyB;AACrC,UAAU,mBAAmB;AAC7B;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD,wDAAe;;AAEjE;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA,IAAI;AACJ;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kCAAkC,8DAAgB,eAAe,sEAAwB;;AAEzF;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;AACL,8BAA8B,aAAa;AAC3C;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iCAAiC,8DAAgB;;AAEjD;AACA;AACA;AACA;AACA,IAAI;;AAEJ;;AAEA;AACA;;AAEA;AACA,2DAA2D,2BAA2B;AACtF;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,QAAQ;AACpB;;AAEA;AACA,0DAA0D,gCAAgC;AAC1F;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;AC7aA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyD;AACV;AACH;AACb;;AAE/B;AACA;AACA;AACA,2CAA2C;AAC3C,YAAY,uEAAuE;AACnF;AACA;AACA;AACe,uBAAuB,sDAAM;AAC5C;AACA;AACA;AACA;AACA,WAAW,iEAAe,EAAE,4DAAU;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;ACpCA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE6C;;AAE7C;;AAEA;AACA;AACA;AACA,qCAAqC,4DAA4D;AACjG;AACA;AACA;AACA;AACe,mCAAmC,uDAAO;AACzD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAM,wDAAwD;AAC9D;AACA;AACA;AACA,cAAc,SAAS;AACvB;;AAEA;AACA,iDAAiD,8CAA8C;AAC/F;AACA;AACA;AACA,cAAc,6CAA6C;AAC3D;;AAEA;AACA,iDAAiD,8CAA8C;AAC/F;AACA;AACA,YAAY;AACZ;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG,IAAI,sBAAsB;AAC7B;;AAEA;AACA,2BAA2B,cAAc,KAAK,kBAAkB;AAChE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,+CAA+C,8CAA8C;AAC7F;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAY,QAAQ;AACpB,YAAY,SAAS;AACrB;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;;AAEA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,IAAI;AACJ;AACA;;;;;;;;;;;;;;;;;;;;;;;ACrHA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEoD;;AAEoD;;AAExG;AACA;AACA;AACA,yEAAyE;AACzE;AACA;AACA,kBAAkB,mEAAmE;AACrF;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,UAAU;AACrB,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,2DAAc;;AAEjC;AACA;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA,EAAE,2DAAc;AAChB;AACA;;AAEA;AACA;AACA;AACA,kBAAkB,6DAA6D;AAC/E;AACA;AACA,WAAW,iCAAiC;AAC5C,aAAa,UAAU;AACvB;AACO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,mBAAmB,2DAAc;;AAEjC;;AAEA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;;AAEA,EAAE,2DAAc;AAChB;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,6DAA6D;AAC/E;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,QAAQ;AACnB,WAAW,+DAA+D;AAC1E;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA,qDAAqD,aAAa;AAClE;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI,kEAAkE;AACtE;AACA;AACA,kCAAkC,uDAAuD;AACzF,IAAI,iEAAiE;AACrE;AACA,kBAAkB,mEAAmE;AACrF;AACA;AACA,WAAW,UAAU;AACrB,WAAW,8BAA8B;AACzC,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,KAAK;;AAEL;AACA,sBAAsB,2DAAc;;AAEpC,4BAA4B,oEAAuB;AACnD;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,iBAAiB,kEAAkE;AACnF;AACA,kBAAkB,mEAAmE;AACrF;AACA;AACA,WAAW,UAAU;AACrB,aAAa,UAAU;AACvB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,UAAU,6BAA6B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,8BAA8B;AACzC,YAAY;AACZ;AACO;AACP;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW,+BAA+B;AAC1C,WAAW,kDAAkD;AAC7D,WAAW,SAAS;AACpB,WAAW,UAAU;AACrB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA,oBAAoB,kEAAa,uBAAuB,iCAAiC;;AAEzF;AACA;AACA;;AAEA;;AAEA;;AAEA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;ACrVA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAE4C;AAKf;;AAEiB;AACA;AACY;AAQ5B;;AAE9B,8BAA8B,mEAAc;;AAE5C;AACA;AACA;AACA,iDAAiD,oEAAoE;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,8BAA8B,sDAAM;AACnD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,yDAAW;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA,UAAU,uBAAuB;;AAEjC;AACA;AACA;AACA,IAAI;;AAEJ;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;AAEJ;AACA,uCAAuC,yDAAW;;AAElD,mCAAmC,6DAAoB;;AAEvD;AACA;AACA;;AAEA;AACA,iDAAiD,2EAAsB,aAAa,mBAAmB;AACvG,6CAA6C,gFAA+B,IAAI,mBAAmB;;AAEnG;AACA;AACA,GAAG,uEAAkB;AACrB,KAAK;AACL;AACA;AACA;AACA,GAAG,wEAAmB;AACtB;AACA;AACA;AACA,GAAG,2EAAsB;AACzB;;AAEA,4CAA4C,2EAAsB;AAClE,yCAAyC,2EAAsB;;AAE/D;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,oHAAoH,gBAAgB;;AAEpI;AACA;AACA,QAAQ,4DAAO;AACf;AACA;AACA;AACA,GAAG,IAAI,mBAAmB;;AAE1B;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;AAEJ;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA,IAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,qCAAqC;AACjD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,iCAAiC;AAC5C,WAAW,4BAA4B;AACvC,aAAa,UAAU;AACvB;AACA;AACA,oBAAoB,sFAAiC;;AAErD;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;;ACjOA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEkD;AACQ;AACd;;AAE5C;AACA;AACA;AACA;AACA;AACA;AACe,yBAAyB,sDAAM;AAC9C;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA,EAAE,8DAAiB,8CAA8C,iEAAY;AAC7E;AACA;;;;;;;;;;;ACnCA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;ACAA;;;;;;;;;;;ACAA;;;;;;UCAA;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;;;;;WCNA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEyD;AAC2B;AACP;AACqC;AACzE;AACmB;AACV;AACW;AAC6B;AACV;AAC/B;AACuB;AACV","file":"list.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-collapsible.ck-collapsible_collapsed>.ck-collapsible__children{display:none}:root{--ck-collapsible-arrow-size:calc(var(--ck-icon-size)*0.5)}.ck.ck-collapsible>.ck.ck-button{border-radius:0;color:inherit;font-weight:700;padding:var(--ck-spacing-medium) var(--ck-spacing-large);width:100%}.ck.ck-collapsible>.ck.ck-button:focus{background:transparent}.ck.ck-collapsible>.ck.ck-button:active,.ck.ck-collapsible>.ck.ck-button:hover:not(:focus),.ck.ck-collapsible>.ck.ck-button:not(:focus){background:transparent;border-color:transparent;box-shadow:none}.ck.ck-collapsible>.ck.ck-button>.ck-icon{margin-right:var(--ck-spacing-medium);width:var(--ck-collapsible-arrow-size)}.ck.ck-collapsible>.ck-collapsible__children{padding:0 var(--ck-spacing-large) var(--ck-spacing-large)}.ck.ck-collapsible.ck-collapsible_collapsed>.ck.ck-button .ck-icon{transform:rotate(-90deg)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/collapsible.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-list/collapsible.css\"],\"names\":[],\"mappings\":\"AAMC,sEACC,YACD,CCHD,MACC,yDACD,CAGC,iCAIC,eAAgB,CAChB,aAAc,CAHd,eAAiB,CACjB,wDAAyD,CAFzD,UAoBD,CAdC,uCACC,sBACD,CAEA,wIACC,sBAAuB,CACvB,wBAAyB,CACzB,eACD,CAEA,0CACC,qCAAsC,CACtC,sCACD,CAGD,6CACC,yDACD,CAGC,mEACC,wBACD\",\"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-collapsible.ck-collapsible_collapsed {\\n\\t& > .ck-collapsible__children {\\n\\t\\tdisplay: none;\\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:root {\\n\\t--ck-collapsible-arrow-size: calc(0.5 * var(--ck-icon-size));\\n}\\n\\n.ck.ck-collapsible {\\n\\t& > .ck.ck-button {\\n\\t\\twidth: 100%;\\n\\t\\tfont-weight: bold;\\n\\t\\tpadding: var(--ck-spacing-medium) var(--ck-spacing-large);\\n\\t\\tborder-radius: 0;\\n\\t\\tcolor: inherit;\\n\\n\\t\\t&:focus {\\n\\t\\t\\tbackground: transparent;\\n\\t\\t}\\n\\n\\t\\t&:active, &:not(:focus), &:hover:not(:focus) {\\n\\t\\t\\tbackground: transparent;\\n\\t\\t\\tborder-color: transparent;\\n\\t\\t\\tbox-shadow: none;\\n\\t\\t}\\n\\n\\t\\t& > .ck-icon {\\n\\t\\t\\tmargin-right: var(--ck-spacing-medium);\\n\\t\\t\\twidth: var(--ck-collapsible-arrow-size);\\n\\t\\t}\\n\\t}\\n\\n\\t& > .ck-collapsible__children {\\n\\t\\tpadding: 0 var(--ck-spacing-large) var(--ck-spacing-large);\\n\\t}\\n\\n\\t&.ck-collapsible_collapsed {\\n\\t\\t& > .ck.ck-button .ck-icon {\\n\\t\\t\\ttransform: rotate(-90deg);\\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-editor__editable .ck-list-bogus-paragraph{display:block}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/documentlist.css\"],\"names\":[],\"mappings\":\"AAKA,8CACC,aACD\",\"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-editor__editable .ck-list-bogus-paragraph {\\n\\tdisplay: block;\\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-list-properties.ck-list-properties_without-styles{padding:var(--ck-spacing-large)}.ck.ck-list-properties.ck-list-properties_without-styles>*{min-width:14em}.ck.ck-list-properties.ck-list-properties_without-styles>*+*{margin-top:var(--ck-spacing-standard)}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-list-styles-list{grid-template-columns:repeat(4,auto)}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-collapsible{border-top:1px solid var(--ck-color-base-border)}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-collapsible>.ck-collapsible__children>*{width:100%}.ck.ck-list-properties.ck-list-properties_with-numbered-properties>.ck-collapsible>.ck-collapsible__children>*+*{margin-top:var(--ck-spacing-standard)}.ck.ck-list-properties .ck.ck-numbered-list-properties__start-index .ck-input{min-width:auto;width:100%}.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order{background:transparent;margin-bottom:calc(var(--ck-spacing-tiny)*-1);padding-left:0;padding-right:0}.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order:active,.ck.ck-list-properties .ck.ck-numbered-list-properties__reversed-order:hover{background:none;border-color:transparent;box-shadow:none}\", \"\",{\"version\":3,\"sources\":[\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-list/listproperties.css\"],\"names\":[],\"mappings\":\"AAOC,yDACC,+BASD,CAPC,2DACC,cAKD,CAHC,6DACC,qCACD,CASD,wFACC,oCACD,CAGA,mFACC,gDAWD,CARE,+GACC,UAKD,CAHC,iHACC,qCACD,CAMJ,8EACC,cAAe,CACf,UACD,CAEA,uEACC,sBAAuB,CAGvB,6CAAgD,CAFhD,cAAe,CACf,eAQD,CALC,2JAGC,eAAgB,CADhB,wBAAyB,CADzB,eAGD\",\"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-list-properties {\\n\\t/* When there are no list styles and there is no collapsible. */\\n\\t&.ck-list-properties_without-styles {\\n\\t\\tpadding: var(--ck-spacing-large);\\n\\n\\t\\t& > * {\\n\\t\\t\\tmin-width: 14em;\\n\\n\\t\\t\\t& + * {\\n\\t\\t\\t\\tmargin-top: var(--ck-spacing-standard);\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t/*\\n\\t * When the numbered list property fields (start at, reversed) should be displayed,\\n\\t * more horizontal space is needed. Reconfigure the style grid to create that space.\\n\\t */\\n\\t&.ck-list-properties_with-numbered-properties {\\n\\t\\t& > .ck-list-styles-list {\\n\\t\\t\\tgrid-template-columns: repeat( 4, auto );\\n\\t\\t}\\n\\n\\t\\t/* When list styles are rendered and property fields are in a collapsible. */\\n\\t\\t& > .ck-collapsible {\\n\\t\\t\\tborder-top: 1px solid var(--ck-color-base-border);\\n\\n\\t\\t\\t& > .ck-collapsible__children {\\n\\t\\t\\t\\t& > * {\\n\\t\\t\\t\\t\\twidth: 100%;\\n\\n\\t\\t\\t\\t\\t& + * {\\n\\t\\t\\t\\t\\t\\tmargin-top: var(--ck-spacing-standard);\\n\\t\\t\\t\\t\\t}\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\t& .ck.ck-numbered-list-properties__start-index .ck-input {\\n\\t\\tmin-width: auto;\\n\\t\\twidth: 100%;\\n\\t}\\n\\n\\t& .ck.ck-numbered-list-properties__reversed-order {\\n\\t\\tbackground: transparent;\\n\\t\\tpadding-left: 0;\\n\\t\\tpadding-right: 0;\\n\\t\\tmargin-bottom: calc(-1 * var(--ck-spacing-tiny));\\n\\n\\t\\t&:active, &:hover {\\n\\t\\t\\tbox-shadow: none;\\n\\t\\t\\tborder-color: transparent;\\n\\t\\t\\tbackground: none;\\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-list-styles-list{display:grid}.ck-content ol{list-style-type:decimal}.ck-content ol ol{list-style-type:lower-latin}.ck-content ol ol ol{list-style-type:lower-roman}.ck-content ol ol ol ol{list-style-type:upper-latin}.ck-content ol ol ol ol ol{list-style-type:upper-roman}.ck-content ul{list-style-type:circle}.ck-content ul ul{list-style-type:disc}.ck-content ul ul ul,.ck-content ul ul ul ul{list-style-type:square}:root{--ck-list-style-button-size:44px}.ck.ck-list-styles-list{column-gap:var(--ck-spacing-medium);grid-template-columns:repeat(3,auto);padding:var(--ck-spacing-large);row-gap:var(--ck-spacing-medium)}.ck.ck-list-styles-list .ck-button{box-sizing:content-box;margin:0;padding:0}.ck.ck-list-styles-list .ck-button,.ck.ck-list-styles-list .ck-button .ck-icon{height:var(--ck-list-style-button-size);width:var(--ck-list-style-button-size)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/liststyles.css\",\"webpack://./../ckeditor5-theme-lark/theme/ckeditor5-list/liststyles.css\"],\"names\":[],\"mappings\":\"AAKA,wBACC,YACD,CAEA,eACC,uBAiBD,CAfC,kBACC,2BAaD,CAXC,qBACC,2BASD,CAPC,wBACC,2BAKD,CAHC,2BACC,2BACD,CAMJ,eACC,sBAaD,CAXC,kBACC,oBASD,CAJE,6CACC,sBACD,CCnCH,MACC,gCACD,CAEA,wBAGC,mCAAoC,CAFpC,oCAAwC,CAGxC,+BAAgC,CAFhC,gCA4BD,CAxBC,mCAiBC,sBAAuB,CAPvB,QAAS,CANT,SAmBD,CAJC,+EAhBA,uCAAwC,CADxC,sCAoBA\",\"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-list-styles-list {\\n\\tdisplay: grid;\\n}\\n\\n.ck-content ol {\\n\\tlist-style-type: decimal;\\n\\n\\t& ol {\\n\\t\\tlist-style-type: lower-latin;\\n\\n\\t\\t& ol {\\n\\t\\t\\tlist-style-type: lower-roman;\\n\\n\\t\\t\\t& ol {\\n\\t\\t\\t\\tlist-style-type: upper-latin;\\n\\n\\t\\t\\t\\t& ol {\\n\\t\\t\\t\\t\\tlist-style-type: upper-roman;\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n}\\n\\n.ck-content ul {\\n\\tlist-style-type: circle;\\n\\n\\t& ul {\\n\\t\\tlist-style-type: disc;\\n\\n\\t\\t& ul {\\n\\t\\t\\tlist-style-type: square;\\n\\n\\t\\t\\t& ul {\\n\\t\\t\\t\\tlist-style-type: square;\\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:root {\\n\\t--ck-list-style-button-size: 44px;\\n}\\n\\n.ck.ck-list-styles-list {\\n\\tgrid-template-columns: repeat( 3, auto );\\n\\trow-gap: var(--ck-spacing-medium);\\n\\tcolumn-gap: var(--ck-spacing-medium);\\n\\tpadding: var(--ck-spacing-large);\\n\\n\\t& .ck-button {\\n\\t\\t/* Make the button look like a thumbnail (the icon \\\"takes it all\\\"). */\\n\\t\\twidth: var(--ck-list-style-button-size);\\n\\t\\theight: var(--ck-list-style-button-size);\\n\\t\\tpadding: 0;\\n\\n\\t\\t/*\\n\\t\\t * Buttons are aligned by the grid so disable default button margins to not collide with the\\n\\t\\t * gaps in the grid.\\n\\t\\t */\\n\\t\\tmargin: 0;\\n\\n\\t\\t/*\\n\\t\\t * Make sure the button border (which is displayed on focus, BTW) does not steal pixels\\n\\t\\t * from the button dimensions and, as a result, decrease the size of the icon\\n\\t\\t * (which becomes blurry as it scales down).\\n\\t\\t */\\n\\t\\tbox-sizing: content-box;\\n\\n\\t\\t& .ck-icon {\\n\\t\\t\\twidth: var(--ck-list-style-button-size);\\n\\t\\t\\theight: var(--ck-list-style-button-size);\\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-todo-list-checkmark-size:16px}.ck-content .todo-list{list-style:none}.ck-content .todo-list li{margin-bottom:5px}.ck-content .todo-list li .todo-list{margin-top:5px}.ck-content .todo-list .todo-list__label>input{-webkit-appearance:none;border:0;display:inline-block;height:var(--ck-todo-list-checkmark-size);left:-25px;margin-left:0;margin-right:-15px;position:relative;right:0;vertical-align:middle;width:var(--ck-todo-list-checkmark-size)}.ck-content .todo-list .todo-list__label>input:before{border:1px solid #333;border-radius:2px;box-sizing:border-box;content:\\\"\\\";display:block;height:100%;position:absolute;transition:box-shadow .25s ease-in-out,background .25s ease-in-out,border .25s ease-in-out;width:100%}.ck-content .todo-list .todo-list__label>input:after{border-color:transparent;border-style:solid;border-width:0 calc(var(--ck-todo-list-checkmark-size)/8) calc(var(--ck-todo-list-checkmark-size)/8) 0;box-sizing:content-box;content:\\\"\\\";display:block;height:calc(var(--ck-todo-list-checkmark-size)/2.6);left:calc(var(--ck-todo-list-checkmark-size)/3);pointer-events:none;position:absolute;top:calc(var(--ck-todo-list-checkmark-size)/5.3);transform:rotate(45deg);width:calc(var(--ck-todo-list-checkmark-size)/5.3)}.ck-content .todo-list .todo-list__label>input[checked]:before{background:#26ab33;border-color:#26ab33}.ck-content .todo-list .todo-list__label>input[checked]:after{border-color:#fff}.ck-content .todo-list .todo-list__label .todo-list__label__description{vertical-align:middle}[dir=rtl] .todo-list .todo-list__label>input{left:0;margin-left:-15px;margin-right:0;right:-25px}.ck-editor__editable .todo-list .todo-list__label>input{cursor:pointer}.ck-editor__editable .todo-list .todo-list__label>input:hover:before{box-shadow:0 0 0 5px rgba(0,0,0,.1)}\", \"\",{\"version\":3,\"sources\":[\"webpack://./theme/todolist.css\"],\"names\":[],\"mappings\":\"AAKA,MACC,kCACD,CAEA,uBACC,eA0ED,CAxEC,0BACC,iBAKD,CAHC,qCACC,cACD,CAIA,+CACC,uBAAwB,CAQxB,QAAS,CAPT,oBAAqB,CAGrB,yCAA0C,CAO1C,UAAW,CAGX,aAAc,CAFd,kBAAmB,CAVnB,iBAAkB,CAWlB,OAAQ,CARR,qBAAsB,CAFtB,wCAqDD,CAxCC,sDAOC,qBAAiC,CACjC,iBAAkB,CALlB,qBAAsB,CACtB,UAAW,CAHX,aAAc,CAKd,WAAY,CAJZ,iBAAkB,CAOlB,0FAAgG,CAJhG,UAKD,CAEA,qDAaC,wBAAyB,CADzB,kBAAmB,CAEnB,sGAA+G,CAX/G,sBAAuB,CAEvB,UAAW,CAJX,aAAc,CAUd,mDAAwD,CAHxD,+CAAoD,CAJpD,mBAAoB,CAFpB,iBAAkB,CAOlB,gDAAqD,CAMrD,uBAAwB,CALxB,kDAMD,CAGC,+DACC,kBAA8B,CAC9B,oBACD,CAEA,8DACC,iBACD,CAIF,wEACC,qBACD,CAKF,6CACC,MAAO,CAGP,iBAAkB,CAFlB,cAAe,CACf,WAED,CAMA,wDACC,cAKD,CAHC,qEACC,mCACD\",\"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-todo-list-checkmark-size: 16px;\\n}\\n\\n.ck-content .todo-list {\\n\\tlist-style: none;\\n\\n\\t& li {\\n\\t\\tmargin-bottom: 5px;\\n\\n\\t\\t& .todo-list {\\n\\t\\t\\tmargin-top: 5px;\\n\\t\\t}\\n\\t}\\n\\n\\t& .todo-list__label {\\n\\t\\t& > input {\\n\\t\\t\\t-webkit-appearance: none;\\n\\t\\t\\tdisplay: inline-block;\\n\\t\\t\\tposition: relative;\\n\\t\\t\\twidth: var(--ck-todo-list-checkmark-size);\\n\\t\\t\\theight: var(--ck-todo-list-checkmark-size);\\n\\t\\t\\tvertical-align: middle;\\n\\n\\t\\t\\t/* Needed on iOS */\\n\\t\\t\\tborder: 0;\\n\\n\\t\\t\\t/* LTR styles */\\n\\t\\t\\tleft: -25px;\\n\\t\\t\\tmargin-right: -15px;\\n\\t\\t\\tright: 0;\\n\\t\\t\\tmargin-left: 0;\\n\\n\\t\\t\\t&::before {\\n\\t\\t\\t\\tdisplay: block;\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tbox-sizing: border-box;\\n\\t\\t\\t\\tcontent: '';\\n\\t\\t\\t\\twidth: 100%;\\n\\t\\t\\t\\theight: 100%;\\n\\t\\t\\t\\tborder: 1px solid hsl(0, 0%, 20%);\\n\\t\\t\\t\\tborder-radius: 2px;\\n\\t\\t\\t\\ttransition: 250ms ease-in-out box-shadow, 250ms ease-in-out background, 250ms ease-in-out border;\\n\\t\\t\\t}\\n\\n\\t\\t\\t&::after {\\n\\t\\t\\t\\tdisplay: block;\\n\\t\\t\\t\\tposition: absolute;\\n\\t\\t\\t\\tbox-sizing: content-box;\\n\\t\\t\\t\\tpointer-events: none;\\n\\t\\t\\t\\tcontent: '';\\n\\n\\t\\t\\t\\t/* Calculate tick position, size and border-width proportional to the checkmark size. */\\n\\t\\t\\t\\tleft: calc( var(--ck-todo-list-checkmark-size) / 3 );\\n\\t\\t\\t\\ttop: calc( var(--ck-todo-list-checkmark-size) / 5.3 );\\n\\t\\t\\t\\twidth: calc( var(--ck-todo-list-checkmark-size) / 5.3 );\\n\\t\\t\\t\\theight: calc( var(--ck-todo-list-checkmark-size) / 2.6 );\\n\\t\\t\\t\\tborder-style: solid;\\n\\t\\t\\t\\tborder-color: transparent;\\n\\t\\t\\t\\tborder-width: 0 calc( var(--ck-todo-list-checkmark-size) / 8 ) calc( var(--ck-todo-list-checkmark-size) / 8 ) 0;\\n\\t\\t\\t\\ttransform: rotate(45deg);\\n\\t\\t\\t}\\n\\n\\t\\t\\t&[checked] {\\n\\t\\t\\t\\t&::before {\\n\\t\\t\\t\\t\\tbackground: hsl(126, 64%, 41%);\\n\\t\\t\\t\\t\\tborder-color: hsl(126, 64%, 41%);\\n\\t\\t\\t\\t}\\n\\n\\t\\t\\t\\t&::after {\\n\\t\\t\\t\\t\\tborder-color: hsl(0, 0%, 100%);\\n\\t\\t\\t\\t}\\n\\t\\t\\t}\\n\\t\\t}\\n\\n\\t\\t& .todo-list__label__description {\\n\\t\\t\\tvertical-align: middle;\\n\\t\\t}\\n\\t}\\n}\\n\\n/* RTL styles */\\n[dir=\\\"rtl\\\"] .todo-list .todo-list__label > input {\\n\\tleft: 0;\\n\\tmargin-right: 0;\\n\\tright: -25px;\\n\\tmargin-left: -15px;\\n}\\n\\n/*\\n * To-do list should be interactive only during the editing\\n * (https://github.com/ckeditor/ckeditor5/issues/2090).\\n */\\n.ck-editor__editable .todo-list .todo-list__label > input {\\n\\tcursor: pointer;\\n\\n\\t&:hover::before {\\n\\t\\tbox-shadow: 0 0 0 5px hsla(0, 0%, 0%, 0.1);\\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=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0C1 4.784 1.777 4 2.75 4c.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75C1.784 7.5 1 6.723 1 5.75zm6 9c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zm-6 0c0-.966.777-1.75 1.75-1.75.966 0 1.75.777 1.75 1.75 0 .966-.777 1.75-1.75 1.75-.966 0-1.75-.777-1.75-1.75z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11 27a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0-10a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4zm0-10a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0 1a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M10.29 15V8.531H9.286c-.14.393-.4.736-.778 1.03-.378.295-.728.495-1.05.6v1.121a4.257 4.257 0 0 0 1.595-.936V15h1.235zm3.343 0v-1.235h-1.235V15h1.235zM11.3 24v-1.147H8.848c.064-.111.148-.226.252-.343.104-.117.351-.354.74-.712.39-.357.66-.631.81-.821.225-.288.39-.562.494-.824.104-.263.156-.539.156-.829 0-.51-.182-.936-.545-1.279-.363-.342-.863-.514-1.499-.514-.58 0-1.063.148-1.45.444-.387.296-.617.784-.69 1.463l1.23.124c.024-.36.112-.619.264-.774.153-.155.358-.233.616-.233.26 0 .465.074.613.222.148.148.222.36.222.635 0 .25-.085.501-.255.756-.126.185-.468.536-1.024 1.055-.692.641-1.155 1.156-1.389 1.544-.234.389-.375.8-.422 1.233H11.3zm2.333 0v-1.235h-1.235V24h1.235zM9.204 34.11c.615 0 1.129-.2 1.542-.598.413-.398.62-.88.62-1.446 0-.39-.11-.722-.332-.997a1.5 1.5 0 0 0-.886-.532c.619-.337.928-.788.928-1.353 0-.399-.151-.756-.453-1.073-.366-.386-.852-.58-1.459-.58a2.25 2.25 0 0 0-.96.2 1.617 1.617 0 0 0-.668.55c-.16.232-.28.544-.358.933l1.138.194c.032-.282.123-.495.272-.642.15-.146.33-.22.54-.22.215 0 .386.065.515.194s.193.302.193.518c0 .255-.087.46-.263.613-.176.154-.43.227-.765.218l-.136 1.006c.22-.061.409-.092.567-.092.24 0 .444.09.61.272.168.182.251.428.251.739 0 .328-.087.589-.261.782a.833.833 0 0 1-.644.29.841.841 0 0 1-.607-.242c-.167-.16-.27-.394-.307-.698l-1.196.145c.062.542.285.98.668 1.316.384.335.868.503 1.45.503zm4.43-.11v-1.235h-1.236V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M5.714 15.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm6.078.914V8.531H10.79c-.14.393-.4.736-.778 1.03-.378.295-.728.495-1.05.6v1.121a4.257 4.257 0 0 0 1.595-.936V15h1.235zm3.344 0v-1.235h-1.235V15h1.235zm-9.422 9.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm7.088.914v-1.147H10.35c.065-.111.149-.226.253-.343.104-.117.35-.354.74-.712.39-.357.66-.631.81-.821.225-.288.39-.562.493-.824.104-.263.156-.539.156-.829 0-.51-.181-.936-.544-1.279-.364-.342-.863-.514-1.499-.514-.58 0-1.063.148-1.45.444-.387.296-.617.784-.69 1.463l1.23.124c.024-.36.112-.619.264-.774.152-.155.357-.233.615-.233.261 0 .465.074.613.222.148.148.222.36.222.635 0 .25-.085.501-.255.756-.126.185-.467.536-1.024 1.055-.691.641-1.154 1.156-1.388 1.544-.235.389-.375.8-.422 1.233h4.328zm2.334 0v-1.235h-1.235V24h1.235zM5.714 34.11c.624 0 1.11-.22 1.46-.66.421-.533.632-1.408.632-2.627 0-1.222-.21-2.096-.629-2.624-.351-.445-.839-.668-1.463-.668-.624 0-1.11.22-1.459.66-.422.533-.633 1.406-.633 2.619 0 1.236.192 2.095.576 2.577.384.482.89.723 1.516.723zm0-1.024a.614.614 0 0 1-.398-.14c-.115-.094-.211-.283-.287-.565-.077-.283-.115-.802-.115-1.558s.043-1.294.128-1.613c.064-.246.155-.417.272-.512a.617.617 0 0 1 .4-.143.61.61 0 0 1 .398.143c.116.095.211.284.288.567.076.283.114.802.114 1.558s-.043 1.292-.128 1.608c-.064.246-.155.417-.272.512a.617.617 0 0 1-.4.143zm4.992 1.024c.616 0 1.13-.2 1.543-.598.413-.398.62-.88.62-1.446 0-.39-.111-.722-.332-.997a1.5 1.5 0 0 0-.886-.532c.618-.337.927-.788.927-1.353 0-.399-.15-.756-.452-1.073-.366-.386-.853-.58-1.46-.58a2.25 2.25 0 0 0-.96.2 1.617 1.617 0 0 0-.667.55c-.16.232-.28.544-.359.933l1.139.194c.032-.282.123-.495.272-.642.15-.146.33-.22.54-.22.214 0 .386.065.515.194s.193.302.193.518c0 .255-.088.46-.264.613-.175.154-.43.227-.764.218l-.136 1.006c.22-.061.408-.092.566-.092.24 0 .444.09.611.272.167.182.25.428.25.739 0 .328-.086.589-.26.782a.833.833 0 0 1-.644.29.841.841 0 0 1-.607-.242c-.167-.16-.27-.394-.308-.698l-1.195.145c.062.542.284.98.668 1.316.384.335.867.503 1.45.503zm4.43-.11v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11 27a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0-9a3 3 0 1 1 0 6 3 3 0 0 1 0-6zm0-9a3 3 0 1 1 0 6 3 3 0 0 1 0-6z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M9.62 14.105c.272 0 .528-.05.768-.153s.466-.257.677-.462c.009.024.023.072.044.145.047.161.086.283.119.365h1.221a2.649 2.649 0 0 1-.222-.626c-.04-.195-.059-.498-.059-.908l.013-1.441c0-.536-.055-.905-.165-1.105-.11-.201-.3-.367-.569-.497-.27-.13-.68-.195-1.23-.195-.607 0-1.064.108-1.371.325-.308.217-.525.55-.65 1.002l1.12.202c.076-.217.176-.369.299-.455.123-.086.294-.13.514-.13.325 0 .546.05.663.152.118.101.176.27.176.508v.123c-.222.093-.622.194-1.2.303-.427.082-.755.178-.982.288-.227.11-.403.268-.53.474a1.327 1.327 0 0 0-.188.706c0 .398.138.728.415.988.277.261.656.391 1.136.391zm.368-.87a.675.675 0 0 1-.492-.189.606.606 0 0 1-.193-.448c0-.176.08-.32.241-.435.106-.07.33-.142.673-.215a7.19 7.19 0 0 0 .751-.19v.247c0 .296-.016.496-.048.602a.773.773 0 0 1-.295.409 1.07 1.07 0 0 1-.637.22zm4.645.765v-1.235h-1.235V14h1.235zM10.2 25.105c.542 0 1.003-.215 1.382-.646.38-.43.57-1.044.57-1.84 0-.771-.187-1.362-.559-1.774a1.82 1.82 0 0 0-1.41-.617c-.522 0-.973.216-1.354.65v-2.32H7.594V25h1.147v-.686a1.9 1.9 0 0 0 .67.592c.26.133.523.2.79.2zm-.299-.975c-.354 0-.638-.164-.852-.492-.153-.232-.229-.59-.229-1.073 0-.468.098-.818.295-1.048a.93.93 0 0 1 .738-.345c.302 0 .55.118.743.354.193.236.29.62.29 1.154 0 .5-.096.868-.288 1.1-.192.233-.424.35-.697.35zm4.478.87v-1.235h-1.234V25h1.234zm-4.017 9.105c.6 0 1.08-.142 1.437-.426.357-.284.599-.704.725-1.261l-1.213-.207c-.061.326-.167.555-.316.688a.832.832 0 0 1-.576.2.916.916 0 0 1-.75-.343c-.185-.228-.278-.62-.278-1.173 0-.498.091-.853.274-1.066.183-.212.429-.318.736-.318.232 0 .42.061.565.184.145.123.238.306.28.55l1.216-.22c-.146-.501-.387-.874-.722-1.119-.336-.244-.788-.366-1.356-.366-.695 0-1.245.214-1.653.643-.407.43-.61 1.03-.61 1.8 0 .762.202 1.358.608 1.788.406.431.95.646 1.633.646zM14.633 34v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11.88 8.7V7.558h-1.234V8.7h1.234zm0 5.3V9.333h-1.234V14h1.234zm2.5 0v-1.235h-1.234V14h1.235zm-4.75 4.7v-1.142H8.395V18.7H9.63zm0 5.3v-4.667H8.395V24H9.63zm2.5-5.3v-1.142h-1.234V18.7h1.235zm0 5.3v-4.667h-1.234V24h1.235zm2.501 0v-1.235h-1.235V24h1.235zM7.38 28.7v-1.142H6.145V28.7H7.38zm0 5.3v-4.667H6.145V34H7.38zm2.5-5.3v-1.142H8.646V28.7H9.88zm0 5.3v-4.667H8.646V34H9.88zm2.5-5.3v-1.142h-1.234V28.7h1.235zm0 5.3v-4.667h-1.234V34h1.235zm2.501 0v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M14 27v6H8v-6h6zm0-9v6H8v-6h6zm0-9v6H8V9h6z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"m7.88 15 .532-1.463h2.575L11.549 15h1.415l-2.58-6.442H9.01L6.5 15h1.38zm2.69-2.549H8.811l.87-2.39.887 2.39zM14.88 15v-1.235h-1.234V15h1.234zM9.352 25c.83-.006 1.352-.02 1.569-.044.346-.038.636-.14.872-.305.236-.166.422-.387.558-.664.137-.277.205-.562.205-.855 0-.372-.106-.695-.317-.97-.21-.276-.512-.471-.905-.585a1.51 1.51 0 0 0 .661-.567 1.5 1.5 0 0 0 .244-.83c0-.28-.066-.53-.197-.754a1.654 1.654 0 0 0-.495-.539 1.676 1.676 0 0 0-.672-.266c-.25-.042-.63-.063-1.14-.063H7.158V25h2.193zm.142-3.88H8.46v-1.49h.747c.612 0 .983.007 1.112.022.217.026.38.102.49.226.11.125.165.287.165.486a.68.68 0 0 1-.192.503.86.86 0 0 1-.525.23 11.47 11.47 0 0 1-.944.023h.18zm.17 2.795H8.46v-1.723h1.05c.592 0 .977.03 1.154.092.177.062.313.16.406.295a.84.84 0 0 1 .14.492c0 .228-.06.41-.181.547a.806.806 0 0 1-.473.257c-.126.026-.423.04-.892.04zM14.88 25v-1.235h-1.234V25h1.234zm-5.018 9.11c.691 0 1.262-.17 1.711-.512.45-.341.772-.864.965-1.567l-1.261-.4c-.109.472-.287.818-.536 1.037-.25.22-.547.33-.892.33-.47 0-.85-.173-1.143-.519-.293-.345-.44-.925-.44-1.74 0-.767.15-1.322.447-1.665.297-.343.684-.514 1.162-.514.346 0 .64.096.881.29.242.193.4.457.477.79l1.288-.307c-.147-.516-.367-.911-.66-1.187-.492-.465-1.132-.698-1.92-.698-.902 0-1.63.296-2.184.89-.554.593-.83 1.426-.83 2.498 0 1.014.275 1.813.825 2.397.551.585 1.254.877 2.11.877zM14.88 34v-1.235h-1.234V34h1.234z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 44 44\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M35 29a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17zm0-9a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H18a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h17z\\\" fill-opacity=\\\".163\\\"/><path d=\\\"M11.916 15V8.558h-1.301V15h1.3zm2.465 0v-1.235h-1.235V15h1.235zM9.665 25v-6.442h-1.3V25h1.3zm2.5 0v-6.442h-1.3V25h1.3zm2.466 0v-1.235h-1.235V25h1.235zm-7.216 9v-6.442h-1.3V34h1.3zm2.5 0v-6.442h-1.3V34h1.3zm2.501 0v-6.442h-1.3V34h1.3zm2.465 0v-1.235h-1.235V34h1.235z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M7 5.75c0 .414.336.75.75.75h9.5a.75.75 0 1 0 0-1.5h-9.5a.75.75 0 0 0-.75.75zM3.5 3v5H2V3.7H1v-1h2.5V3zM.343 17.857l2.59-3.257H2.92a.6.6 0 1 0-1.04 0H.302a2 2 0 1 1 3.995 0h-.001c-.048.405-.16.734-.333.988-.175.254-.59.692-1.244 1.312H4.3v1h-4l.043-.043zM7 14.75a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 20 20\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"m2.315 14.705 2.224-2.24a.689.689 0 0 1 .963 0 .664.664 0 0 1 0 .949L2.865 16.07a.682.682 0 0 1-.112.089.647.647 0 0 1-.852-.051L.688 14.886a.635.635 0 0 1 0-.903.647.647 0 0 1 .91 0l.717.722zm5.185.045a.75.75 0 0 1 .75-.75h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75zM2.329 5.745l2.21-2.226a.689.689 0 0 1 .963 0 .664.664 0 0 1 0 .95L2.865 7.125a.685.685 0 0 1-.496.196.644.644 0 0 1-.468-.187L.688 5.912a.635.635 0 0 1 0-.903.647.647 0 0 1 .91 0l.73.736zM7.5 5.75A.75.75 0 0 1 8.25 5h9.5a.75.75 0 1 1 0 1.5h-9.5a.75.75 0 0 1-.75-.75z\\\"/></svg>\";","export default \"<svg viewBox=\\\"0 0 10 10\\\" xmlns=\\\"http://www.w3.org/2000/svg\\\"><path d=\\\"M.941 4.523a.75.75 0 1 1 1.06-1.06l3.006 3.005 3.005-3.005a.75.75 0 1 1 1.06 1.06l-3.549 3.55a.75.75 0 0 1-1.168-.136L.941 4.523z\\\"/></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]!./collapsible.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]!./documentlist.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]!./listproperties.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]!./liststyles.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]!./todolist.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 list/documentlist\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport DocumentListEditing from './documentlist/documentlistediting';\nimport ListUI from './list/listui';\n\n/**\n * The document list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/documentlist/documentlistediting~DocumentListEditing document list\n * editing feature} and {@link module:list/list/listui~ListUI list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ DocumentListEditing, ListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentList';\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 list/documentlist/converters\n */\n\nimport {\n\tgetAllListItemBlocks,\n\tgetListItemBlocks,\n\tisListItemBlock,\n\tListItemUid\n} from './utils/model';\nimport {\n\tcreateListElement,\n\tcreateListItemElement,\n\tgetIndent,\n\tisListView,\n\tisListItemView\n} from './utils/view';\nimport ListWalker, { iterateSiblingListBlocks } from './utils/listwalker';\nimport { findAndAddListHeadToMap } from './utils/postfixers';\n\nimport { UpcastWriter } from 'ckeditor5/src/engine';\n\n/**\n * Returns the upcast converter for list items. It's supposed to work after the block converters (content inside list items) is converted.\n *\n * @protected\n * @returns {Function}\n */\nexport function listItemUpcastConverter() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema } = conversionApi;\n\n\t\tif ( !data.modelRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst items = Array.from( data.modelRange.getItems( { shallow: true } ) )\n\t\t\t.filter( item => schema.checkAttribute( item, 'listItemId' ) );\n\n\t\tif ( !items.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst attributes = {\n\t\t\tlistItemId: ListItemUid.next(),\n\t\t\tlistIndent: getIndent( data.viewItem ),\n\t\t\tlistType: data.viewItem.parent && data.viewItem.parent.name == 'ol' ? 'numbered' : 'bulleted'\n\t\t};\n\n\t\tfor ( const item of items ) {\n\t\t\t// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n\t\t\tif ( !isListItemBlock( item ) ) {\n\t\t\t\twriter.setAttributes( attributes, item );\n\t\t\t}\n\t\t}\n\n\t\tif ( items.length > 1 ) {\n\t\t\t// Make sure that list item that contain only nested list will preserve paragraph for itself:\n\t\t\t//\t<ul>\n\t\t\t//\t\t<li>\n\t\t\t//\t\t\t<p></p> <-- this one must be kept\n\t\t\t//\t\t\t<ul>\n\t\t\t//\t\t\t\t<li></li>\n\t\t\t//\t\t\t</ul>\n\t\t\t//\t\t</li>\n\t\t\t//\t</ul>\n\t\t\tif ( items[ 1 ].getAttribute( 'listItemId' ) != attributes.listItemId ) {\n\t\t\t\tconversionApi.keepEmptyElement( items[ 0 ] );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns the upcast converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @protected\n * @returns {Function}\n */\nexport function listUpcastCleanList() {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewWriter = new UpcastWriter( data.viewItem.document );\n\n\t\tfor ( const child of Array.from( data.viewItem.getChildren() ) ) {\n\t\t\tif ( !isListItemView( child ) && !isListView( child ) ) {\n\t\t\t\tviewWriter.remove( child );\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * Returns a model document change:data event listener that triggers conversion of related items if needed.\n *\n * @protected\n * @param {module:engine/model/model~Model} model The editor model.\n * @param {module:engine/controller/editingcontroller~EditingController} editing The editing controller.\n * @param {Array.<String>} attributeNames The list of all model list attributes (including registered strategies).\n * @param {module:list/documentlist/documentlistediting~DocumentListEditing} documentListEditing The document list editing plugin.\n * @return {Function}\n */\nexport function reconvertItemsOnDataChange( model, editing, attributeNames, documentListEditing ) {\n\treturn () => {\n\t\tconst changes = model.document.differ.getChanges();\n\t\tconst itemsToRefresh = [];\n\t\tconst itemToListHead = new Map();\n\t\tconst changedItems = new Set();\n\n\t\tfor ( const entry of changes ) {\n\t\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\n\t\t\t\t// Insert of a non-list item.\n\t\t\t\tif ( !entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( entry.position.getShiftedBy( entry.length ), itemToListHead );\n\t\t\t\t} else {\n\t\t\t\t\tchangedItems.add( entry.position.nodeAfter );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Removed list item.\n\t\t\telse if ( entry.type == 'remove' && entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\t\t\t}\n\t\t\t// Changed list attribute.\n\t\t\telse if ( entry.type == 'attribute' ) {\n\t\t\t\tconst item = entry.range.start.nodeAfter;\n\n\t\t\t\tif ( attributeNames.includes( entry.attributeKey ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( entry.range.start, itemToListHead );\n\n\t\t\t\t\tif ( entry.attributeNewValue === null ) {\n\t\t\t\t\t\tfindAndAddListHeadToMap( entry.range.start.getShiftedBy( 1 ), itemToListHead );\n\n\t\t\t\t\t\t// Check if paragraph should be converted from bogus to plain paragraph.\n\t\t\t\t\t\tif ( doesItemParagraphRequiresRefresh( item ) ) {\n\t\t\t\t\t\t\titemsToRefresh.push( item );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tchangedItems.add( item );\n\t\t\t\t\t}\n\t\t\t\t} else if ( isListItemBlock( item ) ) {\n\t\t\t\t\t// Some other attribute was changed on the list item,\n\t\t\t\t\t// check if paragraph does not need to be converted to bogus or back.\n\t\t\t\t\tif ( doesItemParagraphRequiresRefresh( item ) ) {\n\t\t\t\t\t\titemsToRefresh.push( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const listHead of itemToListHead.values() ) {\n\t\t\titemsToRefresh.push( ...collectListItemsToRefresh( listHead, changedItems ) );\n\t\t}\n\n\t\tfor ( const item of new Set( itemsToRefresh ) ) {\n\t\t\tediting.reconvertItem( item );\n\t\t}\n\t};\n\n\tfunction collectListItemsToRefresh( listHead, changedItems ) {\n\t\tconst itemsToRefresh = [];\n\t\tconst visited = new Set();\n\t\tconst stack = [];\n\n\t\tfor ( const { node, previous } of iterateSiblingListBlocks( listHead, 'forward' ) ) {\n\t\t\tif ( visited.has( node ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst itemIndent = node.getAttribute( 'listIndent' );\n\n\t\t\t// Current node is at the lower indent so trim the stack.\n\t\t\tif ( previous && itemIndent < previous.getAttribute( 'listIndent' ) ) {\n\t\t\t\tstack.length = itemIndent + 1;\n\t\t\t}\n\n\t\t\t// Update the stack for the current indent level.\n\t\t\tstack[ itemIndent ] = Object.fromEntries(\n\t\t\t\tArray.from( node.getAttributes() )\n\t\t\t\t\t.filter( ( [ key ] ) => attributeNames.includes( key ) )\n\t\t\t);\n\n\t\t\t// Find all blocks of the current node.\n\t\t\tconst blocks = getListItemBlocks( node, { direction: 'forward' } );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\tvisited.add( block );\n\n\t\t\t\t// Check if bogus vs plain paragraph needs refresh.\n\t\t\t\tif ( doesItemParagraphRequiresRefresh( block, blocks ) ) {\n\t\t\t\t\titemsToRefresh.push( block );\n\t\t\t\t}\n\t\t\t\t// Check if wrapping with UL, OL, LIs needs refresh.\n\t\t\t\telse if ( doesItemWrappingRequiresRefresh( block, stack, changedItems ) ) {\n\t\t\t\t\titemsToRefresh.push( block );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn itemsToRefresh;\n\t}\n\n\tfunction doesItemParagraphRequiresRefresh( item, blocks ) {\n\t\tif ( !item.is( 'element', 'paragraph' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewElement = editing.mapper.toViewElement( item );\n\n\t\tif ( !viewElement ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst useBogus = shouldUseBogusParagraph( item, attributeNames, blocks );\n\n\t\tif ( useBogus && viewElement.is( 'element', 'p' ) ) {\n\t\t\treturn true;\n\t\t} else if ( !useBogus && viewElement.is( 'element', 'span' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tfunction doesItemWrappingRequiresRefresh( item, stack, changedItems ) {\n\t\t// Items directly affected by some \"change\" don't need a refresh, they will be converted by their own changes.\n\t\tif ( changedItems.has( item ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst viewElement = editing.mapper.toViewElement( item );\n\t\tlet indent = stack.length - 1;\n\n\t\t// Traverse down the stack to the root to verify if all ULs, OLs, and LIs are as expected.\n\t\tfor (\n\t\t\tlet element = viewElement.parent;\n\t\t\t!element.is( 'editableElement' );\n\t\t\telement = element.parent\n\t\t) {\n\t\t\tconst isListItemElement = isListItemView( element );\n\t\t\tconst isListElement = isListView( element );\n\n\t\t\tif ( !isListElement && !isListItemElement ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired on changes detected on the model list element to verify if the view representation of a list element\n\t\t\t * is representing those attributes.\n\t\t\t *\n\t\t\t * It allows triggering a re-wrapping of a list item.\n\t\t\t *\n\t\t\t * **Note**: For convenience this event is namespaced and could be captured as `checkAttributes:list` or `checkAttributes:item`.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event module:list/documentlist/documentlistediting~DocumentListEditing#event:checkAttributes\n\t\t\t * @param {module:engine/view/element~Element} viewElement\n\t\t\t * @param {Object} modelAttributes\n\t\t\t */\n\t\t\tconst eventName = `checkAttributes:${ isListItemElement ? 'item' : 'list' }`;\n\t\t\tconst needsRefresh = documentListEditing.fire( eventName, {\n\t\t\t\tviewElement: element,\n\t\t\t\tmodelAttributes: stack[ indent ]\n\t\t\t} );\n\n\t\t\tif ( needsRefresh ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ( isListElement ) {\n\t\t\t\tindent--;\n\n\t\t\t\t// Don't need to iterate further if we already know that the item is wrapped appropriately.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n}\n\n/**\n * Returns the list item downcast converter.\n *\n * @protected\n * @param {Array.<String>} attributeNames A list of attribute names that should be converted if are set.\n * @param {Array.<module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy>} strategies The strategies.\n * @param {module:engine/model/model~Model} model The model.\n * @returns {Function}\n */\nexport function listItemDowncastConverter( attributeNames, strategies, model ) {\n\tconst consumer = createAttributesConsumer( attributeNames );\n\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, mapper, consumable } = conversionApi;\n\n\t\tconst listItem = data.item;\n\n\t\tif ( !attributeNames.includes( data.attributeKey ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Test if attributes on the converted items are not consumed.\n\t\tif ( !consumer( listItem, consumable ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Use positions mapping instead of mapper.toViewElement( listItem ) to find outermost view element.\n\t\t// This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n\t\tconst viewElement = findMappedViewElement( listItem, mapper, model );\n\n\t\t// Unwrap element from current list wrappers.\n\t\tunwrapListItemBlock( viewElement, writer );\n\n\t\t// Then wrap them with the new list wrappers.\n\t\twrapListItemBlock( listItem, writer.createRangeOn( viewElement ), strategies, writer );\n\t};\n}\n\n/**\n * Returns the bogus paragraph view element creator. A bogus paragraph is used if a list item contains only a single block or nested list.\n *\n * @protected\n * @param {Array.<String>} attributeNames The list of all model list attributes (including registered strategies).\n * @param {Object} [options]\n * @param {Boolean} [options.dataPipeline=false]\n * @returns {Function}\n */\nexport function bogusParagraphCreator( attributeNames, { dataPipeline } = {} ) {\n\treturn ( modelElement, { writer } ) => {\n\t\t// Convert only if a bogus paragraph should be used.\n\t\tif ( !shouldUseBogusParagraph( modelElement, attributeNames ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewElement = writer.createContainerElement( 'span', { class: 'ck-list-bogus-paragraph' } );\n\n\t\tif ( dataPipeline ) {\n\t\t\twriter.setCustomProperty( 'dataPipeline:transparentRendering', true, viewElement );\n\t\t}\n\n\t\treturn viewElement;\n\t};\n}\n\n/**\n * Helper for mapping mode to view elements. It's using positions mapping instead of mapper.toViewElement( element )\n * to find outermost view element. This is for cases when mapping is using inner view element like in the code blocks (pre > code).\n *\n * @protected\n * @param {module:engine/model/element~Element} element The model element.\n * @param {module:engine/conversion/mapper~Mapper} mapper The mapper instance.\n * @param {module:engine/model/model~Model} model The model.\n * @returns {module:engine/view/element~Element|null}\n */\nexport function findMappedViewElement( element, mapper, model ) {\n\tconst modelRange = model.createRangeOn( element );\n\tconst viewRange = mapper.toViewRange( modelRange ).getTrimmed();\n\n\treturn viewRange.getContainedElement();\n}\n\n// Unwraps all ol, ul, and li attribute elements that are wrapping the provided view element.\nfunction unwrapListItemBlock( viewElement, viewWriter ) {\n\tlet attributeElement = viewElement.parent;\n\n\twhile ( attributeElement.is( 'attributeElement' ) && [ 'ul', 'ol', 'li' ].includes( attributeElement.name ) ) {\n\t\tconst parentElement = attributeElement.parent;\n\n\t\tviewWriter.unwrap( viewWriter.createRangeOn( viewElement ), attributeElement );\n\n\t\tattributeElement = parentElement;\n\t}\n}\n\n// Wraps the given list item with appropriate attribute elements for ul, ol, and li.\nfunction wrapListItemBlock( listItem, viewRange, strategies, writer ) {\n\tif ( !listItem.hasAttribute( 'listIndent' ) ) {\n\t\treturn;\n\t}\n\n\tconst listItemIndent = listItem.getAttribute( 'listIndent' );\n\tlet currentListItem = listItem;\n\n\tfor ( let indent = listItemIndent; indent >= 0; indent-- ) {\n\t\tconst listItemViewElement = createListItemElement( writer, indent, currentListItem.getAttribute( 'listItemId' ) );\n\t\tconst listViewElement = createListElement( writer, indent, currentListItem.getAttribute( 'listType' ) );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tif ( currentListItem.hasAttribute( strategy.attributeName ) ) {\n\t\t\t\tstrategy.setAttributeOnDowncast(\n\t\t\t\t\twriter,\n\t\t\t\t\tcurrentListItem.getAttribute( strategy.attributeName ),\n\t\t\t\t\tstrategy.scope == 'list' ? listViewElement : listItemViewElement\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tviewRange = writer.wrap( viewRange, listItemViewElement );\n\t\tviewRange = writer.wrap( viewRange, listViewElement );\n\n\t\tif ( indent == 0 ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurrentListItem = ListWalker.first( currentListItem, { lowerIndent: true } );\n\n\t\t// There is no list item with lower indent, this means this is a document fragment containing\n\t\t// only a part of nested list (like copy to clipboard) so we don't need to try to wrap it further.\n\t\tif ( !currentListItem ) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n// Returns the function that is responsible for consuming attributes that are set on the model node.\nfunction createAttributesConsumer( attributeNames ) {\n\treturn ( node, consumable ) => {\n\t\tconst events = [];\n\n\t\t// Collect all set attributes that are triggering conversion.\n\t\tfor ( const attributeName of attributeNames ) {\n\t\t\tif ( node.hasAttribute( attributeName ) ) {\n\t\t\t\tevents.push( `attribute:${ attributeName }` );\n\t\t\t}\n\t\t}\n\n\t\tif ( !events.every( event => consumable.test( node, event ) !== false ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tevents.forEach( event => consumable.consume( node, event ) );\n\n\t\treturn true;\n\t};\n}\n\n// Whether the given item should be rendered as a bogus paragraph.\nfunction shouldUseBogusParagraph( item, attributeNames, blocks = getAllListItemBlocks( item ) ) {\n\tif ( !isListItemBlock( item ) ) {\n\t\treturn false;\n\t}\n\n\tfor ( const attributeKey of item.getAttributeKeys() ) {\n\t\t// Ignore selection attributes stored on block elements.\n\t\tif ( attributeKey.startsWith( 'selection:' ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Don't use bogus paragraph if there are attributes from other features.\n\t\tif ( !attributeNames.includes( attributeKey ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn blocks.length < 2;\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 list/documentlist/documentlistcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\tsplitListItemBefore,\n\texpandListBlocksToCompleteItems,\n\tgetListItemBlocks,\n\tgetListItems,\n\tremoveListAttributes,\n\toutdentFollowingItems,\n\tListItemUid,\n\tsortBlocks,\n\tgetSelectedBlockObject,\n\tisListItemBlock\n} from './utils/model';\n\n/**\n * The list command. It is used by the {@link module:list/documentlist~DocumentList document list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'numbered'|'bulleted'} type List type that will be handled by this command.\n\t */\n\tconstructor( editor, type ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The type of the list created by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'numbered'|'bulleted'}\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false` it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => model.schema.checkAttribute( block, 'listType' ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n\n\t\tmodel.change( writer => {\n\t\t\tif ( turnOff ) {\n\t\t\t\tconst lastBlock = blocks[ blocks.length - 1 ];\n\n\t\t\t\t// Split the first block from the list item.\n\t\t\t\tconst itemBlocks = getListItemBlocks( lastBlock, { direction: 'forward' } );\n\t\t\t\tconst changedBlocks = [];\n\n\t\t\t\tif ( itemBlocks.length > 1 ) {\n\t\t\t\t\tchangedBlocks.push( ...splitListItemBefore( itemBlocks[ 1 ], writer ) );\n\t\t\t\t}\n\n\t\t\t\t// Convert list blocks to plain blocks.\n\t\t\t\tchangedBlocks.push( ...removeListAttributes( blocks, writer ) );\n\n\t\t\t\t// Outdent items following the selected list item.\n\t\t\t\tchangedBlocks.push( ...outdentFollowingItems( lastBlock, writer ) );\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t\t// Turning on the list items for a collapsed selection inside a list item.\n\t\t\telse if ( ( selectedBlockObject || document.selection.isCollapsed ) && isListItemBlock( blocks[ 0 ] ) ) {\n\t\t\t\tconst changedBlocks = getListItems( selectedBlockObject || blocks[ 0 ] );\n\n\t\t\t\tfor ( const block of changedBlocks ) {\n\t\t\t\t\twriter.setAttribute( 'listType', this.type, block );\n\t\t\t\t}\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t\t// Turning on the list items for a non-collapsed selection.\n\t\t\telse {\n\t\t\t\tconst changedBlocks = [];\n\n\t\t\t\tfor ( const block of blocks ) {\n\t\t\t\t\t// Promote the given block to the list item.\n\t\t\t\t\tif ( !block.hasAttribute( 'listType' ) ) {\n\t\t\t\t\t\twriter.setAttributes( {\n\t\t\t\t\t\t\tlistIndent: 0,\n\t\t\t\t\t\t\tlistItemId: ListItemUid.next(),\n\t\t\t\t\t\t\tlistType: this.type\n\t\t\t\t\t\t}, block );\n\n\t\t\t\t\t\tchangedBlocks.push( block );\n\t\t\t\t\t}\n\t\t\t\t\t// Change the type of list item.\n\t\t\t\t\telse {\n\t\t\t\t\t\tfor ( const node of expandListBlocksToCompleteItems( block, { withNested: false } ) ) {\n\t\t\t\t\t\t\tif ( node.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t\t\t\twriter.setAttribute( 'listType', this.type, node );\n\t\t\t\t\t\t\t\tchangedBlocks.push( node );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tif ( !blocks.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const block of blocks ) {\n\t\t\tif ( block.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\t\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\n\t\tif ( !blocks.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tfor ( const block of blocks ) {\n\t\t\tif ( schema.checkAttribute( block, 'listType' ) ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\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 list/documentlist/documentlistediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Enter } from 'ckeditor5/src/enter';\nimport { Delete } from 'ckeditor5/src/typing';\nimport { CKEditorError } from 'ckeditor5/src/utils';\n\nimport DocumentListIndentCommand from './documentlistindentcommand';\nimport DocumentListCommand from './documentlistcommand';\nimport DocumentListMergeCommand from './documentlistmergecommand';\nimport DocumentListSplitCommand from './documentlistsplitcommand';\nimport {\n\tbogusParagraphCreator,\n\tlistItemDowncastConverter,\n\tlistItemUpcastConverter,\n\tlistUpcastCleanList,\n\treconvertItemsOnDataChange\n} from './converters';\nimport {\n\tfindAndAddListHeadToMap,\n\tfixListIndents,\n\tfixListItemIds\n} from './utils/postfixers';\nimport {\n\tgetAllListItemBlocks,\n\tisFirstBlockOfListItem,\n\tisLastBlockOfListItem,\n\tisSingleListItem,\n\tgetSelectedBlockObject,\n\tisListItemBlock,\n\tremoveListAttributes\n} from './utils/model';\nimport {\n\tgetViewElementIdForListType,\n\tgetViewElementNameForListType\n} from './utils/view';\nimport ListWalker, {\n\titerateSiblingListBlocks,\n\tListBlocksIterable\n} from './utils/listwalker';\n\nimport '../../theme/documentlist.css';\n\n/**\n * A list of base list model attributes.\n *\n * @private\n */\nconst LIST_BASE_ATTRIBUTES = [ 'listType', 'listIndent', 'listItemId' ];\n\n/**\n * The editing part of the document-list feature. It handles creating, editing and removing lists and list items.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentListEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Enter, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The list of registered downcast strategies.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<module:list/documentlist/documentlistediting~DowncastStrategy>}\n\t\t */\n\t\tthis._downcastStrategies = [];\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\tif ( editor.plugins.has( 'ListEditing' ) ) {\n\t\t\t/**\n\t\t\t * The `DocumentList` feature can not be loaded together with the `List` plugin.\n\t\t\t *\n\t\t\t * @error document-list-feature-conflict\n\t\t\t * @param {String} conflictPlugin Name of the plugin.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'document-list-feature-conflict', this, { conflictPlugin: 'ListEditing' } );\n\t\t}\n\n\t\tmodel.schema.extend( '$container', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\t\tmodel.schema.extend( '$block', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\t\tmodel.schema.extend( '$blockObject', { allowAttributes: LIST_BASE_ATTRIBUTES } );\n\n\t\tfor ( const attribute of LIST_BASE_ATTRIBUTES ) {\n\t\t\tmodel.schema.setAttributeProperties( attribute, {\n\t\t\t\tcopyOnReplace: true\n\t\t\t} );\n\t\t}\n\n\t\t// Register commands.\n\t\teditor.commands.add( 'numberedList', new DocumentListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new DocumentListCommand( editor, 'bulleted' ) );\n\n\t\teditor.commands.add( 'indentList', new DocumentListIndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new DocumentListIndentCommand( editor, 'backward' ) );\n\n\t\teditor.commands.add( 'mergeListItemBackward', new DocumentListMergeCommand( editor, 'backward' ) );\n\t\teditor.commands.add( 'mergeListItemForward', new DocumentListMergeCommand( editor, 'forward' ) );\n\n\t\teditor.commands.add( 'splitListItemBefore', new DocumentListSplitCommand( editor, 'before' ) );\n\t\teditor.commands.add( 'splitListItemAfter', new DocumentListSplitCommand( editor, 'after' ) );\n\n\t\tthis._setupDeleteIntegration();\n\t\tthis._setupEnterIntegration();\n\t\tthis._setupTabIntegration();\n\t\tthis._setupClipboardIntegration();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\t\tconst commands = editor.commands;\n\t\tconst indent = commands.get( 'indent' );\n\t\tconst outdent = commands.get( 'outdent' );\n\n\t\tif ( indent ) {\n\t\t\t// Priority is high due to integration with `IndentBlock` plugin. We want to indent list first and if it's not possible\n\t\t\t// user can indent content with `IndentBlock` plugin.\n\t\t\tindent.registerChildCommand( commands.get( 'indentList' ), { priority: 'high' } );\n\t\t}\n\n\t\tif ( outdent ) {\n\t\t\t// Priority is lowest due to integration with `IndentBlock` and `IndentCode` plugins.\n\t\t\t// First we want to allow user to outdent all indendations from other features then he can oudent list item.\n\t\t\toutdent.registerChildCommand( commands.get( 'outdentList' ), { priority: 'lowest' } );\n\t\t}\n\n\t\t// Register conversion and model post-fixer after other plugins had a chance to register their attribute strategies.\n\t\tthis._setupModelPostFixing();\n\t\tthis._setupConversion();\n\t}\n\n\t/**\n\t * Registers a downcast strategy.\n\t *\n\t * **Note**: Strategies must be registered in the `Plugin#init()` phase so that it can be applied\n\t * in the `DocumentListEditing#afterInit()`.\n\t *\n\t * @param {module:list/documentlist/documentlistediting~DowncastStrategy} strategy The downcast strategy to register.\n\t */\n\tregisterDowncastStrategy( strategy ) {\n\t\tthis._downcastStrategies.push( strategy );\n\t}\n\n\t/**\n\t * Returns list of model attribute names that should affect downcast conversion.\n\t *\n\t * @private\n\t */\n\t_getListAttributeNames() {\n\t\treturn [\n\t\t\t...LIST_BASE_ATTRIBUTES,\n\t\t\t...this._downcastStrategies.map( strategy => strategy.attributeName )\n\t\t];\n\t}\n\n\t/**\n\t * Attaches the listener to the {@link module:engine/view/document~Document#event:delete} event and handles backspace/delete\n\t * keys in and around document lists.\n\t *\n\t * @private\n\t */\n\t_setupDeleteIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst mergeBackwardCommand = editor.commands.get( 'mergeListItemBackward' );\n\t\tconst mergeForwardCommand = editor.commands.get( 'mergeListItemForward' );\n\n\t\tthis.listenTo( editor.editing.view.document, 'delete', ( evt, data ) => {\n\t\t\tconst selection = editor.model.document.selection;\n\n\t\t\t// Let the Widget plugin take care of block widgets while deleting (https://github.com/ckeditor/ckeditor5/issues/11346).\n\t\t\tif ( getSelectedBlockObject( editor.model ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\teditor.model.change( () => {\n\t\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\t\tif ( selection.isCollapsed && data.direction == 'backward' ) {\n\t\t\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\t\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst previousBlock = ListWalker.first( positionParent, {\n\t\t\t\t\t\tsameAttributes: 'listType',\n\t\t\t\t\t\tsameIndent: true\n\t\t\t\t\t} );\n\n\t\t\t\t\t// Outdent the first block of a first list item.\n\t\t\t\t\tif ( !previousBlock && positionParent.getAttribute( 'listIndent' ) === 0 ) {\n\t\t\t\t\t\tif ( !isLastBlockOfListItem( positionParent ) ) {\n\t\t\t\t\t\t\teditor.execute( 'splitListItemAfter' );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\teditor.execute( 'outdentList' );\n\t\t\t\t\t}\n\t\t\t\t\t// Merge block with previous one (on the block level or on the content level).\n\t\t\t\t\telse {\n\t\t\t\t\t\tif ( !mergeBackwardCommand.isEnabled ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmergeBackwardCommand.execute( {\n\t\t\t\t\t\t\tshouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel( editor.model, 'backward' )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// Non-collapsed selection or forward delete.\n\t\t\t\telse {\n\t\t\t\t\t// Collapsed selection should trigger forward merging only if at the end of a block.\n\t\t\t\t\tif ( selection.isCollapsed && !selection.getLastPosition().isAtEnd ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !mergeForwardCommand.isEnabled ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tmergeForwardCommand.execute( {\n\t\t\t\t\t\tshouldMergeOnBlocksContentLevel: shouldMergeOnBlocksContentLevel( editor.model, 'forward' )\n\t\t\t\t\t} );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t} );\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:enter} event and handles enter key press\n\t * in document lists.\n\t *\n\t * @private\n\t */\n\t_setupEnterIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst commands = editor.commands;\n\t\tconst enterCommand = commands.get( 'enter' );\n\n\t\t// Overwrite the default Enter key behavior: outdent or split the list in certain cases.\n\t\tthis.listenTo( editor.editing.view.document, 'enter', ( evt, data ) => {\n\t\t\tconst doc = model.document;\n\t\t\tconst positionParent = doc.selection.getFirstPosition().parent;\n\n\t\t\tif (\n\t\t\t\tdoc.selection.isCollapsed &&\n\t\t\t\tisListItemBlock( positionParent ) &&\n\t\t\t\tpositionParent.isEmpty &&\n\t\t\t\t!data.isSoft\n\t\t\t) {\n\t\t\t\tconst isFirstBlock = isFirstBlockOfListItem( positionParent );\n\t\t\t\tconst isLastBlock = isLastBlockOfListItem( positionParent );\n\n\t\t\t\t// * a → * a\n\t\t\t\t// * [] → []\n\t\t\t\tif ( isFirstBlock && isLastBlock ) {\n\t\t\t\t\teditor.execute( 'outdentList' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// * [] → * []\n\t\t\t\t// a → * a\n\t\t\t\telse if ( isFirstBlock && !isLastBlock ) {\n\t\t\t\t\teditor.execute( 'splitListItemAfter' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t\t// * a → * a\n\t\t\t\t// [] → * []\n\t\t\t\telse if ( isLastBlock ) {\n\t\t\t\t\teditor.execute( 'splitListItemBefore' );\n\n\t\t\t\t\tdata.preventDefault();\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t}, { context: 'li' } );\n\n\t\t// In some cases, after the default block splitting, we want to modify the new block to become a new list item\n\t\t// instead of an additional block in the same list item.\n\t\tthis.listenTo( enterCommand, 'afterExecute', () => {\n\t\t\tconst splitCommand = commands.get( 'splitListItemBefore' );\n\n\t\t\t// The command has not refreshed because the change block related to EnterCommand#execute() is not over yet.\n\t\t\t// Let's keep it up to date and take advantage of DocumentListSplitCommand#isEnabled.\n\t\t\tsplitCommand.refresh();\n\n\t\t\tif ( !splitCommand.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst doc = editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\t\t\tconst listItemBlocks = getAllListItemBlocks( positionParent );\n\n\t\t\t// Keep in mind this split happens after the default enter handler was executed. For instance:\n\t\t\t//\n\t\t\t// │ Initial state │ After default enter │ Here in #afterExecute │\n\t\t\t// ├───────────────────────────┼───────────────────────────┼───────────────────────────┤\n\t\t\t// │ * a[] │ * a │ * a │\n\t\t\t// │ │ [] │ * [] │\n\t\t\tif ( listItemBlocks.length === 2 ) {\n\t\t\t\tsplitCommand.execute();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches a listener to the {@link module:engine/view/document~Document#event:tab} event and handles tab key and tab+shift keys\n\t * presses in document lists.\n\t *\n\t * @private\n\t */\n\t_setupTabIntegration() {\n\t\tconst editor = this.editor;\n\n\t\tthis.listenTo( editor.editing.view.document, 'tab', ( evt, data ) => {\n\t\t\tconst commandName = data.shiftKey ? 'outdentList' : 'indentList';\n\t\t\tconst command = this.editor.commands.get( commandName );\n\n\t\t\tif ( command.isEnabled ) {\n\t\t\t\teditor.execute( commandName );\n\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * Registers the conversion helpers for the document-list feature.\n\t * @private\n\t */\n\t_setupConversion() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst attributeNames = this._getListAttributeNames();\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.elementToElement( { view: 'li', model: 'paragraph' } )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'element:li', listItemUpcastConverter() );\n\t\t\t\tdispatcher.on( 'element:ul', listUpcastCleanList(), { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:ol', listUpcastCleanList(), { priority: 'high' } );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'paragraph',\n\t\t\t\tview: bogusParagraphCreator( attributeNames ),\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.elementToElement( {\n\t\t\t\tmodel: 'paragraph',\n\t\t\t\tview: bogusParagraphCreator( attributeNames, { dataPipeline: true } ),\n\t\t\t\tconverterPriority: 'high'\n\t\t\t} );\n\n\t\teditor.conversion.for( 'downcast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'attribute', listItemDowncastConverter( attributeNames, this._downcastStrategies, model ) );\n\t\t\t} );\n\n\t\tthis.listenTo( model.document, 'change:data', reconvertItemsOnDataChange( model, editor.editing, attributeNames, this ) );\n\n\t\t// For LI verify if an ID of the attribute element is correct.\n\t\tthis.on( 'checkAttributes:item', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tif ( viewElement.id != modelAttributes.listItemId ) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\n\t\t// For UL and OL check if the name and ID of element is correct.\n\t\tthis.on( 'checkAttributes:list', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tif (\n\t\t\t\tviewElement.name != getViewElementNameForListType( modelAttributes.listType ) ||\n\t\t\t\tviewElement.id != getViewElementIdForListType( modelAttributes.listType, modelAttributes.listIndent )\n\t\t\t) {\n\t\t\t\tevt.return = true;\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Registers model post-fixers.\n\t *\n\t * @private\n\t */\n\t_setupModelPostFixing() {\n\t\tconst model = this.editor.model;\n\t\tconst attributeNames = this._getListAttributeNames();\n\n\t\t// Register list fixing.\n\t\t// First the low level handler.\n\t\tmodel.document.registerPostFixer( writer => modelChangePostFixer( model, writer, attributeNames, this ) );\n\n\t\t// Then the callbacks for the specific lists.\n\t\t// The indentation fixing must be the first one...\n\t\tthis.on( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tevt.return = fixListIndents( listNodes, writer ) || evt.return;\n\t\t}, { priority: 'high' } );\n\n\t\t// ...then the item ids... and after that other fixers that rely on the correct indentation and ids.\n\t\tthis.on( 'postFixer', ( evt, { listNodes, writer, seenIds } ) => {\n\t\t\tevt.return = fixListItemIds( listNodes, seenIds, writer ) || evt.return;\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Integrates the feature with the clipboard via {@link module:engine/model/model~Model#insertContent} and\n\t * {@link module:engine/model/model~Model#getSelectedContent}.\n\t *\n\t * @private\n\t */\n\t_setupClipboardIntegration() {\n\t\tconst model = this.editor.model;\n\n\t\tthis.listenTo( model, 'insertContent', createModelIndentPasteFixer( model ), { priority: 'high' } );\n\n\t\t// To enhance the UX, the editor should not copy list attributes to the clipboard if the selection\n\t\t// started and ended in the same list item.\n\t\t//\n\t\t// If the selection was enclosed in a single list item, there is a good chance the user did not want it\n\t\t// copied as a list item but plain blocks.\n\t\t//\n\t\t// This avoids pasting orphaned list items instead of paragraphs, for instance, straight into the root.\n\t\t//\n\t\t//\t ┌─────────────────────┬───────────────────┐\n\t\t//\t │ Selection │ Clipboard content │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ [* <Widget />] │ <Widget /> │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ [* Foo] │ Foo │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ * Foo [bar] baz │ bar │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ * Fo[o │ o │\n\t\t//\t │ ba]r │ ba │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ * Fo[o │ * o │\n\t\t//\t │ * ba]r │ * ba │\n\t\t//\t ├─────────────────────┼───────────────────┤\n\t\t//\t │ [* Foo │ * Foo │\n\t\t//\t │ * bar] │ * bar │\n\t\t//\t └─────────────────────┴───────────────────┘\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5/issues/11608.\n\t\tthis.listenTo( model, 'getSelectedContent', ( evt, [ selection ] ) => {\n\t\t\tconst isSingleListItemSelected = isSingleListItem( Array.from( selection.getSelectedBlocks() ) );\n\n\t\t\tif ( isSingleListItemSelected ) {\n\t\t\t\tmodel.change( writer => removeListAttributes( Array.from( evt.return.getChildren() ), writer ) );\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * @typedef {Object} module:list/documentlist/documentlistediting~DowncastStrategy\n * @property {'list'|'item'} scope The scope of the downcast (whether it applies to LI or OL/UL).\n * @property {String} attributeName The model attribute name.\n * @property {Function} setAttributeOnDowncast Sets the property on the view element.\n */\n\n// Post-fixer that reacts to changes on document and fixes incorrect model states (invalid `listItemId` and `listIndent` values).\n//\n// In the example below, there is a correct list structure.\n// Then the middle element is removed so the list structure will become incorrect:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>Item 2</paragraph> <--- this is removed.\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n//\n// The list structure after the middle element is removed:\n//\n// \t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>Item 3</paragraph>\n//\n// Should become:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>Item 1</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=1>Item 3</paragraph> <--- note that indent got post-fixed.\n//\n// @param {module:engine/model/model~Model} model The data model.\n// @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n// @param {Array.<String>} attributeNames The list of all model list attributes (including registered strategies).\n// @param {module:list/documentlist/documentlistediting~DocumentListEditing} documentListEditing The document list editing plugin.\n// @returns {Boolean} `true` if any change has been applied, `false` otherwise.\nfunction modelChangePostFixer( model, writer, attributeNames, documentListEditing ) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map();\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name != '$text' ) {\n\t\t\tconst item = entry.position.nodeAfter;\n\n\t\t\t// Remove attributes in case of renamed element.\n\t\t\tif ( !model.schema.checkAttribute( item, 'listItemId' ) ) {\n\t\t\t\tfor ( const attributeName of Array.from( item.getAttributeKeys() ) ) {\n\t\t\t\t\tif ( attributeNames.includes( attributeName ) ) {\n\t\t\t\t\t\twriter.removeAttribute( attributeName, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\n\t\t\t// Insert of a non-list item - check if there is a list after it.\n\t\t\tif ( !entry.attributes.has( 'listItemId' ) ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.position.getShiftedBy( entry.length ), itemToListHead );\n\t\t\t}\n\n\t\t\t// Check if there is no nested list.\n\t\t\tfor ( const { item: innerItem, previousPosition } of model.createRangeIn( item ) ) {\n\t\t\t\tif ( isListItemBlock( innerItem ) ) {\n\t\t\t\t\tfindAndAddListHeadToMap( previousPosition, itemToListHead );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Removed list item or block adjacent to a list.\n\t\telse if ( entry.type == 'remove' ) {\n\t\t\tfindAndAddListHeadToMap( entry.position, itemToListHead );\n\t\t}\n\t\t// Changed list item indent or type.\n\t\telse if ( entry.type == 'attribute' && attributeNames.includes( entry.attributeKey ) ) {\n\t\t\tfindAndAddListHeadToMap( entry.range.start, itemToListHead );\n\n\t\t\tif ( entry.attributeNewValue === null ) {\n\t\t\t\tfindAndAddListHeadToMap( entry.range.start.getShiftedBy( 1 ), itemToListHead );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Make sure that IDs are not shared by split list.\n\tconst seenIds = new Set();\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\t/**\n\t\t * Event fired on changes detected on the model list element to verify if the view representation of a list element\n\t\t * is representing those attributes.\n\t\t *\n\t\t * It allows triggering a re-wrapping of a list item.\n\t\t *\n\t\t * **Note**: For convenience this event is namespaced and could be captured as `checkAttributes:list` or `checkAttributes:item`.\n\t\t *\n\t\t * @protected\n\t\t * @event module:list/documentlist/documentlistediting~DocumentListEditing#event:postFixer\n\t\t * @param {module:engine/model/element~Element} listHead The head element of a list.\n\t\t * @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n\t\t * @param {Set.<String>} seenIds The set of already known IDs.\n\t\t * @param {Object} modelAttributes\n\t\t * @returns {Boolean} If a post-fixer made a change of the model tree, it should return `true`.\n\t\t */\n\t\tapplied = documentListEditing.fire( 'postFixer', {\n\t\t\tlistNodes: new ListBlocksIterable( listHead ),\n\t\t\tlistHead,\n\t\t\twriter,\n\t\t\tseenIds\n\t\t} ) || applied;\n\t}\n\n\treturn applied;\n}\n\n// A fixer for pasted content that includes list items.\n//\n// It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n//\n// Example:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>A</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>B^</paragraph>\n//\t\t// At ^ paste: <paragraph listType=\"bulleted\" listItemId=\"x\" listIndent=4>X</paragraph>\n//\t\t// <paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=5>Y</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>C</paragraph>\n//\n// Should become:\n//\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"a\" listIndent=0>A</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"b\" listIndent=1>BX</paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"y\" listIndent=2>Y/paragraph>\n//\t\t<paragraph listType=\"bulleted\" listItemId=\"c\" listIndent=2>C</paragraph>\n//\nfunction createModelIndentPasteFixer( model ) {\n\treturn ( evt, [ content, selectable ] ) => {\n\t\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t\t// that list will be broken.\n\t\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t\t// would create incorrect model.\n\t\tconst item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\t\tif ( !isListItemBlock( item ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet selection;\n\n\t\tif ( !selectable ) {\n\t\t\tselection = model.document.selection;\n\t\t} else {\n\t\t\tselection = model.createSelection( selectable );\n\t\t}\n\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\n\t\tif ( isListItemBlock( pos.parent ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( isListItemBlock( pos.nodeBefore ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( !refItem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t// Indent of all those items has to be adjusted to reference item.\n\t\tconst indentChange = refItem.getAttribute( 'listIndent' ) - item.getAttribute( 'listIndent' );\n\n\t\t// Fix only if there is anything to fix.\n\t\tif ( indentChange <= 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\tfor ( const { node } of iterateSiblingListBlocks( item, 'forward' ) ) {\n\t\t\t\twriter.setAttribute( 'listIndent', node.getAttribute( 'listIndent' ) + indentChange, node );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// Decides whether the merge should be accompanied by the model's `deleteContent()`, for instance, to get rid of the inline\n// content in the selection or take advantage of the heuristics in `deleteContent()` that helps convert lists into paragraphs\n// in certain cases.\n//\n// @param {module:engine/model/model~Model} model\n// @param {'backward'|'forward'} direction\n// @returns {Boolean}\nfunction shouldMergeOnBlocksContentLevel( model, direction ) {\n\tconst selection = model.document.selection;\n\n\tif ( !selection.isCollapsed ) {\n\t\treturn !getSelectedBlockObject( model );\n\t}\n\n\tif ( direction === 'forward' ) {\n\t\treturn true;\n\t}\n\n\tconst firstPosition = selection.getFirstPosition();\n\tconst positionParent = firstPosition.parent;\n\tconst previousSibling = positionParent.previousSibling;\n\n\tif ( model.schema.isObject( previousSibling ) ) {\n\t\treturn false;\n\t}\n\n\tif ( previousSibling.isEmpty ) {\n\t\treturn true;\n\t}\n\n\treturn isSingleListItem( [ positionParent, previousSibling ] );\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 list/documentlist/documentlistindentcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\texpandListBlocksToCompleteItems,\n\tindentBlocks,\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tisSingleListItem,\n\toutdentBlocksWithMerge,\n\tsortBlocks,\n\tsplitListItemBefore\n} from './utils/model';\nimport ListWalker from './utils/listwalker';\n\n/**\n * The document list indent command. It is used by the {@link module:list/documentlist~DocumentList list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListIndentCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'forward'|'backward'} indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor, indentDirection ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Determines by how much the command will change the list item's indent attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {'forward'|'backward'}\n\t\t */\n\t\tthis._direction = indentDirection;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst blocks = getSelectedListBlocks( model.document.selection );\n\n\t\tmodel.change( writer => {\n\t\t\tconst changedBlocks = [];\n\n\t\t\t// Handle selection contained in the single list item and starting in the following blocks.\n\t\t\tif ( isSingleListItem( blocks ) && !isFirstBlockOfListItem( blocks[ 0 ] ) ) {\n\t\t\t\t// Allow increasing indent of following list item blocks.\n\t\t\t\tif ( this._direction == 'forward' ) {\n\t\t\t\t\tchangedBlocks.push( ...indentBlocks( blocks, writer ) );\n\t\t\t\t}\n\n\t\t\t\t// For indent make sure that indented blocks have a new ID.\n\t\t\t\t// For outdent just split blocks from the list item (give them a new IDs).\n\t\t\t\tchangedBlocks.push( ...splitListItemBefore( blocks[ 0 ], writer ) );\n\t\t\t}\n\t\t\t// More than a single list item is selected, or the first block of list item is selected.\n\t\t\telse {\n\t\t\t\t// Now just update the attributes of blocks.\n\t\t\t\tif ( this._direction == 'forward' ) {\n\t\t\t\t\tchangedBlocks.push( ...indentBlocks( blocks, writer, { expand: true } ) );\n\t\t\t\t} else {\n\t\t\t\t\tchangedBlocks.push( ...outdentBlocksWithMerge( blocks, writer ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Align the list item type to match the previous list item (from the same list).\n\t\t\tfor ( const block of changedBlocks ) {\n\t\t\t\t// This block become a plain block (for example a paragraph).\n\t\t\t\tif ( !block.hasAttribute( 'listType' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst previousItemBlock = ListWalker.first( block, { sameIndent: true } );\n\n\t\t\t\tif ( previousItemBlock ) {\n\t\t\t\t\twriter.setAttribute( 'listType', previousItemBlock.getAttribute( 'listType' ), block );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListIndentCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tlet blocks = getSelectedListBlocks( this.editor.model.document.selection );\n\t\tlet firstBlock = blocks[ 0 ];\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\tif ( this._direction == 'backward' ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// A single block of a list item is selected, so it could be indented as a sublist.\n\t\tif ( isSingleListItem( blocks ) && !isFirstBlockOfListItem( blocks[ 0 ] ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tblocks = expandListBlocksToCompleteItems( blocks );\n\t\tfirstBlock = blocks[ 0 ];\n\n\t\t// Check if there is any list item before selected items that could become a parent of selected items.\n\t\tconst siblingItem = ListWalker.first( firstBlock, { sameIndent: true } );\n\n\t\tif ( !siblingItem ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( siblingItem.getAttribute( 'listType' ) == firstBlock.getAttribute( 'listType' ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n// Returns an array of selected blocks truncated to the first non list block element.\nfunction getSelectedListBlocks( selection ) {\n\tconst blocks = Array.from( selection.getSelectedBlocks() );\n\tconst firstNonListBlockIndex = blocks.findIndex( block => !isListItemBlock( block ) );\n\n\tif ( firstNonListBlockIndex != -1 ) {\n\t\tblocks.length = firstNonListBlockIndex;\n\t}\n\n\treturn blocks;\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 list/documentlist/documentlistmergecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\tgetNestedListBlocks,\n\tindentBlocks,\n\tsortBlocks,\n\tisFirstBlockOfListItem,\n\tmergeListItemBefore,\n\tisSingleListItem,\n\tgetSelectedBlockObject,\n\tisListItemBlock\n} from './utils/model';\nimport ListWalker from './utils/listwalker';\n\n/**\n * The document list merge command. It is used by the {@link module:list/documentlist~DocumentList list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListMergeCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'backward'|'forward'} direction Whether list item should be merged before or after the selected block.\n\t */\n\tconstructor( editor, direction ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Whether list item should be merged before or after the selected block.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {'backward'|'forward'}\n\t\t */\n\t\tthis._direction = direction;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Merges list blocks together (depending on the {@link #constructor}'s `direction` parameter).\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t * @param {Object} [options] Command options.\n\t * @param {String|Boolean} [options.shouldMergeOnBlocksContentLevel=false] When set `true`, merging will be performed together\n\t * with {@link module:engine/model/model~Model#deleteContent} to get rid of the inline content in the selection or take advantage\n\t * of the heuristics in `deleteContent()` that helps convert lists into paragraphs in certain cases.\n\t */\n\texecute( { shouldMergeOnBlocksContentLevel = false } = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst changedBlocks = [];\n\n\t\tmodel.change( writer => {\n\t\t\tconst { firstElement, lastElement } = this._getMergeSubjectElements( selection, shouldMergeOnBlocksContentLevel );\n\n\t\t\tconst firstIndent = firstElement.getAttribute( 'listIndent' ) || 0;\n\t\t\tconst lastIndent = lastElement.getAttribute( 'listIndent' );\n\t\t\tconst lastElementId = lastElement.getAttribute( 'listItemId' );\n\n\t\t\tif ( firstIndent != lastIndent ) {\n\t\t\t\tconst nestedLastElementBlocks = getNestedListBlocks( lastElement );\n\n\t\t\t\tchangedBlocks.push( ...indentBlocks( [ lastElement, ...nestedLastElementBlocks ], writer, {\n\t\t\t\t\tindentBy: firstIndent - lastIndent,\n\n\t\t\t\t\t// If outdenting, the entire sub-tree that follows must be included.\n\t\t\t\t\texpand: firstIndent < lastIndent\n\t\t\t\t} ) );\n\t\t\t}\n\n\t\t\tif ( shouldMergeOnBlocksContentLevel ) {\n\t\t\t\tlet sel = selection;\n\n\t\t\t\tif ( selection.isCollapsed ) {\n\t\t\t\t\tsel = writer.createSelection( writer.createRange(\n\t\t\t\t\t\twriter.createPositionAt( firstElement, 'end' ),\n\t\t\t\t\t\twriter.createPositionAt( lastElement, 0 )\n\t\t\t\t\t) );\n\t\t\t\t}\n\n\t\t\t\t// Delete selected content. Replace entire content only for non-collapsed selection.\n\t\t\t\tmodel.deleteContent( sel, { doNotResetEntireContent: selection.isCollapsed } );\n\n\t\t\t\t// Get the last \"touched\" element after deleteContent call (can't use the lastElement because\n\t\t\t\t// it could get merged into the firstElement while deleting content).\n\t\t\t\tconst lastElementAfterDelete = sel.getLastPosition().parent;\n\n\t\t\t\t// Check if the element after it was in the same list item and adjust it if needed.\n\t\t\t\tconst nextSibling = lastElementAfterDelete.nextSibling;\n\n\t\t\t\tchangedBlocks.push( lastElementAfterDelete );\n\n\t\t\t\tif ( nextSibling && nextSibling !== lastElement && nextSibling.getAttribute( 'listItemId' ) == lastElementId ) {\n\t\t\t\t\tchangedBlocks.push( ...mergeListItemBefore( nextSibling, lastElementAfterDelete, writer ) );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tchangedBlocks.push( ...mergeListItemBefore( lastElement, firstElement, writer ) );\n\t\t\t}\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListMergeCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst model = this.editor.model;\n\t\tconst selection = model.document.selection;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\n\t\tif ( selection.isCollapsed || selectedBlockObject ) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n\n\t\t\tif ( !isListItemBlock( positionParent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst siblingNode = this._direction == 'backward' ?\n\t\t\t\tpositionParent.previousSibling :\n\t\t\t\tpositionParent.nextSibling;\n\n\t\t\tif ( !siblingNode ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( isSingleListItem( [ positionParent, siblingNode ] ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\tconst lastPosition = selection.getLastPosition();\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\t// If deleting within a single block of a list item, there's no need to merge anything.\n\t\t\t// The default delete should be executed instead.\n\t\t\tif ( lastPosition.parent === firstPosition.parent ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ( !isListItemBlock( lastPosition.parent ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns the boundary elements the merge should be executed for. These are not necessarily selection's first\n\t * and last position parents but sometimes sibling or even further blocks depending on the context.\n\t *\n\t * @param {module:engine/model/selection~Selection} selection The selection the merge is executed for.\n\t * @param {Boolean} shouldMergeOnBlocksContentLevel When `true`, merge is performed together with\n\t * {@link module:engine/model/model~Model#deleteContent} to remove the inline content within the selection.\n\t * @returns {Object} elements\n\t * @returns {module:engine/model/element~Element} elements.firstElement\n\t * @returns {module:engine/model/element~Element} elements.lastElement\n\t */\n\t_getMergeSubjectElements( selection, shouldMergeOnBlocksContentLevel ) {\n\t\tconst model = this.editor.model;\n\t\tconst selectedBlockObject = getSelectedBlockObject( model );\n\t\tlet firstElement, lastElement;\n\n\t\tif ( selection.isCollapsed || selectedBlockObject ) {\n\t\t\tconst positionParent = selectedBlockObject || selection.getFirstPosition().parent;\n\t\t\tconst isFirstBlock = isFirstBlockOfListItem( positionParent );\n\n\t\t\tif ( this._direction == 'backward' ) {\n\t\t\t\tlastElement = positionParent;\n\n\t\t\t\tif ( isFirstBlock && !shouldMergeOnBlocksContentLevel ) {\n\t\t\t\t\t// For the \"c\" as an anchorElement:\n\t\t\t\t\t// * a\n\t\t\t\t\t// * b\n\t\t\t\t\t// * [c] <-- this block should be merged with \"a\"\n\t\t\t\t\t// It should find \"a\" element to merge with:\n\t\t\t\t\t// * a\n\t\t\t\t\t// * b\n\t\t\t\t\t// c\n\t\t\t\t\tfirstElement = ListWalker.first( positionParent, { sameIndent: true, lowerIndent: true } );\n\t\t\t\t} else {\n\t\t\t\t\tfirstElement = positionParent.previousSibling;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// In case of the forward merge there is no case as above, just merge with next sibling.\n\t\t\t\tfirstElement = positionParent;\n\t\t\t\tlastElement = positionParent.nextSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tfirstElement = selection.getFirstPosition().parent;\n\t\t\tlastElement = selection.getLastPosition().parent;\n\t\t}\n\n\t\treturn { firstElement, lastElement };\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 list/documentlist/documentlistsplitcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport {\n\tisFirstBlockOfListItem,\n\tisListItemBlock,\n\tsortBlocks,\n\tsplitListItemBefore\n} from './utils/model';\n\n/**\n * The document list split command that splits the list item at the selection.\n *\n * It is used by the {@link module:list/documentlist~DocumentList document list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListSplitCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'before'|'after'} direction Whether list item should be split before or after the selected block.\n\t */\n\tconstructor( editor, direction ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Whether list item should be split before or after the selected block.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {'before'|'after'}\n\t\t */\n\t\tthis._direction = direction;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Splits the list item at the selection.\n\t *\n\t * @fires execute\n\t * @fires afterExecute\n\t */\n\texecute() {\n\t\tconst editor = this.editor;\n\n\t\teditor.model.change( writer => {\n\t\t\tconst changedBlocks = splitListItemBefore( this._getStartBlock(), writer );\n\n\t\t\tthis._fireAfterExecute( changedBlocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Fires the `afterExecute` event.\n\t *\n\t * @private\n\t * @param {Array.<module:engine/model/element~Element>} changedBlocks The changed list elements.\n\t */\n\t_fireAfterExecute( changedBlocks ) {\n\t\t/**\n\t\t * Event fired by the {@link #execute} method.\n\t\t *\n\t\t * It allows to execute an action after executing the {@link ~DocumentListSplitCommand#execute} method,\n\t\t * for example adjusting attributes of changed list items.\n\t\t *\n\t\t * @protected\n\t\t * @event afterExecute\n\t\t */\n\t\tthis.fire( 'afterExecute', sortBlocks( new Set( changedBlocks ) ) );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst block = this._getStartBlock();\n\n\t\treturn selection.isCollapsed &&\n\t\t\tisListItemBlock( block ) &&\n\t\t\t!isFirstBlockOfListItem( block );\n\t}\n\n\t/**\n\t * Returns the model element that is the main focus of the command (according to the current selection and command direction).\n\t *\n\t * @private\n\t * @returns {module:engine/model/element~Element}\n\t */\n\t_getStartBlock() {\n\t\tconst doc = this.editor.model.document;\n\t\tconst positionParent = doc.selection.getFirstPosition().parent;\n\n\t\treturn this._direction == 'before' ? positionParent : positionParent.nextSibling;\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 list/documentlist/utils/listwalker\n */\n\nimport { first, toArray } from 'ckeditor5/src/utils';\nimport { isListItemBlock } from './model';\n\n/**\n * Document list blocks iterator.\n */\nexport default class ListWalker {\n\t/**\n\t * Creates a document list iterator.\n\t *\n\t * @param {module:engine/model/element~Element} startElement The start list item block element.\n\t * @param {Object} options\n\t * @param {'forward'|'backward'} [options.direction='backward'] The iterating direction.\n\t * @param {Boolean} [options.includeSelf=false] Whether start block should be included in the result (if it's matching other criteria).\n\t * @param {Array.<String>|String} [options.sameAttributes=[]] Additional attributes that must be the same for each block.\n\t * @param {Boolean} [options.sameIndent=false] Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.lowerIndent=false] Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t */\n\tconstructor( startElement, options ) {\n\t\t/**\n\t\t * The start list item block element.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/element~Element}\n\t\t */\n\t\tthis._startElement = startElement;\n\n\t\t/**\n\t\t * The reference indent. Initialized by the indent of the start block.\n\t\t *\n\t\t * @private\n\t\t * @type {Number}\n\t\t */\n\t\tthis._referenceIndent = startElement.getAttribute( 'listIndent' );\n\n\t\t/**\n\t\t * The iterating direction.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._isForward = options.direction == 'forward';\n\n\t\t/**\n\t\t * Whether start block should be included in the result (if it's matching other criteria).\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._includeSelf = !!options.includeSelf;\n\n\t\t/**\n\t\t * Additional attributes that must be the same for each block.\n\t\t *\n\t\t * @private\n\t\t * @type {Array.<String>}\n\t\t */\n\t\tthis._sameAttributes = toArray( options.sameAttributes || [] );\n\n\t\t/**\n\t\t * Whether blocks with the same indent level as the start block should be included in the result.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._sameIndent = !!options.sameIndent;\n\n\t\t/**\n\t\t * Whether blocks with a lower indent level than the start block should be included in the result.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._lowerIndent = !!options.lowerIndent;\n\n\t\t/**\n\t\t * Whether blocks with a higher indent level than the start block should be included in the result.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._higherIndent = !!options.higherIndent;\n\t}\n\n\t/**\n\t * Performs only first step of iteration and returns the result.\n\t *\n\t * @param {module:engine/model/element~Element} startElement The start list item block element.\n\t * @param {Object} options\n\t * @param {'forward'|'backward'} [options.direction='backward'] The iterating direction.\n\t * @param {Boolean} [options.includeSelf=false] Whether start block should be included in the result (if it's matching other criteria).\n\t * @param {Array.<String>|String} [options.sameAttributes=[]] Additional attributes that must be the same for each block.\n\t * @param {Boolean} [options.sameIndent=false] Whether blocks with the same indent level as the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.lowerIndent=false] Whether blocks with a lower indent level than the start block should be included\n\t * in the result.\n\t * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n\t * in the result.\n\t * @returns {module:engine/model/element~Element|null}\n\t */\n\tstatic first( startElement, options ) {\n\t\tconst walker = new this( startElement, options );\n\t\tconst iterator = walker[ Symbol.iterator ]();\n\n\t\treturn first( iterator );\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.<module:engine/model/element~Element>}\n\t */\n\t* [ Symbol.iterator ]() {\n\t\tconst nestedItems = [];\n\n\t\tfor ( const { node } of iterateSiblingListBlocks( this._getStartNode(), this._isForward ? 'forward' : 'backward' ) ) {\n\t\t\tconst indent = node.getAttribute( 'listIndent' );\n\n\t\t\t// Leaving a nested list.\n\t\t\tif ( indent < this._referenceIndent ) {\n\t\t\t\t// Abort searching blocks.\n\t\t\t\tif ( !this._lowerIndent ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// While searching for lower indents, update the reference indent to find another parent in the next step.\n\t\t\t\tthis._referenceIndent = indent;\n\t\t\t}\n\t\t\t// Entering a nested list.\n\t\t\telse if ( indent > this._referenceIndent ) {\n\t\t\t\t// Ignore nested blocks.\n\t\t\t\tif ( !this._higherIndent ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Collect nested blocks to verify if they are really nested, or it's a different item.\n\t\t\t\tif ( !this._isForward ) {\n\t\t\t\t\tnestedItems.push( node );\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Same indent level block.\n\t\t\telse {\n\t\t\t\t// Ignore same indent block.\n\t\t\t\tif ( !this._sameIndent ) {\n\t\t\t\t\t// While looking for nested blocks, stop iterating while encountering first same indent block.\n\t\t\t\t\tif ( this._higherIndent ) {\n\t\t\t\t\t\t// No more nested blocks so yield nested items.\n\t\t\t\t\t\tif ( nestedItems.length ) {\n\t\t\t\t\t\t\tyield* nestedItems;\n\t\t\t\t\t\t\tnestedItems.length = 0;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Abort if item has any additionally specified attribute different.\n\t\t\t\tif ( this._sameAttributes.some( attr => node.getAttribute( attr ) !== this._startElement.getAttribute( attr ) ) ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// There is another block for the same list item so the nested items were in the same list item.\n\t\t\tif ( nestedItems.length ) {\n\t\t\t\tyield* nestedItems;\n\t\t\t\tnestedItems.length = 0;\n\t\t\t}\n\n\t\t\tyield node;\n\t\t}\n\t}\n\n\t/**\n\t * Returns the model element to start iterating.\n\t *\n\t * @private\n\t * @returns {module:engine/model/element~Element}\n\t */\n\t_getStartNode() {\n\t\tif ( this._includeSelf ) {\n\t\t\treturn this._startElement;\n\t\t}\n\n\t\treturn this._isForward ?\n\t\t\tthis._startElement.nextSibling :\n\t\t\tthis._startElement.previousSibling;\n\t}\n}\n\n/**\n * Iterates sibling list blocks starting from the given node.\n *\n * @protected\n * @param {module:engine/model/node~Node} node The model node.\n * @param {'backward'|'forward'} [direction='forward'] Iteration direction.\n * @returns {Iterator.<module:list/documentlist/utils/listwalker~ListIteratorValue>} The object with `node` and `previous`\n * {@link module:engine/model/element~Element blocks}.\n */\nexport function* iterateSiblingListBlocks( node, direction = 'forward' ) {\n\tconst isForward = direction == 'forward';\n\tlet previous = null;\n\n\twhile ( isListItemBlock( node ) ) {\n\t\tyield { node, previous };\n\n\t\tprevious = node;\n\t\tnode = isForward ? node.nextSibling : node.previousSibling;\n\t}\n}\n\n/**\n * The iterable protocol over the list elements.\n *\n * @protected\n */\nexport class ListBlocksIterable {\n\t/**\n\t * @param {module:engine/model/element~Element} listHead The head element of a list.\n\t */\n\tconstructor( listHead ) {\n\t\tthis._listHead = listHead;\n\t}\n\n\t/**\n\t * List blocks iterator.\n\t *\n\t * Iterates over all blocks of a list.\n\t *\n\t * @returns {Iterator.<module:list/documentlist/utils/listwalker~ListIteratorValue>}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn iterateSiblingListBlocks( this._listHead, 'forward' );\n\t}\n}\n\n/**\n * Object returned by `iterateSiblingListBlocks()` when traversing a list.\n *\n * @protected\n * @typedef {Object} module:list/documentlist/utils/listwalker~ListIteratorValue\n * @property {module:engine/model/node~Node} node The current list node.\n * @property {module:engine/model/node~Node} previous The previous list node.\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 list/documentlist/utils/model\n */\n\nimport { uid, toArray } from 'ckeditor5/src/utils';\nimport ListWalker, { iterateSiblingListBlocks } from './listwalker';\n\n/**\n * The list item ID generator.\n *\n * @protected\n */\nexport class ListItemUid {\n\t/**\n\t * Returns the next ID.\n\t *\n\t * @protected\n\t * @returns {String}\n\t */\n\t/* istanbul ignore next: static function definition */\n\tstatic next() {\n\t\treturn uid();\n\t}\n}\n\n/**\n * Returns true if the given model node is a list item block.\n *\n * @protected\n * @param {module:engine/model/node~Node} node A model node.\n * @returns {Boolean}\n */\nexport function isListItemBlock( node ) {\n\treturn !!node && node.is( 'element' ) && node.hasAttribute( 'listItemId' );\n}\n\n/**\n * Returns an array with all elements that represents the same list item.\n *\n * It means that values for `listIndent`, and `listItemId` for all items are equal.\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @param {Object} [options]\n * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n * in the result.\n * @return {Array.<module:engine/model/element~Element>}\n */\nexport function getAllListItemBlocks( listItem, options = {} ) {\n\treturn [\n\t\t...getListItemBlocks( listItem, { ...options, direction: 'backward' } ),\n\t\t...getListItemBlocks( listItem, { ...options, direction: 'forward' } )\n\t];\n}\n\n/**\n * Returns an array with elements that represents the same list item in the specified direction.\n *\n * It means that values for `listIndent` and `listItemId` for all items are equal.\n *\n * **Note**: For backward search the provided item is not included, but for forward search it is included in the result.\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @param {Object} [options]\n * @param {'forward'|'backward'} [options.direction='backward'] Walking direction.\n * @param {Boolean} [options.higherIndent=false] Whether blocks with a higher indent level than the start block should be included\n * in the result.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getListItemBlocks( listItem, options = {} ) {\n\tconst isForward = options.direction == 'forward';\n\n\tconst items = Array.from( new ListWalker( listItem, {\n\t\t...options,\n\t\tincludeSelf: isForward,\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} ) );\n\n\treturn isForward ? items : items.reverse();\n}\n\n/**\n * Returns a list items nested inside the given list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getNestedListBlocks( listItem ) {\n\treturn Array.from( new ListWalker( listItem, {\n\t\tdirection: 'forward',\n\t\thigherIndent: true\n\t} ) );\n}\n\n/**\n * Returns array of all blocks/items of the same list as given block (same indent, same type and properties).\n *\n * @protected\n * @param {module:engine/model/element~Element} listItem Starting list item element.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getListItems( listItem ) {\n\tconst backwardBlocks = new ListWalker( listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listType'\n\t} );\n\n\tconst forwardBlocks = new ListWalker( listItem, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listType',\n\t\tincludeSelf: true,\n\t\tdirection: 'forward'\n\t} );\n\n\treturn [\n\t\t...Array.from( backwardBlocks ).reverse(),\n\t\t...forwardBlocks\n\t];\n}\n\n/**\n * Check if the given block is the first in the list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @returns {Boolean}\n */\nexport function isFirstBlockOfListItem( listBlock ) {\n\tconst previousSibling = ListWalker.first( listBlock, {\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} );\n\n\tif ( !previousSibling ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if the given block is the last in the list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @returns {Boolean}\n */\nexport function isLastBlockOfListItem( listBlock ) {\n\tconst nextSibling = ListWalker.first( listBlock, {\n\t\tdirection: 'forward',\n\t\tsameIndent: true,\n\t\tsameAttributes: 'listItemId'\n\t} );\n\n\tif ( !nextSibling ) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Expands the given list of selected blocks to include the leading and tailing blocks of partially selected list items.\n *\n * @protected\n * @param {module:engine/model/element~Element|Array.<module:engine/model/element~Element>} blocks The list of selected blocks.\n * @param {Object} [options]\n * @param {Boolean} [options.withNested=true] Whether should include nested list items.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function expandListBlocksToCompleteItems( blocks, options = {} ) {\n\tblocks = toArray( blocks );\n\n\tconst higherIndent = options.withNested !== false;\n\tconst allBlocks = new Set();\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const itemBlock of getAllListItemBlocks( block, { higherIndent } ) ) {\n\t\t\tallBlocks.add( itemBlock );\n\t\t}\n\t}\n\n\treturn sortBlocks( allBlocks );\n}\n\n/**\n * Expands the given list of selected blocks to include all the items of the lists they're in.\n *\n * @protected\n * @param {module:engine/model/element~Element|Array.<module:engine/model/element~Element>} blocks The list of selected blocks.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function expandListBlocksToCompleteList( blocks ) {\n\tblocks = toArray( blocks );\n\n\tconst allBlocks = new Set();\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const itemBlock of getListItems( block ) ) {\n\t\t\tallBlocks.add( itemBlock );\n\t\t}\n\t}\n\n\treturn sortBlocks( allBlocks );\n}\n\n/**\n * Splits the list item just before the provided list block.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} The array of updated blocks.\n */\nexport function splitListItemBefore( listBlock, writer ) {\n\tconst blocks = getListItemBlocks( listBlock, { direction: 'forward' } );\n\tconst id = ListItemUid.next();\n\n\tfor ( const block of blocks ) {\n\t\twriter.setAttribute( 'listItemId', id, block );\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Merges the list item with the parent list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} listBlock The list block element.\n * @param {module:engine/model/element~Element} parentBlock The list block element to merge with.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} The array of updated blocks.\n */\nexport function mergeListItemBefore( listBlock, parentBlock, writer ) {\n\tconst attributes = {};\n\n\tfor ( const [ key, value ] of parentBlock.getAttributes() ) {\n\t\tif ( key.startsWith( 'list' ) ) {\n\t\t\tattributes[ key ] = value;\n\t\t}\n\t}\n\n\tconst blocks = getListItemBlocks( listBlock, { direction: 'forward' } );\n\n\tfor ( const block of blocks ) {\n\t\twriter.setAttributes( attributes, block );\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Increases indentation of given list blocks.\n *\n * @protected\n * @param {module:engine/model/element~Element|Iterable.<module:engine/model/element~Element>} blocks The block or iterable of blocks.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @param {Object} [options]\n * @param {Boolean} [options.expand=false] Whether should expand the list of blocks to include complete list items.\n * @param {Number} [options.indentBy=1] The number of levels the indentation should change (could be negative).\n */\nexport function indentBlocks( blocks, writer, { expand, indentBy = 1 } = {} ) {\n\tblocks = toArray( blocks );\n\n\t// Expand the selected blocks to contain the whole list items.\n\tconst allBlocks = expand ? expandListBlocksToCompleteItems( blocks ) : blocks;\n\n\tfor ( const block of allBlocks ) {\n\t\tconst blockIndent = block.getAttribute( 'listIndent' ) + indentBy;\n\n\t\tif ( blockIndent < 0 ) {\n\t\t\tremoveListAttributes( block, writer );\n\t\t} else {\n\t\t\twriter.setAttribute( 'listIndent', blockIndent, block );\n\t\t}\n\t}\n\n\treturn allBlocks;\n}\n\n/**\n * Decreases indentation of given list of blocks. If the indentation of some blocks matches the indentation\n * of surrounding blocks, they get merged together.\n *\n * @protected\n * @param {module:engine/model/element~Element|Iterable.<module:engine/model/element~Element>} blocks The block or iterable of blocks.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n */\nexport function outdentBlocksWithMerge( blocks, writer ) {\n\tblocks = toArray( blocks );\n\n\t// Expand the selected blocks to contain the whole list items.\n\tconst allBlocks = expandListBlocksToCompleteItems( blocks );\n\tconst visited = new Set();\n\n\tconst referenceIndent = Math.min( ...allBlocks.map( block => block.getAttribute( 'listIndent' ) ) );\n\tconst parentBlocks = new Map();\n\n\t// Collect parent blocks before the list structure gets altered.\n\tfor ( const block of allBlocks ) {\n\t\tparentBlocks.set( block, ListWalker.first( block, { lowerIndent: true } ) );\n\t}\n\n\tfor ( const block of allBlocks ) {\n\t\tif ( visited.has( block ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvisited.add( block );\n\n\t\tconst blockIndent = block.getAttribute( 'listIndent' ) - 1;\n\n\t\tif ( blockIndent < 0 ) {\n\t\t\tremoveListAttributes( block, writer );\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Merge with parent list item while outdenting and indent matches reference indent.\n\t\tif ( block.getAttribute( 'listIndent' ) == referenceIndent ) {\n\t\t\tconst mergedBlocks = mergeListItemIfNotLast( block, parentBlocks.get( block ), writer );\n\n\t\t\t// All list item blocks are updated while merging so add those to visited set.\n\t\t\tfor ( const mergedBlock of mergedBlocks ) {\n\t\t\t\tvisited.add( mergedBlock );\n\t\t\t}\n\n\t\t\t// The indent level was updated while merging so continue to next block.\n\t\t\tif ( mergedBlocks.length ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\twriter.setAttribute( 'listIndent', blockIndent, block );\n\t}\n\n\treturn sortBlocks( visited );\n}\n\n/**\n * Removes all list attributes from the given blocks.\n *\n * @protected\n * @param {module:engine/model/element~Element|Iterable.<module:engine/model/element~Element>} blocks The block or iterable of blocks.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} Array of altered blocks.\n */\nexport function removeListAttributes( blocks, writer ) {\n\tblocks = toArray( blocks );\n\n\tfor ( const block of blocks ) {\n\t\tfor ( const attributeKey of block.getAttributeKeys() ) {\n\t\t\tif ( attributeKey.startsWith( 'list' ) ) {\n\t\t\t\twriter.removeAttribute( attributeKey, block );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn blocks;\n}\n\n/**\n * Checks whether the given blocks are related to a single list item.\n *\n * @protected\n * @param {Array.<module:engine/model/element~Element>} blocks The list block elements.\n * @returns {Boolean}\n */\nexport function isSingleListItem( blocks ) {\n\tif ( !blocks.length ) {\n\t\treturn false;\n\t}\n\n\tconst firstItemId = blocks[ 0 ].getAttribute( 'listItemId' );\n\n\tif ( !firstItemId ) {\n\t\treturn false;\n\t}\n\n\treturn !blocks.some( item => item.getAttribute( 'listItemId' ) != firstItemId );\n}\n\n/**\n * Modifies the indents of list blocks following the given list block so the indentation is valid after\n * the given block is no longer a list item.\n *\n * @protected\n * @param {module:engine/model/element~Element} lastBlock The last list block that has become a non-list element.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Array.<module:engine/model/element~Element>} Array of altered blocks.\n */\nexport function outdentFollowingItems( lastBlock, writer ) {\n\tconst changedBlocks = [];\n\n\t// Start from the model item that is just after the last turned-off item.\n\tlet currentIndent = Number.POSITIVE_INFINITY;\n\n\t// Correct indent of all items after the last turned off item.\n\t// Rules that should be followed:\n\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t// will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t// should not end up as a child of any of list items that they were not children of before.\n\t// 3. All other items should have their indent changed relatively to it's parent.\n\t//\n\t// For example:\n\t// 1 * --------\n\t// 2 * --------\n\t// 3 * --------\t\t\t<-- this is turned off.\n\t// 4 * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t// 5 * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t// 6 * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t// 7 * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t// 8 * --------\t\t\t\t<-- this has to become indent = 0.\n\t// 9 * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t// 10 * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t// 11 * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t// 13 * --------\n\t// 14 * --------\n\t//\n\t// After turning off 3 the list becomes:\n\t//\n\t// 1 * --------\n\t// 2 * --------\n\t//\n\t// 3 --------\n\t//\n\t// 4 * --------\n\t// 5 * --------\n\t// 6 * --------\n\t// 7 * --------\n\t// 8 * --------\n\t// 9 * --------\n\t// 10 * --------\n\t// 11 * --------\n\t// 12 * --------\n\t// 13 * --------\n\t// 14 * --------\n\t//\n\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t// less conversion (faster).\n\tfor ( const { node } of iterateSiblingListBlocks( lastBlock.nextSibling, 'forward' ) ) {\n\t\t// Check each next list item, as long as its indent is higher than 0.\n\t\tconst indent = node.getAttribute( 'listIndent' );\n\n\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\tif ( indent == 0 ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// We check if that's item indent is lower than current relative indent.\n\t\tif ( indent < currentIndent ) {\n\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\tcurrentIndent = indent;\n\t\t}\n\n\t\t// Fix indent relatively to current relative indent.\n\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\tconst newIndent = indent - currentIndent;\n\n\t\twriter.setAttribute( 'listIndent', newIndent, node );\n\t\tchangedBlocks.push( node );\n\t}\n\n\treturn changedBlocks;\n}\n\n/**\n * Returns the array of given blocks sorted by model indexes (document order).\n *\n * @protected\n * @param {Iterable.<module:engine/model/element~Element>} blocks The array of blocks.\n * @returns {Array.<module:engine/model/element~Element>} The sorted array of blocks.\n */\nexport function sortBlocks( blocks ) {\n\treturn Array.from( blocks )\n\t\t.filter( block => block.root.rootName !== '$graveyard' )\n\t\t.sort( ( a, b ) => a.index - b.index );\n}\n\n/**\n * Returns a selected block object. If a selected object is inline or when there is no selected\n * object, `null` is returned.\n *\n * @protected\n * @param {module:engine/model/model~Model} model The instance of editor model.\n * @returns {module:engine/model/element~Element|null} Selected block object or `null`.\n */\nexport function getSelectedBlockObject( model ) {\n\tconst selectedElement = model.document.selection.getSelectedElement();\n\n\tif ( !selectedElement ) {\n\t\treturn null;\n\t}\n\n\tif ( model.schema.isObject( selectedElement ) && model.schema.isBlock( selectedElement ) ) {\n\t\treturn selectedElement;\n\t}\n\n\treturn null;\n}\n\n// Merges a given block to the given parent block if parent is a list item and there is no more blocks in the same item.\nfunction mergeListItemIfNotLast( block, parentBlock, writer ) {\n\tconst parentItemBlocks = getListItemBlocks( parentBlock, { direction: 'forward' } );\n\n\t// Merge with parent only if outdented item wasn't the last one in its parent.\n\t// Merge:\n\t// * a\t\t\t->\t\t* a\n\t// * [b]\t\t->\t\t b\n\t// c\t\t\t->\t\t c\n\t// Don't merge:\n\t// * a\t\t\t->\t\t* a\n\t// * [b]\t\t-> \t\t* b\n\t// * c\t\t\t->\t\t* c\n\tif ( parentItemBlocks.pop().index > block.index ) {\n\t\treturn mergeListItemBefore( block, parentBlock, writer );\n\t}\n\n\treturn [];\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 list/documentlist/utils/postfixers\n */\n\nimport { iterateSiblingListBlocks } from './listwalker';\nimport { getListItemBlocks, isListItemBlock, ListItemUid } from './model';\n\n/**\n * Based on the provided positions looks for the list head and stores it in the provided map.\n *\n * @protected\n * @param {module:engine/model/position~Position} position The search starting position.\n * @param {Map.<module:engine/model/element~Element,module:engine/model/element~Element>} itemToListHead The map from list item element\n * to the list head element.\n */\nexport function findAndAddListHeadToMap( position, itemToListHead ) {\n\tconst previousNode = position.nodeBefore;\n\n\tif ( !isListItemBlock( previousNode ) ) {\n\t\tconst item = position.nodeAfter;\n\n\t\tif ( isListItemBlock( item ) ) {\n\t\t\titemToListHead.set( item, item );\n\t\t}\n\t} else {\n\t\tlet listHead = previousNode;\n\n\t\tfor ( { node: listHead } of iterateSiblingListBlocks( listHead, 'backward' ) ) {\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\titemToListHead.set( previousNode, listHead );\n\t}\n}\n\n/**\n * Scans the list starting from the given list head element and fixes items' indentation.\n *\n * @protected\n * @param {Iterable.<module:list/documentlist/utils/listwalker~ListIteratorValue>} listNodes The iterable of list nodes.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Boolean} Whether the model was modified.\n */\nexport function fixListIndents( listNodes, writer ) {\n\tlet maxIndent = 0; // Guards local sublist max indents that need fixing.\n\tlet prevIndent = -1; // Previous item indent.\n\tlet fixBy = null;\n\tlet applied = false;\n\n\tfor ( const { node } of listNodes ) {\n\t\tconst itemIndent = node.getAttribute( 'listIndent' );\n\n\t\tif ( itemIndent > maxIndent ) {\n\t\t\tlet newIndent;\n\n\t\t\tif ( fixBy === null ) {\n\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\tnewIndent = maxIndent;\n\t\t\t} else {\n\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t}\n\n\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t}\n\n\t\t\tif ( newIndent > prevIndent + 1 ) {\n\t\t\t\tnewIndent = prevIndent + 1;\n\t\t\t}\n\n\t\t\twriter.setAttribute( 'listIndent', newIndent, node );\n\n\t\t\tapplied = true;\n\t\t\tprevIndent = newIndent;\n\t\t} else {\n\t\t\tfixBy = null;\n\t\t\tmaxIndent = itemIndent + 1;\n\t\t\tprevIndent = itemIndent;\n\t\t}\n\t}\n\n\treturn applied;\n}\n\n/**\n * Scans the list starting from the given list head element and fixes items' types.\n *\n * @protected\n * @param {Iterable.<module:list/documentlist/utils/listwalker~ListIteratorValue>} listNodes The iterable of list nodes.\n * @param {Set.<String>} seenIds The set of already known IDs.\n * @param {module:engine/model/writer~Writer} writer The model writer.\n * @returns {Boolean} Whether the model was modified.\n */\nexport function fixListItemIds( listNodes, seenIds, writer ) {\n\tconst visited = new Set();\n\tlet applied = false;\n\n\tfor ( const { node } of listNodes ) {\n\t\tif ( visited.has( node ) ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet listType = node.getAttribute( 'listType' );\n\t\tlet listItemId = node.getAttribute( 'listItemId' );\n\n\t\t// Use a new ID if this one was spot earlier (even in other list).\n\t\tif ( seenIds.has( listItemId ) ) {\n\t\t\tlistItemId = ListItemUid.next();\n\t\t}\n\n\t\tseenIds.add( listItemId );\n\n\t\tfor ( const block of getListItemBlocks( node, { direction: 'forward' } ) ) {\n\t\t\tvisited.add( block );\n\n\t\t\t// Use a new ID if a block of a bigger list item has different type.\n\t\t\tif ( block.getAttribute( 'listType' ) != listType ) {\n\t\t\t\tlistItemId = ListItemUid.next();\n\t\t\t\tlistType = block.getAttribute( 'listType' );\n\t\t\t}\n\n\t\t\tif ( block.getAttribute( 'listItemId' ) != listItemId ) {\n\t\t\t\twriter.setAttribute( 'listItemId', listItemId, block );\n\n\t\t\t\tapplied = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn applied;\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 list/documentlist/utils/view\n */\n\n/**\n * Checks if view element is a list type (ul or ol).\n *\n * @protected\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isListView( viewElement ) {\n\treturn viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );\n}\n\n/**\n * Checks if view element is a list item (li).\n *\n * @protected\n * @param {module:engine/view/element~Element} viewElement\n * @returns {Boolean}\n */\nexport function isListItemView( viewElement ) {\n\treturn viewElement.is( 'element', 'li' );\n}\n\n/**\n * Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n *\n * Also, fixes non HTML compliant lists indents:\n *\n * \t\tbefore: fixed list:\n * \t\tOL OL\n * \t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n * \t\t |-> OL |-> OL\n * \t\t |-> OL |\n * \t\t | |-> OL |\n * \t\t | |-> OL |\n * \t\t | |-> LI (parent LIs: 1) |-> LI (indent: 1)\n * \t\t |-> LI (parent LIs: 1) |-> LI (indent: 1)\n *\n * \t\tbefore: fixed list:\n * \t\tOL OL\n * \t\t|-> OL |\n * \t\t |-> OL |\n * \t\t |-> OL |\n * \t\t |-> LI (parent LIs: 0) |-> LI (indent: 0)\n *\n * \t\tbefore: fixed list:\n * \t\tOL OL\n * \t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n * \t\t|-> OL |-> OL\n * \t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n *\n * @protected\n * @param {module:engine/view/element~Element} listItem\n * @returns {Number}\n */\nexport function getIndent( listItem ) {\n\tlet indent = 0;\n\tlet parent = listItem.parent;\n\n\twhile ( parent ) {\n\t\t// Each LI in the tree will result in an increased indent for HTML compliant lists.\n\t\tif ( isListItemView( parent ) ) {\n\t\t\tindent++;\n\t\t} else {\n\t\t\t// If however the list is nested in other list we should check previous sibling of any of the list elements...\n\t\t\tconst previousSibling = parent.previousSibling;\n\n\t\t\t// ...because the we might need increase its indent:\n\t\t\t//\t\tbefore: fixed list:\n\t\t\t//\t\tOL OL\n\t\t\t//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n\t\t\t//\t\t|-> OL |-> OL\n\t\t\t//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n\t\t\tif ( previousSibling && isListItemView( previousSibling ) ) {\n\t\t\t\tindent++;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn indent;\n}\n\n/**\n * Creates a list attribute element (ol or ul).\n *\n * @protected\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The downcast writer.\n * @param {Number} indent The list item indent.\n * @param {'bulleted'|'numbered'} type The list type.\n * @returns {module:engine/view/attributeelement~AttributeElement}\n */\nexport function createListElement( writer, indent, type, id = getViewElementIdForListType( type, indent ) ) {\n\t// Negative priorities so that restricted editing attribute won't wrap lists.\n\treturn writer.createAttributeElement( getViewElementNameForListType( type ), null, {\n\t\tpriority: 2 * indent / 100 - 100,\n\t\tid\n\t} );\n}\n\n/**\n * Creates a list item attribute element (li).\n *\n * @protected\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The downcast writer.\n * @param {Number} indent The list item indent.\n * @param {String} id The list item ID.\n * @returns {module:engine/view/attributeelement~AttributeElement}\n */\nexport function createListItemElement( writer, indent, id ) {\n\t// Negative priorities so that restricted editing attribute won't wrap list items.\n\treturn writer.createAttributeElement( 'li', null, {\n\t\tpriority: ( 2 * indent + 1 ) / 100 - 100,\n\t\tid\n\t} );\n}\n\n/**\n * Returns a view element name for the given list type.\n *\n * @protected\n * @param {'bulleted'|'numbered'} type The list type.\n * @returns {String}\n */\nexport function getViewElementNameForListType( type ) {\n\treturn type == 'numbered' ? 'ol' : 'ul';\n}\n\n/**\n * Returns a view element ID for the given list type and indent.\n *\n * @protected\n * @param {'bulleted'|'numbered'} type The list type.\n * @param {Number} indent The list indent level.\n * @returns {String}\n */\nexport function getViewElementIdForListType( type, indent ) {\n\treturn `list-${ type }-${ indent }`;\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 list/documentlistproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport DocumentListPropertiesEditing from './documentlistproperties/documentlistpropertiesediting';\nimport ListPropertiesUI from './listproperties/listpropertiesui';\n\n/**\n * The document list properties feature.\n *\n * This is a \"glue\" plugin that loads the\n * {@link module:list/documentlistproperties/documentlistpropertiesediting~DocumentListPropertiesEditing document list properties\n * editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ DocumentListPropertiesEditing, ListPropertiesUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentListProperties';\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 list/documentlistproperties/converters\n */\n\n/**\n * Returns a converter that consumes the `style`, `reversed`, and `start` attributes.\n * In `style`, it searches for the `list-style-type` definition.\n * If not found, the `\"default\"` value will be used.\n *\n * @protected\n * @param {module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy} strategy\n * @returns {Function}\n */\nexport function listPropertiesUpcastConverter( strategy ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst { writer, schema, consumable } = conversionApi;\n\n\t\t// If there is no view consumable to consume, set the default attribute value to be able to reconvert nested lists on parent change.\n\t\t// So abort converting if attribute was directly consumed.\n\t\tif ( consumable.test( data.viewItem, strategy.viewConsumables ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !data.modelRange ) {\n\t\t\tObject.assign( data, conversionApi.convertChildren( data.viewItem, data.modelCursor ) );\n\t\t}\n\n\t\tlet applied = false;\n\n\t\tfor ( const item of data.modelRange.getItems( { shallow: true } ) ) {\n\t\t\tif ( !schema.checkAttribute( item, strategy.attributeName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ( !strategy.appliesToListItem( item ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Set list attributes only on same level items, those nested deeper are already handled by the recursive conversion.\n\t\t\tif ( item.hasAttribute( strategy.attributeName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\twriter.setAttribute( strategy.attributeName, strategy.getAttributeOnUpcast( data.viewItem ), item );\n\t\t\tapplied = true;\n\t\t}\n\n\t\tif ( applied ) {\n\t\t\tconsumable.consume( data.viewItem, strategy.viewConsumables );\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 list/documentlistproperties/documentlistpropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\n\nimport DocumentListEditing from '../documentlist/documentlistediting';\nimport DocumentListStartCommand from './documentliststartcommand';\nimport DocumentListStyleCommand from './documentliststylecommand';\nimport DocumentListReversedCommand from './documentlistreversedcommand';\nimport { listPropertiesUpcastConverter } from './converters';\nimport {\n\tgetAllSupportedStyleTypes,\n\tgetListTypeFromListStyleType,\n\tgetListStyleTypeFromTypeAttribute,\n\tgetTypeAttributeFromListStyleType\n} from './utils/style';\n\nconst DEFAULT_LIST_TYPE = 'default';\n\n/**\n * The document list properties engine feature.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listproperties~ListPropertiesConfig}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DocumentListPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ DocumentListEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DocumentListPropertiesEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list', {\n\t\t\tproperties: {\n\t\t\t\tstyles: true,\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t}\n\t\t} );\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 documentListEditing = editor.plugins.get( DocumentListEditing );\n\n\t\tconst enabledProperties = editor.config.get( 'list.properties' );\n\t\tconst strategies = createAttributeStrategies( enabledProperties );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tstrategy.addCommand( editor );\n\n\t\t\tmodel.schema.extend( '$container', { allowAttributes: strategy.attributeName } );\n\t\t\tmodel.schema.extend( '$block', { allowAttributes: strategy.attributeName } );\n\t\t\tmodel.schema.extend( '$blockObject', { allowAttributes: strategy.attributeName } );\n\n\t\t\t// Register downcast strategy.\n\t\t\tdocumentListEditing.registerDowncastStrategy( {\n\t\t\t\tscope: 'list',\n\t\t\t\tattributeName: strategy.attributeName,\n\n\t\t\t\tsetAttributeOnDowncast( writer, attributeValue, viewElement ) {\n\t\t\t\t\tstrategy.setAttributeOnDowncast( writer, attributeValue, viewElement );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Set up conversion.\n\t\teditor.conversion.for( 'upcast' ).add( dispatcher => {\n\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\tdispatcher.on( 'element:ol', listPropertiesUpcastConverter( strategy ) );\n\t\t\t\tdispatcher.on( 'element:ul', listPropertiesUpcastConverter( strategy ) );\n\t\t\t}\n\t\t} );\n\n\t\t// Verify if the list view element (ul or ol) requires refreshing.\n\t\tdocumentListEditing.on( 'checkAttributes:list', ( evt, { viewElement, modelAttributes } ) => {\n\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\tif ( strategy.getAttributeOnUpcast( viewElement ) != modelAttributes[ strategy.attributeName ] ) {\n\t\t\t\t\tevt.return = true;\n\t\t\t\t\tevt.stop();\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Reset list properties after indenting list items.\n\t\tthis.listenTo( editor.commands.get( 'indentList' ), 'afterExecute', ( evt, changedBlocks ) => {\n\t\t\tmodel.change( writer => {\n\t\t\t\tfor ( const node of changedBlocks ) {\n\t\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\t\tif ( strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\t\t// Just reset the attribute.\n\t\t\t\t\t\t\t// If there is a previous indented list that this node should be merged into,\n\t\t\t\t\t\t\t// the postfixer will unify all the attributes of both sub-lists.\n\t\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, strategy.defaultValue, node );\n\t\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\t\t// Add or remove list properties attributes depending on the list type.\n\t\tdocumentListEditing.on( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tfor ( const { node } of listNodes ) {\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\t// Check if attribute is valid.\n\t\t\t\t\tif ( strategy.hasValidAttribute( node ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Add missing default property attributes...\n\t\t\t\t\tif ( strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, strategy.defaultValue, node );\n\t\t\t\t\t}\n\t\t\t\t\t// ...or remove invalid property attributes.\n\t\t\t\t\telse {\n\t\t\t\t\t\twriter.removeAttribute( strategy.attributeName, node );\n\t\t\t\t\t}\n\n\t\t\t\t\tevt.return = true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\t// Make sure that all items in a single list (items at the same level & listType) have the same properties.\n\t\tdocumentListEditing.on( 'postFixer', ( evt, { listNodes, writer } ) => {\n\t\t\tconst previousNodesByIndent = []; // Last seen nodes of lower indented lists.\n\n\t\t\tfor ( const { node, previous } of listNodes ) {\n\t\t\t\t// For the first list block there is nothing to compare with.\n\t\t\t\tif ( !previous ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst nodeIndent = node.getAttribute( 'listIndent' );\n\t\t\t\tconst previousNodeIndent = previous.getAttribute( 'listIndent' );\n\n\t\t\t\tlet previousNodeInList = null; // It's like `previous` but has the same indent as current node.\n\n\t\t\t\t// Let's find previous node for the same indent.\n\t\t\t\t// We're going to need that when we get back to previous indent.\n\t\t\t\tif ( nodeIndent > previousNodeIndent ) {\n\t\t\t\t\tpreviousNodesByIndent[ previousNodeIndent ] = previous;\n\t\t\t\t}\n\t\t\t\t// Restore the one for given indent.\n\t\t\t\telse if ( nodeIndent < previousNodeIndent ) {\n\t\t\t\t\tpreviousNodeInList = previousNodesByIndent[ nodeIndent ];\n\t\t\t\t\tpreviousNodesByIndent.length = nodeIndent;\n\t\t\t\t}\n\t\t\t\t// Same indent.\n\t\t\t\telse {\n\t\t\t\t\tpreviousNodeInList = previous;\n\t\t\t\t}\n\n\t\t\t\t// This is a first item of a nested list.\n\t\t\t\tif ( !previousNodeInList ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// This is a first block of a list of a different type.\n\t\t\t\tif ( previousNodeInList.getAttribute( 'listType' ) != node.getAttribute( 'listType' ) ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Copy properties from the previous one.\n\t\t\t\tfor ( const strategy of strategies ) {\n\t\t\t\t\tconst { attributeName } = strategy;\n\n\t\t\t\t\tif ( !strategy.appliesToListItem( node ) ) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst value = previousNodeInList.getAttribute( attributeName );\n\n\t\t\t\t\tif ( node.getAttribute( attributeName ) != value ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, value, node );\n\t\t\t\t\t\tevt.return = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n}\n\n/**\n * Strategy for dealing with `listItem` attributes supported by this plugin.\n *\n * @typedef {Object} module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy\n * @protected\n * @property {String} attributeName The model attribute name.\n * @property {*} defaultValue The model attribute default value.\n * @property {Object} viewConsumables The view consumable as expected by\n * {@link module:engine/conversion/viewconsumable~ViewConsumable#consume `ViewConsumable`}.\n * @property {Function} addCommand Registers an editor command.\n * @property {Function} appliesToListItem Verifies whether the strategy is applicable for the specified model element.\n * @property {Function} hasValidAttribute Verifies whether the model attribute value is valid.\n * @property {Function} setAttributeOnDowncast Sets the property on the view element.\n * @property {Function} getAttributeOnUpcast Retrieves the property value from the view element.\n */\n\n// Creates an array of strategies for dealing with enabled listItem attributes.\n//\n// @param {Object} enabledProperties\n// @param {Boolean|Object} enabledProperties.styles\n// @param {Boolean} [enabledProperties.styles.useAttribute]\n// @param {Boolean} enabledProperties.reversed\n// @param {Boolean} enabledProperties.startIndex\n// @returns {Array.<module:list/documentlistproperties/documentlistpropertiesediting~AttributeStrategy>}\nfunction createAttributeStrategies( enabledProperties ) {\n\tconst strategies = [];\n\n\tif ( enabledProperties.styles ) {\n\t\tconst useAttribute = typeof enabledProperties.styles == 'object' && enabledProperties.styles.useAttribute;\n\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStyle',\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\t\t\tviewConsumables: { styles: 'list-style-type' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\tlet supportedTypes = getAllSupportedStyleTypes();\n\n\t\t\t\tif ( useAttribute ) {\n\t\t\t\t\tsupportedTypes = supportedTypes.filter( styleType => !!getTypeAttributeFromListStyleType( styleType ) );\n\t\t\t\t}\n\n\t\t\t\teditor.commands.add( 'listStyle', new DocumentListStyleCommand( editor, DEFAULT_LIST_TYPE, supportedTypes ) );\n\t\t\t},\n\n\t\t\tappliesToListItem() {\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\tif ( !item.hasAttribute( 'listStyle' ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst value = item.getAttribute( 'listStyle' );\n\n\t\t\t\tif ( value == DEFAULT_LIST_TYPE ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\treturn getListTypeFromListStyleType( value ) == item.getAttribute( 'listType' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStyle, element ) {\n\t\t\t\tif ( listStyle && listStyle !== DEFAULT_LIST_TYPE ) {\n\t\t\t\t\tif ( useAttribute ) {\n\t\t\t\t\t\tconst value = getTypeAttributeFromListStyleType( listStyle );\n\n\t\t\t\t\t\tif ( value ) {\n\t\t\t\t\t\t\twriter.setAttribute( 'type', value, element );\n\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.setStyle( 'list-style-type', listStyle, element );\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\twriter.removeStyle( 'list-style-type', element );\n\t\t\t\twriter.removeAttribute( 'type', element );\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\tconst style = listParent.getStyle( 'list-style-type' );\n\n\t\t\t\tif ( style ) {\n\t\t\t\t\treturn style;\n\t\t\t\t}\n\n\t\t\t\tconst attribute = listParent.getAttribute( 'type' );\n\n\t\t\t\tif ( attribute ) {\n\t\t\t\t\treturn getListStyleTypeFromTypeAttribute( attribute );\n\t\t\t\t}\n\n\t\t\t\treturn DEFAULT_LIST_TYPE;\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listReversed',\n\t\t\tdefaultValue: false,\n\t\t\tviewConsumables: { attributes: 'reversed' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listReversed', new DocumentListReversedCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\treturn this.appliesToListItem( item ) == item.hasAttribute( 'listReversed' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listReversed, element ) {\n\t\t\t\tif ( listReversed ) {\n\t\t\t\t\twriter.setAttribute( 'reversed', 'reversed', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'reversed', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.hasAttribute( 'reversed' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStart',\n\t\t\tdefaultValue: 1,\n\t\t\tviewConsumables: { attributes: 'start' },\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStart', new DocumentListStartCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\thasValidAttribute( item ) {\n\t\t\t\treturn this.appliesToListItem( item ) == item.hasAttribute( 'listStart' );\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStart, element ) {\n\t\t\t\tif ( listStart && listStart > 1 ) {\n\t\t\t\t\twriter.setAttribute( 'start', listStart, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'start', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getAttribute( 'start' ) || 1;\n\t\t\t}\n\t\t} );\n\t}\n\n\treturn strategies;\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 list/documentlistproperties/documentlistreversedcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../documentlist/utils/model';\n\n/**\n * The list reversed command. It changes the `listReversed` attribute of the selected list items,\n * letting the user to choose the order of an ordered list.\n * It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListReversedCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.reversed=false] Whether the list should be reversed.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listReversed', !!options.reversed, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tif ( isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn block.getAttribute( 'listReversed' );\n\t\t}\n\n\t\treturn null;\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 list/documentlistproperties/documentliststartcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../documentlist/utils/model';\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items,\n * letting the user to choose the starting point of an ordered list.\n * It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListStartCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options]\n\t * @param {Number} [options.startIndex=1] The list start index.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listStart', options.startIndex || 1, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Number|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tconst block = first( document.selection.getSelectedBlocks() );\n\n\t\tif ( block && isListItemBlock( block ) && block.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn block.getAttribute( 'listStart' );\n\t\t}\n\n\t\treturn null;\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 list/documentlistproperties/documentliststylecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\nimport {\n\texpandListBlocksToCompleteList,\n\tisListItemBlock\n} from '../documentlist/utils/model';\nimport { getListTypeFromListStyleType } from './utils/style';\n\n/**\n * The list style command. It changes `listStyle` attribute of the selected list items,\n * letting the user choose styles for the list item markers.\n * It is used by the {@link module:list/documentlistproperties~DocumentListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class DocumentListStyleCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {String} defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t * @param {Array.<String>} [supportedTypes] The list of supported style types by this command.\n\t */\n\tconstructor( editor, defaultType, supportedTypes ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The default type of the list style.\n\t\t *\n\t\t * @protected\n\t\t * @member {String}\n\t\t */\n\t\tthis._defaultType = defaultType;\n\n\t\t/**\n\t\t * The list of supported style types by this command.\n\t\t *\n\t\t * @private\n\t\t * @member {Array.<String>|undefined}\n\t\t */\n\t\tthis._supportedTypes = supportedTypes;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\n\t\tmodel.change( writer => {\n\t\t\tthis._tryToConvertItemsToList( options );\n\n\t\t\tlet blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t\t.filter( block => block.hasAttribute( 'listType' ) );\n\n\t\t\tif ( !blocks.length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tblocks = expandListBlocksToCompleteList( blocks );\n\n\t\t\tfor ( const block of blocks ) {\n\t\t\t\twriter.setAttribute( 'listStyle', options.type || this._defaultType, block );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks if the given style type is supported by this plugin.\n\t *\n\t * @param {String} value\n\t * @returns {Boolean}\n\t */\n\tisStyleTypeSupported( value ) {\n\t\tif ( !this._supportedTypes ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn this._supportedTypes.includes( value );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {String|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\tif ( isListItemBlock( listItem ) ) {\n\t\t\treturn listItem.getAttribute( 'listStyle' );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst editor = this.editor;\n\n\t\tconst numberedList = editor.commands.get( 'numberedList' );\n\t\tconst bulletedList = editor.commands.get( 'bulletedList' );\n\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\n\t/**\n\t * Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t *\n\t * @private\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style. If `null` is specified, the function does nothing.\n\t*/\n\t_tryToConvertItemsToList( options ) {\n\t\tif ( !options.type ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listType = getListTypeFromListStyleType( options.type );\n\n\t\tif ( !listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst commandName = listType + 'List';\n\t\tconst command = editor.commands.get( commandName );\n\n\t\tif ( !command.value ) {\n\t\t\teditor.execute( commandName );\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 list/documentlistproperties/utils/style\n*/\n\nconst LIST_STYLE_TO_LIST_TYPE = {};\nconst LIST_STYLE_TO_TYPE_ATTRIBUTE = {};\nconst TYPE_ATTRIBUTE_TO_LIST_STYLE = {};\n\nconst LIST_STYLE_TYPES = [\n\t{ listStyle: 'disc', typeAttribute: 'disc', listType: 'bulleted' },\n\t{ listStyle: 'circle', typeAttribute: 'circle', listType: 'bulleted' },\n\t{ listStyle: 'square', typeAttribute: 'square', listType: 'bulleted' },\n\t{ listStyle: 'decimal', typeAttribute: '1', listType: 'numbered' },\n\t{ listStyle: 'decimal-leading-zero', typeAttribute: null, listType: 'numbered' },\n\t{ listStyle: 'lower-roman', typeAttribute: 'i', listType: 'numbered' },\n\t{ listStyle: 'upper-roman', typeAttribute: 'I', listType: 'numbered' },\n\t{ listStyle: 'lower-alpha', typeAttribute: 'a', listType: 'numbered' },\n\t{ listStyle: 'upper-alpha', typeAttribute: 'A', listType: 'numbered' },\n\t{ listStyle: 'lower-latin', typeAttribute: 'a', listType: 'numbered' },\n\t{ listStyle: 'upper-latin', typeAttribute: 'A', listType: 'numbered' }\n];\n\nfor ( const { listStyle, typeAttribute, listType } of LIST_STYLE_TYPES ) {\n\tLIST_STYLE_TO_LIST_TYPE[ listStyle ] = listType;\n\tLIST_STYLE_TO_TYPE_ATTRIBUTE[ listStyle ] = typeAttribute;\n\n\tif ( typeAttribute ) {\n\t\tTYPE_ATTRIBUTE_TO_LIST_STYLE[ typeAttribute ] = listStyle;\n\t}\n}\n\n/**\n * Gets all the style types supported by given list type.\n *\n * @returns {Array.<String>}\n */\nexport function getAllSupportedStyleTypes() {\n\treturn LIST_STYLE_TYPES.map( x => x.listStyle );\n}\n\n/**\n* Checks whether the given list-style-type is supported by numbered or bulleted list.\n*\n* @param {String} listStyleType\n* @returns {'bulleted'|'numbered'|null}\n*/\nexport function getListTypeFromListStyleType( listStyleType ) {\n\treturn LIST_STYLE_TO_LIST_TYPE[ listStyleType ] || null;\n}\n\n/**\n * Converts `type` attribute of `<ul>` or `<ol>` elements to `list-style-type` equivalent.\n *\n * @param {String} value\n * @returns {String|null}\n */\nexport function getListStyleTypeFromTypeAttribute( value ) {\n\treturn TYPE_ATTRIBUTE_TO_LIST_STYLE[ value ] || null;\n}\n\n/**\n * Converts `list-style-type` style to `type` attribute of `<ul>` or `<ol>` elements.\n *\n * @param {String} value\n * @returns {String|null}\n */\nexport function getTypeAttributeFromListStyleType( value ) {\n\treturn LIST_STYLE_TO_TYPE_ATTRIBUTE[ value ] || null;\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 list/list\n */\n\nimport ListEditing from './list/listediting';\nimport ListUI from './list/listui';\n\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/list/listediting~ListEditing list editing feature}\n * and {@link module:list/list/listui~ListUI list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class List extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing, ListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'List';\n\t}\n}\n\n/**\n * The configuration of the {@link module:list/list~List list} feature\n * and the {@link module:list/documentlist~DocumentList document list} feature.\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tlist: ... // The list feature configuration.\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 ListConfig\n */\n\n/**\n * The configuration of the {@link module:list/list~List} feature and the {@link module:list/documentlist~DocumentList} feature.\n *\n * Read more in {@link module:list/list~ListConfig}.\n *\n * @member {module:module:list/list~ListConfig} module:core/editor/editorconfig~EditorConfig#list\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 list/list/converters\n */\n\nimport { TreeWalker } from 'ckeditor5/src/engine';\n\nimport {\n\tgenerateLiInUl,\n\tinjectViewList,\n\tmergeViewLists,\n\tgetSiblingListItem,\n\tpositionAfterUiElements\n} from './utils';\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It creates a `<ul><li></li><ul>` (or `<ol>`) view structure out of a `listItem` model element, inserts it at the correct\n * position, and merges the list with surrounding lists (if available).\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewInsertion( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconsumable.consume( data.item, 'insert' );\n\t\tconsumable.consume( data.item, 'attribute:listType' );\n\t\tconsumable.consume( data.item, 'attribute:listIndent' );\n\n\t\tconst modelItem = data.item;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for the `listItem` model element removal.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewRemove( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\t\tconst viewStart = viewPosition.getLastMatchingPosition( value => !value.item.is( 'element', 'li' ) );\n\t\tconst viewItem = viewStart.nodeAfter;\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item - the one to remove.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Remove the list with the item to remove.\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tconst removed = viewWriter.remove( removeRange );\n\n\t\t// 3. Merge the whole created by breaking and removing the list.\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 4. Bring back nested list that was in the removed <li>.\n\t\tconst modelItem = conversionApi.mapper.toModelElement( viewItem );\n\n\t\thoistNestedLists( modelItem.getAttribute( 'listIndent' ) + 1, data.position, removeRange.start, viewItem, conversionApi, model );\n\n\t\t// 5. Unbind removed view item and all children.\n\t\tfor ( const child of viewWriter.createRangeIn( removed ).getItems() ) {\n\t\t\tconversionApi.mapper.unbindViewElement( child );\n\t\t}\n\n\t\tevt.stop();\n\t};\n}\n\n/**\n * A model-to-view converter for the `type` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes from `<ul>` to `<ol>` (or vice versa). This is accomplished\n * by breaking view elements and changing their name. The next {@link module:list/list/converters~modelViewMergeAfterChangeType}\n * converter will attempt to merge split nodes.\n *\n * Splitting this conversion into 2 steps makes it possible to add an additional conversion in the middle.\n * Check {@link module:list/todolist/todolistconverters~modelViewChangeType} to see an example of it.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewChangeType( evt, data, conversionApi ) {\n\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\treturn;\n\t}\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\tconst viewWriter = conversionApi.writer;\n\n\t// Break the container after and before the list item.\n\t// This will create a view list with one view list item -- the one that changed type.\n\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t// Change name of the view list that holds the changed view item.\n\t// We cannot just change name property, because that would not render properly.\n\tconst viewList = viewItem.parent;\n\tconst listName = data.attributeNewValue == 'numbered' ? 'ol' : 'ul';\n\n\tviewWriter.rename( listName, viewList );\n}\n\n/**\n * A model-to-view converter that attempts to merge nodes split by {@link module:list/list/converters~modelViewChangeType}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewMergeAfterChangeType( evt, data, conversionApi ) {\n\tconversionApi.consumable.consume( data.item, evt.name );\n\n\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\tconst viewList = viewItem.parent;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Merge the changed view list with other lists, if possible.\n\tmergeViewLists( viewWriter, viewList, viewList.nextSibling );\n\tmergeViewLists( viewWriter, viewList.previousSibling, viewList );\n}\n\n/**\n * A model-to-view converter for the `listIndent` attribute change on the `listItem` model element.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeIndent( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:listIndent' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\t// 1. Break the container after and before the list item.\n\t\t// This will create a view list with one view list item -- the one that changed type.\n\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\n\t\t// 2. Extract view list with changed view list item and merge \"hole\" possibly created by breaking and removing elements.\n\t\tconst viewList = viewItem.parent;\n\t\tconst viewListPrev = viewList.previousSibling;\n\t\tconst removeRange = viewWriter.createRangeOn( viewList );\n\t\tviewWriter.remove( removeRange );\n\n\t\tif ( viewListPrev && viewListPrev.nextSibling ) {\n\t\t\tmergeViewLists( viewWriter, viewListPrev, viewListPrev.nextSibling );\n\t\t}\n\n\t\t// 3. Bring back nested list that was in the removed <li>.\n\t\thoistNestedLists( data.attributeOldValue + 1, data.range.start, removeRange.start, viewItem, conversionApi, model );\n\n\t\t// 4. Inject view list like it is newly inserted.\n\t\tinjectViewList( data.item, viewItem, conversionApi, model );\n\n\t\t// 5. Consume insertion of children inside the item. They are already handled by re-building the item in view.\n\t\tfor ( const child of data.item.getChildren() ) {\n\t\t\tconversionApi.consumable.consume( child, 'insert' );\n\t\t}\n\t};\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter is fired for\n * insert change of every model item, and should be fired before the actual converter. The converter checks whether the inserted\n * model item is a non-`listItem` element. If it is, and it is inserted inside a view list, the converter breaks the\n * list so the model element is inserted to the view parent element corresponding to its model parent element.\n *\n * The converter prevents such situations:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul><p>xxx</p><ul><li>bar</li></ul>\n *\t\t<paragraph>xxx</paragraph> // Instead of this wrong view state:\n *\t\t<listItem>bar</listItem> <ul><li>foo</li><p>xxx</p><li>bar</li></ul>\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewSplitOnInsert( evt, data, conversionApi ) {\n\tif ( !conversionApi.consumable.test( data.item, evt.name ) ) {\n\t\treturn;\n\t}\n\n\tif ( data.item.name != 'listItem' ) {\n\t\tlet viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst lists = [];\n\n\t\t// Break multiple ULs/OLs if there are.\n\t\t//\n\t\t// Imagine following list:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// Insert paragraph after item 1.1.1:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\t// In this case 1.1.2 has to become beginning of a new list.\n\t\t// We need to break list before 1.1.2 (obvious), then we need to break list also before 1.2.\n\t\t// Then we need to move those broken pieces one after another and merge:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t//\n\t\t// Lorem ipsum.\n\t\t//\n\t\t// 1.1.2 --------\n\t\t// 1.1.3 --------\n\t\t// 1.1.3.1 --------\n\t\t// 1.2 --------\n\t\t// 1.2.1 --------\n\t\t// 2 --------\n\t\t//\n\t\twhile ( viewPosition.parent.name == 'ul' || viewPosition.parent.name == 'ol' ) {\n\t\t\tviewPosition = viewWriter.breakContainer( viewPosition );\n\n\t\t\tif ( viewPosition.parent.name != 'li' ) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Remove lists that are after inserted element.\n\t\t\t// They will be brought back later, below the inserted element.\n\t\t\tconst removeStart = viewPosition;\n\t\t\tconst removeEnd = viewWriter.createPositionAt( viewPosition.parent, 'end' );\n\n\t\t\t// Don't remove if there is nothing to remove.\n\t\t\tif ( !removeStart.isEqual( removeEnd ) ) {\n\t\t\t\tconst removed = viewWriter.remove( viewWriter.createRange( removeStart, removeEnd ) );\n\t\t\t\tlists.push( removed );\n\t\t\t}\n\n\t\t\tviewPosition = viewWriter.createPositionAfter( viewPosition.parent );\n\t\t}\n\n\t\t// Bring back removed lists.\n\t\tif ( lists.length > 0 ) {\n\t\t\tfor ( let i = 0; i < lists.length; i++ ) {\n\t\t\t\tconst previousList = viewPosition.nodeBefore;\n\t\t\t\tconst insertedRange = viewWriter.insert( viewPosition, lists[ i ] );\n\t\t\t\tviewPosition = insertedRange.end;\n\n\t\t\t\t// Don't merge first list! We want a split in that place (this is why this converter is introduced).\n\t\t\t\tif ( i > 0 ) {\n\t\t\t\t\tconst mergePos = mergeViewLists( viewWriter, previousList, previousList.nextSibling );\n\n\t\t\t\t\t// If `mergePos` is in `previousList` it means that the lists got merged.\n\t\t\t\t\t// In this case, we need to fix insert position.\n\t\t\t\t\tif ( mergePos && mergePos.parent == previousList ) {\n\t\t\t\t\t\tviewPosition.offset--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Merge last inserted list with element after it.\n\t\t\tmergeViewLists( viewWriter, viewPosition.nodeBefore, viewPosition.nodeAfter );\n\t\t}\n\t}\n}\n\n/**\n * A special model-to-view converter introduced by the {@link module:list/list~List list feature}. This converter takes care of\n * merging view lists after something is removed or moved from near them.\n *\n * Example:\n *\n *\t\t// Model: // View:\n *\t\t<listItem>foo</listItem> <ul><li>foo</li></ul>\n *\t\t<paragraph>xxx</paragraph> <p>xxx</p>\n *\t\t<listItem>bar</listItem> <ul><li>bar</li></ul>\n *\n *\t\t// After change: // Correct view guaranteed by this converter:\n *\t\t<listItem>foo</listItem> <ul>\n *\t\t<listItem>bar</listItem> <li>foo</li>\n *\t\t <li>bar</li>\n *\t\t </ul>\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data Additional information about the change.\n * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface.\n */\nexport function modelViewMergeAfter( evt, data, conversionApi ) {\n\tconst viewPosition = conversionApi.mapper.toViewPosition( data.position );\n\tconst viewItemPrev = viewPosition.nodeBefore;\n\tconst viewItemNext = viewPosition.nodeAfter;\n\n\t// Merge lists if something (remove, move) was done from inside of list.\n\t// Merging will be done only if both items are view lists of the same type.\n\t// The check is done inside the helper function.\n\tmergeViewLists( conversionApi.writer, viewItemPrev, viewItemNext );\n}\n\n/**\n * A view-to-model converter that converts the `<li>` view elements into the `listItem` model elements.\n *\n * To set correct values of the `listType` and `listIndent` attributes the converter:\n * * checks `<li>`'s parent,\n * * stores and increases the `conversionApi.store.indent` value when `<li>`'s sub-items are converted.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function viewModelConverter( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.consume( data.viewItem, { name: true } ) ) {\n\t\tconst writer = conversionApi.writer;\n\n\t\t// 1. Create `listItem` model element.\n\t\tconst listItem = writer.createElement( 'listItem' );\n\n\t\t// 2. Handle `listItem` model element attributes.\n\t\tconst indent = getIndent( data.viewItem );\n\n\t\twriter.setAttribute( 'listIndent', indent, listItem );\n\n\t\t// Set 'bulleted' as default. If this item is pasted into a context,\n\t\tconst type = data.viewItem.parent && data.viewItem.parent.name == 'ol' ? 'numbered' : 'bulleted';\n\t\twriter.setAttribute( 'listType', type, listItem );\n\n\t\tif ( !conversionApi.safeInsert( listItem, data.modelCursor ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextPosition = viewToModelListItemChildrenConverter( listItem, data.viewItem.getChildren(), conversionApi );\n\n\t\t// Result range starts before the first item and ends after the last.\n\t\tdata.modelRange = writer.createRange( data.modelCursor, nextPosition );\n\n\t\tconversionApi.updateConversionResult( listItem, data );\n\t}\n}\n\n/**\n * A view-to-model converter for the `<ul>` and `<ol>` view elements that cleans the input view of garbage.\n * This is mostly to clean whitespaces from between the `<li>` view elements inside the view list element, however, also\n * incorrect data can be cleared if the view was incorrect.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function cleanList( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\t// Caching children because when we start removing them iterating fails.\n\t\tconst children = Array.from( data.viewItem.getChildren() );\n\n\t\tfor ( const child of children ) {\n\t\t\tconst isWrongElement = !( child.is( 'element', 'li' ) || isList( child ) );\n\n\t\t\tif ( isWrongElement ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * A view-to-model converter for the `<li>` elements that cleans whitespace formatting from the input view.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input and a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function cleanListItem( evt, data, conversionApi ) {\n\tif ( conversionApi.consumable.test( data.viewItem, { name: true } ) ) {\n\t\tif ( data.viewItem.childCount === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst children = [ ...data.viewItem.getChildren() ];\n\n\t\tlet foundList = false;\n\n\t\tfor ( const child of children ) {\n\t\t\tif ( foundList && !isList( child ) ) {\n\t\t\t\tchild._remove();\n\t\t\t}\n\n\t\t\tif ( isList( child ) ) {\n\t\t\t\t// If this is a <ul> or <ol>, do not process it, just mark that we already visited list element.\n\t\t\t\tfoundList = true;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Returns a callback for model position to view position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `listItem` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:modelToViewPosition\n * @param {module:engine/view/view~View} view A view instance.\n * @returns {Function}\n */\nexport function modelToViewPosition( view ) {\n\treturn ( evt, data ) => {\n\t\tif ( data.isPhantom ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.modelPosition.nodeBefore;\n\n\t\tif ( modelItem && modelItem.is( 'element', 'listItem' ) ) {\n\t\t\tconst viewItem = data.mapper.toViewElement( modelItem );\n\t\t\tconst topmostViewList = viewItem.getAncestors().find( isList );\n\t\t\tconst walker = view.createPositionAt( viewItem, 0 ).getWalker();\n\n\t\t\tfor ( const value of walker ) {\n\t\t\t\tif ( value.type == 'elementStart' && value.item.is( 'element', 'li' ) ) {\n\t\t\t\t\tdata.viewPosition = value.previousPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ( value.type == 'elementEnd' && value.item == topmostViewList ) {\n\t\t\t\t\tdata.viewPosition = value.nextPosition;\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n/**\n * The callback for view position to model position mapping for {@link module:engine/conversion/mapper~Mapper}. The callback fixes\n * positions between the `<li>` elements that would be incorrectly mapped because of how list items are represented in the model\n * and in the view.\n *\n * @see module:engine/conversion/mapper~Mapper#event:viewToModelPosition\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function viewToModelPosition( model ) {\n\treturn ( evt, data ) => {\n\t\tconst viewPos = data.viewPosition;\n\t\tconst viewParent = viewPos.parent;\n\t\tconst mapper = data.mapper;\n\n\t\tif ( viewParent.name == 'ul' || viewParent.name == 'ol' ) {\n\t\t\t// Position is directly in <ul> or <ol>.\n\t\t\tif ( !viewPos.isAtEnd ) {\n\t\t\t\t// If position is not at the end, it must be before <li>.\n\t\t\t\t// Get that <li>, map it to `listItem` and set model position before that `listItem`.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeAfter );\n\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode );\n\t\t\t} else {\n\t\t\t\t// Position is at the end of <ul> or <ol>, so there is no <li> after it to be mapped.\n\t\t\t\t// There is <li> before the position, but we cannot just map it to `listItem` and set model position after it,\n\t\t\t\t// because that <li> may contain nested items.\n\t\t\t\t// We will check \"model length\" of that <li>, in other words - how many `listItem`s are in that <li>.\n\t\t\t\tconst modelNode = mapper.toModelElement( viewPos.nodeBefore );\n\t\t\t\tconst modelLength = mapper.getModelLength( viewPos.nodeBefore );\n\n\t\t\t\t// Then we get model position before mapped `listItem` and shift it accordingly.\n\t\t\t\tdata.modelPosition = model.createPositionBefore( modelNode ).getShiftedBy( modelLength );\n\t\t\t}\n\n\t\t\tevt.stop();\n\t\t} else if (\n\t\t\tviewParent.name == 'li' &&\n\t\t\tviewPos.nodeBefore &&\n\t\t\t( viewPos.nodeBefore.name == 'ul' || viewPos.nodeBefore.name == 'ol' )\n\t\t) {\n\t\t\t// In most cases when view position is in <li> it is in text and this is a correct position.\n\t\t\t// However, if position is after <ul> or <ol> we have to fix it -- because in model <ul>/<ol> are not in the `listItem`.\n\t\t\tconst modelNode = mapper.toModelElement( viewParent );\n\n\t\t\t// Check all <ul>s and <ol>s that are in the <li> but before mapped position.\n\t\t\t// Get model length of those elements and then add it to the offset of `listItem` mapped to the original <li>.\n\t\t\tlet modelLength = 1; // Starts from 1 because the original <li> has to be counted in too.\n\t\t\tlet viewList = viewPos.nodeBefore;\n\n\t\t\twhile ( viewList && isList( viewList ) ) {\n\t\t\t\tmodelLength += mapper.getModelLength( viewList );\n\n\t\t\t\tviewList = viewList.previousSibling;\n\t\t\t}\n\n\t\t\tdata.modelPosition = model.createPositionBefore( modelNode ).getShiftedBy( modelLength );\n\n\t\t\tevt.stop();\n\t\t}\n\t};\n}\n\n/**\n * Post-fixer that reacts to changes on document and fixes incorrect model states.\n *\n * In the example below, there is a correct list structure.\n * Then the middle element is removed so the list structure will become incorrect:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>Item 2</listItem> <--- this is removed.\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n *\n * The list structure after the middle element is removed:\n *\n * \t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Item 3</listItem>\n *\n * Should become:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>Item 1</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>Item 3</listItem> <--- note that indent got post-fixed.\n *\n * @param {module:engine/model/model~Model} model The data model.\n * @param {module:engine/model/writer~Writer} writer The writer to do changes with.\n * @returns {Boolean} `true` if any change has been applied, `false` otherwise.\n */\nexport function modelChangePostFixer( model, writer ) {\n\tconst changes = model.document.differ.getChanges();\n\tconst itemToListHead = new Map();\n\n\tlet applied = false;\n\n\tfor ( const entry of changes ) {\n\t\tif ( entry.type == 'insert' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'insert' && entry.name != 'listItem' ) {\n\t\t\tif ( entry.name != '$text' ) {\n\t\t\t\t// In case of renamed element.\n\t\t\t\tconst item = entry.position.nodeAfter;\n\n\t\t\t\tif ( item.hasAttribute( 'listIndent' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listIndent', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listType' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listType', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listStyle' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listStyle', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listReversed' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listReversed', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tif ( item.hasAttribute( 'listStart' ) ) {\n\t\t\t\t\twriter.removeAttribute( 'listStart', item );\n\n\t\t\t\t\tapplied = true;\n\t\t\t\t}\n\n\t\t\t\tfor ( const innerItem of Array.from( model.createRangeIn( item ) ).filter( e => e.item.is( 'element', 'listItem' ) ) ) {\n\t\t\t\t\t_addListToFix( innerItem.previousPosition );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst posAfter = entry.position.getShiftedBy( entry.length );\n\n\t\t\t_addListToFix( posAfter );\n\t\t} else if ( entry.type == 'remove' && entry.name == 'listItem' ) {\n\t\t\t_addListToFix( entry.position );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listIndent' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t} else if ( entry.type == 'attribute' && entry.attributeKey == 'listType' ) {\n\t\t\t_addListToFix( entry.range.start );\n\t\t}\n\t}\n\n\tfor ( const listHead of itemToListHead.values() ) {\n\t\t_fixListIndents( listHead );\n\t\t_fixListTypes( listHead );\n\t}\n\n\treturn applied;\n\n\tfunction _addListToFix( position ) {\n\t\tconst previousNode = position.nodeBefore;\n\n\t\tif ( !previousNode || !previousNode.is( 'element', 'listItem' ) ) {\n\t\t\tconst item = position.nodeAfter;\n\n\t\t\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\t\titemToListHead.set( item, item );\n\t\t\t}\n\t\t} else {\n\t\t\tlet listHead = previousNode;\n\n\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (\n\t\t\t\t// Cache previousSibling and reuse for performance reasons. See #6581.\n\t\t\t\tlet previousSibling = listHead.previousSibling;\n\t\t\t\tpreviousSibling && previousSibling.is( 'element', 'listItem' );\n\t\t\t\tpreviousSibling = listHead.previousSibling\n\t\t\t) {\n\t\t\t\tlistHead = previousSibling;\n\n\t\t\t\tif ( itemToListHead.has( listHead ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\titemToListHead.set( previousNode, listHead );\n\t\t}\n\t}\n\n\tfunction _fixListIndents( item ) {\n\t\tlet maxIndent = 0;\n\t\tlet fixBy = null;\n\n\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\t\tif ( itemIndent > maxIndent ) {\n\t\t\t\tlet newIndent;\n\n\t\t\t\tif ( fixBy === null ) {\n\t\t\t\t\tfixBy = itemIndent - maxIndent;\n\t\t\t\t\tnewIndent = maxIndent;\n\t\t\t\t} else {\n\t\t\t\t\tif ( fixBy > itemIndent ) {\n\t\t\t\t\t\tfixBy = itemIndent;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewIndent = itemIndent - fixBy;\n\t\t\t\t}\n\n\t\t\t\twriter.setAttribute( 'listIndent', newIndent, item );\n\n\t\t\t\tapplied = true;\n\t\t\t} else {\n\t\t\t\tfixBy = null;\n\t\t\t\tmaxIndent = item.getAttribute( 'listIndent' ) + 1;\n\t\t\t}\n\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n\n\tfunction _fixListTypes( item ) {\n\t\tlet typesStack = [];\n\t\tlet prev = null;\n\n\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\t\tif ( prev && prev.getAttribute( 'listIndent' ) > itemIndent ) {\n\t\t\t\ttypesStack = typesStack.slice( 0, itemIndent + 1 );\n\t\t\t}\n\n\t\t\tif ( itemIndent != 0 ) {\n\t\t\t\tif ( typesStack[ itemIndent ] ) {\n\t\t\t\t\tconst type = typesStack[ itemIndent ];\n\n\t\t\t\t\tif ( item.getAttribute( 'listType' ) != type ) {\n\t\t\t\t\t\twriter.setAttribute( 'listType', type, item );\n\n\t\t\t\t\t\tapplied = true;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttypesStack[ itemIndent ] = item.getAttribute( 'listType' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tprev = item;\n\t\t\titem = item.nextSibling;\n\t\t}\n\t}\n}\n\n/**\n * A fixer for pasted content that includes list items.\n *\n * It fixes indentation of pasted list items so the pasted items match correctly to the context they are pasted into.\n *\n * Example:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>A</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>B^</listItem>\n *\t\t// At ^ paste: <listItem listType=\"bulleted\" listIndent=4>X</listItem>\n *\t\t// <listItem listType=\"bulleted\" listIndent=5>Y</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>C</listItem>\n *\n * Should become:\n *\n *\t\t<listItem listType=\"bulleted\" listIndent=0>A</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=1>BX</listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>Y/listItem>\n *\t\t<listItem listType=\"bulleted\" listIndent=2>C</listItem>\n *\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Array} args Arguments of {@link module:engine/model/model~Model#insertContent}.\n */\nexport function modelIndentPasteFixer( evt, [ content, selectable ] ) {\n\t// Check whether inserted content starts from a `listItem`. If it does not, it means that there are some other\n\t// elements before it and there is no need to fix indents, because even if we insert that content into a list,\n\t// that list will be broken.\n\t// Note: we also need to handle singular elements because inserting item with indent 0 into 0,1,[],2\n\t// would create incorrect model.\n\tlet item = content.is( 'documentFragment' ) ? content.getChild( 0 ) : content;\n\n\tlet selection;\n\n\tif ( !selectable ) {\n\t\tselection = this.document.selection;\n\t} else {\n\t\tselection = this.createSelection( selectable );\n\t}\n\n\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t// Get a reference list item. Inserted list items will be fixed according to that item.\n\t\tconst pos = selection.getFirstPosition();\n\t\tlet refItem = null;\n\n\t\tif ( pos.parent.is( 'element', 'listItem' ) ) {\n\t\t\trefItem = pos.parent;\n\t\t} else if ( pos.nodeBefore && pos.nodeBefore.is( 'element', 'listItem' ) ) {\n\t\t\trefItem = pos.nodeBefore;\n\t\t}\n\n\t\t// If there is `refItem` it means that we do insert list items into an existing list.\n\t\tif ( refItem ) {\n\t\t\t// First list item in `data` has indent equal to 0 (it is a first list item). It should have indent equal\n\t\t\t// to the indent of reference item. We have to fix the first item and all of it's children and following siblings.\n\t\t\t// Indent of all those items has to be adjusted to reference item.\n\t\t\tconst indentChange = refItem.getAttribute( 'listIndent' );\n\n\t\t\t// Fix only if there is anything to fix.\n\t\t\tif ( indentChange > 0 ) {\n\t\t\t\t// Adjust indent of all \"first\" list items in inserted data.\n\t\t\t\twhile ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\t\t\titem._setAttribute( 'listIndent', item.getAttribute( 'listIndent' ) + indentChange );\n\n\t\t\t\t\titem = item.nextSibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Helper function that converts children of a given `<li>` view element into corresponding model elements.\n// The function maintains proper order of elements if model `listItem` is split during the conversion\n// due to block children conversion.\n//\n// @param {module:engine/model/element~Element} listItemModel List item model element to which converted children will be inserted.\n// @param {Iterable.<module:engine/view/node~Node>} viewChildren View elements which will be converted.\n// @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n// @returns {module:engine/model/position~Position} Position on which next elements should be inserted after children conversion.\nfunction viewToModelListItemChildrenConverter( listItemModel, viewChildren, conversionApi ) {\n\tconst { writer, schema } = conversionApi;\n\n\t// A position after the last inserted `listItem`.\n\tlet nextPosition = writer.createPositionAfter( listItemModel );\n\n\t// Check all children of the converted `<li>`. At this point we assume there are no \"whitespace\" view text nodes\n\t// in view list, between view list items. This should be handled by `<ul>` and `<ol>` converters.\n\tfor ( const child of viewChildren ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\t// If the children is a list, we will insert its conversion result after currently handled `listItem`.\n\t\t\t// Then, next insertion position will be set after all the new list items (and maybe other elements if\n\t\t\t// something split list item).\n\t\t\t//\n\t\t\t// If this is a list, we expect that some `listItem`s and possibly other blocks will be inserted, however `.modelCursor`\n\t\t\t// should be set after last `listItem` (or block). This is why it feels safe to use it as `nextPosition`\n\t\t\tnextPosition = conversionApi.convertItem( child, nextPosition ).modelCursor;\n\t\t} else {\n\t\t\t// If this is not a list, try inserting content at the end of the currently handled `listItem`.\n\t\t\tconst result = conversionApi.convertItem( child, writer.createPositionAt( listItemModel, 'end' ) );\n\n\t\t\t// It may end up that the current `listItem` becomes split (if that content cannot be inside `listItem`). For example:\n\t\t\t//\n\t\t\t// <li><p>Foo</p></li>\n\t\t\t//\n\t\t\t// will be converted to:\n\t\t\t//\n\t\t\t// <listItem></listItem><paragraph>Foo</paragraph><listItem></listItem>\n\t\t\t//\n\t\t\tconst convertedChild = result.modelRange.start.nodeAfter;\n\t\t\tconst wasSplit = convertedChild && convertedChild.is( 'element' ) && !schema.checkChild( listItemModel, convertedChild.name );\n\n\t\t\tif ( wasSplit ) {\n\t\t\t\t// As `lastListItem` got split, we need to update it to the second part of the split `listItem` element.\n\t\t\t\t//\n\t\t\t\t// `modelCursor` should be set to a position where the conversion should continue. There are multiple possible scenarios\n\t\t\t\t// that may happen. Usually, `modelCursor` (marked as `#` below) would point to the second list item after conversion:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><p>Foo</p></li>` -> `<listItem></listItem><paragraph>Foo</paragraph><listItem>#</listItem>`\n\t\t\t\t//\n\t\t\t\t// However, in some cases, like auto-paragraphing, the position is placed at the end of the block element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div>Foo</div></li>` -> `<listItem></listItem><paragraph>Foo#</paragraph><listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// or after an element if another element broken auto-paragraphed element:\n\t\t\t\t//\n\t\t\t\t//\t\t`<li><div><h2>Foo</h2></div></li>` -> `<listItem></listItem><heading1>Foo</heading1>#<listItem></listItem>`\n\t\t\t\t//\n\t\t\t\t// We need to check for such cases and use proper list item and position based on it.\n\t\t\t\t//\n\t\t\t\tif ( result.modelCursor.parent.is( 'element', 'listItem' ) ) {\n\t\t\t\t\t// (1).\n\t\t\t\t\tlistItemModel = result.modelCursor.parent;\n\t\t\t\t} else {\n\t\t\t\t\t// (2), (3).\n\t\t\t\t\tlistItemModel = findNextListItem( result.modelCursor );\n\t\t\t\t}\n\n\t\t\t\tnextPosition = writer.createPositionAfter( listItemModel );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nextPosition;\n}\n\n// Helper function that seeks for a next list item starting from given `startPosition`.\nfunction findNextListItem( startPosition ) {\n\tconst treeWalker = new TreeWalker( { startPosition } );\n\n\tlet value;\n\n\tdo {\n\t\tvalue = treeWalker.next();\n\t} while ( !value.value.item.is( 'element', 'listItem' ) );\n\n\treturn value.value.item;\n}\n\n// Helper function that takes all children of given `viewRemovedItem` and moves them in a correct place, according\n// to other given parameters.\nfunction hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStartPosition, viewRemovedItem, conversionApi, model ) {\n\t// Find correct previous model list item element.\n\t// The element has to have either same or smaller indent than given reference indent.\n\t// This will be the model element which will get nested items (if it has smaller indent) or sibling items (if it has same indent).\n\t// Keep in mind that such element might not be found, if removed item was the first item.\n\tconst prevModelItem = getSiblingListItem( modelRemoveStartPosition.nodeBefore, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: nextIndent,\n\t\tfoo: 'b'\n\t} );\n\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// Indent of found element or `null` if the element has not been found.\n\tconst prevIndent = prevModelItem ? prevModelItem.getAttribute( 'listIndent' ) : null;\n\n\tlet insertPosition;\n\n\tif ( !prevModelItem ) {\n\t\t// If element has not been found, simply insert lists at the position where the removed item was:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1 -------- <--- this is removed, no previous list item, put nested items in place of removed item.\n\t\t// 1.1 -------- <--- this is reference indent.\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// Lorem ipsum.\n\t\t// 1.1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\tinsertPosition = viewRemoveStartPosition;\n\t} else if ( prevIndent == nextIndent ) {\n\t\t// If element has been found and has same indent as reference indent it means that nested items should\n\t\t// become siblings of found element:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 -------- <--- this is `prevModelItem`.\n\t\t// 2 -------- <--- this is removed, previous list item has indent same as reference indent.\n\t\t// 2.1 -------- <--- this is reference indent, this and 2.2 should become siblings of 1.2.\n\t\t// 2.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1 --------\n\t\t// 1.2 --------\n\t\t// 2.1 --------\n\t\t// 2.2 --------\n\t\tconst prevViewList = mapper.toViewElement( prevModelItem ).parent;\n\t\tinsertPosition = viewWriter.createPositionAfter( prevViewList );\n\t} else {\n\t\t// If element has been found and has smaller indent as reference indent it means that nested items\n\t\t// should become nested items of found item:\n\t\t//\n\t\t// 1 -------- <--- this is `prevModelItem`.\n\t\t// 1.1 -------- <--- this is removed, previous list item has indent smaller than reference indent.\n\t\t// 1.1.1 -------- <--- this is reference indent, this and 1.1.1 should become nested items of 1.\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Becomes:\n\t\t//\n\t\t// 1 --------\n\t\t// 1.1.1 --------\n\t\t// 1.1.2 --------\n\t\t// 1.2 --------\n\t\t//\n\t\t// Note: in this case 1.1.1 have indent 2 while 1 have indent 0. In model that should not be possible,\n\t\t// because following item may have indent bigger only by one. But this is fixed by postfixer.\n\t\tconst modelPosition = model.createPositionAt( prevModelItem, 'end' );\n\t\tinsertPosition = mapper.toViewPosition( modelPosition );\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Handle multiple lists. This happens if list item has nested numbered and bulleted lists. Following lists\n\t// are inserted after the first list (no need to recalculate insertion position for them).\n\tfor ( const child of [ ...viewRemovedItem.getChildren() ] ) {\n\t\tif ( isList( child ) ) {\n\t\t\tinsertPosition = viewWriter.move( viewWriter.createRangeOn( child ), insertPosition ).end;\n\n\t\t\tmergeViewLists( viewWriter, child, child.nextSibling );\n\t\t\tmergeViewLists( viewWriter, child.previousSibling, child );\n\t\t}\n\t}\n}\n\n// Checks if view element is a list type (ul or ol).\n//\n// @param {module:engine/view/element~Element} viewElement\n// @returns {Boolean}\nfunction isList( viewElement ) {\n\treturn viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );\n}\n\n// Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.\n//\n// Also, fixes non HTML compliant lists indents:\n//\n//\t\tbefore: fixed list:\n//\t\tOL OL\n//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n//\t\t |-> OL |-> OL\n//\t\t |-> OL |\n//\t\t | |-> OL |\n//\t\t | |-> OL |\n//\t\t | |-> LI (parent LIs: 1) |-> LI (indent: 1)\n//\t\t |-> LI (parent LIs: 1) |-> LI (indent: 1)\n//\n//\t\tbefore: fixed list:\n//\t\tOL OL\n//\t\t|-> OL |\n//\t\t |-> OL |\n//\t\t |-> OL |\n//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 0)\n//\n//\t\tbefore: fixed list:\n//\t\tOL OL\n//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n//\t\t|-> OL |-> OL\n//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n//\n// @param {module:engine/view/element~Element} listItem\n// @param {Object} conversionStore\n// @returns {Number}\nfunction getIndent( listItem ) {\n\tlet indent = 0;\n\n\tlet parent = listItem.parent;\n\n\twhile ( parent ) {\n\t\t// Each LI in the tree will result in an increased indent for HTML compliant lists.\n\t\tif ( parent.is( 'element', 'li' ) ) {\n\t\t\tindent++;\n\t\t} else {\n\t\t\t// If however the list is nested in other list we should check previous sibling of any of the list elements...\n\t\t\tconst previousSibling = parent.previousSibling;\n\n\t\t\t// ...because the we might need increase its indent:\n\t\t\t//\t\tbefore: fixed list:\n\t\t\t//\t\tOL OL\n\t\t\t//\t\t|-> LI (parent LIs: 0) |-> LI (indent: 0)\n\t\t\t//\t\t|-> OL |-> OL\n\t\t\t//\t\t |-> LI (parent LIs: 0) |-> LI (indent: 1)\n\t\t\tif ( previousSibling && previousSibling.is( 'element', 'li' ) ) {\n\t\t\t\tindent++;\n\t\t\t}\n\t\t}\n\n\t\tparent = parent.parent;\n\t}\n\n\treturn indent;\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 list/list/indentcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\n\n/**\n * The list indent command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class IndentCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'forward'|'backward'} indentDirection The direction of indent. If it is equal to `backward`, the command\n\t * will outdent a list item.\n\t */\n\tconstructor( editor, indentDirection ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * Determines by how much the command will change the list item's indent attribute.\n\t\t *\n\t\t * @readonly\n\t\t * @private\n\t\t * @member {Number}\n\t\t */\n\t\tthis._indentBy = indentDirection == 'forward' ? 1 : -1;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Indents or outdents (depending on the {@link #constructor}'s `indentDirection` parameter) selected list items.\n\t *\n\t * @fires execute\n\t * @fires _executeCleanup\n\t */\n\texecute() {\n\t\tconst model = this.editor.model;\n\t\tconst doc = model.document;\n\t\tlet itemsToChange = Array.from( doc.selection.getSelectedBlocks() );\n\n\t\tmodel.change( writer => {\n\t\t\tconst lastItem = itemsToChange[ itemsToChange.length - 1 ];\n\n\t\t\t// Indenting a list item should also indent all the items that are already sub-items of indented item.\n\t\t\tlet next = lastItem.nextSibling;\n\n\t\t\t// Check all items after last indented item, as long as their indent is bigger than indent of that item.\n\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) > lastItem.getAttribute( 'listIndent' ) ) {\n\t\t\t\titemsToChange.push( next );\n\n\t\t\t\tnext = next.nextSibling;\n\t\t\t}\n\n\t\t\t// We need to be sure to keep model in correct state after each small change, because converters\n\t\t\t// bases on that state and assumes that model is correct.\n\t\t\t// Because of that, if the command outdents items, we will outdent them starting from the last item, as\n\t\t\t// it is safer.\n\t\t\tif ( this._indentBy < 0 ) {\n\t\t\t\titemsToChange = itemsToChange.reverse();\n\t\t\t}\n\n\t\t\tfor ( const item of itemsToChange ) {\n\t\t\t\tconst indent = item.getAttribute( 'listIndent' ) + this._indentBy;\n\n\t\t\t\t// If indent is lower than 0, it means that the item got outdented when it was not indented.\n\t\t\t\t// This means that we need to convert that list item to paragraph.\n\t\t\t\tif ( indent < 0 ) {\n\t\t\t\t\t// To keep the model as correct as possible, first rename listItem, then remove attributes,\n\t\t\t\t\t// as listItem without attributes is very incorrect and will cause problems in converters.\n\t\t\t\t\t// No need to remove attributes, will be removed by post fixer.\n\t\t\t\t\twriter.rename( item, 'paragraph' );\n\t\t\t\t}\n\t\t\t\t// If indent is >= 0, change the attribute value.\n\t\t\t\telse {\n\t\t\t\t\twriter.setAttribute( 'listIndent', indent, item );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired by the {@link #execute} method.\n\t\t\t *\n\t\t\t * It allows to execute an action after executing the {@link ~IndentCommand#execute} method, for example adjusting\n\t\t\t * attributes of changed list items.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event _executeCleanup\n\t\t\t */\n\t\t\tthis.fire( '_executeCleanup', itemsToChange );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// Check whether any of position's ancestor is a list item.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\t// If selection is not in a list item, the command is disabled.\n\t\tif ( !listItem || !listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this._indentBy > 0 ) {\n\t\t\t// Cannot indent first item in it's list. Check if before `listItem` is a list item that is in same list.\n\t\t\t// To be in the same list, the item has to have same attributes and cannot be \"split\" by an item with lower indent.\n\t\t\tconst indent = listItem.getAttribute( 'listIndent' );\n\t\t\tconst type = listItem.getAttribute( 'listType' );\n\n\t\t\tlet prev = listItem.previousSibling;\n\n\t\t\twhile ( prev && prev.is( 'element', 'listItem' ) && prev.getAttribute( 'listIndent' ) >= indent ) {\n\t\t\t\tif ( prev.getAttribute( 'listIndent' ) == indent ) {\n\t\t\t\t\t// The item is on the same level.\n\t\t\t\t\t// If it has same type, it means that we found a preceding sibling from the same list.\n\t\t\t\t\t// If it does not have same type, it means that `listItem` is on different list (this can happen only\n\t\t\t\t\t// on top level lists, though).\n\t\t\t\t\treturn prev.getAttribute( 'listType' ) == type;\n\t\t\t\t}\n\n\t\t\t\tprev = prev.previousSibling;\n\t\t\t}\n\n\t\t\t// Could not find similar list item, this means that `listItem` is first in its list.\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we are outdenting it is enough to be in list item. Every list item can always be outdented.\n\t\treturn true;\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 list/list/listcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { first } from 'ckeditor5/src/utils';\n\n/**\n * The list command. It is used by the {@link module:list/list~List list feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {'numbered'|'bulleted'} type List type that will be handled by this command.\n\t */\n\tconstructor( editor, type ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The type of the list created by the command.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'numbered'|'bulleted'|'todo'}\n\t\t */\n\t\tthis.type = type;\n\n\t\t/**\n\t\t * A flag indicating whether the command is active, which means that the selection starts in a list of the same type.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #value\n\t\t */\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the list command.\n\t *\n\t * @fires execute\n\t * @param {Object} [options] Command options.\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will try to convert the\n\t * selected items and potentially the neighbor elements to the proper list items. If set to `false`, it will convert selected elements\n\t * to paragraphs. If not set, the command will toggle selected elements to list items or paragraphs, depending on the selection.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst document = model.document;\n\t\tconst blocks = Array.from( document.selection.getSelectedBlocks() )\n\t\t\t.filter( block => checkCanBecomeListItem( block, model.schema ) );\n\n\t\t// Whether we are turning off some items.\n\t\tconst turnOff = options.forceValue !== undefined ? !options.forceValue : this.value;\n\n\t\t// If we are turning off items, we are going to rename them to paragraphs.\n\n\t\tmodel.change( writer => {\n\t\t\t// If part of a list got turned off, we need to handle (outdent) all of sub-items of the last turned-off item.\n\t\t\t// To be sure that model is all the time in a good state, we first fix items below turned-off item.\n\t\t\tif ( turnOff ) {\n\t\t\t\t// Start from the model item that is just after the last turned-off item.\n\t\t\t\tlet next = blocks[ blocks.length - 1 ].nextSibling;\n\t\t\t\tlet currentIndent = Number.POSITIVE_INFINITY;\n\t\t\t\tlet changes = [];\n\n\t\t\t\t// Correct indent of all items after the last turned off item.\n\t\t\t\t// Rules that should be followed:\n\t\t\t\t// 1. All direct sub-items of turned-off item should become indent 0, because the first item after it\n\t\t\t\t// will be the first item of a new list. Other items are at the same level, so should have same 0 index.\n\t\t\t\t// 2. All items with indent lower than indent of turned-off item should become indent 0, because they\n\t\t\t\t// should not end up as a child of any of list items that they were not children of before.\n\t\t\t\t// 3. All other items should have their indent changed relatively to it's parent.\n\t\t\t\t//\n\t\t\t\t// For example:\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t// 3 * --------\t\t\t<-- this is turned off.\n\t\t\t\t// 4 * --------\t\t<-- this has to become indent = 0, because it will be first item on a new list.\n\t\t\t\t// 5 * --------\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 6 * --------\t\t\t<-- this has to become indent = 0, because it should not be a child of any of items above.\n\t\t\t\t// 7 * --------\t\t<-- this should be still be a child of item above, so indent = 1.\n\t\t\t\t// 8 * --------\t\t\t\t<-- this has to become indent = 0.\n\t\t\t\t// 9 * --------\t\t\t<-- this should still be a child of item above, so indent = 1.\n\t\t\t\t// 10 * --------\t\t<-- this should still be a child of item above, so indent = 2.\n\t\t\t\t// 11 * --------\t\t<-- this should still be at the same level as item above, so indent = 2.\n\t\t\t\t// 12 * --------\t\t\t\t<-- this and all below are left unchanged.\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// After turning off 3 the list becomes:\n\t\t\t\t//\n\t\t\t\t// 1 * --------\n\t\t\t\t// 2 * --------\n\t\t\t\t//\n\t\t\t\t// 3 --------\n\t\t\t\t//\n\t\t\t\t// 4 * --------\n\t\t\t\t// 5 * --------\n\t\t\t\t// 6 * --------\n\t\t\t\t// 7 * --------\n\t\t\t\t// 8 * --------\n\t\t\t\t// 9 * --------\n\t\t\t\t// 10 * --------\n\t\t\t\t// 11 * --------\n\t\t\t\t// 12 * --------\n\t\t\t\t// 13 * --------\n\t\t\t\t// 14 * --------\n\t\t\t\t//\n\t\t\t\t// Thanks to this algorithm no lists are mismatched and no items get unexpected children/parent, while\n\t\t\t\t// those parent-child connection which are possible to maintain are still maintained. It's worth noting\n\t\t\t\t// that this is the same effect that we would be get by multiple use of outdent command. However doing\n\t\t\t\t// it like this is much more efficient because it's less operation (less memory usage, easier OT) and\n\t\t\t\t// less conversion (faster).\n\t\t\t\twhile ( next && next.name == 'listItem' && next.getAttribute( 'listIndent' ) !== 0 ) {\n\t\t\t\t\t// Check each next list item, as long as its indent is bigger than 0.\n\t\t\t\t\t// If the indent is 0 we are not going to change anything anyway.\n\t\t\t\t\tconst indent = next.getAttribute( 'listIndent' );\n\n\t\t\t\t\t// We check if that's item indent is lower as current relative indent.\n\t\t\t\t\tif ( indent < currentIndent ) {\n\t\t\t\t\t\t// If it is, current relative indent becomes that indent.\n\t\t\t\t\t\tcurrentIndent = indent;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fix indent relatively to current relative indent.\n\t\t\t\t\t// Note, that if we just changed the current relative indent, the newIndent will be equal to 0.\n\t\t\t\t\tconst newIndent = indent - currentIndent;\n\n\t\t\t\t\t// Save the entry in changes array. We do not apply it at the moment, because we will need to\n\t\t\t\t\t// reverse the changes so the last item is changed first.\n\t\t\t\t\t// This is to keep model in correct state all the time.\n\t\t\t\t\tchanges.push( { element: next, listIndent: newIndent } );\n\n\t\t\t\t\t// Find next item.\n\t\t\t\t\tnext = next.nextSibling;\n\t\t\t\t}\n\n\t\t\t\tchanges = changes.reverse();\n\n\t\t\t\tfor ( const item of changes ) {\n\t\t\t\t\twriter.setAttribute( 'listIndent', item.listIndent, item.element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we are turning on, we might change some items that are already `listItem`s but with different type.\n\t\t\t// Changing one nested list item to other type should also trigger changing all its siblings so the\n\t\t\t// whole nested list is of the same type.\n\t\t\t// Example (assume changing to numbered list):\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ------\t\t<-- fix, because latter list item of this item's list is changed\n\t\t\t// * ---[--\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t\t<-- already in selection, but does not cause other list items to change because is top-level\n\t\t\t// * ---]--\t\t\t<-- already in selection\n\t\t\t// * ------\t\t\t<-- fix, because preceding list item of this item's list is changed\n\t\t\t// * ------\t\t<-- do not fix, item is not affected (different list)\n\t\t\t// * ------\t\t\t\t<-- do not fix, top level item\n\t\t\tif ( !turnOff ) {\n\t\t\t\t// Find lowest indent among selected items. This will be indicator what is the indent of\n\t\t\t\t// top-most list affected by the command.\n\t\t\t\tlet lowestIndent = Number.POSITIVE_INFINITY;\n\n\t\t\t\tfor ( const item of blocks ) {\n\t\t\t\t\tif ( item.is( 'element', 'listItem' ) && item.getAttribute( 'listIndent' ) < lowestIndent ) {\n\t\t\t\t\t\tlowestIndent = item.getAttribute( 'listIndent' );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Do not execute the fix for top-level lists.\n\t\t\t\tlowestIndent = lowestIndent === 0 ? 1 : lowestIndent;\n\n\t\t\t\t// Fix types of list items that are \"before\" the selected blocks.\n\t\t\t\t_fixType( blocks, true, lowestIndent );\n\n\t\t\t\t// Fix types of list items that are \"after\" the selected blocks.\n\t\t\t\t_fixType( blocks, false, lowestIndent );\n\t\t\t}\n\n\t\t\t// Phew! Now it will be easier :).\n\t\t\t// For each block element that was in the selection, we will either: turn it to list item,\n\t\t\t// turn it to paragraph, or change it's type. Or leave it as it is.\n\t\t\t// Do it in reverse as there might be multiple blocks (same as with changing indents).\n\t\t\tfor ( const element of blocks.reverse() ) {\n\t\t\t\tif ( turnOff && element.name == 'listItem' ) {\n\t\t\t\t\t// We are turning off and the element is a `listItem` - it should be converted to `paragraph`.\n\t\t\t\t\t// List item specific attributes are removed by post fixer.\n\t\t\t\t\twriter.rename( element, 'paragraph' );\n\t\t\t\t} else if ( !turnOff && element.name != 'listItem' ) {\n\t\t\t\t\t// We are turning on and the element is not a `listItem` - it should be converted to `listItem`.\n\t\t\t\t\t// The order of operations is important to keep model in correct state.\n\t\t\t\t\twriter.setAttributes( { listType: this.type, listIndent: 0 }, element );\n\t\t\t\t\twriter.rename( element, 'listItem' );\n\t\t\t\t} else if ( !turnOff && element.name == 'listItem' && element.getAttribute( 'listType' ) != this.type ) {\n\t\t\t\t\t// We are turning on and the element is a `listItem` but has different type - change it's type and\n\t\t\t\t\t// type of it's all siblings that have same indent.\n\t\t\t\t\twriter.setAttribute( 'listType', this.type, element );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Event fired by the {@link #execute} method.\n\t\t\t *\n\t\t\t * It allows to execute an action after executing the {@link ~ListCommand#execute} method, for example adjusting\n\t\t\t * attributes of changed blocks.\n\t\t\t *\n\t\t\t * @protected\n\t\t\t * @event _executeCleanup\n\t\t\t */\n\t\t\tthis.fire( '_executeCleanup', blocks );\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean} The current value.\n\t */\n\t_getValue() {\n\t\t// Check whether closest `listItem` ancestor of the position has a correct type.\n\t\tconst listItem = first( this.editor.model.document.selection.getSelectedBlocks() );\n\n\t\treturn !!listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == this.type;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\t// If command value is true it means that we are in list item, so the command should be enabled.\n\t\tif ( this.value ) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst selection = this.editor.model.document.selection;\n\t\tconst schema = this.editor.model.schema;\n\n\t\tconst firstBlock = first( selection.getSelectedBlocks() );\n\n\t\tif ( !firstBlock ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Otherwise, check if list item can be inserted at the position start.\n\t\treturn checkCanBecomeListItem( firstBlock, schema );\n\t}\n}\n\n// Helper function used when one or more list item have their type changed. Fixes type of other list items\n// that are affected by the change (are in same lists) but are not directly in selection. The function got extracted\n// not to duplicated code, as same fix has to be performed before and after selection.\n//\n// @param {Array.<module:engine/model/node~Node>} blocks Blocks that are in selection.\n// @param {Boolean} isBackward Specified whether fix will be applied for blocks before first selected block (`true`)\n// or blocks after last selected block (`false`).\n// @param {Number} lowestIndent Lowest indent among selected blocks.\nfunction _fixType( blocks, isBackward, lowestIndent ) {\n\t// We need to check previous sibling of first changed item and next siblings of last changed item.\n\tconst startingItem = isBackward ? blocks[ 0 ] : blocks[ blocks.length - 1 ];\n\n\tif ( startingItem.is( 'element', 'listItem' ) ) {\n\t\tlet item = startingItem[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t// During processing items, keeps the lowest indent of already processed items.\n\t\t// This saves us from changing too many items.\n\t\t// Following example is for going forward as it is easier to read, however same applies to going backward.\n\t\t// * ------\n\t\t// * ------\n\t\t// * --[---\n\t\t// * ------\t\t<-- `lowestIndent` should be 1\n\t\t// * --]---\t\t<-- `startingItem`, `currentIndent` = 2, `lowestIndent` == 1\n\t\t// * ------\t\t<-- should be fixed, `indent` == 2 == `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, set `currentIndent` to 1, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t<-- should not be fixed, item is in different list, `indent` = 2, `indent` != `currentIndent`\n\t\t// * ------\t\t<-- should be fixed, `indent` == 1 == `currentIndent`\n\t\t// * ------\t\t\t<-- break loop (`indent` < `lowestIndent`)\n\t\tlet currentIndent = startingItem.getAttribute( 'listIndent' );\n\n\t\t// Look back until a list item with indent lower than reference `lowestIndent`.\n\t\t// That would be the parent of nested sublist which contains item having `lowestIndent`.\n\t\twhile ( item && item.is( 'element', 'listItem' ) && item.getAttribute( 'listIndent' ) >= lowestIndent ) {\n\t\t\tif ( currentIndent > item.getAttribute( 'listIndent' ) ) {\n\t\t\t\tcurrentIndent = item.getAttribute( 'listIndent' );\n\t\t\t}\n\n\t\t\t// Found an item that is in the same nested sublist.\n\t\t\tif ( item.getAttribute( 'listIndent' ) == currentIndent ) {\n\t\t\t\t// Just add the item to selected blocks like it was selected by the user.\n\t\t\t\tblocks[ isBackward ? 'unshift' : 'push' ]( item );\n\t\t\t}\n\n\t\t\titem = item[ isBackward ? 'previousSibling' : 'nextSibling' ];\n\t\t}\n\t}\n}\n\n// Checks whether the given block can be replaced by a listItem.\n//\n// @private\n// @param {module:engine/model/element~Element} block A block to be tested.\n// @param {module:engine/model/schema~Schema} schema The schema of the document.\n// @returns {Boolean}\nfunction checkCanBecomeListItem( block, schema ) {\n\treturn schema.checkChild( block.parent, 'listItem' ) && !schema.isObject( block );\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 list/list/listediting\n */\n\nimport ListCommand from './listcommand';\nimport IndentCommand from './indentcommand';\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { Enter } from 'ckeditor5/src/enter';\nimport { Delete } from 'ckeditor5/src/typing';\n\nimport {\n\tcleanList,\n\tcleanListItem,\n\tmodelViewInsertion,\n\tmodelViewChangeType,\n\tmodelViewMergeAfterChangeType,\n\tmodelViewMergeAfter,\n\tmodelViewRemove,\n\tmodelViewSplitOnInsert,\n\tmodelViewChangeIndent,\n\tmodelChangePostFixer,\n\tmodelIndentPasteFixer,\n\tviewModelConverter,\n\tmodelToViewPosition,\n\tviewToModelPosition\n} from './converters';\n\n/**\n * The engine of the list feature. It handles creating, editing and removing lists and list items.\n *\n * It registers the `'numberedList'`, `'bulletedList'`, `'indentList'` and `'outdentList'` commands.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ Enter, Delete ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\n\t\t// Schema.\n\t\t// Note: in case `$block` will ever be allowed in `listItem`, keep in mind that this feature\n\t\t// uses `Selection#getSelectedBlocks()` without any additional processing to obtain all selected list items.\n\t\t// If there are blocks allowed inside list item, algorithms using `getSelectedBlocks()` will have to be modified.\n\t\teditor.model.schema.register( 'listItem', {\n\t\t\tinheritAllFrom: '$block',\n\t\t\tallowAttributes: [ 'listType', 'listIndent' ]\n\t\t} );\n\n\t\t// Converters.\n\t\tconst data = editor.data;\n\t\tconst editing = editor.editing;\n\n\t\teditor.model.document.registerPostFixer( writer => modelChangePostFixer( editor.model, writer ) );\n\n\t\tediting.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\t\tdata.mapper.registerViewToModelLength( 'li', getViewListItemLength );\n\n\t\tediting.mapper.on( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\t\tediting.mapper.on( 'viewToModelPosition', viewToModelPosition( editor.model ) );\n\t\tdata.mapper.on( 'modelToViewPosition', modelToViewPosition( editing.view ) );\n\n\t\teditor.conversion.for( 'editingDowncast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\t\t\tdispatcher.on( 'attribute:listType:listItem', modelViewChangeType, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'attribute:listType:listItem', modelViewMergeAfterChangeType, { priority: 'low' } );\n\t\t\t\tdispatcher.on( 'attribute:listIndent:listItem', modelViewChangeIndent( editor.model ) );\n\t\t\t\tdispatcher.on( 'remove:listItem', modelViewRemove( editor.model ) );\n\t\t\t\tdispatcher.on( 'remove', modelViewMergeAfter, { priority: 'low' } );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'dataDowncast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'insert', modelViewSplitOnInsert, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'insert:listItem', modelViewInsertion( editor.model ) );\n\t\t\t} );\n\n\t\teditor.conversion.for( 'upcast' )\n\t\t\t.add( dispatcher => {\n\t\t\t\tdispatcher.on( 'element:ul', cleanList, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:ol', cleanList, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:li', cleanListItem, { priority: 'high' } );\n\t\t\t\tdispatcher.on( 'element:li', viewModelConverter );\n\t\t\t} );\n\n\t\t// Fix indentation of pasted items.\n\t\teditor.model.on( 'insertContent', modelIndentPasteFixer, { priority: 'high' } );\n\n\t\t// Register commands for numbered and bulleted list.\n\t\teditor.commands.add( 'numberedList', new ListCommand( editor, 'numbered' ) );\n\t\teditor.commands.add( 'bulletedList', new ListCommand( editor, 'bulleted' ) );\n\n\t\t// Register commands for indenting.\n\t\teditor.commands.add( 'indentList', new IndentCommand( editor, 'forward' ) );\n\t\teditor.commands.add( 'outdentList', new IndentCommand( editor, 'backward' ) );\n\n\t\tconst viewDocument = editing.view.document;\n\n\t\t// Overwrite default Enter key behavior.\n\t\t// If Enter key is pressed with selection collapsed in empty list item, outdent it instead of breaking it.\n\t\tthis.listenTo( viewDocument, 'enter', ( evt, data ) => {\n\t\t\tconst doc = this.editor.model.document;\n\t\t\tconst positionParent = doc.selection.getLastPosition().parent;\n\n\t\t\tif ( doc.selection.isCollapsed && positionParent.name == 'listItem' && positionParent.isEmpty ) {\n\t\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\n\t\t// Overwrite default Backspace key behavior.\n\t\t// If Backspace key is pressed with selection collapsed on first position in first list item, outdent it. #83\n\t\tthis.listenTo( viewDocument, 'delete', ( evt, data ) => {\n\t\t\t// Check conditions from those that require less computations like those immediately available.\n\t\t\tif ( data.direction !== 'backward' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst selection = this.editor.model.document.selection;\n\n\t\t\tif ( !selection.isCollapsed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\n\t\t\tif ( !firstPosition.isAtStart ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst positionParent = firstPosition.parent;\n\n\t\t\tif ( positionParent.name !== 'listItem' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst previousIsAListItem = positionParent.previousSibling && positionParent.previousSibling.name === 'listItem';\n\n\t\t\tif ( previousIsAListItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis.editor.execute( 'outdentList' );\n\n\t\t\tdata.preventDefault();\n\t\t\tevt.stop();\n\t\t}, { context: 'li' } );\n\n\t\tthis.listenTo( editor.editing.view.document, 'tab', ( evt, data ) => {\n\t\t\tconst commandName = data.shiftKey ? 'outdentList' : 'indentList';\n\t\t\tconst command = this.editor.commands.get( commandName );\n\n\t\t\tif ( command.isEnabled ) {\n\t\t\t\teditor.execute( commandName );\n\n\t\t\t\tdata.stopPropagation();\n\t\t\t\tdata.preventDefault();\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { context: 'li' } );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst commands = this.editor.commands;\n\n\t\tconst indent = commands.get( 'indent' );\n\t\tconst outdent = commands.get( 'outdent' );\n\n\t\tif ( indent ) {\n\t\t\tindent.registerChildCommand( commands.get( 'indentList' ) );\n\t\t}\n\n\t\tif ( outdent ) {\n\t\t\toutdent.registerChildCommand( commands.get( 'outdentList' ) );\n\t\t}\n\t}\n}\n\nfunction getViewListItemLength( element ) {\n\tlet length = 1;\n\n\tfor ( const child of element.getChildren() ) {\n\t\tif ( child.name == 'ul' || child.name == 'ol' ) {\n\t\t\tfor ( const item of child.getChildren() ) {\n\t\t\t\tlength += getViewListItemLength( item );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 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 list/list/listui\n */\n\nimport { createUIComponent } from './utils';\n\nimport numberedListIcon from '../../theme/icons/numberedlist.svg';\nimport bulletedListIcon from '../../theme/icons/bulletedlist.svg';\n\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The list UI feature. It introduces the `'numberedList'` and `'bulletedList'` buttons that\n * allow to convert paragraphs to and from list items and indent or outdent them.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst t = this.editor.t;\n\n\t\t// Create two buttons and link them with numberedList and bulletedList commands.\n\t\tcreateUIComponent( this.editor, 'numberedList', t( 'Numbered List' ), numberedListIcon );\n\t\tcreateUIComponent( this.editor, 'bulletedList', t( 'Bulleted List' ), bulletedListIcon );\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 list/list/utils\n */\n\nimport { TreeWalker, getFillerOffset } from 'ckeditor5/src/engine';\nimport { ButtonView } from 'ckeditor5/src/ui';\n\n/**\n * Creates a list item {@link module:engine/view/containerelement~ContainerElement}.\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} writer The writer instance.\n * @returns {module:engine/view/containerelement~ContainerElement}\n */\nexport function createViewListItemElement( writer ) {\n\tconst viewItem = writer.createContainerElement( 'li' );\n\n\tviewItem.getFillerOffset = getListItemFillerOffset;\n\n\treturn viewItem;\n}\n\n/**\n * Helper function that creates a `<ul><li></li></ul>` or (`<ol>`) structure out of the given `modelItem` model `listItem` element.\n * Then, it binds the created view list item (`<li>`) with the model `listItem` element.\n * The function then returns the created view list item (`<li>`).\n *\n * @param {module:engine/model/item~Item} modelItem Model list item.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface.\n * @returns {module:engine/view/containerelement~ContainerElement} View list element.\n */\nexport function generateLiInUl( modelItem, conversionApi ) {\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\tconst listType = modelItem.getAttribute( 'listType' ) == 'numbered' ? 'ol' : 'ul';\n\tconst viewItem = createViewListItemElement( viewWriter );\n\n\tconst viewList = viewWriter.createContainerElement( listType, null );\n\n\tviewWriter.insert( viewWriter.createPositionAt( viewList, 0 ), viewItem );\n\n\tmapper.bindElements( modelItem, viewItem );\n\n\treturn viewItem;\n}\n\n/**\n * Helper function that inserts a view list at a correct place and merges it with its siblings.\n * It takes a model list item element (`modelItem`) and a corresponding view list item element (`injectedItem`). The view list item\n * should be in a view list element (`<ul>` or `<ol>`) and should be its only child.\n * See comments below to better understand the algorithm.\n *\n * @param {module:engine/view/item~Item} modelItem Model list item.\n * @param {module:engine/view/containerelement~ContainerElement} injectedItem\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface.\n * @param {module:engine/model/model~Model} model The model instance.\n */\nexport function injectViewList( modelItem, injectedItem, conversionApi, model ) {\n\tconst injectedList = injectedItem.parent;\n\tconst mapper = conversionApi.mapper;\n\tconst viewWriter = conversionApi.writer;\n\n\t// The position where the view list will be inserted.\n\tlet insertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\n\t// 1. Find the previous list item that has the same or smaller indent. Basically we are looking for the first model item\n\t// that is a \"parent\" or \"sibling\" of the injected model item.\n\t// If there is no such list item, it means that the injected list item is the first item in \"its list\".\n\tconst refItem = getSiblingListItem( modelItem.previousSibling, {\n\t\tsameIndent: true,\n\t\tsmallerIndent: true,\n\t\tlistIndent: modelItem.getAttribute( 'listIndent' )\n\t} );\n\tconst prevItem = modelItem.previousSibling;\n\n\tif ( refItem && refItem.getAttribute( 'listIndent' ) == modelItem.getAttribute( 'listIndent' ) ) {\n\t\t// There is a list item with the same indent - we found the same-level sibling.\n\t\t// Break the list after it. The inserted view item will be added in the broken space.\n\t\tconst viewItem = mapper.toViewElement( refItem );\n\t\tinsertPosition = viewWriter.breakContainer( viewWriter.createPositionAfter( viewItem ) );\n\t} else {\n\t\t// There is no list item with the same indent. Check the previous model item.\n\t\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\t\t// If it is a list item, it has to have a lower indent.\n\t\t\t// It means that the inserted item should be added to it as its nested item.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionAt( prevItem, 'end' ) );\n\n\t\t\t// There could be some not mapped elements (eg. span in to-do list) but we need to insert\n\t\t\t// a nested list directly inside the li element.\n\t\t\tconst mappedViewAncestor = mapper.findMappedViewAncestor( insertPosition );\n\t\t\tconst nestedList = findNestedList( mappedViewAncestor );\n\n\t\t\t// If there already is some nested list, then use it's position.\n\t\t\tif ( nestedList ) {\n\t\t\t\tinsertPosition = viewWriter.createPositionBefore( nestedList );\n\t\t\t} else {\n\t\t\t\t// Else just put new list on the end of list item content.\n\t\t\t\tinsertPosition = viewWriter.createPositionAt( mappedViewAncestor, 'end' );\n\t\t\t}\n\t\t} else {\n\t\t\t// The previous item is not a list item (or does not exist at all).\n\t\t\t// Just map the position and insert the view item at the mapped position.\n\t\t\tinsertPosition = mapper.toViewPosition( model.createPositionBefore( modelItem ) );\n\t\t}\n\t}\n\n\tinsertPosition = positionAfterUiElements( insertPosition );\n\n\t// Insert the view item.\n\tviewWriter.insert( insertPosition, injectedList );\n\n\t// 2. Handle possible children of the injected model item.\n\tif ( prevItem && prevItem.name == 'listItem' ) {\n\t\tconst prevView = mapper.toViewElement( prevItem );\n\n\t\tconst walkerBoundaries = viewWriter.createRange( viewWriter.createPositionAt( prevView, 0 ), insertPosition );\n\t\tconst walker = walkerBoundaries.getWalker( { ignoreElementEnd: true } );\n\n\t\tfor ( const value of walker ) {\n\t\t\tif ( value.item.is( 'element', 'li' ) ) {\n\t\t\t\tconst breakPosition = viewWriter.breakContainer( viewWriter.createPositionBefore( value.item ) );\n\t\t\t\tconst viewList = value.item.parent;\n\n\t\t\t\tconst targetPosition = viewWriter.createPositionAt( injectedItem, 'end' );\n\t\t\t\tmergeViewLists( viewWriter, targetPosition.nodeBefore, targetPosition.nodeAfter );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( viewList ), targetPosition );\n\n\t\t\t\twalker.position = breakPosition;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tconst nextViewList = injectedList.nextSibling;\n\n\t\tif ( nextViewList && ( nextViewList.is( 'element', 'ul' ) || nextViewList.is( 'element', 'ol' ) ) ) {\n\t\t\tlet lastSubChild = null;\n\n\t\t\tfor ( const child of nextViewList.getChildren() ) {\n\t\t\t\tconst modelChild = mapper.toModelElement( child );\n\n\t\t\t\tif ( modelChild && modelChild.getAttribute( 'listIndent' ) > modelItem.getAttribute( 'listIndent' ) ) {\n\t\t\t\t\tlastSubChild = child;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( lastSubChild ) {\n\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionAfter( lastSubChild ) );\n\t\t\t\tviewWriter.move( viewWriter.createRangeOn( lastSubChild.parent ), viewWriter.createPositionAt( injectedItem, 'end' ) );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Merge the inserted view list with its possible neighbor lists.\n\tmergeViewLists( viewWriter, injectedList, injectedList.nextSibling );\n\tmergeViewLists( viewWriter, injectedList.previousSibling, injectedList );\n}\n\n/**\n * Helper function that takes two parameters that are expected to be view list elements, and merges them.\n * The merge happens only if both parameters are list elements of the same type (the same element name and the same class attributes).\n *\n * @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter The writer instance.\n * @param {module:engine/view/item~Item} firstList The first element to compare.\n * @param {module:engine/view/item~Item} secondList The second element to compare.\n * @returns {module:engine/view/position~Position|null} The position after merge or `null` when there was no merge.\n */\nexport function mergeViewLists( viewWriter, firstList, secondList ) {\n\t// Check if two lists are going to be merged.\n\tif ( !firstList || !secondList || ( firstList.name != 'ul' && firstList.name != 'ol' ) ) {\n\t\treturn null;\n\t}\n\n\t// Both parameters are list elements, so compare types now.\n\tif ( firstList.name != secondList.name || firstList.getAttribute( 'class' ) !== secondList.getAttribute( 'class' ) ) {\n\t\treturn null;\n\t}\n\n\treturn viewWriter.mergeContainers( viewWriter.createPositionAfter( firstList ) );\n}\n\n/**\n * Helper function that for a given `view.Position`, returns a `view.Position` that is after all `view.UIElement`s that\n * are after the given position.\n *\n * For example:\n * `<container:p>foo^<ui:span></ui:span><ui:span></ui:span>bar</container:p>`\n * For position ^, the position before \"bar\" will be returned.\n *\n * @param {module:engine/view/position~Position} viewPosition\n * @returns {module:engine/view/position~Position}\n */\nexport function positionAfterUiElements( viewPosition ) {\n\treturn viewPosition.getLastMatchingPosition( value => value.item.is( 'uiElement' ) );\n}\n\n/**\n * Helper function that searches for a previous list item sibling of a given model item that meets the given criteria\n * passed by the options object.\n *\n * @param {module:engine/model/item~Item} modelItem\n * @param {Object} options Search criteria.\n * @param {Boolean} [options.sameIndent=false] Whether the sought sibling should have the same indentation.\n * @param {Boolean} [options.smallerIndent=false] Whether the sought sibling should have a smaller indentation.\n * @param {Number} [options.listIndent] The reference indentation.\n * @param {'forward'|'backward'} [options.direction='backward'] Walking direction.\n * @returns {module:engine/model/item~Item|null}\n */\nexport function getSiblingListItem( modelItem, options ) {\n\tconst sameIndent = !!options.sameIndent;\n\tconst smallerIndent = !!options.smallerIndent;\n\tconst indent = options.listIndent;\n\n\tlet item = modelItem;\n\n\twhile ( item && item.name == 'listItem' ) {\n\t\tconst itemIndent = item.getAttribute( 'listIndent' );\n\n\t\tif ( ( sameIndent && indent == itemIndent ) || ( smallerIndent && indent > itemIndent ) ) {\n\t\t\treturn item;\n\t\t}\n\n\t\tif ( options.direction === 'forward' ) {\n\t\t\titem = item.nextSibling;\n\t\t} else {\n\t\t\titem = item.previousSibling;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Helper method for creating a UI button and linking it with an appropriate command.\n *\n * @private\n * @param {module:core/editor/editor~Editor} editor The editor instance to which the UI component will be added.\n * @param {String} commandName The name of the command.\n * @param {String} label The button label.\n * @param {String} icon The source of the icon.\n */\nexport function createUIComponent( editor, commandName, label, icon ) {\n\teditor.ui.componentFactory.add( commandName, locale => {\n\t\tconst command = editor.commands.get( commandName );\n\t\tconst buttonView = new ButtonView( locale );\n\n\t\tbuttonView.set( {\n\t\t\tlabel,\n\t\t\ticon,\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\t// Bind button model to command.\n\t\tbuttonView.bind( 'isOn', 'isEnabled' ).to( command, 'value', 'isEnabled' );\n\n\t\t// Execute command.\n\t\tbuttonView.on( 'execute', () => {\n\t\t\teditor.execute( commandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn buttonView;\n\t} );\n}\n\n/**\n * Returns a first list view element that is direct child of the given view element.\n *\n * @param {module:engine/view/element~Element} viewElement\n * @return {module:engine/view/element~Element|null}\n */\nexport function findNestedList( viewElement ) {\n\tfor ( const node of viewElement.getChildren() ) {\n\t\tif ( node.name == 'ul' || node.name == 'ol' ) {\n\t\t\treturn node;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Returns an array with all `listItem` elements that represent the same list.\n *\n * It means that values of `listIndent`, `listType`, `listStyle`, `listReversed` and `listStart` for all items are equal.\n *\n * Additionally, if the `position` is inside a list item, that list item will be returned as well.\n *\n * @param {module:engine/model/position~Position} position Starting position.\n * @param {'forward'|'backward'} direction Walking direction.\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getSiblingNodes( position, direction ) {\n\tconst items = [];\n\tconst listItem = position.parent;\n\tconst walkerOptions = {\n\t\tignoreElementEnd: false,\n\t\tstartPosition: position,\n\t\tshallow: true,\n\t\tdirection\n\t};\n\tconst limitIndent = listItem.getAttribute( 'listIndent' );\n\tconst nodes = [ ...new TreeWalker( walkerOptions ) ]\n\t\t.filter( value => value.item.is( 'element' ) )\n\t\t.map( value => value.item );\n\n\tfor ( const element of nodes ) {\n\t\t// If found something else than `listItem`, we're out of the list scope.\n\t\tif ( !element.is( 'element', 'listItem' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// If current parsed item has lower indent that element that the element that was a starting point,\n\t\t// it means we left a nested list. Abort searching items.\n\t\t//\n\t\t// ■ List item 1. [listIndent=0]\n\t\t// ○ List item 2.[] [listIndent=1], limitIndent = 1,\n\t\t// ○ List item 3. [listIndent=1]\n\t\t// ■ List item 4. [listIndent=0]\n\t\t//\n\t\t// Abort searching when leave nested list.\n\t\tif ( element.getAttribute( 'listIndent' ) < limitIndent ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ■ List item 1.[] [listIndent=0] limitIndent = 0,\n\t\t// ○ List item 2. [listIndent=1]\n\t\t// ○ List item 3. [listIndent=1]\n\t\t// ■ List item 4. [listIndent=0]\n\t\t//\n\t\t// Ignore nested lists.\n\t\tif ( element.getAttribute( 'listIndent' ) > limitIndent ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// ■ List item 1.[] [listType=bulleted]\n\t\t// 1. List item 2. [listType=numbered]\n\t\t// 2.List item 3. [listType=numbered]\n\t\t//\n\t\t// Abort searching when found a different kind of a list.\n\t\tif ( element.getAttribute( 'listType' ) !== listItem.getAttribute( 'listType' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ■ List item 1.[] [listType=bulleted]\n\t\t// ■ List item 2. [listType=bulleted]\n\t\t// ○ List item 3. [listType=bulleted]\n\t\t// ○ List item 4. [listType=bulleted]\n\t\t//\n\t\t// Abort searching when found a different list style,\n\t\tif ( element.getAttribute( 'listStyle' ) !== listItem.getAttribute( 'listStyle' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ... different direction\n\t\tif ( element.getAttribute( 'listReversed' ) !== listItem.getAttribute( 'listReversed' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\t// ... and different start index\n\t\tif ( element.getAttribute( 'listStart' ) !== listItem.getAttribute( 'listStart' ) ) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif ( direction === 'backward' ) {\n\t\t\titems.unshift( element );\n\t\t} else {\n\t\t\titems.push( element );\n\t\t}\n\t}\n\n\treturn items;\n}\n\n/**\n * Returns an array with all `listItem` elements in the model selection.\n *\n * It returns all the items even if only a part of the list is selected, including items that belong to nested lists.\n * If no list is selected, it returns an empty array.\n * The order of the elements is not specified.\n *\n * @protected\n * @param {module:engine/model/model~Model} model\n * @returns {Array.<module:engine/model/element~Element>}\n */\nexport function getSelectedListItems( model ) {\n\tconst document = model.document;\n\n\t// For all selected blocks find all list items that are being selected\n\t// and update the `listStyle` attribute in those lists.\n\tlet listItems = [ ...document.selection.getSelectedBlocks() ]\n\t\t.filter( element => element.is( 'element', 'listItem' ) )\n\t\t.map( element => {\n\t\t\tconst position = model.change( writer => writer.createPositionAt( element, 0 ) );\n\n\t\t\treturn [\n\t\t\t\t...getSiblingNodes( position, 'backward' ),\n\t\t\t\t...getSiblingNodes( position, 'forward' )\n\t\t\t];\n\t\t} )\n\t\t.flat();\n\n\t// Since `getSelectedBlocks()` can return items that belong to the same list, and\n\t// `getSiblingNodes()` returns the entire list, we need to remove duplicated items.\n\tlistItems = [ ...new Set( listItems ) ];\n\n\treturn listItems;\n}\n\nconst BULLETED_LIST_STYLE_TYPES = [ 'disc', 'circle', 'square' ];\n\n// There's a lot of them (https://www.w3.org/TR/css-counter-styles-3/#typedef-counter-style).\n// Let's support only those that can be selected by ListPropertiesUI.\nconst NUMBERED_LIST_STYLE_TYPES = [\n\t'decimal',\n\t'decimal-leading-zero',\n\t'lower-roman',\n\t'upper-roman',\n\t'lower-latin',\n\t'upper-latin'\n];\n\n/**\n * Checks whether the given list-style-type is supported by numbered or bulleted list.\n *\n * @param {String} listStyleType\n * @returns {'bulleted'|'numbered'|null}\n */\nexport function getListTypeFromListStyleType( listStyleType ) {\n\tif ( BULLETED_LIST_STYLE_TYPES.includes( listStyleType ) ) {\n\t\treturn 'bulleted';\n\t}\n\n\tif ( NUMBERED_LIST_STYLE_TYPES.includes( listStyleType ) ) {\n\t\treturn 'numbered';\n\t}\n\n\treturn null;\n}\n\n// Implementation of getFillerOffset for view list item element.\n//\n// @returns {Number|null} Block filler offset or `null` if block filler is not needed.\nfunction getListItemFillerOffset() {\n\tconst hasOnlyLists = !this.isEmpty && ( this.getChild( 0 ).name == 'ul' || this.getChild( 0 ).name == 'ol' );\n\n\tif ( this.isEmpty || hasOnlyLists ) {\n\t\treturn 0;\n\t}\n\n\treturn getFillerOffset.call( this );\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 list/listproperties\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ListPropertiesEditing from './listproperties/listpropertiesediting';\nimport ListPropertiesUI from './listproperties/listpropertiesui';\n\n/**\n * The list properties feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/listproperties/listpropertiesediting~ListPropertiesEditing list properties\n * editing feature} and the {@link module:list/listproperties/listpropertiesui~ListPropertiesUI list properties UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListProperties extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListPropertiesEditing, ListPropertiesUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListProperties';\n\t}\n}\n\n/**\n * The configuration of the {@link module:list/listproperties~ListProperties list properties} feature and the\n * {@link module:list/documentlistproperties~DocumentListProperties document list properties} feature.\n *\n * This configuration controls the individual list properties. For instance, it enables or disables specific editor commands\n * operating on lists ({@link module:list/listproperties/liststylecommand~ListStyleCommand `'listStyle'`},\n * {@link module:list/listproperties/liststartcommand~ListStartCommand `'listStart'`},\n * {@link module:list/listproperties/listreversedcommand~ListReversedCommand `'listReversed'`}, or on the document lists\n * {@link module:list/documentlistproperties/documentliststylecommand~DocumentListStyleCommand `'listStyle'`},\n * {@link module:list/documentlistproperties/documentliststartcommand~DocumentListStartCommand `'listStart'`},\n * {@link module:list/documentlistproperties/documentlistreversedcommand~DocumentListReversedCommand `'listReversed'`}), the look of the UI\n * (`'numberedList'` and `'bulletedList'` dropdowns), and the editor data pipeline (allowed HTML attributes).\n *\n *\t\tClassicEditor\n *\t\t\t.create( editorElement, {\n *\t\t\t\tlist: {\n *\t\t\t\t\tproperties: {\n *\t\t\t\t\t\tstyles: true,\n *\t\t\t\t\t\tstartIndex: true,\n *\t\t\t\t\t\treversed: true\n *\t\t\t\t\t}\n *\t\t\t\t}\n *\t\t\t} )\n *\t\t\t.then( ... )\n *\t\t\t.catch( ... );\n *\n * @interface ListPropertiesConfig\n */\n\n/**\n * When set, the list style feature will be enabled. It allows changing the `list-style-type` style or the `type` HTML attribute of a list.\n *\n * **Note**: Styling using the `type` HTML attribute is only available in\n * {@link module:list/documentlistproperties~DocumentListProperties document list properties}\n * ({@link module:list/listproperties~ListPropertiesStyleConfig learn more}).\n *\n * @default true\n * @member {Boolean|module:list/listproperties~ListPropertiesStyleConfig} module:list/listproperties~ListPropertiesConfig#styles\n */\n\n/**\n * When set, the list start index feature will be enabled. It allows changing the `start` HTML attribute of the numbered lists. As a\n * result, it will be possible to specify the start value of the first item in an ordered list.\n *\n * **Note**: This configuration does not affect bulleted and to-do lists.\n *\n * @default false\n * @member {Boolean} module:list/listproperties~ListPropertiesConfig#startIndex\n */\n\n/**\n * When set, the reversed list feature will be enabled. It allows changing the `reversed` HTML attribute of the numbered lists. As a\n * result, it will be possible to make the list order descending instead of ascending.\n *\n * **Note**: This configuration does not affect bulleted and to-do lists.\n *\n * @default false\n * @member {Boolean} module:list/listproperties~ListPropertiesConfig#reversed\n */\n\n/**\n * The configuration of the {@link module:list/listproperties~ListProperties} feature and the\n * {@link module:list/documentlistproperties~DocumentListProperties document list properties} feature.\n *\n * Read more in {@link module:list/listproperties~ListPropertiesConfig}.\n *\n * @member {module:list/listproperties~ListPropertiesConfig} module:list/list~ListConfig#properties\n */\n\n/**\n * @interface ListPropertiesStyleConfig\n */\n\n/**\n * When set `true`, the list style feature will use the `type` attribute of `<ul>` and `<ol>` elements instead of the `list-style-type`\n * style.\n *\n *\t\t{\n *\t\t\tlist: {\n *\t\t\t\tproperties: {\n *\t\t\t\t\tstyles: {\n *\t\t\t\t\t\tuseAttribute: true\n *\t\t\t\t\t},\n *\n *\t\t\t\t\t// ...\n *\t\t\t\t}\n *\t\t\t},\n *\n *\t\t\t// ...\n *\t\t}\n *\n * **Note**: Due to limitations of HTML, the \"Decimal with leading zero\" style is impossible to set using the `type` attribute.\n *\n * **Note**: This configuration works only with {@link module:list/documentlistproperties~DocumentListProperties document list properties}.\n *\n * @default false\n * @member {Boolean} module:list/listproperties~ListPropertiesStyleConfig#useAttribute\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 list/listproperties/listpropertiesediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport ListEditing from '../list/listediting';\nimport ListStyleCommand from './liststylecommand';\nimport ListReversedCommand from './listreversedcommand';\nimport ListStartCommand from './liststartcommand';\nimport { getSiblingListItem, getSiblingNodes } from '../list/utils';\n\nconst DEFAULT_LIST_TYPE = 'default';\n\n/**\n * The engine of the list properties feature.\n *\n * It sets the value for the `listItem` attribute of the {@link module:list/list~List `<listItem>`} element that\n * allows modifying the list style type.\n *\n * It registers the `'listStyle'`, `'listReversed'` and `'listStart'` commands if they are enabled in the configuration.\n * Read more in {@link module:list/listproperties~ListPropertiesConfig}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListPropertiesEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListPropertiesEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\teditor.config.define( 'list', {\n\t\t\tproperties: {\n\t\t\t\tstyles: true,\n\t\t\t\tstartIndex: false,\n\t\t\t\treversed: false\n\t\t\t}\n\t\t} );\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\tconst enabledProperties = editor.config.get( 'list.properties' );\n\t\tconst strategies = createAttributeStrategies( enabledProperties );\n\n\t\t// Extend schema.\n\t\tmodel.schema.extend( 'listItem', {\n\t\t\tallowAttributes: strategies.map( s => s.attributeName )\n\t\t} );\n\n\t\tfor ( const strategy of strategies ) {\n\t\t\tstrategy.addCommand( editor );\n\t\t}\n\n\t\t// Fix list attributes when modifying their nesting levels (the `listIndent` attribute).\n\t\tthis.listenTo( editor.commands.get( 'indentList' ), '_executeCleanup', fixListAfterIndentListCommand( editor, strategies ) );\n\t\tthis.listenTo( editor.commands.get( 'outdentList' ), '_executeCleanup', fixListAfterOutdentListCommand( editor, strategies ) );\n\n\t\tthis.listenTo( editor.commands.get( 'bulletedList' ), '_executeCleanup', restoreDefaultListStyle( editor ) );\n\t\tthis.listenTo( editor.commands.get( 'numberedList' ), '_executeCleanup', restoreDefaultListStyle( editor ) );\n\n\t\t// Register a post-fixer that ensures that the attributes is specified in each `listItem` element.\n\t\tmodel.document.registerPostFixer( fixListAttributesOnListItemElements( editor, strategies ) );\n\n\t\t// Set up conversion.\n\t\teditor.conversion.for( 'upcast' ).add( upcastListItemAttributes( strategies ) );\n\t\teditor.conversion.for( 'downcast' ).add( downcastListItemAttributes( strategies ) );\n\n\t\t// Handle merging two separated lists into the single one.\n\t\tthis._mergeListAttributesWhileMergingLists( strategies );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tafterInit() {\n\t\tconst editor = this.editor;\n\n\t\t// Enable post-fixer that removes the attributes from to-do list items only if the \"TodoList\" plugin is on.\n\t\t// We need to registry the hook here since the `TodoList` plugin can be added after the `ListPropertiesEditing`.\n\t\tif ( editor.commands.get( 'todoList' ) ) {\n\t\t\teditor.model.document.registerPostFixer( removeListItemAttributesFromTodoList( editor ) );\n\t\t}\n\t}\n\n\t/**\n\t * Starts listening to {@link module:engine/model/model~Model#deleteContent} and checks whether two lists will be merged into a single\n\t * one after deleting the content.\n\t *\n\t * The purpose of this action is to adjust the `listStyle`, `listReversed` and `listStart` values\n\t * for the list that was merged.\n\t *\n\t * Consider the following model's content:\n\t *\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <paragraph>[A paragraph.]</paragraph>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t *\n\t * After removing the paragraph element, the second list will be merged into the first one.\n\t * We want to inherit the `listStyle` attribute for the second list from the first one.\n\t *\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t * <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t *\n\t * See https://github.com/ckeditor/ckeditor5/issues/7879.\n\t *\n\t * @private\n\t * @param {Array.<module:list/listproperties/listpropertiesediting~AttributeStrategy>} attributeStrategies Strategies for the\n\t * enabled attributes.\n\t */\n\t_mergeListAttributesWhileMergingLists( attributeStrategies ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\t// First the outer-most`listItem` in the first list reference.\n\t\t// If found, the lists should be merged and this `listItem` provides the attributes\n\t\t// and it is also a starting point when searching for items in the second list.\n\t\tlet firstMostOuterItem;\n\n\t\t// Check whether the removed content is between two lists.\n\t\tthis.listenTo( model, 'deleteContent', ( evt, [ selection ] ) => {\n\t\t\tconst firstPosition = selection.getFirstPosition();\n\t\t\tconst lastPosition = selection.getLastPosition();\n\n\t\t\t// Typing or removing content in a single item. Aborting.\n\t\t\tif ( firstPosition.parent === lastPosition.parent ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// An element before the content that will be removed is not a list.\n\t\t\tif ( !firstPosition.parent.is( 'element', 'listItem' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst nextSibling = lastPosition.parent.nextSibling;\n\n\t\t\t// An element after the content that will be removed is not a list.\n\t\t\tif ( !nextSibling || !nextSibling.is( 'element', 'listItem' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Find the outermost list item based on the `listIndent` attribute. We can't assume that `listIndent=0`\n\t\t\t// because the selection can be hooked in nested lists.\n\t\t\t//\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List [item 1.1</listItem>\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1.</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"circle\">UL List ]item 1.1</listItem>\n\t\t\t//\n\t\t\t// After deleting the content, we would like to inherit the \"square\" attribute for the last element:\n\t\t\t//\n\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t// <listItem listIndent=\"1\" listType=\"bulleted\" listStyle=\"square\">UL List []item 1.1</listItem>\n\t\t\tconst mostOuterItemList = getSiblingListItem( firstPosition.parent, {\n\t\t\t\tsameIndent: true,\n\t\t\t\tlistIndent: nextSibling.getAttribute( 'listIndent' )\n\t\t\t} );\n\n\t\t\t// The outermost list item may not exist while removing elements between lists with different value\n\t\t\t// of the `listIndent` attribute. In such a case we don't want to update anything. See: #8073.\n\t\t\tif ( !mostOuterItemList ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( mostOuterItemList.getAttribute( 'listType' ) === nextSibling.getAttribute( 'listType' ) ) {\n\t\t\t\tfirstMostOuterItem = mostOuterItemList;\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// If so, update the `listStyle` attribute for the second list.\n\t\tthis.listenTo( model, 'deleteContent', () => {\n\t\t\tif ( !firstMostOuterItem ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tmodel.change( writer => {\n\t\t\t\t// Find the first most-outer item list in the merged list.\n\t\t\t\t// A case when the first list item in the second list was merged into the last item in the first list.\n\t\t\t\t//\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 1</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"square\">UL List item 2</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">[]UL List item 1</listItem>\n\t\t\t\t// <listItem listIndent=\"0\" listType=\"bulleted\" listStyle=\"circle\">UL List item 2</listItem>\n\t\t\t\tconst secondListMostOuterItem = getSiblingListItem( firstMostOuterItem.nextSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: firstMostOuterItem.getAttribute( 'listIndent' ),\n\t\t\t\t\tdirection: 'forward'\n\t\t\t\t} );\n\n\t\t\t\t// If the selection ends in a non-list element, there are no <listItem>s that would require adjustments.\n\t\t\t\t// See: #8642.\n\t\t\t\tif ( !secondListMostOuterItem ) {\n\t\t\t\t\tfirstMostOuterItem = null;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst items = [\n\t\t\t\t\tsecondListMostOuterItem,\n\t\t\t\t\t...getSiblingNodes( writer.createPositionAt( secondListMostOuterItem, 0 ), 'forward' )\n\t\t\t\t];\n\n\t\t\t\tfor ( const listItem of items ) {\n\t\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\t\tif ( strategy.appliesToListItem( listItem ) ) {\n\t\t\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\t\t\tconst value = firstMostOuterItem.getAttribute( attributeName );\n\n\t\t\t\t\t\t\twriter.setAttribute( attributeName, value, listItem );\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\tfirstMostOuterItem = null;\n\t\t}, { priority: 'low' } );\n\t}\n}\n\n/**\n * Strategy for dealing with `listItem` attributes supported by this plugin.\n *\n * @typedef {Object} AttributeStrategy\n * @private\n * @property {String} #attributeName\n * @property {*} #defaultValue\n * @property {Function} #addCommand\n * @property {Function} #appliesToListItem\n * @property {Function} #setAttributeOnDowncast\n * @property {Function} #getAttributeOnUpcast\n*/\n\n// Creates an array of strategies for dealing with enabled listItem attributes.\n//\n// @param {Object} enabledProperties\n// @param {Boolean} enabledProperties.styles\n// @param {Boolean} enabledProperties.reversed\n// @param {Boolean} enabledProperties.startIndex\n// @returns {Array.<module:list/listpropertiesediting~AttributeStrategy>}\nfunction createAttributeStrategies( enabledProperties ) {\n\tconst strategies = [];\n\n\tif ( enabledProperties.styles ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStyle',\n\t\t\tdefaultValue: DEFAULT_LIST_TYPE,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStyle', new ListStyleCommand( editor, DEFAULT_LIST_TYPE ) );\n\t\t\t},\n\n\t\t\tappliesToListItem() {\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStyle, element ) {\n\t\t\t\tif ( listStyle && listStyle !== DEFAULT_LIST_TYPE ) {\n\t\t\t\t\twriter.setStyle( 'list-style-type', listStyle, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeStyle( 'list-style-type', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getStyle( 'list-style-type' ) || DEFAULT_LIST_TYPE;\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listReversed',\n\t\t\tdefaultValue: false,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listReversed', new ListReversedCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listReversed, element ) {\n\t\t\t\tif ( listReversed ) {\n\t\t\t\t\twriter.setAttribute( 'reversed', 'reversed', element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'reversed', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.hasAttribute( 'reversed' );\n\t\t\t}\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tstrategies.push( {\n\t\t\tattributeName: 'listStart',\n\t\t\tdefaultValue: 1,\n\n\t\t\taddCommand( editor ) {\n\t\t\t\teditor.commands.add( 'listStart', new ListStartCommand( editor ) );\n\t\t\t},\n\n\t\t\tappliesToListItem( item ) {\n\t\t\t\treturn item.getAttribute( 'listType' ) == 'numbered';\n\t\t\t},\n\n\t\t\tsetAttributeOnDowncast( writer, listStart, element ) {\n\t\t\t\tif ( listStart != 1 ) {\n\t\t\t\t\twriter.setAttribute( 'start', listStart, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( 'start', element );\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tgetAttributeOnUpcast( listParent ) {\n\t\t\t\treturn listParent.getAttribute( 'start' ) || 1;\n\t\t\t}\n\t\t} );\n\t}\n\n\treturn strategies;\n}\n\n// Returns a converter consumes the `style`, `reversed` and `start` attribute.\n// In `style` it searches for the `list-style-type` definition.\n// If not found, the `\"default\"` value will be used.\n//\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction upcastListItemAttributes( attributeStrategies ) {\n\treturn dispatcher => {\n\t\tdispatcher.on( 'element:li', ( evt, data, conversionApi ) => {\n\t\t\tconst listParent = data.viewItem.parent;\n\n\t\t\t// It may happen that the native spell checker fixes a word inside a list item.\n\t\t\t// When the children mutation is fired, the `<li>` does not have the parent element. See: #9325.\n\t\t\tif ( !listParent ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst listItem = data.modelRange.start.nodeAfter || data.modelRange.end.nodeBefore;\n\n\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\tif ( strategy.appliesToListItem( listItem ) ) {\n\t\t\t\t\tconst listStyle = strategy.getAttributeOnUpcast( listParent );\n\t\t\t\t\tconversionApi.writer.setAttribute( strategy.attributeName, listStyle, listItem );\n\t\t\t\t}\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t};\n}\n\n// Returns a converter that adds `reversed`, `start` attributes and adds `list-style-type` definition as a value for the `style` attribute.\n// The `\"default\"` values are removed and not present in the view/data.\n//\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction downcastListItemAttributes( attributeStrategies ) {\n\treturn dispatcher => {\n\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\tdispatcher.on( `attribute:${ strategy.attributeName }:listItem`, ( evt, data, conversionApi ) => {\n\t\t\t\tconst viewWriter = conversionApi.writer;\n\t\t\t\tconst currentElement = data.item;\n\n\t\t\t\tconst previousElement = getSiblingListItem( currentElement.previousSibling, {\n\t\t\t\t\tsameIndent: true,\n\t\t\t\t\tlistIndent: currentElement.getAttribute( 'listIndent' ),\n\t\t\t\t\tdirection: 'backward'\n\t\t\t\t} );\n\n\t\t\t\tconst viewItem = conversionApi.mapper.toViewElement( currentElement );\n\n\t\t\t\t// A case when elements represent different lists. We need to separate their container.\n\t\t\t\tif ( !areRepresentingSameList( currentElement, previousElement ) ) {\n\t\t\t\t\tviewWriter.breakContainer( viewWriter.createPositionBefore( viewItem ) );\n\t\t\t\t}\n\t\t\t\tstrategy.setAttributeOnDowncast( viewWriter, data.attributeNewValue, viewItem.parent );\n\t\t\t}, { priority: 'low' } );\n\t\t}\n\t};\n\n\t// Checks whether specified list items belong to the same list.\n\t//\n\t// @param {module:engine/model/element~Element} `listItem1` The first list item to check.\n\t// @param {module:engine/model/element~Element|null} `listItem2` The second list item to check.\n\t// @returns {Boolean}\n\tfunction areRepresentingSameList( listItem1, listItem2 ) {\n\t\treturn listItem2 &&\n\t\t\tlistItem1.getAttribute( 'listType' ) === listItem2.getAttribute( 'listType' ) &&\n\t\t\tlistItem1.getAttribute( 'listIndent' ) === listItem2.getAttribute( 'listIndent' ) &&\n\t\t\tlistItem1.getAttribute( 'listStyle' ) === listItem2.getAttribute( 'listStyle' ) &&\n\t\t\tlistItem1.getAttribute( 'listReversed' ) === listItem2.getAttribute( 'listReversed' ) &&\n\t\t\tlistItem1.getAttribute( 'listStart' ) === listItem2.getAttribute( 'listStart' );\n\t}\n}\n\n// When indenting list, nested list should clear its value for the attributes or inherit from nested lists.\n//\n// ■ List item 1.\n// ■ List item 2.[]\n// ■ List item 3.\n// editor.execute( 'indentList' );\n//\n// ■ List item 1.\n// ○ List item 2.[]\n// ■ List item 3.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction fixListAfterIndentListCommand( editor, attributeStrategies ) {\n\treturn ( evt, changedItems ) => {\n\t\tconst root = changedItems[ 0 ];\n\t\tconst rootIndent = root.getAttribute( 'listIndent' );\n\n\t\tconst itemsToUpdate = changedItems.filter( item => item.getAttribute( 'listIndent' ) === rootIndent );\n\n\t\t// A case where a few list items are indented must be checked separately\n\t\t// since `getSiblingListItem()` returns the first changed element.\n\t\t// ■ List item 1.\n\t\t// ○ [List item 2.\n\t\t// ○ List item 3.]\n\t\t// ■ List item 4.\n\t\t//\n\t\t// List items: `2` and `3` should be adjusted.\n\t\tlet previousSibling = null;\n\n\t\tif ( root.previousSibling.getAttribute( 'listIndent' ) + 1 !== rootIndent ) {\n\t\t\tpreviousSibling = getSiblingListItem( root.previousSibling, {\n\t\t\t\tsameIndent: true, direction: 'backward', listIndent: rootIndent\n\t\t\t} );\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\tfor ( const item of itemsToUpdate ) {\n\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\tif ( strategy.appliesToListItem( item ) ) {\n\t\t\t\t\t\tconst valueToSet = previousSibling == null ?\n\t\t\t\t\t\t\tstrategy.defaultValue :\n\t\t\t\t\t\t\tpreviousSibling.getAttribute( strategy.attributeName );\n\n\t\t\t\t\t\twriter.setAttribute( strategy.attributeName, valueToSet, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// When outdenting a list, a nested list should copy attribute values\n// from the previous sibling list item including the same value for the `listIndent` value.\n//\n// ■ List item 1.\n// ○ List item 2.[]\n// ■ List item 3.\n//\n// editor.execute( 'outdentList' );\n//\n// ■ List item 1.\n// ■ List item 2.[]\n// ■ List item 3.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction fixListAfterOutdentListCommand( editor, attributeStrategies ) {\n\treturn ( evt, changedItems ) => {\n\t\tchangedItems = changedItems.reverse().filter( item => item.is( 'element', 'listItem' ) );\n\n\t\tif ( !changedItems.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst indent = changedItems[ 0 ].getAttribute( 'listIndent' );\n\t\tconst listType = changedItems[ 0 ].getAttribute( 'listType' );\n\t\tlet listItem = changedItems[ 0 ].previousSibling;\n\n\t\t// ■ List item 1.\n\t\t// ○ List item 2.\n\t\t// ○ List item 3.[]\n\t\t// ■ List item 4.\n\t\t//\n\t\t// After outdenting a list, `List item 3` should inherit the `listStyle` attribute from `List item 1`.\n\t\t//\n\t\t// ■ List item 1.\n\t\t// ○ List item 2.\n\t\t// ■ List item 3.[]\n\t\t// ■ List item 4.\n\t\tif ( listItem.is( 'element', 'listItem' ) ) {\n\t\t\twhile ( listItem.getAttribute( 'listIndent' ) !== indent ) {\n\t\t\t\tlistItem = listItem.previousSibling;\n\t\t\t}\n\t\t} else {\n\t\t\tlistItem = null;\n\t\t}\n\n\t\t// Outdenting such a list should restore values based on `List item 4`.\n\t\t// ■ List item 1.[]\n\t\t// ○ List item 2.\n\t\t// ○ List item 3.\n\t\t// ■ List item 4.\n\t\tif ( !listItem ) {\n\t\t\tlistItem = changedItems[ changedItems.length - 1 ].nextSibling;\n\t\t}\n\n\t\t// And such a list should not modify anything.\n\t\t// However, `listItem` can indicate a node below the list. Be sure that we have the `listItem` element.\n\t\t// ■ List item 1.[]\n\t\t// ○ List item 2.\n\t\t// ○ List item 3.\n\t\t// <paragraph>The later if check.</paragraph>\n\t\tif ( !listItem || !listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Do not modify the list if found `listItem` represents other type of list than outdented list items.\n\t\tif ( listItem.getAttribute( 'listType' ) !== listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\teditor.model.change( writer => {\n\t\t\tconst itemsToUpdate = changedItems.filter( item => item.getAttribute( 'listIndent' ) === indent );\n\n\t\t\tfor ( const item of itemsToUpdate ) {\n\t\t\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\t\t\tif ( strategy.appliesToListItem( item ) ) {\n\t\t\t\t\t\tconst attributeName = strategy.attributeName;\n\t\t\t\t\t\tconst valueToSet = listItem.getAttribute( attributeName );\n\n\t\t\t\t\t\twriter.setAttribute( attributeName, valueToSet, item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// Each `listItem` element must have specified the `listStyle`, `listReversed` and `listStart` attributes\n// if they are enabled and supported by its `listType`.\n// This post-fixer checks whether inserted elements `listItem` elements should inherit the attribute values from\n// their sibling nodes or should use the default values.\n//\n// Paragraph[]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2. // ...\n// ■ List item 3. // ...\n//\n// editor.execute( 'bulletedList' )\n//\n// ■ Paragraph[] // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2.\n// ■ List item 3.\n//\n// It also covers a such change:\n//\n// [Paragraph 1\n// Paragraph 2]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2. // ...\n// ■ List item 3. // ...\n//\n// editor.execute( 'numberedList' )\n//\n// 1. [Paragraph 1 // [listStyle=\"default\", listType=\"numbered\"]\n// 2. Paragraph 2] // [listStyle=\"default\", listType=\"numbered\"]\n// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n// ■ List item 2. // ...\n// ■ List item 3. // ...\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.<module:list/listpropertiesediting~AttributeStrategy>} attributeStrategies\n// @returns {Function}\nfunction fixListAttributesOnListItemElements( editor, attributeStrategies ) {\n\treturn writer => {\n\t\tlet wasFixed = false;\n\n\t\tconst insertedListItems = getChangedListItems( editor.model.document.differ.getChanges() )\n\t\t\t.filter( item => {\n\t\t\t\t// Don't touch todo lists. They are handled in another post-fixer.\n\t\t\t\treturn item.getAttribute( 'listType' ) !== 'todo';\n\t\t\t} );\n\n\t\tif ( !insertedListItems.length ) {\n\t\t\treturn wasFixed;\n\t\t}\n\n\t\t// Check whether the last inserted element is next to the `listItem` element.\n\t\t//\n\t\t// ■ Paragraph[] // <-- The inserted item.\n\t\t// ■ List item 1.\n\t\tlet existingListItem = insertedListItems[ insertedListItems.length - 1 ].nextSibling;\n\n\t\t// If it doesn't, maybe the `listItem` was inserted at the end of the list.\n\t\t//\n\t\t// ■ List item 1.\n\t\t// ■ Paragraph[] // <-- The inserted item.\n\t\tif ( !existingListItem || !existingListItem.is( 'element', 'listItem' ) ) {\n\t\t\texistingListItem = insertedListItems[ 0 ].previousSibling;\n\n\t\t\tif ( existingListItem ) {\n\t\t\t\tconst indent = insertedListItems[ 0 ].getAttribute( 'listIndent' );\n\n\t\t\t\t// But we need to find a `listItem` with the `listIndent=0` attribute.\n\t\t\t\t// If doesn't, maybe the `listItem` was inserted at the end of the list.\n\t\t\t\t//\n\t\t\t\t// ■ List item 1.\n\t\t\t\t// ○ List item 2.\n\t\t\t\t// ■ Paragraph[] // <-- The inserted item.\n\t\t\t\twhile ( existingListItem.is( 'element', 'listItem' ) && existingListItem.getAttribute( 'listIndent' ) !== indent ) {\n\t\t\t\t\texistingListItem = existingListItem.previousSibling;\n\n\t\t\t\t\t// If the item does not exist, most probably there is no other content in the editor. See: #8072.\n\t\t\t\t\tif ( !existingListItem ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor ( const strategy of attributeStrategies ) {\n\t\t\tconst attributeName = strategy.attributeName;\n\n\t\t\tfor ( const item of insertedListItems ) {\n\t\t\t\tif ( !strategy.appliesToListItem( item ) ) {\n\t\t\t\t\twriter.removeAttribute( attributeName, item );\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ( !item.hasAttribute( attributeName ) ) {\n\t\t\t\t\tif ( shouldInheritListType( existingListItem, item, strategy ) ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, existingListItem.getAttribute( attributeName ), item );\n\t\t\t\t\t} else {\n\t\t\t\t\t\twriter.setAttribute( attributeName, strategy.defaultValue, item );\n\t\t\t\t\t}\n\t\t\t\t\twasFixed = true;\n\t\t\t\t} else {\n\t\t\t\t\t// Adjust the `listStyle`, `listReversed` and `listStart`\n\t\t\t\t\t// attributes for inserted (pasted) items. See #8160.\n\t\t\t\t\t//\n\t\t\t\t\t// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ [] (selection is here)\n\t\t\t\t\t//\n\t\t\t\t\t// Then, pasting a list with different attributes (listStyle, listType):\n\t\t\t\t\t//\n\t\t\t\t\t// 1. First. // [listStyle=\"decimal\", listType=\"numbered\"]\n\t\t\t\t\t// 2. Second // [listStyle=\"decimal\", listType=\"numbered\"]\n\t\t\t\t\t//\n\t\t\t\t\t// The `listType` attribute will be corrected by the `ListEditing` converters.\n\t\t\t\t\t// We need to adjust the `listStyle` attribute. Expected structure:\n\t\t\t\t\t//\n\t\t\t\t\t// ■ List item 1. // [listStyle=\"square\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ List item 1.1. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ First. // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\t// ○ Second // [listStyle=\"circle\", listType=\"bulleted\"]\n\t\t\t\t\tconst previousSibling = item.previousSibling;\n\n\t\t\t\t\tif ( shouldInheritListTypeFromPreviousItem( previousSibling, item, strategy.attributeName ) ) {\n\t\t\t\t\t\twriter.setAttribute( attributeName, previousSibling.getAttribute( attributeName ), item );\n\n\t\t\t\t\t\twasFixed = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn wasFixed;\n\t};\n}\n\n// Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n// should be copied from the `baseItem` element.\n//\n// The attribute should be copied if the inserted element does not have defined it and\n// the value for the element is other than default in the base element.\n//\n// @param {module:engine/model/element~Element|null} baseItem\n// @param {module:engine/model/element~Element} itemToChange\n// @param {module:list/listpropertiesediting~AttributeStrategy} attributeStrategy\n// @returns {Boolean}\nfunction shouldInheritListType( baseItem, itemToChange, attributeStrategy ) {\n\tif ( !baseItem ) {\n\t\treturn false;\n\t}\n\n\tconst baseListAttribute = baseItem.getAttribute( attributeStrategy.attributeName );\n\n\tif ( !baseListAttribute ) {\n\t\treturn false;\n\t}\n\n\tif ( baseListAttribute == attributeStrategy.defaultValue ) {\n\t\treturn false;\n\t}\n\n\tif ( baseItem.getAttribute( 'listType' ) !== itemToChange.getAttribute( 'listType' ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n// Checks whether the `listStyle`, `listReversed` and `listStart` attributes\n// should be copied from previous list item.\n//\n// The attribute should be copied if there's a mismatch of styles of the pasted list into a nested list.\n// Top-level lists are not normalized as we allow side-by-side list of different types.\n//\n// @param {module:engine/model/element~Element|null} previousItem\n// @param {module:engine/model/element~Element} itemToChange\n// @returns {Boolean}\nfunction shouldInheritListTypeFromPreviousItem( previousItem, itemToChange, attributeName ) {\n\tif ( !previousItem || !previousItem.is( 'element', 'listItem' ) ) {\n\t\treturn false;\n\t}\n\n\tif ( itemToChange.getAttribute( 'listType' ) !== previousItem.getAttribute( 'listType' ) ) {\n\t\treturn false;\n\t}\n\n\tconst previousItemIndent = previousItem.getAttribute( 'listIndent' );\n\n\tif ( previousItemIndent < 1 || previousItemIndent !== itemToChange.getAttribute( 'listIndent' ) ) {\n\t\treturn false;\n\t}\n\n\tconst previousItemListAttribute = previousItem.getAttribute( attributeName );\n\n\tif ( !previousItemListAttribute || previousItemListAttribute === itemToChange.getAttribute( attributeName ) ) {\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n// Removes the `listStyle`, `listReversed` and `listStart` attributes from \"todo\" list items.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @returns {Function}\nfunction removeListItemAttributesFromTodoList( editor ) {\n\treturn writer => {\n\t\tconst todoListItems = getChangedListItems( editor.model.document.differ.getChanges() )\n\t\t\t.filter( item => {\n\t\t\t\t// Handle the todo lists only. The rest is handled in another post-fixer.\n\t\t\t\treturn item.getAttribute( 'listType' ) === 'todo' && (\n\t\t\t\t\titem.hasAttribute( 'listStyle' ) ||\n\t\t\t\t\titem.hasAttribute( 'listReversed' ) ||\n\t\t\t\t\titem.hasAttribute( 'listStart' )\n\t\t\t\t);\n\t\t\t} );\n\n\t\tif ( !todoListItems.length ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor ( const item of todoListItems ) {\n\t\t\twriter.removeAttribute( 'listStyle', item );\n\t\t\twriter.removeAttribute( 'listReversed', item );\n\t\t\twriter.removeAttribute( 'listStart', item );\n\t\t}\n\n\t\treturn true;\n\t};\n}\n\n// Restores the `listStyle` attribute after changing the list type.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @returns {Function}\nfunction restoreDefaultListStyle( editor ) {\n\treturn ( evt, changedItems ) => {\n\t\tchangedItems = changedItems.filter( item => item.is( 'element', 'listItem' ) );\n\n\t\teditor.model.change( writer => {\n\t\t\tfor ( const item of changedItems ) {\n\t\t\t\t// Remove the attribute. Post-fixer will restore the proper value.\n\t\t\t\twriter.removeAttribute( 'listStyle', item );\n\t\t\t}\n\t\t} );\n\t};\n}\n\n// Returns the `listItem` that was inserted or changed.\n//\n// @param {Array.<Object>} changes The changes list returned by the differ.\n// @returns {Array.<module:engine/model/element~Element>}\nfunction getChangedListItems( changes ) {\n\tconst items = [];\n\n\tfor ( const change of changes ) {\n\t\tconst item = getItemFromChange( change );\n\n\t\tif ( item && item.is( 'element', 'listItem' ) ) {\n\t\t\titems.push( item );\n\t\t}\n\t}\n\n\treturn items;\n}\n\nfunction getItemFromChange( change ) {\n\tif ( change.type === 'attribute' ) {\n\t\treturn change.range.start.nodeAfter;\n\t}\n\n\tif ( change.type === 'insert' ) {\n\t\treturn change.position.nodeAfter;\n\t}\n\n\treturn null;\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 list/listproperties/listpropertiesui\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport { ButtonView, SplitButtonView, createDropdown, focusChildOnDropdownOpen } from 'ckeditor5/src/ui';\n\nimport ListPropertiesView from './ui/listpropertiesview';\n\nimport bulletedListIcon from '../../theme/icons/bulletedlist.svg';\nimport numberedListIcon from '../../theme/icons/numberedlist.svg';\n\nimport listStyleDiscIcon from '../../theme/icons/liststyledisc.svg';\nimport listStyleCircleIcon from '../../theme/icons/liststylecircle.svg';\nimport listStyleSquareIcon from '../../theme/icons/liststylesquare.svg';\nimport listStyleDecimalIcon from '../../theme/icons/liststyledecimal.svg';\nimport listStyleDecimalWithLeadingZeroIcon from '../../theme/icons/liststyledecimalleadingzero.svg';\nimport listStyleLowerRomanIcon from '../../theme/icons/liststylelowerroman.svg';\nimport listStyleUpperRomanIcon from '../../theme/icons/liststyleupperroman.svg';\nimport listStyleLowerLatinIcon from '../../theme/icons/liststylelowerlatin.svg';\nimport listStyleUpperLatinIcon from '../../theme/icons/liststyleupperlatin.svg';\n\nimport '../../theme/liststyles.css';\n\n/**\n * The list properties UI plugin. It introduces the extended `'bulletedList'` and `'numberedList'` toolbar\n * buttons that allow users to control such aspects of list as the marker, start index or order.\n *\n * **Note**: Buttons introduced by this plugin override implementations from the {@link module:list/list/listui~ListUI}\n * (because they share the same names).\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class ListPropertiesUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'ListPropertiesUI';\n\t}\n\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst t = editor.locale.t;\n\t\tconst enabledProperties = editor.config.get( 'list.properties' );\n\n\t\t// Note: When this plugin does not register the \"bulletedList\" dropdown due to properties configuration,\n\t\t// a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n\t\t// in most editor configuration because the List plugin automatically requires ListUI.\n\t\tif ( enabledProperties.styles ) {\n\t\t\teditor.ui.componentFactory.add( 'bulletedList', getDropdownViewCreator( {\n\t\t\t\teditor,\n\t\t\t\tparentCommandName: 'bulletedList',\n\t\t\t\tbuttonLabel: t( 'Bulleted List' ),\n\t\t\t\tbuttonIcon: bulletedListIcon,\n\t\t\t\tstyleGridAriaLabel: t( 'Bulleted list styles toolbar' ),\n\t\t\t\tstyleDefinitions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the disc list style' ),\n\t\t\t\t\t\ttooltip: t( 'Disc' ),\n\t\t\t\t\t\ttype: 'disc',\n\t\t\t\t\t\ticon: listStyleDiscIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the circle list style' ),\n\t\t\t\t\t\ttooltip: t( 'Circle' ),\n\t\t\t\t\t\ttype: 'circle',\n\t\t\t\t\t\ticon: listStyleCircleIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the square list style' ),\n\t\t\t\t\t\ttooltip: t( 'Square' ),\n\t\t\t\t\t\ttype: 'square',\n\t\t\t\t\t\ticon: listStyleSquareIcon\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t} ) );\n\t\t}\n\n\t\t// Note: When this plugin does not register the \"numberedList\" dropdown due to properties configuration,\n\t\t// a simple button will be still registered under the same name by ListUI as a fallback. This should happen\n\t\t// in most editor configuration because the List plugin automatically requires ListUI.\n\t\tif ( enabledProperties.styles || enabledProperties.startIndex || enabledProperties.reversed ) {\n\t\t\teditor.ui.componentFactory.add( 'numberedList', getDropdownViewCreator( {\n\t\t\t\teditor,\n\t\t\t\tparentCommandName: 'numberedList',\n\t\t\t\tbuttonLabel: t( 'Numbered List' ),\n\t\t\t\tbuttonIcon: numberedListIcon,\n\t\t\t\tstyleGridAriaLabel: t( 'Numbered list styles toolbar' ),\n\t\t\t\tstyleDefinitions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the decimal list style' ),\n\t\t\t\t\t\ttooltip: t( 'Decimal' ),\n\t\t\t\t\t\ttype: 'decimal',\n\t\t\t\t\t\ticon: listStyleDecimalIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the decimal with leading zero list style' ),\n\t\t\t\t\t\ttooltip: t( 'Decimal with leading zero' ),\n\t\t\t\t\t\ttype: 'decimal-leading-zero',\n\t\t\t\t\t\ticon: listStyleDecimalWithLeadingZeroIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the lower–roman list style' ),\n\t\t\t\t\t\ttooltip: t( 'Lower–roman' ),\n\t\t\t\t\t\ttype: 'lower-roman',\n\t\t\t\t\t\ticon: listStyleLowerRomanIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the upper–roman list style' ),\n\t\t\t\t\t\ttooltip: t( 'Upper-roman' ),\n\t\t\t\t\t\ttype: 'upper-roman',\n\t\t\t\t\t\ticon: listStyleUpperRomanIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the lower–latin list style' ),\n\t\t\t\t\t\ttooltip: t( 'Lower-latin' ),\n\t\t\t\t\t\ttype: 'lower-latin',\n\t\t\t\t\t\ticon: listStyleLowerLatinIcon\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlabel: t( 'Toggle the upper–latin list style' ),\n\t\t\t\t\t\ttooltip: t( 'Upper-latin' ),\n\t\t\t\t\t\ttype: 'upper-latin',\n\t\t\t\t\t\ticon: listStyleUpperLatinIcon\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t} ) );\n\t\t}\n\t}\n}\n\n// A helper that returns a function that creates a split button with a toolbar in the dropdown,\n// which in turn contains buttons allowing users to change list styles in the context of the current selection.\n//\n// @param {Object} options\n// @param {module:core/editor/editor~Editor} options.editor\n// @param {'bulletedList'|'numberedList'} options.parentCommandName The name of the higher-order editor command associated with\n// the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n// @param {String} options.buttonLabel Label of the main part of the split button.\n// @param {String} options.buttonIcon The SVG string of an icon for the main part of the split button.\n// @param {String} options.styleGridAriaLabel The ARIA label for the styles grid in the split button dropdown.\n// @param {Object} options.styleDefinitions Definitions of the style buttons.\n// @returns {Function} A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\nfunction getDropdownViewCreator( { editor, parentCommandName, buttonLabel, buttonIcon, styleGridAriaLabel, styleDefinitions } ) {\n\tconst parentCommand = editor.commands.get( parentCommandName );\n\n\t// @param {module:utils/locale~Locale} locale\n\t// @returns {module:ui/dropdown/dropdownview~DropdownView}\n\treturn locale => {\n\t\tconst dropdownView = createDropdown( locale, SplitButtonView );\n\t\tconst mainButtonView = dropdownView.buttonView;\n\n\t\tdropdownView.bind( 'isEnabled' ).to( parentCommand );\n\t\tdropdownView.class = 'ck-list-styles-dropdown';\n\n\t\t// Main button was clicked.\n\t\tmainButtonView.on( 'execute', () => {\n\t\t\teditor.execute( parentCommandName );\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\tmainButtonView.set( {\n\t\t\tlabel: buttonLabel,\n\t\t\ticon: buttonIcon,\n\t\t\ttooltip: true,\n\t\t\tisToggleable: true\n\t\t} );\n\n\t\tmainButtonView.bind( 'isOn' ).to( parentCommand, 'value', value => !!value );\n\n\t\tconst listPropertiesView = createListPropertiesView( {\n\t\t\teditor,\n\t\t\tdropdownView,\n\t\t\tparentCommandName,\n\t\t\tstyleGridAriaLabel,\n\t\t\tstyleDefinitions\n\t\t} );\n\n\t\tdropdownView.panelView.children.add( listPropertiesView );\n\n\t\t// Focus the editable after executing the command.\n\t\t// Overrides a default behaviour where the focus is moved to the dropdown button (#12125).\n\t\tdropdownView.on( 'execute', () => {\n\t\t\teditor.editing.view.focus();\n\t\t} );\n\n\t\treturn dropdownView;\n\t};\n}\n\n// A helper that returns a function (factory) that creates individual buttons used by users to change styles\n// of lists.\n//\n// @param {Object} options\n// @param {module:core/editor/editor~Editor} options.editor\n// @param {module:list/liststylecommand~ListStylesCommand} options.listStyleCommand The instance of the `ListStylesCommand` class.\n// @param {'bulletedList'|'numberedList'} options.parentCommandName The name of the higher-order command associated with a\n// particular list style (e.g. \"bulletedList\" is associated with \"square\" and \"numberedList\" is associated with \"roman\").\n// @returns {Function} A function that can be passed straight into {@link module:ui/componentfactory~ComponentFactory#add}.\nfunction getStyleButtonCreator( { editor, listStyleCommand, parentCommandName } ) {\n\tconst locale = editor.locale;\n\tconst parentCommand = editor.commands.get( parentCommandName );\n\n\t// @param {String} label The label of the style button.\n\t// @param {String} type The type of the style button (e.g. \"roman\" or \"circle\").\n\t// @param {String} icon The SVG string of an icon of the style button.\n\t// @param {String} tooltip The tooltip text of the button (shorter than verbose label).\n\t// @returns {module:ui/button/buttonview~ButtonView}\n\treturn ( { label, type, icon, tooltip } ) => {\n\t\tconst button = new ButtonView( locale );\n\n\t\tbutton.set( { label, icon, tooltip } );\n\n\t\tlistStyleCommand.on( 'change:value', () => {\n\t\t\tbutton.isOn = listStyleCommand.value === type;\n\t\t} );\n\n\t\tbutton.on( 'execute', () => {\n\t\t\t// If the content the selection is anchored to is a list, let's change its style.\n\t\t\tif ( parentCommand.value ) {\n\t\t\t\t// If the current list style is not set in the model or the style is different than the\n\t\t\t\t// one to be applied, simply apply the new style.\n\t\t\t\tif ( listStyleCommand.value !== type ) {\n\t\t\t\t\teditor.execute( 'listStyle', { type } );\n\t\t\t\t}\n\t\t\t\t// If the style was the same, remove it (the button works as an off toggle).\n\t\t\t\telse {\n\t\t\t\t\teditor.execute( 'listStyle', { type: listStyleCommand._defaultType } );\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise, leave the creation of the styled list to the `ListStyleCommand`.\n\t\t\telse {\n\t\t\t\teditor.model.change( () => {\n\t\t\t\t\teditor.execute( 'listStyle', { type } );\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\n\t\treturn button;\n\t};\n}\n\n// A helper that creates the properties view for the individual style dropdown.\n//\n// @param {Object} options\n// @param {module:core/editor/editor~Editor} options.editor Editor instance.\n// @param {module:ui/dropdown/dropdownview~DropdownView} options.dropdownView Styles dropdown view that hosts the properties view.\n// @param {'bulletedList'|'numberedList'} options.parentCommandName The name of the higher-order editor command associated with\n// the set of particular list styles (e.g. \"bulletedList\" for \"disc\", \"circle\", and \"square\" styles).\n// @param {Object} options.styleDefinitions Definitions of the style buttons.\n// @param {String} options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n// @returns {module:list/ui/listpropertiesview~ListPropertiesView}\nfunction createListPropertiesView( {\n\teditor,\n\tdropdownView,\n\tparentCommandName,\n\tstyleDefinitions,\n\tstyleGridAriaLabel\n} ) {\n\tconst locale = editor.locale;\n\tconst enabledProperties = editor.config.get( 'list.properties' );\n\tlet styleButtonViews;\n\n\tif ( parentCommandName != 'numberedList' ) {\n\t\tenabledProperties.startIndex = false;\n\t\tenabledProperties.reversed = false;\n\t}\n\n\tif ( enabledProperties.styles ) {\n\t\tconst listStyleCommand = editor.commands.get( 'listStyle' );\n\n\t\tconst styleButtonCreator = getStyleButtonCreator( {\n\t\t\teditor,\n\t\t\tparentCommandName,\n\t\t\tlistStyleCommand\n\t\t} );\n\n\t\t// The command can be ListStyleCommand or DocumentListStyleCommand.\n\t\tconst isStyleTypeSupported = typeof listStyleCommand.isStyleTypeSupported == 'function' ?\n\t\t\tstyleDefinition => listStyleCommand.isStyleTypeSupported( styleDefinition.type ) :\n\t\t\t() => true;\n\n\t\tstyleButtonViews = styleDefinitions.filter( isStyleTypeSupported ).map( styleButtonCreator );\n\t}\n\n\tconst listPropertiesView = new ListPropertiesView( locale, {\n\t\tstyleGridAriaLabel,\n\t\tenabledProperties,\n\t\tstyleButtonViews\n\t} );\n\n\tif ( enabledProperties.styles ) {\n\t\t// Accessibility: focus the first active style when opening the dropdown.\n\t\tfocusChildOnDropdownOpen( dropdownView, () => {\n\t\t\treturn listPropertiesView.stylesView.children.find( child => child.isOn );\n\t\t} );\n\t}\n\n\tif ( enabledProperties.startIndex ) {\n\t\tconst listStartCommand = editor.commands.get( 'listStart' );\n\n\t\tlistPropertiesView.startIndexFieldView.bind( 'isEnabled' ).to( listStartCommand );\n\t\tlistPropertiesView.startIndexFieldView.fieldView.bind( 'value' ).to( listStartCommand );\n\t\tlistPropertiesView.on( 'listStart', ( evt, data ) => editor.execute( 'listStart', data ) );\n\t}\n\n\tif ( enabledProperties.reversed ) {\n\t\tconst listReversedCommand = editor.commands.get( 'listReversed' );\n\n\t\tlistPropertiesView.reversedSwitchButtonView.bind( 'isEnabled' ).to( listReversedCommand );\n\t\tlistPropertiesView.reversedSwitchButtonView.bind( 'isOn' ).to( listReversedCommand, 'value' );\n\t\tlistPropertiesView.on( 'listReversed', () => {\n\t\t\tconst isReversed = listReversedCommand.value;\n\n\t\t\teditor.execute( 'listReversed', { reversed: !isReversed } );\n\t\t} );\n\t}\n\n\t// Make sure applying styles closes the dropdown.\n\tlistPropertiesView.delegate( 'execute' ).to( dropdownView );\n\n\treturn listPropertiesView;\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 list/listproperties/listreversedcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getSelectedListItems } from '../list/utils';\n\n/**\n * The reversed list command. It changes the `listReversed` attribute of the selected list items. As a result, the list order will be\n * reversed.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListReversedCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {Boolean} [options.reversed=false] Whether the list should be reversed.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model )\n\t\t\t.filter( item => item.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listReversed', !!options.reversed, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn listItem.getAttribute( 'listReversed' );\n\t\t}\n\n\t\treturn null;\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 list/listproperties/liststartcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getSelectedListItems } from '../list/utils';\n\n/**\n * The list start index command. It changes the `listStart` attribute of the selected list items.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListStartCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tconst value = this._getValue();\n\t\tthis.value = value;\n\t\tthis.isEnabled = value != null;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {Number} [options.startIndex=1] The list start index.\n\t */\n\texecute( options = {} ) {\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model )\n\t\t\t.filter( item => item.getAttribute( 'listType' ) == 'numbered' );\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listStart', options.startIndex || 1, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {Boolean|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == 'numbered' ) {\n\t\t\treturn listItem.getAttribute( 'listStart' );\n\t\t}\n\n\t\treturn null;\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 list/listproperties/liststylecommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\nimport { getListTypeFromListStyleType, getSelectedListItems } from '../list/utils';\n\n/**\n * The list style command. It changes the `listStyle` attribute of the selected list items.\n *\n * If the list type (numbered or bulleted) can be inferred from the passed style type,\n * the command tries to convert selected items to a list of that type.\n * It is used by the {@link module:list/listproperties~ListProperties list properties feature}.\n *\n * @extends module:core/command~Command\n */\nexport default class ListStyleCommand extends Command {\n\t/**\n\t * Creates an instance of the command.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor The editor instance.\n\t * @param {String} defaultType The list type that will be used by default if the value was not specified during\n\t * the command execution.\n\t */\n\tconstructor( editor, defaultType ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * The default type of the list style.\n\t\t *\n\t\t * @protected\n\t\t * @member {String}\n\t\t */\n\t\tthis._defaultType = defaultType;\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trefresh() {\n\t\tthis.value = this._getValue();\n\t\tthis.isEnabled = this._checkEnabled();\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @fires execute\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style, e.g. `'disc'` or `'square'`. If `null` is specified, the default\n\t * style will be applied.\n\t */\n\texecute( options = {} ) {\n\t\tthis._tryToConvertItemsToList( options );\n\n\t\tconst model = this.editor.model;\n\t\tconst listItems = getSelectedListItems( model );\n\n\t\tif ( !listItems.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tmodel.change( writer => {\n\t\t\tfor ( const item of listItems ) {\n\t\t\t\twriter.setAttribute( 'listStyle', options.type || this._defaultType, item );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Checks the command's {@link #value}.\n\t *\n\t * @private\n\t * @returns {String|null} The current value.\n\t */\n\t_getValue() {\n\t\tconst listItem = this.editor.model.document.selection.getFirstPosition().parent;\n\n\t\tif ( listItem && listItem.is( 'element', 'listItem' ) ) {\n\t\t\treturn listItem.getAttribute( 'listStyle' );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Checks whether the command can be enabled in the current context.\n\t *\n\t * @private\n\t * @returns {Boolean} Whether the command should be enabled.\n\t */\n\t_checkEnabled() {\n\t\tconst editor = this.editor;\n\n\t\tconst numberedList = editor.commands.get( 'numberedList' );\n\t\tconst bulletedList = editor.commands.get( 'bulletedList' );\n\n\t\treturn numberedList.isEnabled || bulletedList.isEnabled;\n\t}\n\n\t/**\n\t * Check if the provided list style is valid. Also change the selection to a list if it's not set yet.\n\t *\n\t * @param {Object} options\n\t * @param {String|null} [options.type] The type of the list style. If `null` is specified, the function does nothing.\n\t * @private\n\t*/\n\t_tryToConvertItemsToList( options ) {\n\t\tif ( !options.type ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst listType = getListTypeFromListStyleType( options.type );\n\n\t\tif ( !listType ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst editor = this.editor;\n\t\tconst commandName = listType + 'List';\n\t\tconst command = editor.commands.get( commandName );\n\n\t\tif ( !command.value ) {\n\t\t\teditor.execute( commandName );\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 list/ui/collapsibleview\n */\n\nimport { View, ButtonView } from 'ckeditor5/src/ui';\n\n// eslint-disable-next-line ckeditor5-rules/ckeditor-imports\nimport dropdownArrowIcon from '@ckeditor/ckeditor5-ui/theme/icons/dropdown-arrow.svg';\n\nimport '../../../theme/collapsible.css';\n\n/**\n * A collapsible UI component. Consists of a labeled button and a container which can be collapsed\n * by clicking the button. The collapsible container can be a host to other UI views.\n *\n * @protected\n * @extends module:ui/view~View\n */\nexport default class CollapsibleView extends View {\n\t/**\n\t * Creates an instance of the collapsible view.\n\t *\n\t * @param {module:utils/locale~Locale} locale The {@link module:core/editor/editor~Editor#locale} instance.\n\t * @param {Array.<module:ui/view~View>} [childViews] An optional array of initial child views to be inserted\n\t * into the collapsible.\n\t */\n\tconstructor( locale, childViews ) {\n\t\tsuper( locale );\n\n\t\tconst bind = this.bindTemplate;\n\n\t\t/**\n\t\t * `true` when the container with {@link #children} is collapsed. `false` otherwise.\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isCollapsed\n\t\t */\n\t\tthis.set( 'isCollapsed', false );\n\n\t\t/**\n\t\t * The text label of the {@link #buttonView}.\n\t\t *\n\t\t * @observable\n\t\t * @member {String} #label\n\t\t * @default 'Show more'\n\t\t */\n\t\tthis.set( 'label', '' );\n\n\t\t/**\n\t\t * The main button that, when clicked, collapses or expands the container with {@link #children}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/button/buttonview~ButtonView} #buttonView\n\t\t */\n\t\tthis.buttonView = this._createButtonView();\n\n\t\t/**\n\t\t * A collection of the child views that can be collapsed by clicking the {@link #buttonView}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/viewcollection~ViewCollection} #children\n\t\t */\n\t\tthis.children = this.createCollection();\n\n\t\t/**\n\t\t * The ID of the label inside the {@link #buttonView} that describes the collapsible\n\t\t * container for assistive technologies. Set after the button was {@link #render rendered}.\n\t\t *\n\t\t * @private\n\t\t * @readonly\n\t\t * @observable\n\t\t * @member {String} #_collapsibleAriaLabelUid\n\t\t */\n\t\tthis.set( '_collapsibleAriaLabelUid' );\n\n\t\tif ( childViews ) {\n\t\t\tthis.children.addMany( childViews );\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-collapsible',\n\t\t\t\t\tbind.if( 'isCollapsed', 'ck-collapsible_collapsed' )\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: [\n\t\t\t\tthis.buttonView,\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: [\n\t\t\t\t\t\t\t'ck',\n\t\t\t\t\t\t\t'ck-collapsible__children'\n\t\t\t\t\t\t],\n\t\t\t\t\t\trole: 'region',\n\t\t\t\t\t\thidden: bind.if( 'isCollapsed', 'hidden' ),\n\t\t\t\t\t\t'aria-labelledby': bind.to( '_collapsibleAriaLabelUid' )\n\t\t\t\t\t},\n\t\t\t\t\tchildren: this.children\n\t\t\t\t}\n\t\t\t]\n\t\t} );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\trender() {\n\t\tsuper.render();\n\n\t\tthis._collapsibleAriaLabelUid = this.buttonView.labelView.element.id;\n\t}\n\n\t/**\n\t * Creates the main {@link #buttonView} of the collapsible.\n\t *\n\t * @private\n\t * @returns {module:ui/button/buttonview~ButtonView}\n\t */\n\t_createButtonView() {\n\t\tconst buttonView = new ButtonView( this.locale );\n\t\tconst bind = buttonView.bindTemplate;\n\n\t\tbuttonView.set( {\n\t\t\twithText: true,\n\t\t\ticon: dropdownArrowIcon\n\t\t} );\n\n\t\tbuttonView.extendTemplate( {\n\t\t\tattributes: {\n\t\t\t\t'aria-expanded': bind.to( 'isOn', value => String( value ) )\n\t\t\t}\n\t\t} );\n\n\t\tbuttonView.bind( 'label' ).to( this );\n\t\tbuttonView.bind( 'isOn' ).to( this, 'isCollapsed', isCollapsed => !isCollapsed );\n\n\t\tbuttonView.on( 'execute', () => {\n\t\t\tthis.isCollapsed = !this.isCollapsed;\n\t\t} );\n\n\t\treturn buttonView;\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 list/ui/listpropertiesview\n */\n\nimport {\n\tView,\n\tViewCollection,\n\tFocusCycler,\n\tSwitchButtonView,\n\tLabeledFieldView,\n\tcreateLabeledInputNumber,\n\taddKeyboardHandlingForGrid\n} from 'ckeditor5/src/ui';\nimport {\n\tFocusTracker,\n\tKeystrokeHandler,\n\tglobal\n} from 'ckeditor5/src/utils';\n\nimport CollapsibleView from './collapsibleview';\n\nimport '../../../theme/listproperties.css';\n\n/**\n * The list properties view to be displayed in the list dropdown.\n *\n * Contains a grid of available list styles and, for numbered list, also the list start index and reversed fields.\n *\n * @extends module:ui/view~View\n */\nexport default class ListPropertiesView extends View {\n\t/**\n\t * Creates an instance of the list properties 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 Options of the view.\n\t * @param {Object.<String,Boolean>} options.enabledProperties An object containing the configuration of enabled list property names.\n\t * Allows conditional rendering the sub-components of the properties view.\n\t * @param {Array.<module:ui/button/buttonview~ButtonView>|null} options.styleButtonViews A list of style buttons to be rendered\n\t * inside the styles grid. The grid will not be rendered when `enabledProperties` does not include the `'styles'` key.\n\t * @param {String} options.styleGridAriaLabel An assistive technologies label set on the grid of styles (if the grid is rendered).\n\t */\n\tconstructor( locale, { enabledProperties, styleButtonViews, styleGridAriaLabel } ) {\n\t\tsuper( locale );\n\n\t\tconst elementCssClasses = [\n\t\t\t'ck',\n\t\t\t'ck-list-properties'\n\t\t];\n\n\t\t/**\n\t\t * A collection of the child views.\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\t/**\n\t\t * A view that renders the grid of list styles.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/view~View|null}\n\t\t */\n\t\tthis.stylesView = null;\n\n\t\t/**\n\t\t * A collapsible view that hosts additional list property fields ({@link #startIndexFieldView} and\n\t\t * {@link #reversedSwitchButtonView}) to visually separate them from the {@link #stylesView grid of styles}.\n\t\t *\n\t\t * **Note**: Only present when:\n\t\t * * the view represents **numbered** list properties,\n\t\t * * and the {@link #stylesView} is rendered,\n\t\t * * and either {@link #startIndexFieldView} or {@link #reversedSwitchButtonView} is rendered.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:list/ui/collapsibleview~CollapsibleView|null}\n\t\t */\n\t\tthis.additionalPropertiesCollapsibleView = null;\n\n\t\t/**\n\t\t * A labeled number field allowing the user to set the start index of the list.\n\t\t *\n\t\t * **Note**: Only present when the view represents **numbered** list properties.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/labeledfield/labeledfieldview~LabeledFieldView|null}\n\t\t */\n\t\tthis.startIndexFieldView = null;\n\n\t\t/**\n\t\t * A switch button allowing the user to make the edited list reversed.\n\t\t *\n\t\t * **Note**: Only present when the view represents **numbered** list properties.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:ui/button/switchbuttonview~SwitchButtonView|null}\n\t\t */\n\t\tthis.reversedSwitchButtonView = null;\n\n\t\t/**\n\t\t * Tracks information about the DOM focus in the view.\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 views that can be focused in the properties view.\n\t\t *\n\t\t * @readonly\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 view.\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 #children backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.\n\t\t\t\tfocusPrevious: 'shift + tab',\n\n\t\t\t\t// Navigate #children forwards using the <kbd>Tab</kbd> key.\n\t\t\t\tfocusNext: 'tab'\n\t\t\t}\n\t\t} );\n\n\t\t// The rendering of the styles grid is conditional. When there is no styles grid, the view will render without collapsible\n\t\t// for numbered list properties, hence simplifying the layout.\n\t\tif ( enabledProperties.styles ) {\n\t\t\tthis.stylesView = this._createStylesView( styleButtonViews, styleGridAriaLabel );\n\t\t\tthis.children.add( this.stylesView );\n\t\t} else {\n\t\t\telementCssClasses.push( 'ck-list-properties_without-styles' );\n\t\t}\n\n\t\t// The rendering of the numbered list property views is also conditional. It only makes sense for the numbered list\n\t\t// dropdown. The unordered list does not have such properties.\n\t\tif ( enabledProperties.startIndex || enabledProperties.reversed ) {\n\t\t\tthis._addNumberedListPropertyViews( enabledProperties, styleButtonViews );\n\n\t\t\telementCssClasses.push( 'ck-list-properties_with-numbered-properties' );\n\t\t}\n\n\t\tthis.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\tclass: elementCssClasses\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\tif ( this.stylesView ) {\n\t\t\tthis.focusables.add( this.stylesView );\n\t\t\tthis.focusTracker.add( this.stylesView.element );\n\n\t\t\t// Register the collapsible toggle button to the focus system.\n\t\t\tif ( this.startIndexFieldView || this.reversedSwitchButtonView ) {\n\t\t\t\tthis.focusables.add( this.children.last.buttonView );\n\t\t\t\tthis.focusTracker.add( this.children.last.buttonView.element );\n\t\t\t}\n\n\t\t\tfor ( const item of this.stylesView.children ) {\n\t\t\t\tthis.stylesView.focusTracker.add( item.element );\n\t\t\t}\n\n\t\t\taddKeyboardHandlingForGrid( {\n\t\t\t\tkeystrokeHandler: this.stylesView.keystrokes,\n\t\t\t\tfocusTracker: this.stylesView.focusTracker,\n\t\t\t\tgridItems: this.stylesView.children,\n\t\t\t\t// Note: The styles view has a different number of columns depending on whether the other properties\n\t\t\t\t// are enabled in the dropdown or not (https://github.com/ckeditor/ckeditor5/issues/12340)\n\t\t\t\tnumberOfColumns: () => global.window\n\t\t\t\t\t.getComputedStyle( this.stylesView.element )\n\t\t\t\t\t.getPropertyValue( 'grid-template-columns' )\n\t\t\t\t\t.split( ' ' )\n\t\t\t\t\t.length\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.startIndexFieldView ) {\n\t\t\tthis.focusables.add( this.startIndexFieldView );\n\t\t\tthis.focusTracker.add( this.startIndexFieldView.element );\n\n\t\t\t// Intercept the `selectstart` event, which is blocked by default because of the default behavior\n\t\t\t// of the DropdownView#panelView.\n\t\t\t// TODO: blocking `selectstart` in the #panelView should be configurable per–drop–down instance.\n\t\t\tthis.listenTo( this.startIndexFieldView.element, 'selectstart', ( evt, domEvt ) => {\n\t\t\t\tdomEvt.stopPropagation();\n\t\t\t}, { priority: 'high' } );\n\n\t\t\tconst stopPropagation = data => data.stopPropagation();\n\n\t\t\t// Since the form is in the dropdown panel which is a child of the toolbar, the toolbar's\n\t\t\t// keystroke handler would take over the key management in the input. We need to prevent\n\t\t\t// this ASAP. Otherwise, the basic caret movement using the arrow keys will be impossible.\n\t\t\tthis.keystrokes.set( 'arrowright', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowleft', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowup', stopPropagation );\n\t\t\tthis.keystrokes.set( 'arrowdown', stopPropagation );\n\t\t}\n\n\t\tif ( this.reversedSwitchButtonView ) {\n\t\t\tthis.focusables.add( this.reversedSwitchButtonView );\n\t\t\tthis.focusTracker.add( this.reversedSwitchButtonView.element );\n\t\t}\n\n\t\t// Start listening for the keystrokes coming from #element.\n\t\tthis.keystrokes.listenTo( this.element );\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocus() {\n\t\tthis.focusCycler.focusFirst();\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tfocusLast() {\n\t\tthis.focusCycler.focusLast();\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 * Creates the list styles grid.\n\t *\n\t * @protected\n\t * @param {Array.<module:ui/button/buttonview~ButtonView>} styleButtons Buttons to be placed in the grid.\n\t * @param {String} styleGridAriaLabel The assistive technology label of the grid.\n\t * @returns {module:ui/view~View}\n\t */\n\t_createStylesView( styleButtons, styleGridAriaLabel ) {\n\t\tconst stylesView = new View( this.locale );\n\n\t\tstylesView.children = stylesView.createCollection( this.locale );\n\t\tstylesView.children.addMany( styleButtons );\n\n\t\tstylesView.setTemplate( {\n\t\t\ttag: 'div',\n\t\t\tattributes: {\n\t\t\t\t'aria-label': styleGridAriaLabel,\n\t\t\t\tclass: [\n\t\t\t\t\t'ck',\n\t\t\t\t\t'ck-list-styles-list'\n\t\t\t\t]\n\t\t\t},\n\t\t\tchildren: stylesView.children\n\t\t} );\n\n\t\tstylesView.children.delegate( 'execute' ).to( this );\n\n\t\tstylesView.focus = function() {\n\t\t\tthis.children.first.focus();\n\t\t};\n\n\t\tstylesView.focusTracker = new FocusTracker();\n\t\tstylesView.keystrokes = new KeystrokeHandler();\n\n\t\tstylesView.render();\n\n\t\tstylesView.keystrokes.listenTo( stylesView.element );\n\n\t\treturn stylesView;\n\t}\n\n\t/**\n\t * Renders {@link #startIndexFieldView} and/or {@link #reversedSwitchButtonView} depending on the configuration of the properties view.\n\t *\n\t * @private\n\t * @param {Object.<String,Boolean>} options.enabledProperties An object containing the configuration of enabled list property names\n\t * (see {@link #constructor}).\n\t */\n\t_addNumberedListPropertyViews( enabledProperties ) {\n\t\tconst t = this.locale.t;\n\t\tconst numberedPropertyViews = [];\n\n\t\tif ( enabledProperties.startIndex ) {\n\t\t\tthis.startIndexFieldView = this._createStartIndexField();\n\t\t\tnumberedPropertyViews.push( this.startIndexFieldView );\n\t\t}\n\n\t\tif ( enabledProperties.reversed ) {\n\t\t\tthis.reversedSwitchButtonView = this._createReversedSwitchButton();\n\t\t\tnumberedPropertyViews.push( this.reversedSwitchButtonView );\n\t\t}\n\n\t\t// When there are some style buttons, pack the numbered list properties into a collapsible to separate them.\n\t\tif ( enabledProperties.styles ) {\n\t\t\tthis.additionalPropertiesCollapsibleView = new CollapsibleView( this.locale, numberedPropertyViews );\n\n\t\t\tthis.additionalPropertiesCollapsibleView.set( {\n\t\t\t\tlabel: t( 'List properties' ),\n\t\t\t\tisCollapsed: true\n\t\t\t} );\n\n\t\t\t// Don't enable the collapsible view unless either start index or reversed field is enabled (e.g. when no list is selected).\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.bind( 'isEnabled' ).toMany(\n\t\t\t\tnumberedPropertyViews, 'isEnabled', ( ...areEnabled ) => areEnabled.some( isEnabled => isEnabled ) );\n\n\t\t\t// Automatically collapse the additional properties collapsible when either start index or reversed field gets disabled.\n\t\t\tthis.additionalPropertiesCollapsibleView.buttonView.on( 'change:isEnabled', ( evt, data, isEnabled ) => {\n\t\t\t\tif ( !isEnabled ) {\n\t\t\t\t\tthis.additionalPropertiesCollapsibleView.isCollapsed = true;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\tthis.children.add( this.additionalPropertiesCollapsibleView );\n\t\t} else {\n\t\t\tthis.children.addMany( numberedPropertyViews );\n\t\t}\n\t}\n\n\t/**\n\t * Creates the list start index labeled field.\n\t *\n\t * @private\n\t * @protected\n\t * @returns {module:ui/labeledfield/labeledfieldview~LabeledFieldView}\n\t */\n\t_createStartIndexField() {\n\t\tconst t = this.locale.t;\n\t\tconst startIndexFieldView = new LabeledFieldView( this.locale, createLabeledInputNumber );\n\n\t\tstartIndexFieldView.set( {\n\t\t\tlabel: t( 'Start at' ),\n\t\t\tclass: 'ck-numbered-list-properties__start-index'\n\t\t} );\n\n\t\tstartIndexFieldView.fieldView.set( {\n\t\t\tmin: 1,\n\t\t\tstep: 1,\n\t\t\tvalue: 1,\n\t\t\tinputMode: 'numeric'\n\t\t} );\n\n\t\tstartIndexFieldView.fieldView.on( 'input', () => {\n\t\t\tconst inputElement = startIndexFieldView.fieldView.element;\n\t\t\tconst startIndex = inputElement.valueAsNumber;\n\n\t\t\tif ( Number.isNaN( startIndex ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !inputElement.checkValidity() ) {\n\t\t\t\tstartIndexFieldView.errorText = t( 'Start index must be greater than 0.' );\n\t\t\t} else {\n\t\t\t\tthis.fire( 'listStart', { startIndex } );\n\t\t\t}\n\t\t} );\n\n\t\treturn startIndexFieldView;\n\t}\n\n\t/**\n\t * Creates the reversed list switch button.\n\t *\n\t * @private\n\t * @protected\n\t * @returns {module:ui/button/switchbuttonview~SwitchButtonView}\n\t */\n\t_createReversedSwitchButton() {\n\t\tconst t = this.locale.t;\n\t\tconst reversedButtonView = new SwitchButtonView( this.locale );\n\n\t\treversedButtonView.set( {\n\t\t\twithText: true,\n\t\t\tlabel: t( 'Reversed order' ),\n\t\t\tclass: 'ck-numbered-list-properties__reversed-order'\n\t\t} );\n\n\t\treversedButtonView.delegate( 'execute' ).to( this, 'listReversed' );\n\n\t\treturn reversedButtonView;\n\t}\n\n\t/**\n\t * Fired when the list start index value has changed via {@link #startIndexFieldView}.\n\t *\n\t * @event listStart\n\t * @param {Object} data\n\t * @param {Number} data.startIndex The new start index of the list.\n\t */\n\n\t/**\n\t * Fired when the list order has changed (reversed) via {@link #reversedSwitchButtonView}.\n\t *\n\t * @event listReversed\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 list/todolist\n */\n\nimport TodoListEditing from './todolist/todolistediting';\nimport TodoListUI from './todolist/todolistui';\nimport { Plugin } from 'ckeditor5/src/core';\nimport '../theme/todolist.css';\n\n/**\n * The to-do list feature.\n *\n * This is a \"glue\" plugin that loads the {@link module:list/todolist/todolistediting~TodoListEditing to-do list editing feature}\n * and the {@link module:list/todolist/todolistui~TodoListUI to-do list UI feature}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TodoList extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ TodoListEditing, TodoListUI ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TodoList';\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 list/todolist/checktodolistcommand\n */\n\nimport { Command } from 'ckeditor5/src/core';\n\nconst attributeKey = 'todoListChecked';\n\n/**\n * The check to-do command.\n *\n * The command is registered by the {@link module:list/todolist/todolistediting~TodoListEditing} as\n * the `checkTodoList` editor command and it is also available via aliased `todoListCheck` name.\n *\n * @extends module:core/command~Command\n */\nexport default class CheckTodoListCommand extends Command {\n\t/**\n\t * @inheritDoc\n\t */\n\tconstructor( editor ) {\n\t\tsuper( editor );\n\n\t\t/**\n\t\t * A flag indicating whether the command is active. The command is active when at least one of\n\t\t * {@link module:engine/model/selection~Selection selected} elements is a to-do list item.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\n\t\t/**\n\t\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Array.<module:engine/model/element~Element>} #value\n\t\t */\n\n\t\t/**\n\t\t * A list of to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t\t *\n\t\t * @protected\n\t\t * @type {Array.<module:engine/model/element~Element>}\n\t\t */\n\t\tthis._selectedElements = [];\n\n\t\t// Refresh command before executing to be sure all values are up to date.\n\t\t// It is needed when selection has changed before command execution, in the same change block.\n\t\tthis.on( 'execute', () => {\n\t\t\tthis.refresh();\n\t\t}, { priority: 'highest' } );\n\t}\n\n\t/**\n\t * Updates the command's {@link #value} and {@link #isEnabled} properties based on the current selection.\n\t */\n\trefresh() {\n\t\tthis._selectedElements = this._getSelectedItems();\n\t\tthis.value = this._selectedElements.every( element => !!element.getAttribute( 'todoListChecked' ) );\n\t\tthis.isEnabled = !!this._selectedElements.length;\n\t}\n\n\t/**\n\t * Gets all to-do list items selected by the {@link module:engine/model/selection~Selection}.\n\t *\n\t * @private\n\t * @returns {Array.<module:engine/model/element~Element>}\n\t */\n\t_getSelectedItems() {\n\t\tconst model = this.editor.model;\n\t\tconst schema = model.schema;\n\n\t\tconst selectionRange = model.document.selection.getFirstRange();\n\t\tconst startElement = selectionRange.start.parent;\n\t\tconst elements = [];\n\n\t\tif ( schema.checkAttribute( startElement, attributeKey ) ) {\n\t\t\telements.push( startElement );\n\t\t}\n\n\t\tfor ( const item of selectionRange.getItems() ) {\n\t\t\tif ( schema.checkAttribute( item, attributeKey ) && !elements.includes( item ) ) {\n\t\t\t\telements.push( item );\n\t\t\t}\n\t\t}\n\n\t\treturn elements;\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.forceValue] If set, it will force the command behavior. If `true`, the command will apply\n\t * the attribute. Otherwise, the command will remove the attribute. If not set, the command will look for its current\n\t * value to decide what it should do.\n\t */\n\texecute( options = {} ) {\n\t\tthis.editor.model.change( writer => {\n\t\t\tfor ( const element of this._selectedElements ) {\n\t\t\t\tconst value = ( options.forceValue === undefined ) ? !this.value : options.forceValue;\n\n\t\t\t\tif ( value ) {\n\t\t\t\t\twriter.setAttribute( attributeKey, true, element );\n\t\t\t\t} else {\n\t\t\t\t\twriter.removeAttribute( attributeKey, element );\n\t\t\t\t}\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 list/todolist/todolistconverters\n */\n\n/* global document */\n\nimport { createElement } from 'ckeditor5/src/utils';\n\nimport { generateLiInUl, injectViewList, positionAfterUiElements, findNestedList } from '../list/utils';\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It converts the `listItem` model element to an unordered list with a {@link module:engine/view/uielement~UIElement checkbox element}\n * at the beginning of each list item. It also merges the list with surrounding lists (if available).\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @param {Function} onCheckboxChecked Callback function.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewInsertion( model, onCheckboxChecked ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.item;\n\n\t\tconsumable.consume( modelItem, 'insert' );\n\t\tconsumable.consume( modelItem, 'attribute:listType' );\n\t\tconsumable.consume( modelItem, 'attribute:listIndent' );\n\t\tconsumable.consume( modelItem, 'attribute:todoListChecked' );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tconst isChecked = !!modelItem.getAttribute( 'todoListChecked' );\n\t\tconst checkmarkElement = createCheckmarkElement( modelItem, viewWriter, isChecked, onCheckboxChecked );\n\n\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\tclass: 'todo-list__label__description'\n\t\t} );\n\n\t\tviewWriter.addClass( 'todo-list', viewItem.parent );\n\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );\n\t\tviewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A model-to-view converter for the `listItem` model element insertion.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert\n * @param {module:engine/model/model~Model} model Model instance.\n * @returns {Function} Returns a conversion callback.\n */\nexport function dataModelViewInsertion( model ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tconst consumable = conversionApi.consumable;\n\n\t\tif ( !consumable.test( data.item, 'insert' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listType' ) ||\n\t\t\t!consumable.test( data.item, 'attribute:listIndent' )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst modelItem = data.item;\n\n\t\tconsumable.consume( modelItem, 'insert' );\n\t\tconsumable.consume( modelItem, 'attribute:listType' );\n\t\tconsumable.consume( modelItem, 'attribute:listIndent' );\n\t\tconsumable.consume( modelItem, 'attribute:todoListChecked' );\n\n\t\tconst viewWriter = conversionApi.writer;\n\t\tconst viewItem = generateLiInUl( modelItem, conversionApi );\n\n\t\tviewWriter.addClass( 'todo-list', viewItem.parent );\n\n\t\tconst label = viewWriter.createContainerElement( 'label', {\n\t\t\tclass: 'todo-list__label'\n\t\t} );\n\n\t\tconst checkbox = viewWriter.createEmptyElement( 'input', {\n\t\t\ttype: 'checkbox',\n\t\t\tdisabled: 'disabled'\n\t\t} );\n\n\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\tclass: 'todo-list__label__description'\n\t\t} );\n\n\t\tif ( modelItem.getAttribute( 'todoListChecked' ) ) {\n\t\t\tviewWriter.setAttribute( 'checked', 'checked', checkbox );\n\t\t}\n\n\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), label );\n\t\tviewWriter.insert( viewWriter.createPositionAt( label, 0 ), checkbox );\n\t\tviewWriter.insert( viewWriter.createPositionAfter( checkbox ), span );\n\n\t\tinjectViewList( modelItem, viewItem, conversionApi, model );\n\t};\n}\n\n/**\n * A view-to-model converter for the checkbox element inside a view list item.\n *\n * It changes the `listType` of the model `listItem` to a `todo` value.\n * When a view checkbox element is marked as checked, an additional `todoListChecked=\"true\"` attribute is added to the model item.\n *\n * It is used by {@link module:engine/controller/datacontroller~DataController}.\n *\n * @see module:engine/conversion/upcastdispatcher~UpcastDispatcher#event:element\n * @param {module:utils/eventinfo~EventInfo} evt An object containing information about the fired event.\n * @param {Object} data An object containing conversion input, a placeholder for conversion output and possibly other values.\n * @param {module:engine/conversion/upcastdispatcher~UpcastConversionApi} conversionApi Conversion interface to be used by the callback.\n */\nexport function dataViewModelCheckmarkInsertion( evt, data, conversionApi ) {\n\tconst modelCursor = data.modelCursor;\n\tconst modelItem = modelCursor.parent;\n\tconst viewItem = data.viewItem;\n\n\tif ( viewItem.getAttribute( 'type' ) != 'checkbox' || modelItem.name != 'listItem' || !modelCursor.isAtStart ) {\n\t\treturn;\n\t}\n\n\tif ( !conversionApi.consumable.consume( viewItem, { name: true } ) ) {\n\t\treturn;\n\t}\n\n\tconst writer = conversionApi.writer;\n\n\twriter.setAttribute( 'listType', 'todo', modelItem );\n\n\tif ( data.viewItem.hasAttribute( 'checked' ) ) {\n\t\twriter.setAttribute( 'todoListChecked', true, modelItem );\n\t}\n\n\tdata.modelRange = writer.createRange( modelCursor );\n}\n\n/**\n * A model-to-view converter for the `listType` attribute change on the `listItem` model element.\n *\n * This change means that the `<li>` element parent changes to `<ul class=\"todo-list\">` and a\n * {@link module:engine/view/uielement~UIElement checkbox UI element} is added at the beginning\n * of the list item element (or vice versa).\n *\n * This converter is preceded by {@link module:list/list/converters~modelViewChangeType} and followed by\n * {@link module:list/list/converters~modelViewMergeAfterChangeType} to handle splitting and merging surrounding lists of the same type.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {Function} onCheckedChange Callback fired after clicking the checkbox UI element.\n * @param {module:engine/view/view~View} view Editing view controller.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeType( onCheckedChange, view ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\tif ( !conversionApi.consumable.consume( data.item, evt.name ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewItem = conversionApi.mapper.toViewElement( data.item );\n\t\tconst viewWriter = conversionApi.writer;\n\n\t\tconst labelElement = findLabel( viewItem, view );\n\n\t\tif ( data.attributeNewValue == 'todo' ) {\n\t\t\tconst isChecked = !!data.item.getAttribute( 'todoListChecked' );\n\t\t\tconst checkmarkElement = createCheckmarkElement( data.item, viewWriter, isChecked, onCheckedChange );\n\n\t\t\tconst span = viewWriter.createContainerElement( 'span', {\n\t\t\t\tclass: 'todo-list__label__description'\n\t\t\t} );\n\n\t\t\tconst itemRange = viewWriter.createRangeIn( viewItem );\n\t\t\tconst nestedList = findNestedList( viewItem );\n\n\t\t\tconst descriptionStart = positionAfterUiElements( itemRange.start );\n\t\t\tconst descriptionEnd = nestedList ? viewWriter.createPositionBefore( nestedList ) : itemRange.end;\n\t\t\tconst descriptionRange = viewWriter.createRange( descriptionStart, descriptionEnd );\n\n\t\t\tviewWriter.addClass( 'todo-list', viewItem.parent );\n\t\t\tviewWriter.move( descriptionRange, viewWriter.createPositionAt( span, 0 ) );\n\t\t\tviewWriter.insert( viewWriter.createPositionAt( viewItem, 0 ), checkmarkElement );\n\t\t\tviewWriter.insert( viewWriter.createPositionAfter( checkmarkElement ), span );\n\t\t} else if ( data.attributeOldValue == 'todo' ) {\n\t\t\tconst descriptionSpan = findDescription( viewItem, view );\n\n\t\t\tviewWriter.removeClass( 'todo-list', viewItem.parent );\n\t\t\tviewWriter.remove( labelElement );\n\t\t\tviewWriter.move( viewWriter.createRangeIn( descriptionSpan ), viewWriter.createPositionBefore( descriptionSpan ) );\n\t\t\tviewWriter.remove( descriptionSpan );\n\t\t}\n\t};\n}\n\n/**\n * A model-to-view converter for the `todoListChecked` attribute change on the `listItem` model element.\n *\n * It marks the {@link module:engine/view/uielement~UIElement checkbox UI element} as checked.\n *\n * It is used by {@link module:engine/controller/editingcontroller~EditingController}.\n *\n * @see module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute\n * @param {Function} onCheckedChange Callback fired after clicking the checkbox UI element.\n * @returns {Function} Returns a conversion callback.\n */\nexport function modelViewChangeChecked( onCheckedChange ) {\n\treturn ( evt, data, conversionApi ) => {\n\t\t// Do not convert `todoListChecked` attribute when to-do list item has changed to other list item.\n\t\t// This attribute will be removed by the model post fixer.\n\t\tif ( data.item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !conversionApi.consumable.consume( data.item, 'attribute:todoListChecked' ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { mapper, writer: viewWriter } = conversionApi;\n\t\tconst isChecked = !!data.item.getAttribute( 'todoListChecked' );\n\t\tconst viewItem = mapper.toViewElement( data.item );\n\t\t// Because of m -> v position mapper we can be sure checkbox is always at the beginning.\n\t\tconst oldCheckmarkElement = viewItem.getChild( 0 );\n\t\tconst newCheckmarkElement = createCheckmarkElement( data.item, viewWriter, isChecked, onCheckedChange );\n\n\t\tviewWriter.insert( viewWriter.createPositionAfter( oldCheckmarkElement ), newCheckmarkElement );\n\t\tviewWriter.remove( oldCheckmarkElement );\n\t};\n}\n\n/**\n * A model-to-view position at zero offset mapper.\n *\n * This helper ensures that position inside todo-list in the view is mapped after the checkbox.\n *\n * It only handles the position at the beginning of a list item as other positions are properly mapped be the default mapper.\n *\n * @param {module:engine/view/view~View} view\n * @return {Function}\n */\nexport function mapModelToViewPosition( view ) {\n\treturn ( evt, data ) => {\n\t\tconst modelPosition = data.modelPosition;\n\t\tconst parent = modelPosition.parent;\n\n\t\tif ( !parent.is( 'element', 'listItem' ) || parent.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst viewLi = data.mapper.toViewElement( parent );\n\t\tconst descSpan = findDescription( viewLi, view );\n\n\t\tif ( descSpan ) {\n\t\t\tdata.viewPosition = data.mapper.findPositionIn( descSpan, modelPosition.offset );\n\t\t}\n\t};\n}\n\n// Creates a checkbox UI element.\n//\n// @private\n// @param {module:engine/model/item~Item} modelItem\n// @param {module:engine/view/downcastwriter~DowncastWriter} viewWriter\n// @param {Boolean} isChecked\n// @param {Function} onChange\n// @returns {module:view/uielement~UIElement}\nfunction createCheckmarkElement( modelItem, viewWriter, isChecked, onChange ) {\n\tconst uiElement = viewWriter.createUIElement(\n\t\t'label',\n\t\t{\n\t\t\tclass: 'todo-list__label',\n\t\t\tcontenteditable: false\n\t\t},\n\t\tfunction( domDocument ) {\n\t\t\tconst checkbox = createElement( document, 'input', { type: 'checkbox', tabindex: -1 } );\n\n\t\t\tif ( isChecked ) {\n\t\t\t\tcheckbox.setAttribute( 'checked', 'checked' );\n\t\t\t}\n\n\t\t\tcheckbox.addEventListener( 'change', () => onChange( modelItem ) );\n\n\t\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t\tdomElement.appendChild( checkbox );\n\n\t\t\treturn domElement;\n\t\t}\n\t);\n\n\treturn uiElement;\n}\n\n// Helper method to find label element inside li.\nfunction findLabel( viewItem, view ) {\n\tconst range = view.createRangeIn( viewItem );\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'uiElement', 'label' ) ) {\n\t\t\treturn value.item;\n\t\t}\n\t}\n}\n\nfunction findDescription( viewItem, view ) {\n\tconst range = view.createRangeIn( viewItem );\n\n\tfor ( const value of range ) {\n\t\tif ( value.item.is( 'containerElement', 'span' ) && value.item.hasClass( 'todo-list__label__description' ) ) {\n\t\t\treturn value.item;\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 list/todolist/todolistediting\n */\n\nimport { Plugin } from 'ckeditor5/src/core';\nimport {\n\tgetCode,\n\tparseKeystroke,\n\tgetLocalizedArrowKeyCodeDirection\n} from 'ckeditor5/src/utils';\n\nimport ListCommand from '../list/listcommand';\nimport ListEditing from '../list/listediting';\nimport CheckTodoListCommand from './checktodolistcommand';\nimport {\n\tdataModelViewInsertion,\n\tdataViewModelCheckmarkInsertion,\n\tmapModelToViewPosition,\n\tmodelViewChangeChecked,\n\tmodelViewChangeType,\n\tmodelViewInsertion\n} from './todolistconverters';\n\nconst ITEM_TOGGLE_KEYSTROKE = parseKeystroke( 'Ctrl+Enter' );\n\n/**\n * The engine of the to-do list feature. It handles creating, editing and removing to-do lists and their items.\n *\n * It registers the entire functionality of the {@link module:list/list/listediting~ListEditing list editing plugin} and extends\n * it with the commands:\n *\n * - `'todoList'`,\n * - `'checkTodoList'`,\n * - `'todoListCheck'` as an alias for `checkTodoList` command.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TodoListEditing extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TodoListEditing';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ListEditing ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst { editing, data, model } = editor;\n\n\t\t// Extend schema.\n\t\tmodel.schema.extend( 'listItem', {\n\t\t\tallowAttributes: [ 'todoListChecked' ]\n\t\t} );\n\n\t\t// Disallow todoListChecked attribute on other nodes than listItem with to-do listType.\n\t\tmodel.schema.addAttributeCheck( ( context, attributeName ) => {\n\t\t\tconst item = context.last;\n\n\t\t\tif ( attributeName == 'todoListChecked' && item.name == 'listItem' && item.getAttribute( 'listType' ) != 'todo' ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} );\n\n\t\t// Register `todoList` command.\n\t\teditor.commands.add( 'todoList', new ListCommand( editor, 'todo' ) );\n\n\t\tconst checkTodoListCommand = new CheckTodoListCommand( editor );\n\n\t\t// Register `checkTodoList` command and add `todoListCheck` command as an alias for backward compatibility.\n\t\teditor.commands.add( 'checkTodoList', checkTodoListCommand );\n\t\teditor.commands.add( 'todoListCheck', checkTodoListCommand );\n\n\t\t// Define converters.\n\t\tdata.downcastDispatcher.on( 'insert:listItem', dataModelViewInsertion( model ), { priority: 'high' } );\n\t\tdata.upcastDispatcher.on( 'element:input', dataViewModelCheckmarkInsertion, { priority: 'high' } );\n\n\t\tediting.downcastDispatcher.on(\n\t\t\t'insert:listItem',\n\t\t\tmodelViewInsertion( model, listItem => this._handleCheckmarkChange( listItem ) ),\n\t\t\t{ priority: 'high' }\n\t\t);\n\t\tediting.downcastDispatcher.on(\n\t\t\t'attribute:listType:listItem',\n\t\t\tmodelViewChangeType( listItem => this._handleCheckmarkChange( listItem ), editing.view )\n\t\t);\n\t\tediting.downcastDispatcher.on(\n\t\t\t'attribute:todoListChecked:listItem',\n\t\t\tmodelViewChangeChecked( listItem => this._handleCheckmarkChange( listItem ) )\n\t\t);\n\n\t\tediting.mapper.on( 'modelToViewPosition', mapModelToViewPosition( editing.view ) );\n\t\tdata.mapper.on( 'modelToViewPosition', mapModelToViewPosition( editing.view ) );\n\n\t\t// Jump at the end of the previous node on left arrow key press, when selection is after the checkbox.\n\t\t//\n\t\t// <blockquote><p>Foo</p></blockquote>\n\t\t// <ul><li><checkbox/>{}Bar</li></ul>\n\t\t//\n\t\t// press: `<-`\n\t\t//\n\t\t// <blockquote><p>Foo{}</p></blockquote>\n\t\t// <ul><li><checkbox/>Bar</li></ul>\n\t\t//\n\t\tthis.listenTo( editing.view.document, 'arrowKey', jumpOverCheckmarkOnSideArrowKeyPress( model, editor.locale ), { context: 'li' } );\n\n\t\t// Toggle check state of selected to-do list items on keystroke.\n\t\tthis.listenTo( editing.view.document, 'keydown', ( evt, data ) => {\n\t\t\tif ( getCode( data ) === ITEM_TOGGLE_KEYSTROKE ) {\n\t\t\t\teditor.execute( 'checkTodoList' );\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// Remove `todoListChecked` attribute when a host element is no longer a to-do list item.\n\t\tconst listItemsToFix = new Set();\n\n\t\tthis.listenTo( model, 'applyOperation', ( evt, args ) => {\n\t\t\tconst operation = args[ 0 ];\n\n\t\t\tif ( operation.type == 'rename' && operation.oldName == 'listItem' ) {\n\t\t\t\tconst item = operation.position.nodeAfter;\n\n\t\t\t\tif ( item.hasAttribute( 'todoListChecked' ) ) {\n\t\t\t\t\tlistItemsToFix.add( item );\n\t\t\t\t}\n\t\t\t} else if ( operation.type == 'changeAttribute' && operation.key == 'listType' && operation.oldValue === 'todo' ) {\n\t\t\t\tfor ( const item of operation.range.getItems() ) {\n\t\t\t\t\tif ( item.hasAttribute( 'todoListChecked' ) && item.getAttribute( 'listType' ) !== 'todo' ) {\n\t\t\t\t\t\tlistItemsToFix.add( item );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tmodel.document.registerPostFixer( writer => {\n\t\t\tlet hasChanged = false;\n\n\t\t\tfor ( const listItem of listItemsToFix ) {\n\t\t\t\twriter.removeAttribute( 'todoListChecked', listItem );\n\t\t\t\thasChanged = true;\n\t\t\t}\n\n\t\t\tlistItemsToFix.clear();\n\n\t\t\treturn hasChanged;\n\t\t} );\n\t}\n\n\t/**\n\t * Handles the checkbox element change, moves the selection to the corresponding model item to make it possible\n\t * to toggle the `todoListChecked` attribute using the command, and restores the selection position.\n\t *\n\t * Some say it's a hack :) Moving the selection only for executing the command on a certain node and restoring it after,\n\t * is not a clear solution. We need to design an API for using commands beyond the selection range.\n\t * See https://github.com/ckeditor/ckeditor5/issues/1954.\n\t *\n\t * @private\n\t * @param {module:engine/model/element~Element} listItem\n\t */\n\t_handleCheckmarkChange( listItem ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst previousSelectionRanges = Array.from( model.document.selection.getRanges() );\n\n\t\tmodel.change( writer => {\n\t\t\twriter.setSelection( listItem, 'end' );\n\t\t\teditor.execute( 'checkTodoList' );\n\t\t\twriter.setSelection( previousSelectionRanges );\n\t\t} );\n\t}\n}\n\n// Handles the left/right (LTR/RTL content) arrow key and moves the selection at the end of the previous block element\n// if the selection is just after the checkbox element. In other words, it jumps over the checkbox element when\n// moving the selection to the left/right (LTR/RTL).\n//\n// @private\n// @param {module:engine/model/model~Model} model\n// @param {module:utils/locale~Locale} locale\n// @returns {Function} Callback for 'keydown' events.\nfunction jumpOverCheckmarkOnSideArrowKeyPress( model, locale ) {\n\treturn ( eventInfo, domEventData ) => {\n\t\tconst direction = getLocalizedArrowKeyCodeDirection( domEventData.keyCode, locale.contentLanguageDirection );\n\n\t\tif ( direction != 'left' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst schema = model.schema;\n\t\tconst selection = model.document.selection;\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst position = selection.getFirstPosition();\n\t\tconst parent = position.parent;\n\n\t\tif ( parent.name === 'listItem' && parent.getAttribute( 'listType' ) == 'todo' && position.isAtStart ) {\n\t\t\tconst newRange = schema.getNearestSelectionRange( model.createPositionBefore( parent ), 'backward' );\n\n\t\t\tif ( newRange ) {\n\t\t\t\tmodel.change( writer => writer.setSelection( newRange ) );\n\t\t\t}\n\n\t\t\tdomEventData.preventDefault();\n\t\t\tdomEventData.stopPropagation();\n\t\t\teventInfo.stop();\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 list/todolist/todolistui\n */\n\nimport { createUIComponent } from '../list/utils';\nimport todoListIcon from '../../theme/icons/todolist.svg';\nimport { Plugin } from 'ckeditor5/src/core';\n\n/**\n * The to-do list UI feature. It introduces the `'todoList'` button that\n * allows to convert elements to and from to-do list items and to indent or outdent them.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class TodoListUI extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'TodoListUI';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst t = this.editor.t;\n\n\t\tcreateUIComponent( this.editor, 'todoList', t( 'To-do List' ), todoListIcon );\n\t}\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/enter.js\");","module.exports = (__webpack_require__(/*! dll-reference CKEditor5.dll */ \"dll-reference CKEditor5.dll\"))(\"./src/typing.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 = CKEditor5.dll;","// 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};","__webpack_require__.nc = undefined;","/**\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 list\n */\n\nexport { default as DocumentList } from './documentlist';\nexport { default as DocumentListEditing } from './documentlist/documentlistediting';\nexport { default as DocumentListProperties } from './documentlistproperties';\nexport { default as DocumentListPropertiesEditing } from './documentlistproperties/documentlistpropertiesediting';\nexport { default as List } from './list';\nexport { default as ListEditing } from './list/listediting';\nexport { default as ListUI } from './list/listui';\nexport { default as ListProperties } from './listproperties';\nexport { default as ListPropertiesEditing } from './listproperties/listpropertiesediting';\nexport { default as ListPropertiesUI } from './listproperties/listpropertiesui';\nexport { default as TodoList } from './todolist';\nexport { default as TodoListEditing } from './todolist/todolistediting';\nexport { default as TodoListUI } from './todolist/todolistui';\n"],"sourceRoot":""}