@cqa-lib/cqa-ui 1.1.551 → 1.1.552

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.
@@ -8,6 +8,7 @@ export const DEFAULT_MODULAR_CONFIG = {
8
8
  allowCreateFolder: true,
9
9
  allowRenameFolder: true,
10
10
  allowDeleteFolder: true,
11
+ allowDuplicateFolder: false,
11
12
  allowNestedFolders: true,
12
13
  allowTestDragDrop: true,
13
14
  allowBulkSelection: true,
@@ -93,4 +94,4 @@ export const DEFAULT_REORDER_LABELS = {
93
94
  export const ROW_DRAG_MIME = 'application/x-cqa-test-ids';
94
95
  /** Custom MIME for folder-row drags in the sidebar. Payload is a JSON-stringified folder id. */
95
96
  export const FOLDER_DRAG_MIME = 'application/x-cqa-folder-id';
96
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxhci10YWJsZS10ZW1wbGF0ZS5tb2RlbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RlbXBsYXRlcy9tb2R1bGFyLXRhYmxlLXRlbXBsYXRlL21vZHVsYXItdGFibGUtdGVtcGxhdGUubW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQStDQSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBa0I7SUFDbkQsV0FBVyxFQUFFLElBQUk7SUFDakIsY0FBYyxFQUFFLElBQUk7SUFDcEIsY0FBYyxFQUFFLElBQUk7SUFDcEIsc0JBQXNCLEVBQUUsSUFBSTtJQUM1QixvQkFBb0IsRUFBRSxJQUFJO0lBQzFCLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLGlCQUFpQixFQUFFLElBQUk7SUFDdkIsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLGtCQUFrQixFQUFFLElBQUk7SUFDeEIsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixrQkFBa0IsRUFBRSxJQUFJO0lBQ3hCLGdCQUFnQixFQUFFLElBQUk7Q0FDdkIsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLFFBQVEsQ0FBQztBQW1GL0MsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQWtCO0lBQ25ELE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLFdBQVcsRUFBRSxhQUFhO0lBQzFCLFNBQVMsRUFBRSxZQUFZO0lBQ3ZCLHdCQUF3QixFQUFFLG1CQUFtQjtJQUM3QyxVQUFVLEVBQUUsYUFBYTtJQUN6QixZQUFZLEVBQUUsZUFBZTtJQUM3QixZQUFZLEVBQUUsZ0JBQWdCO0lBQzlCLE1BQU0sRUFBRSxTQUFTO0lBQ2pCLE1BQU0sRUFBRSxRQUFRO0lBQ2hCLFNBQVMsRUFBRSxZQUFZO0lBQ3ZCLGtCQUFrQixFQUFFLFFBQVE7SUFDNUIsZ0JBQWdCLEVBQUUsV0FBVztJQUM3QixvQkFBb0IsRUFBRSxVQUFVO0lBQ2hDLGtCQUFrQixFQUFFLGFBQWE7SUFDakMsc0JBQXNCLEVBQUUsYUFBYTtJQUNyQyxvQkFBb0IsRUFBRSxnQkFBZ0I7SUFDdEMsWUFBWSxFQUFFLGFBQWE7SUFDM0IsZUFBZSxFQUFFLGdCQUFnQjtJQUNqQyxXQUFXLEVBQUUsY0FBYztJQUMzQixlQUFlLEVBQUUsZ0JBQWdCO0lBQ2pDLGdCQUFnQixFQUFFLFFBQVE7SUFDMUIsaUJBQWlCLEVBQUUsV0FBVztJQUM5QixjQUFjLEVBQUUsYUFBYTtJQUM3Qiw2QkFBNkIsRUFBRSx5Q0FBeUM7SUFDeEUsMkJBQTJCLEVBQUUsNENBQTRDO0lBRXpFLG9CQUFvQixFQUFFLFlBQVk7SUFDbEMsMEJBQTBCLEVBQUUsZ0RBQWdEO0lBQzVFLHdCQUF3QixFQUFFLGFBQWE7SUFDdkMsOEJBQThCLEVBQUUsOENBQThDO0lBQzlFLDBCQUEwQixFQUFFLDBCQUEwQjtJQUN0RCx5QkFBeUIsRUFBRSxNQUFNO0lBQ2pDLHlCQUF5QixFQUFFLHlCQUF5QjtJQUNwRCxxQkFBcUIsRUFBRSxRQUFRO0lBQy9CLHNCQUFzQixFQUFFLGVBQWU7SUFDdkMsZ0NBQWdDLEVBQUUseUJBQXlCO0lBQzNELGlDQUFpQyxFQUFFLHlDQUF5QztJQUU1RSx5QkFBeUIsRUFBRSxrQkFBa0I7SUFDN0MsZ0JBQWdCLEVBQUUsUUFBUTtJQUMxQixjQUFjLEVBQUUsYUFBYTtJQUM3QixtQkFBbUIsRUFBRSxrQkFBa0I7SUFDdkMsZ0JBQWdCLEVBQUUsZUFBZTtJQUVqQyx1QkFBdUIsRUFBRSxlQUFlO0lBQ3hDLDhCQUE4QixFQUFFLDJEQUEyRDtJQUMzRixzQ0FBc0MsRUFBRSxhQUFhO0lBQ3JELG9DQUFvQyxFQUFFLGdCQUFnQjtJQUN0RCx1Q0FBdUMsRUFBRSxjQUFjO0lBQ3ZELHFDQUFxQyxFQUFFLGlCQUFpQjtJQUN4RCwwQkFBMEIsRUFBRSxLQUFLO0lBQ2pDLG1DQUFtQyxFQUFFLHVCQUF1QjtJQUM1RCx5Q0FBeUMsRUFBRSwwQ0FBMEM7SUFDckYsd0NBQXdDLEVBQUUscUJBQXFCO0lBQy9ELDhDQUE4QyxFQUFFLHNDQUFzQztJQUN0Rix3QkFBd0IsRUFBRSxRQUFRO0lBQ2xDLHlCQUF5QixFQUFFLGVBQWU7SUFFMUMseUJBQXlCLEVBQUUsb0JBQW9CO0lBQy9DLCtCQUErQixFQUFFLGtEQUFrRDtJQUVuRixpQkFBaUIsRUFBRSxRQUFRO0lBQzNCLG1CQUFtQixFQUFFLGFBQWE7SUFDbEMsY0FBYyxFQUFFLGtCQUFrQjtJQUNsQywwQkFBMEIsRUFBRSx3Q0FBd0M7SUFDcEUsd0JBQXdCLEVBQUUsMkNBQTJDO0NBQ3RFLENBQUM7QUE0RUYsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQWtCO0lBQ25ELGFBQWEsRUFBRSxTQUFTO0lBQ3hCLFlBQVksRUFBRSxRQUFRO0lBQ3RCLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLFlBQVksRUFBRSxXQUFXO0lBQ3pCLFdBQVcsRUFBRSxjQUFjO0lBQzNCLGlCQUFpQixFQUFFLDBDQUEwQztDQUM5RCxDQUFDO0FBTUYsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLDRCQUE0QixDQUFDO0FBRTFELGdHQUFnRztBQUNoRyxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyw2QkFBNkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgRm9sZGVyTm9kZSB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbiAgLyoqIERpcmVjdCB0ZXN0LWNhc2UgY291bnQg4oCUIGNhc2VzIHdpdGggYGZvbGRlcklkID09PSB0aGlzLmlkYC4gUmVuZGVyZWQgYXMgdGhlIHJvdyBiYWRnZS4gKi9cbiAgY291bnQ/OiBudW1iZXI7XG4gIC8qKiBUb3RhbCB0ZXN0LWNhc2UgY291bnQgaW5jbHVkaW5nIGFsbCBkZXNjZW5kYW50cy4gUmVuZGVyZWQgYXMgYSB0b29sdGlwIG9uIHRoZSBmb2xkZXIgcm93LiAqL1xuICB0b3RhbENvdW50PzogbnVtYmVyO1xuICBjb2xvcj86IHN0cmluZztcbiAgY2hpbGRyZW4/OiBGb2xkZXJOb2RlW107XG4gIC8qKiBCYWNrZW5kIGhpbnQ6IHRydWUgd2hlbiB0aGlzIG5vZGUgaGFzIGF0IGxlYXN0IG9uZSBkaXJlY3QgY2hpbGQuIERyaXZlc1xuICAgKiAgdGhlIHNpZGViYXIgY2hldnJvbiB1bmRlciBsYXp5IGxvYWRpbmcsIHNvIHRoZSBhZmZvcmRhbmNlIHNob3dzIGV2ZW5cbiAgICogIGJlZm9yZSBgY2hpbGRyZW5gIGhhcyBiZWVuIGZldGNoZWQuICovXG4gIGhhc0NoaWxkcmVuPzogYm9vbGVhbjtcbiAgLyoqIEJhY2tlbmQtcmVwb3J0ZWQgdG90YWwgbnVtYmVyIG9mIGRpcmVjdCBjaGlsZHJlbi4gVGhlIHNpZGViYXIgc2hvd3MgYVxuICAgKiAgXCJMb2FkIG1vcmVcIiByb3cgd2hlbiBgKGNoaWxkcmVuPy5sZW5ndGggPz8gMCkgPCB0b3RhbENoaWxkcmVuYC4gKi9cbiAgdG90YWxDaGlsZHJlbj86IG51bWJlcjtcbiAgLyoqIExhc3QgMC1iYXNlZCBwYWdlIGFscmVhZHkgZmV0Y2hlZCBpbnRvIGBjaGlsZHJlbmAuIGB1bmRlZmluZWRgIG1lYW5zIHRoZVxuICAgKiAgc3VidHJlZSBoYXMgbm90IGJlZW4gbG9hZGVkIHlldCDigJQgdGhlIGhvc3Qgc2hvdWxkIGZldGNoIG9uIGZpcnN0IGV4cGFuZC4gKi9cbiAgbG9hZGVkUGFnZXM/OiBudW1iZXI7XG4gIC8qKiBUcnVlIHdoaWxlIGEgY2hpbGRyZW4tcGFnZSBmZXRjaCBpcyBpbiBmbGlnaHQsIHNvIHRoZSBzaWRlYmFyIGNhbiByZW5kZXJcbiAgICogIGEgc3Bpbm5lciByb3cgYW5kIHRoZSBob3N0IGNhbiBzdXBwcmVzcyBkdXBsaWNhdGUgcmVxdWVzdHMuICovXG4gIGNoaWxkcmVuTG9hZGluZz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCB0eXBlIEZvbGRlcklkQWNjZXNzb3IgPSAocm93OiBhbnkpID0+IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9kdWxhckNvbmZpZyB7XG4gIHNob3dTaWRlYmFyOiBib29sZWFuO1xuICBzaG93QnJlYWRjcnVtYjogYm9vbGVhbjtcbiAgc2hvd0ZvbGRlckdyaWQ6IGJvb2xlYW47XG4gIHNob3dVbm9yZ2FuaXplZFNlY3Rpb246IGJvb2xlYW47XG4gIHNob3dTdWJmb2xkZXJTZWN0aW9uOiBib29sZWFuO1xuICBzaG93Q291bnRzOiBib29sZWFuO1xuICBhbGxvd0NyZWF0ZUZvbGRlcjogYm9vbGVhbjtcbiAgYWxsb3dSZW5hbWVGb2xkZXI6IGJvb2xlYW47XG4gIGFsbG93RGVsZXRlRm9sZGVyOiBib29sZWFuO1xuICBhbGxvd05lc3RlZEZvbGRlcnM6IGJvb2xlYW47XG4gIGFsbG93VGVzdERyYWdEcm9wOiBib29sZWFuO1xuICBhbGxvd0J1bGtTZWxlY3Rpb246IGJvb2xlYW47XG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIHRoZSB0YWJsZSByZW5kZXJzIGEgZm9sZGVyIGNvbHVtbiAoaWNvbiArIGZvbGRlciBuYW1lKSBhbmQgbGlzdHMgaXQgaW4gdGhlXG4gICAqIHNldHRpbmdzIGRyb3Bkb3duLiBEZWZhdWx0IHZpc2liaWxpdHkgb24gZmlyc3QgaW5pdCBmb2xsb3dzIGB2aWV3TW9kZWA6IHNob3duIGluIGxpc3QsXG4gICAqIGhpZGRlbiBpbiBtb2R1bGFyLiBPbmNlIHRoZSB1c2VyIHRvZ2dsZXMgaXQgdGhlIGNob2ljZSBwZXJzaXN0cy5cbiAgICovXG4gIHNob3dGb2xkZXJDb2x1bW46IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX01PRFVMQVJfQ09ORklHOiBNb2R1bGFyQ29uZmlnID0ge1xuICBzaG93U2lkZWJhcjogdHJ1ZSxcbiAgc2hvd0JyZWFkY3J1bWI6IHRydWUsXG4gIHNob3dGb2xkZXJHcmlkOiB0cnVlLFxuICBzaG93VW5vcmdhbml6ZWRTZWN0aW9uOiB0cnVlLFxuICBzaG93U3ViZm9sZGVyU2VjdGlvbjogdHJ1ZSxcbiAgc2hvd0NvdW50czogdHJ1ZSxcbiAgYWxsb3dDcmVhdGVGb2xkZXI6IHRydWUsXG4gIGFsbG93UmVuYW1lRm9sZGVyOiB0cnVlLFxuICBhbGxvd0RlbGV0ZUZvbGRlcjogdHJ1ZSxcbiAgYWxsb3dOZXN0ZWRGb2xkZXJzOiB0cnVlLFxuICBhbGxvd1Rlc3REcmFnRHJvcDogdHJ1ZSxcbiAgYWxsb3dCdWxrU2VsZWN0aW9uOiB0cnVlLFxuICBzaG93Rm9sZGVyQ29sdW1uOiB0cnVlLFxufTtcblxuLyoqXG4gKiBSZXNlcnZlZCBmaWVsZElkIGZvciB0aGUgYXV0by1pbmplY3RlZCBmb2xkZXIgY29sdW1uLiBIb3N0cyBzaG91bGQgYXZvaWRcbiAqIGRlZmluaW5nIGEgY29sdW1uIHdpdGggdGhpcyBpZCBvZiB0aGVpciBvd24uXG4gKi9cbmV4cG9ydCBjb25zdCBGT0xERVJfQ09MVU1OX0ZJRUxEX0lEID0gJ2ZvbGRlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTW9kdWxhckxhYmVscyB7XG4gIGZvbGRlcnM6IHN0cmluZztcbiAgb3JnYW5pemVkOiBzdHJpbmc7XG4gIHVub3JnYW5pemVkOiBzdHJpbmc7XG4gIG5ld0ZvbGRlcjogc3RyaW5nO1xuICBzZWFyY2hGb2xkZXJzUGxhY2Vob2xkZXI6IHN0cmluZztcbiAgYWxsRm9sZGVyczogc3RyaW5nO1xuICBzdWJmb2xkZXJzSW46IHN0cmluZztcbiAgbW92ZVRvRm9sZGVyOiBzdHJpbmc7XG4gIGFkZFRhZzogc3RyaW5nO1xuICBkZWxldGU6IHN0cmluZztcbiAgc2VsZWN0QWxsOiBzdHJpbmc7XG4gIHRlc3RzQ291bnRTaW5ndWxhcjogc3RyaW5nO1xuICB0ZXN0c0NvdW50UGx1cmFsOiBzdHJpbmc7XG4gIGZvbGRlcnNDb3VudFNpbmd1bGFyOiBzdHJpbmc7XG4gIGZvbGRlcnNDb3VudFBsdXJhbDogc3RyaW5nO1xuICBzdWJmb2xkZXJDb3VudFNpbmd1bGFyOiBzdHJpbmc7XG4gIHN1YmZvbGRlckNvdW50UGx1cmFsOiBzdHJpbmc7XG4gIG9uZVN1YmZvbGRlcjogc3RyaW5nO1xuICBzdWJmb2xkZXJzQ291bnQ6IHN0cmluZztcbiAgY2xlYXJGaWx0ZXI6IHN0cmluZztcbiAgbW92ZURpYWxvZ1RpdGxlOiBzdHJpbmc7XG4gIG1vdmVEaWFsb2dDYW5jZWw6IHN0cmluZztcbiAgbW92ZURpYWxvZ0NvbmZpcm06IHN0cmluZztcbiAgbW92ZURpYWxvZ1Jvb3Q6IHN0cmluZztcbiAgbW92ZURpYWxvZ0Rlc2NyaXB0aW9uU2luZ3VsYXI6IHN0cmluZztcbiAgbW92ZURpYWxvZ0Rlc2NyaXB0aW9uUGx1cmFsOiBzdHJpbmc7XG5cbiAgLy8gTmV3IEZvbGRlciBkaWFsb2dcbiAgbmV3Rm9sZGVyRGlhbG9nVGl0bGU6IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nRGVzY3JpcHRpb246IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZUxhYmVsOiBzdHJpbmc7XG4gIG5ld0ZvbGRlckRpYWxvZ05hbWVQbGFjZWhvbGRlcjogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dQYXJlbnRMYWJlbDogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dQYXJlbnROb25lOiBzdHJpbmc7XG4gIG5ld0ZvbGRlckRpYWxvZ0NvbG9yTGFiZWw6IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nQ2FuY2VsOiBzdHJpbmc7XG4gIG5ld0ZvbGRlckRpYWxvZ0NvbmZpcm06IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZVJlcXVpcmVkRXJyb3I6IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZU1heExlbmd0aEVycm9yOiBzdHJpbmc7XG5cbiAgLy8gRm9sZGVyIHJvdyBjb250ZXh0IG1lbnUgKHJpZ2h0LWNsaWNrIC8gZWxsaXBzaXMpXG4gIGZvbGRlck1lbnVDcmVhdGVTdWJmb2xkZXI6IHN0cmluZztcbiAgZm9sZGVyTWVudVJlbmFtZTogc3RyaW5nO1xuICBmb2xkZXJNZW51TW92ZTogc3RyaW5nO1xuICBmb2xkZXJNZW51RHVwbGljYXRlOiBzdHJpbmc7XG4gIGZvbGRlck1lbnVEZWxldGU6IHN0cmluZztcblxuICAvLyBEZWxldGUgRm9sZGVyIGRpYWxvZ1xuICBkZWxldGVGb2xkZXJEaWFsb2dUaXRsZTogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dCb2R5VGVtcGxhdGU6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVRlc3RDYXNlU2luZ3VsYXI6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVRlc3RDYXNlUGx1cmFsOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlTdGVwR3JvdXBTaW5ndWxhcjogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dCb2R5U3RlcEdyb3VwUGx1cmFsOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlKb2luOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ01vdmVUb1BhcmVudFRpdGxlOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ01vdmVUb1BhcmVudERlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ01vdmVUb1Vub3JnYW5pemVkVGl0bGU6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvVW5vcmdhbml6ZWREZXNjcmlwdGlvbjogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dDYW5jZWw6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQ29uZmlybTogc3RyaW5nO1xuXG4gIC8vIEF1dG8tZGVyaXZlZCBlbXB0eSBzdGF0ZXMgKHNob3duIHdoZW4gcGFnZWRSb3dzIGlzIGVtcHR5IGFuZCBob3N0IGRpZCBub3Qgc2V0IGlzRW1wdHlTdGF0ZSlcbiAgZW1wdHlOb1Rlc3RzSW5Gb2xkZXJUaXRsZTogc3RyaW5nO1xuICBlbXB0eU5vVGVzdHNJbkZvbGRlckRlc2NyaXB0aW9uOiBzdHJpbmc7XG5cbiAgLyoqIEhlYWRlciBsYWJlbCBmb3IgdGhlIGF1dG8taW5qZWN0ZWQgZm9sZGVyIGNvbHVtbi4gKi9cbiAgZm9sZGVyQ29sdW1uTGFiZWw6IHN0cmluZztcbiAgLyoqIENlbGwgbGFiZWwgZm9yIHJvd3Mgd2l0aCBubyBmb2xkZXJJZCAoaS5lLiB0aGUgXCJVbm9yZ2FuaXplZFwiIGJ1Y2tldCkuICovXG4gIHVub3JnYW5pemVkUm93TGFiZWw6IHN0cmluZztcbiAgLyoqIFNob3duIGluIHRoZSBmb2xkZXIgc2lkZWJhciB3aGVuIHRoZSBzZWFyY2ggaW5wdXQgZmlsdGVycyBvdXQgZXZlcnkgZm9sZGVyLiAqL1xuICBub0ZvbGRlcnNGb3VuZDogc3RyaW5nO1xuICAvKiogU2lkZWJhciBmb2xkZXItcm93IGhvdmVyIHRvb2x0aXAgY291bnQgbGluZS4gYHtufWAgaXMgdGhlIGRlc2NlbmRhbnQgdG90YWxcbiAgICogIChGb2xkZXJOb2RlLnRvdGFsQ291bnQpLiBUaGUgaG9zdCBzd2FwcyB0aGUgbm91biBmb3IgXCJzdGVwIGdyb3VwXCIgd2hlbiBpblxuICAgKiAgc3RlcC1ncm91cCBtb2RlIGJ5IG92ZXJyaWRpbmcgdGhlc2UgdHdvIGtleXMuIFRoZSBmdWxsIHRvb2x0aXAgaXMgY29tcG9zZWRcbiAgICogIGFzIGAke25vZGUubmFtZX1cXG4ke3RwbC5yZXBsYWNlKCd7bn0nLCB0b3RhbCl9YC4gKi9cbiAgZm9sZGVyVG9vbHRpcFRvdGFsU2luZ3VsYXI6IHN0cmluZztcbiAgZm9sZGVyVG9vbHRpcFRvdGFsUGx1cmFsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX01PRFVMQVJfTEFCRUxTOiBNb2R1bGFyTGFiZWxzID0ge1xuICBmb2xkZXJzOiAnRm9sZGVycycsXG4gIG9yZ2FuaXplZDogJ09yZ2FuaXplZCcsXG4gIHVub3JnYW5pemVkOiAnVW5vcmdhbml6ZWQnLFxuICBuZXdGb2xkZXI6ICdOZXcgZm9sZGVyJyxcbiAgc2VhcmNoRm9sZGVyc1BsYWNlaG9sZGVyOiAnU2VhcmNoIGZvbGRlcnMuLi4nLFxuICBhbGxGb2xkZXJzOiAnQWxsIGZvbGRlcnMnLFxuICBzdWJmb2xkZXJzSW46ICdTdWJmb2xkZXJzIGluJyxcbiAgbW92ZVRvRm9sZGVyOiAnTW92ZSB0byBmb2xkZXInLFxuICBhZGRUYWc6ICdBZGQgVGFnJyxcbiAgZGVsZXRlOiAnRGVsZXRlJyxcbiAgc2VsZWN0QWxsOiAnU2VsZWN0IGFsbCcsXG4gIHRlc3RzQ291bnRTaW5ndWxhcjogJzEgdGVzdCcsXG4gIHRlc3RzQ291bnRQbHVyYWw6ICd7bn0gdGVzdHMnLFxuICBmb2xkZXJzQ291bnRTaW5ndWxhcjogJzEgZm9sZGVyJyxcbiAgZm9sZGVyc0NvdW50UGx1cmFsOiAne259IGZvbGRlcnMnLFxuICBzdWJmb2xkZXJDb3VudFNpbmd1bGFyOiAnMSBzdWJmb2xkZXInLFxuICBzdWJmb2xkZXJDb3VudFBsdXJhbDogJ3tufSBzdWJmb2xkZXJzJyxcbiAgb25lU3ViZm9sZGVyOiAnMSBzdWJmb2xkZXInLFxuICBzdWJmb2xkZXJzQ291bnQ6ICd7bn0gc3ViZm9sZGVycycsXG4gIGNsZWFyRmlsdGVyOiAnQ2xlYXIgZmlsdGVyJyxcbiAgbW92ZURpYWxvZ1RpdGxlOiAnTW92ZSB0byBGb2xkZXInLFxuICBtb3ZlRGlhbG9nQ2FuY2VsOiAnQ2FuY2VsJyxcbiAgbW92ZURpYWxvZ0NvbmZpcm06ICdNb3ZlIGhlcmUnLFxuICBtb3ZlRGlhbG9nUm9vdDogJ1Vub3JnYW5pemVkJyxcbiAgbW92ZURpYWxvZ0Rlc2NyaXB0aW9uU2luZ3VsYXI6ICdNb3ZpbmcgMSB0ZXN0IGNhc2Ug4oCUIHNlbGVjdCBkZXN0aW5hdGlvbicsXG4gIG1vdmVEaWFsb2dEZXNjcmlwdGlvblBsdXJhbDogJ01vdmluZyB7bn0gdGVzdCBjYXNlcyDigJQgc2VsZWN0IGRlc3RpbmF0aW9uJyxcblxuICBuZXdGb2xkZXJEaWFsb2dUaXRsZTogJ05ldyBGb2xkZXInLFxuICBuZXdGb2xkZXJEaWFsb2dEZXNjcmlwdGlvbjogJ1JlbmFtZSBhbnkgdGltZSBieSBkb3VibGUtY2xpY2tpbmcgaW4gdGhlIHRyZWUnLFxuICBuZXdGb2xkZXJEaWFsb2dOYW1lTGFiZWw6ICdGb2xkZXIgbmFtZScsXG4gIG5ld0ZvbGRlckRpYWxvZ05hbWVQbGFjZWhvbGRlcjogJ2UuZy4gQ2hlY2tvdXQgRmxvdywgVXNlciBBdXRoLCBQYXltZW50IFRlc3RzJyxcbiAgbmV3Rm9sZGVyRGlhbG9nUGFyZW50TGFiZWw6ICdQYXJlbnQgZm9sZGVyIChvcHRpb25hbCknLFxuICBuZXdGb2xkZXJEaWFsb2dQYXJlbnROb25lOiAnTm9uZScsXG4gIG5ld0ZvbGRlckRpYWxvZ0NvbG9yTGFiZWw6ICdGb2xkZXIgY29sb3IgKG9wdGlvbmFsKScsXG4gIG5ld0ZvbGRlckRpYWxvZ0NhbmNlbDogJ0NhbmNlbCcsXG4gIG5ld0ZvbGRlckRpYWxvZ0NvbmZpcm06ICdDcmVhdGUgZm9sZGVyJyxcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZVJlcXVpcmVkRXJyb3I6ICdGb2xkZXIgbmFtZSBpcyByZXF1aXJlZCcsXG4gIG5ld0ZvbGRlckRpYWxvZ05hbWVNYXhMZW5ndGhFcnJvcjogJ0ZvbGRlciBuYW1lIGNhbm5vdCBleGNlZWQgMjAgY2hhcmFjdGVycycsXG5cbiAgZm9sZGVyTWVudUNyZWF0ZVN1YmZvbGRlcjogJ0NyZWF0ZSBzdWJmb2xkZXInLFxuICBmb2xkZXJNZW51UmVuYW1lOiAnUmVuYW1lJyxcbiAgZm9sZGVyTWVudU1vdmU6ICdNb3ZlIGZvbGRlcicsXG4gIGZvbGRlck1lbnVEdXBsaWNhdGU6ICdEdXBsaWNhdGUgZm9sZGVyJyxcbiAgZm9sZGVyTWVudURlbGV0ZTogJ0RlbGV0ZSBmb2xkZXInLFxuXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ1RpdGxlOiAnRGVsZXRlIGZvbGRlcicsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlUZW1wbGF0ZTogJ1RoaXMgZm9sZGVyIGNvbnRhaW5zIHtpdGVtc30uIFdoYXQgc2hvdWxkIGhhcHBlbiB0byB0aGVtPycsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlUZXN0Q2FzZVNpbmd1bGFyOiAnMSB0ZXN0IGNhc2UnLFxuICBkZWxldGVGb2xkZXJEaWFsb2dCb2R5VGVzdENhc2VQbHVyYWw6ICd7bn0gdGVzdCBjYXNlcycsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlTdGVwR3JvdXBTaW5ndWxhcjogJzEgc3RlcCBncm91cCcsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlTdGVwR3JvdXBQbHVyYWw6ICd7bn0gc3RlcCBncm91cHMnLFxuICBkZWxldGVGb2xkZXJEaWFsb2dCb2R5Sm9pbjogJ2FuZCcsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ01vdmVUb1BhcmVudFRpdGxlOiAnTW92ZSB0byBwYXJlbnQgZm9sZGVyJyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvUGFyZW50RGVzY3JpcHRpb246ICdNb3ZlIHRoZW0gb25lIGxldmVsIHVwIOKAlCBub3RoaW5nIGlzIGxvc3QnLFxuICBkZWxldGVGb2xkZXJEaWFsb2dNb3ZlVG9Vbm9yZ2FuaXplZFRpdGxlOiAnTW92ZSB0byBVbm9yZ2FuaXplZCcsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ01vdmVUb1Vub3JnYW5pemVkRGVzY3JpcHRpb246ICdNb3ZlIHRoZW0gdG8gdGhlIFVub3JnYW5pemVkIHNlY3Rpb24nLFxuICBkZWxldGVGb2xkZXJEaWFsb2dDYW5jZWw6ICdDYW5jZWwnLFxuICBkZWxldGVGb2xkZXJEaWFsb2dDb25maXJtOiAnRGVsZXRlIGZvbGRlcicsXG5cbiAgZW1wdHlOb1Rlc3RzSW5Gb2xkZXJUaXRsZTogJ05vIFRlc3QgQ2FzZSBGb3VuZCcsXG4gIGVtcHR5Tm9UZXN0c0luRm9sZGVyRGVzY3JpcHRpb246ICdUaGlzIGZvbGRlciBkb2VzIG5vdCBjb250YWluIGFueSB0ZXN0IGNhc2VzIHlldC4nLFxuXG4gIGZvbGRlckNvbHVtbkxhYmVsOiAnRm9sZGVyJyxcbiAgdW5vcmdhbml6ZWRSb3dMYWJlbDogJ1Vub3JnYW5pemVkJyxcbiAgbm9Gb2xkZXJzRm91bmQ6ICdObyBGb2xkZXJzIEZvdW5kJyxcbiAgZm9sZGVyVG9vbHRpcFRvdGFsU2luZ3VsYXI6ICcxIHRvdGFsIHRlc3QgY2FzZSBpbmNsdWRpbmcgc3ViZm9sZGVycycsXG4gIGZvbGRlclRvb2x0aXBUb3RhbFBsdXJhbDogJ3tufSB0b3RhbCB0ZXN0IGNhc2VzIGluY2x1ZGluZyBzdWJmb2xkZXJzJyxcbn07XG5cbi8qKlxuICogRW1pdHRlZCBhZnRlciBhIHN1Y2Nlc3NmdWwgaW5saW5lIGZvbGRlciByZW5hbWUuIENhcnJpZXMgdGhlIGZ1bGwgcmVuYW1lZCBub2RlXG4gKiAod2l0aCB0aGUgbmV3IG5hbWUgYWxyZWFkeSBhcHBsaWVkKSBwbHVzIGl0cyBwYXJlbnQgaWQsIHNvIGhvc3RzIGNhbiBpc3N1ZVxuICogYSBjb21wbGV0ZSB1cGRhdGUgcmVxdWVzdCAoZS5nLiBgUFVUIC90ZXN0X2Nhc2VfZm9sZGVycy97aWR9YCkgd2l0aG91dCBhXG4gKiBzZWNvbmRhcnkgbG9va3VwIGFnYWluc3QgdGhlaXIgY2FjaGVkIHRyZWUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRm9sZGVyUmVuYW1lZFBheWxvYWQge1xuICBmb2xkZXI6IEZvbGRlck5vZGU7XG4gIHBhcmVudElkOiBudW1iZXIgfCBudWxsO1xuICAvKiogUHJldmlvdXMgbmFtZSwgdXNlZnVsIGZvciB1bmRvIG1lc3NhZ2VzIC8gYXVkaXQgbG9ncy4gKi9cbiAgcHJldmlvdXNOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9sZGVyQ3JlYXRlZFBheWxvYWQge1xuICBwYXJlbnRJZDogbnVtYmVyIHwgbnVsbDtcbiAgbmFtZTogc3RyaW5nO1xuICBjb2xvcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZWxldGUgc3RyYXRlZ2llcyBtYXRjaCB0aGUgYmFja2VuZCBgc3RyYXRlZ3lgIHF1ZXJ5IHBhcmFtIHZhbHVlcyBvblxuICogYERFTEVURSAvdGVzdF9jYXNlX2ZvbGRlcnMve2lkfT9zdHJhdGVneT3igKZgLiBPbmx5IHRoZSB0d28gbW92ZSBzdHJhdGVnaWVzXG4gKiBhcmUgY292ZXJlZCBieSB0aGUgbGlicmFyeSdzIGludGVybmFsIGRpYWxvZzsgYERFTEVURV9JRl9FTVBUWWAgaXMgdGhlXG4gKiBob3N0J3MgcmVzcG9uc2liaWxpdHkgKHByZWNoZWNrIGBjb3VudCA9PT0gMCAmJiB0b3RhbENvdW50ID09PSAwYCkuXG4gKi9cbmV4cG9ydCB0eXBlIEZvbGRlckRlbGV0ZVN0cmF0ZWd5ID0gJ01PVkVfVE9fUEFSRU5UJyB8ICdNT1ZFX1RPX1VOT1JHQU5JU0VEJztcblxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJEZWxldGVSZXF1ZXN0ZWRQYXlsb2FkIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICB0ZXN0Q291bnQ6IG51bWJlcjtcbiAgaGFzUGFyZW50OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZvbGRlck1vdmVSZXF1ZXN0ZWRQYXlsb2FkIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICBoYXNQYXJlbnQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9sZGVyTW92ZWRQYXlsb2FkIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmV3UGFyZW50SWQ6IG51bWJlciB8IG51bGw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9sZGVyRHVwbGljYXRlUmVxdWVzdGVkUGF5bG9hZCB7XG4gIGlkOiBudW1iZXI7XG4gIG5hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJEZWxldGVkUGF5bG9hZCB7XG4gIGlkOiBudW1iZXI7XG4gIHN0cmF0ZWd5PzogRm9sZGVyRGVsZXRlU3RyYXRlZ3k7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdHNNb3ZlZFBheWxvYWQge1xuICB0ZXN0SWRzOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+O1xuICB0YXJnZXRGb2xkZXJJZDogbnVtYmVyIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCdWxrQWN0aW9uSW52b2tlZFBheWxvYWQge1xuICBpZDogc3RyaW5nO1xuICBzZWxlY3RlZDogYW55W107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVvcmRlckxhYmVscyB7XG4gIHJlb3JkZXJCdXR0b246IHN0cmluZztcbiAgY2FuY2VsQnV0dG9uOiBzdHJpbmc7XG4gIGRvbmVCdXR0b246IHN0cmluZztcbiAgc2F2aW5nQnV0dG9uOiBzdHJpbmc7XG4gIGJhbm5lclRpdGxlOiBzdHJpbmc7XG4gIGJhbm5lckRlc2NyaXB0aW9uOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1JFT1JERVJfTEFCRUxTOiBSZW9yZGVyTGFiZWxzID0ge1xuICByZW9yZGVyQnV0dG9uOiAnUmVvcmRlcicsXG4gIGNhbmNlbEJ1dHRvbjogJ0NhbmNlbCcsXG4gIGRvbmVCdXR0b246ICdEb25lJyxcbiAgc2F2aW5nQnV0dG9uOiAnU2F2aW5nLi4uJyxcbiAgYmFubmVyVGl0bGU6ICdSZW9yZGVyIG1vZGUnLFxuICBiYW5uZXJEZXNjcmlwdGlvbjogJ0RyYWcgcm93cyB1c2luZyB0aGUgaGFuZGxlIHRvIHJlYXJyYW5nZS4nLFxufTtcblxuZXhwb3J0IGludGVyZmFjZSBSZW9yZGVyU2F2ZVBheWxvYWQge1xuICBvcmRlcmVkSXRlbXM6IGFueVtdO1xufVxuXG5leHBvcnQgY29uc3QgUk9XX0RSQUdfTUlNRSA9ICdhcHBsaWNhdGlvbi94LWNxYS10ZXN0LWlkcyc7XG5cbi8qKiBDdXN0b20gTUlNRSBmb3IgZm9sZGVyLXJvdyBkcmFncyBpbiB0aGUgc2lkZWJhci4gUGF5bG9hZCBpcyBhIEpTT04tc3RyaW5naWZpZWQgZm9sZGVyIGlkLiAqL1xuZXhwb3J0IGNvbnN0IEZPTERFUl9EUkFHX01JTUUgPSAnYXBwbGljYXRpb24veC1jcWEtZm9sZGVyLWlkJztcbiJdfQ==
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxhci10YWJsZS10ZW1wbGF0ZS5tb2RlbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3RlbXBsYXRlcy9tb2R1bGFyLXRhYmxlLXRlbXBsYXRlL21vZHVsYXItdGFibGUtdGVtcGxhdGUubW9kZWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWdEQSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBa0I7SUFDbkQsV0FBVyxFQUFFLElBQUk7SUFDakIsY0FBYyxFQUFFLElBQUk7SUFDcEIsY0FBYyxFQUFFLElBQUk7SUFDcEIsc0JBQXNCLEVBQUUsSUFBSTtJQUM1QixvQkFBb0IsRUFBRSxJQUFJO0lBQzFCLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLGlCQUFpQixFQUFFLElBQUk7SUFDdkIsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLG9CQUFvQixFQUFFLEtBQUs7SUFDM0Isa0JBQWtCLEVBQUUsSUFBSTtJQUN4QixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLGtCQUFrQixFQUFFLElBQUk7SUFDeEIsZ0JBQWdCLEVBQUUsSUFBSTtDQUN2QixDQUFDO0FBRUY7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsUUFBUSxDQUFDO0FBbUYvQyxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBa0I7SUFDbkQsT0FBTyxFQUFFLFNBQVM7SUFDbEIsU0FBUyxFQUFFLFdBQVc7SUFDdEIsV0FBVyxFQUFFLGFBQWE7SUFDMUIsU0FBUyxFQUFFLFlBQVk7SUFDdkIsd0JBQXdCLEVBQUUsbUJBQW1CO0lBQzdDLFVBQVUsRUFBRSxhQUFhO0lBQ3pCLFlBQVksRUFBRSxlQUFlO0lBQzdCLFlBQVksRUFBRSxnQkFBZ0I7SUFDOUIsTUFBTSxFQUFFLFNBQVM7SUFDakIsTUFBTSxFQUFFLFFBQVE7SUFDaEIsU0FBUyxFQUFFLFlBQVk7SUFDdkIsa0JBQWtCLEVBQUUsUUFBUTtJQUM1QixnQkFBZ0IsRUFBRSxXQUFXO0lBQzdCLG9CQUFvQixFQUFFLFVBQVU7SUFDaEMsa0JBQWtCLEVBQUUsYUFBYTtJQUNqQyxzQkFBc0IsRUFBRSxhQUFhO0lBQ3JDLG9CQUFvQixFQUFFLGdCQUFnQjtJQUN0QyxZQUFZLEVBQUUsYUFBYTtJQUMzQixlQUFlLEVBQUUsZ0JBQWdCO0lBQ2pDLFdBQVcsRUFBRSxjQUFjO0lBQzNCLGVBQWUsRUFBRSxnQkFBZ0I7SUFDakMsZ0JBQWdCLEVBQUUsUUFBUTtJQUMxQixpQkFBaUIsRUFBRSxXQUFXO0lBQzlCLGNBQWMsRUFBRSxhQUFhO0lBQzdCLDZCQUE2QixFQUFFLHlDQUF5QztJQUN4RSwyQkFBMkIsRUFBRSw0Q0FBNEM7SUFFekUsb0JBQW9CLEVBQUUsWUFBWTtJQUNsQywwQkFBMEIsRUFBRSxnREFBZ0Q7SUFDNUUsd0JBQXdCLEVBQUUsYUFBYTtJQUN2Qyw4QkFBOEIsRUFBRSw4Q0FBOEM7SUFDOUUsMEJBQTBCLEVBQUUsMEJBQTBCO0lBQ3RELHlCQUF5QixFQUFFLE1BQU07SUFDakMseUJBQXlCLEVBQUUseUJBQXlCO0lBQ3BELHFCQUFxQixFQUFFLFFBQVE7SUFDL0Isc0JBQXNCLEVBQUUsZUFBZTtJQUN2QyxnQ0FBZ0MsRUFBRSx5QkFBeUI7SUFDM0QsaUNBQWlDLEVBQUUseUNBQXlDO0lBRTVFLHlCQUF5QixFQUFFLGtCQUFrQjtJQUM3QyxnQkFBZ0IsRUFBRSxRQUFRO0lBQzFCLGNBQWMsRUFBRSxhQUFhO0lBQzdCLG1CQUFtQixFQUFFLGtCQUFrQjtJQUN2QyxnQkFBZ0IsRUFBRSxlQUFlO0lBRWpDLHVCQUF1QixFQUFFLGVBQWU7SUFDeEMsOEJBQThCLEVBQUUsMkRBQTJEO0lBQzNGLHNDQUFzQyxFQUFFLGFBQWE7SUFDckQsb0NBQW9DLEVBQUUsZ0JBQWdCO0lBQ3RELHVDQUF1QyxFQUFFLGNBQWM7SUFDdkQscUNBQXFDLEVBQUUsaUJBQWlCO0lBQ3hELDBCQUEwQixFQUFFLEtBQUs7SUFDakMsbUNBQW1DLEVBQUUsdUJBQXVCO0lBQzVELHlDQUF5QyxFQUFFLDBDQUEwQztJQUNyRix3Q0FBd0MsRUFBRSxxQkFBcUI7SUFDL0QsOENBQThDLEVBQUUsc0NBQXNDO0lBQ3RGLHdCQUF3QixFQUFFLFFBQVE7SUFDbEMseUJBQXlCLEVBQUUsZUFBZTtJQUUxQyx5QkFBeUIsRUFBRSxvQkFBb0I7SUFDL0MsK0JBQStCLEVBQUUsa0RBQWtEO0lBRW5GLGlCQUFpQixFQUFFLFFBQVE7SUFDM0IsbUJBQW1CLEVBQUUsYUFBYTtJQUNsQyxjQUFjLEVBQUUsa0JBQWtCO0lBQ2xDLDBCQUEwQixFQUFFLHdDQUF3QztJQUNwRSx3QkFBd0IsRUFBRSwyQ0FBMkM7Q0FDdEUsQ0FBQztBQTRFRixNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBa0I7SUFDbkQsYUFBYSxFQUFFLFNBQVM7SUFDeEIsWUFBWSxFQUFFLFFBQVE7SUFDdEIsVUFBVSxFQUFFLE1BQU07SUFDbEIsWUFBWSxFQUFFLFdBQVc7SUFDekIsV0FBVyxFQUFFLGNBQWM7SUFDM0IsaUJBQWlCLEVBQUUsMENBQTBDO0NBQzlELENBQUM7QUFNRixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsNEJBQTRCLENBQUM7QUFFMUQsZ0dBQWdHO0FBQ2hHLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLDZCQUE2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBGb2xkZXJOb2RlIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xuICAvKiogRGlyZWN0IHRlc3QtY2FzZSBjb3VudCDigJQgY2FzZXMgd2l0aCBgZm9sZGVySWQgPT09IHRoaXMuaWRgLiBSZW5kZXJlZCBhcyB0aGUgcm93IGJhZGdlLiAqL1xuICBjb3VudD86IG51bWJlcjtcbiAgLyoqIFRvdGFsIHRlc3QtY2FzZSBjb3VudCBpbmNsdWRpbmcgYWxsIGRlc2NlbmRhbnRzLiBSZW5kZXJlZCBhcyBhIHRvb2x0aXAgb24gdGhlIGZvbGRlciByb3cuICovXG4gIHRvdGFsQ291bnQ/OiBudW1iZXI7XG4gIGNvbG9yPzogc3RyaW5nO1xuICBjaGlsZHJlbj86IEZvbGRlck5vZGVbXTtcbiAgLyoqIEJhY2tlbmQgaGludDogdHJ1ZSB3aGVuIHRoaXMgbm9kZSBoYXMgYXQgbGVhc3Qgb25lIGRpcmVjdCBjaGlsZC4gRHJpdmVzXG4gICAqICB0aGUgc2lkZWJhciBjaGV2cm9uIHVuZGVyIGxhenkgbG9hZGluZywgc28gdGhlIGFmZm9yZGFuY2Ugc2hvd3MgZXZlblxuICAgKiAgYmVmb3JlIGBjaGlsZHJlbmAgaGFzIGJlZW4gZmV0Y2hlZC4gKi9cbiAgaGFzQ2hpbGRyZW4/OiBib29sZWFuO1xuICAvKiogQmFja2VuZC1yZXBvcnRlZCB0b3RhbCBudW1iZXIgb2YgZGlyZWN0IGNoaWxkcmVuLiBUaGUgc2lkZWJhciBzaG93cyBhXG4gICAqICBcIkxvYWQgbW9yZVwiIHJvdyB3aGVuIGAoY2hpbGRyZW4/Lmxlbmd0aCA/PyAwKSA8IHRvdGFsQ2hpbGRyZW5gLiAqL1xuICB0b3RhbENoaWxkcmVuPzogbnVtYmVyO1xuICAvKiogTGFzdCAwLWJhc2VkIHBhZ2UgYWxyZWFkeSBmZXRjaGVkIGludG8gYGNoaWxkcmVuYC4gYHVuZGVmaW5lZGAgbWVhbnMgdGhlXG4gICAqICBzdWJ0cmVlIGhhcyBub3QgYmVlbiBsb2FkZWQgeWV0IOKAlCB0aGUgaG9zdCBzaG91bGQgZmV0Y2ggb24gZmlyc3QgZXhwYW5kLiAqL1xuICBsb2FkZWRQYWdlcz86IG51bWJlcjtcbiAgLyoqIFRydWUgd2hpbGUgYSBjaGlsZHJlbi1wYWdlIGZldGNoIGlzIGluIGZsaWdodCwgc28gdGhlIHNpZGViYXIgY2FuIHJlbmRlclxuICAgKiAgYSBzcGlubmVyIHJvdyBhbmQgdGhlIGhvc3QgY2FuIHN1cHByZXNzIGR1cGxpY2F0ZSByZXF1ZXN0cy4gKi9cbiAgY2hpbGRyZW5Mb2FkaW5nPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IHR5cGUgRm9sZGVySWRBY2Nlc3NvciA9IChyb3c6IGFueSkgPT4gbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuZXhwb3J0IGludGVyZmFjZSBNb2R1bGFyQ29uZmlnIHtcbiAgc2hvd1NpZGViYXI6IGJvb2xlYW47XG4gIHNob3dCcmVhZGNydW1iOiBib29sZWFuO1xuICBzaG93Rm9sZGVyR3JpZDogYm9vbGVhbjtcbiAgc2hvd1Vub3JnYW5pemVkU2VjdGlvbjogYm9vbGVhbjtcbiAgc2hvd1N1YmZvbGRlclNlY3Rpb246IGJvb2xlYW47XG4gIHNob3dDb3VudHM6IGJvb2xlYW47XG4gIGFsbG93Q3JlYXRlRm9sZGVyOiBib29sZWFuO1xuICBhbGxvd1JlbmFtZUZvbGRlcjogYm9vbGVhbjtcbiAgYWxsb3dEZWxldGVGb2xkZXI6IGJvb2xlYW47XG4gIGFsbG93RHVwbGljYXRlRm9sZGVyOiBib29sZWFuO1xuICBhbGxvd05lc3RlZEZvbGRlcnM6IGJvb2xlYW47XG4gIGFsbG93VGVzdERyYWdEcm9wOiBib29sZWFuO1xuICBhbGxvd0J1bGtTZWxlY3Rpb246IGJvb2xlYW47XG4gIC8qKlxuICAgKiBXaGVuIHRydWUsIHRoZSB0YWJsZSByZW5kZXJzIGEgZm9sZGVyIGNvbHVtbiAoaWNvbiArIGZvbGRlciBuYW1lKSBhbmQgbGlzdHMgaXQgaW4gdGhlXG4gICAqIHNldHRpbmdzIGRyb3Bkb3duLiBEZWZhdWx0IHZpc2liaWxpdHkgb24gZmlyc3QgaW5pdCBmb2xsb3dzIGB2aWV3TW9kZWA6IHNob3duIGluIGxpc3QsXG4gICAqIGhpZGRlbiBpbiBtb2R1bGFyLiBPbmNlIHRoZSB1c2VyIHRvZ2dsZXMgaXQgdGhlIGNob2ljZSBwZXJzaXN0cy5cbiAgICovXG4gIHNob3dGb2xkZXJDb2x1bW46IGJvb2xlYW47XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX01PRFVMQVJfQ09ORklHOiBNb2R1bGFyQ29uZmlnID0ge1xuICBzaG93U2lkZWJhcjogdHJ1ZSxcbiAgc2hvd0JyZWFkY3J1bWI6IHRydWUsXG4gIHNob3dGb2xkZXJHcmlkOiB0cnVlLFxuICBzaG93VW5vcmdhbml6ZWRTZWN0aW9uOiB0cnVlLFxuICBzaG93U3ViZm9sZGVyU2VjdGlvbjogdHJ1ZSxcbiAgc2hvd0NvdW50czogdHJ1ZSxcbiAgYWxsb3dDcmVhdGVGb2xkZXI6IHRydWUsXG4gIGFsbG93UmVuYW1lRm9sZGVyOiB0cnVlLFxuICBhbGxvd0RlbGV0ZUZvbGRlcjogdHJ1ZSxcbiAgYWxsb3dEdXBsaWNhdGVGb2xkZXI6IGZhbHNlLFxuICBhbGxvd05lc3RlZEZvbGRlcnM6IHRydWUsXG4gIGFsbG93VGVzdERyYWdEcm9wOiB0cnVlLFxuICBhbGxvd0J1bGtTZWxlY3Rpb246IHRydWUsXG4gIHNob3dGb2xkZXJDb2x1bW46IHRydWUsXG59O1xuXG4vKipcbiAqIFJlc2VydmVkIGZpZWxkSWQgZm9yIHRoZSBhdXRvLWluamVjdGVkIGZvbGRlciBjb2x1bW4uIEhvc3RzIHNob3VsZCBhdm9pZFxuICogZGVmaW5pbmcgYSBjb2x1bW4gd2l0aCB0aGlzIGlkIG9mIHRoZWlyIG93bi5cbiAqL1xuZXhwb3J0IGNvbnN0IEZPTERFUl9DT0xVTU5fRklFTERfSUQgPSAnZm9sZGVyJztcblxuZXhwb3J0IGludGVyZmFjZSBNb2R1bGFyTGFiZWxzIHtcbiAgZm9sZGVyczogc3RyaW5nO1xuICBvcmdhbml6ZWQ6IHN0cmluZztcbiAgdW5vcmdhbml6ZWQ6IHN0cmluZztcbiAgbmV3Rm9sZGVyOiBzdHJpbmc7XG4gIHNlYXJjaEZvbGRlcnNQbGFjZWhvbGRlcjogc3RyaW5nO1xuICBhbGxGb2xkZXJzOiBzdHJpbmc7XG4gIHN1YmZvbGRlcnNJbjogc3RyaW5nO1xuICBtb3ZlVG9Gb2xkZXI6IHN0cmluZztcbiAgYWRkVGFnOiBzdHJpbmc7XG4gIGRlbGV0ZTogc3RyaW5nO1xuICBzZWxlY3RBbGw6IHN0cmluZztcbiAgdGVzdHNDb3VudFNpbmd1bGFyOiBzdHJpbmc7XG4gIHRlc3RzQ291bnRQbHVyYWw6IHN0cmluZztcbiAgZm9sZGVyc0NvdW50U2luZ3VsYXI6IHN0cmluZztcbiAgZm9sZGVyc0NvdW50UGx1cmFsOiBzdHJpbmc7XG4gIHN1YmZvbGRlckNvdW50U2luZ3VsYXI6IHN0cmluZztcbiAgc3ViZm9sZGVyQ291bnRQbHVyYWw6IHN0cmluZztcbiAgb25lU3ViZm9sZGVyOiBzdHJpbmc7XG4gIHN1YmZvbGRlcnNDb3VudDogc3RyaW5nO1xuICBjbGVhckZpbHRlcjogc3RyaW5nO1xuICBtb3ZlRGlhbG9nVGl0bGU6IHN0cmluZztcbiAgbW92ZURpYWxvZ0NhbmNlbDogc3RyaW5nO1xuICBtb3ZlRGlhbG9nQ29uZmlybTogc3RyaW5nO1xuICBtb3ZlRGlhbG9nUm9vdDogc3RyaW5nO1xuICBtb3ZlRGlhbG9nRGVzY3JpcHRpb25TaW5ndWxhcjogc3RyaW5nO1xuICBtb3ZlRGlhbG9nRGVzY3JpcHRpb25QbHVyYWw6IHN0cmluZztcblxuICAvLyBOZXcgRm9sZGVyIGRpYWxvZ1xuICBuZXdGb2xkZXJEaWFsb2dUaXRsZTogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dEZXNjcmlwdGlvbjogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dOYW1lTGFiZWw6IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZVBsYWNlaG9sZGVyOiBzdHJpbmc7XG4gIG5ld0ZvbGRlckRpYWxvZ1BhcmVudExhYmVsOiBzdHJpbmc7XG4gIG5ld0ZvbGRlckRpYWxvZ1BhcmVudE5vbmU6IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nQ29sb3JMYWJlbDogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dDYW5jZWw6IHN0cmluZztcbiAgbmV3Rm9sZGVyRGlhbG9nQ29uZmlybTogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dOYW1lUmVxdWlyZWRFcnJvcjogc3RyaW5nO1xuICBuZXdGb2xkZXJEaWFsb2dOYW1lTWF4TGVuZ3RoRXJyb3I6IHN0cmluZztcblxuICAvLyBGb2xkZXIgcm93IGNvbnRleHQgbWVudSAocmlnaHQtY2xpY2sgLyBlbGxpcHNpcylcbiAgZm9sZGVyTWVudUNyZWF0ZVN1YmZvbGRlcjogc3RyaW5nO1xuICBmb2xkZXJNZW51UmVuYW1lOiBzdHJpbmc7XG4gIGZvbGRlck1lbnVNb3ZlOiBzdHJpbmc7XG4gIGZvbGRlck1lbnVEdXBsaWNhdGU6IHN0cmluZztcbiAgZm9sZGVyTWVudURlbGV0ZTogc3RyaW5nO1xuXG4gIC8vIERlbGV0ZSBGb2xkZXIgZGlhbG9nXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ1RpdGxlOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlUZW1wbGF0ZTogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dCb2R5VGVzdENhc2VTaW5ndWxhcjogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dCb2R5VGVzdENhc2VQbHVyYWw6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVN0ZXBHcm91cFNpbmd1bGFyOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlTdGVwR3JvdXBQbHVyYWw6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keUpvaW46IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvUGFyZW50VGl0bGU6IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvUGFyZW50RGVzY3JpcHRpb246IHN0cmluZztcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvVW5vcmdhbml6ZWRUaXRsZTogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dNb3ZlVG9Vbm9yZ2FuaXplZERlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0NhbmNlbDogc3RyaW5nO1xuICBkZWxldGVGb2xkZXJEaWFsb2dDb25maXJtOiBzdHJpbmc7XG5cbiAgLy8gQXV0by1kZXJpdmVkIGVtcHR5IHN0YXRlcyAoc2hvd24gd2hlbiBwYWdlZFJvd3MgaXMgZW1wdHkgYW5kIGhvc3QgZGlkIG5vdCBzZXQgaXNFbXB0eVN0YXRlKVxuICBlbXB0eU5vVGVzdHNJbkZvbGRlclRpdGxlOiBzdHJpbmc7XG4gIGVtcHR5Tm9UZXN0c0luRm9sZGVyRGVzY3JpcHRpb246IHN0cmluZztcblxuICAvKiogSGVhZGVyIGxhYmVsIGZvciB0aGUgYXV0by1pbmplY3RlZCBmb2xkZXIgY29sdW1uLiAqL1xuICBmb2xkZXJDb2x1bW5MYWJlbDogc3RyaW5nO1xuICAvKiogQ2VsbCBsYWJlbCBmb3Igcm93cyB3aXRoIG5vIGZvbGRlcklkIChpLmUuIHRoZSBcIlVub3JnYW5pemVkXCIgYnVja2V0KS4gKi9cbiAgdW5vcmdhbml6ZWRSb3dMYWJlbDogc3RyaW5nO1xuICAvKiogU2hvd24gaW4gdGhlIGZvbGRlciBzaWRlYmFyIHdoZW4gdGhlIHNlYXJjaCBpbnB1dCBmaWx0ZXJzIG91dCBldmVyeSBmb2xkZXIuICovXG4gIG5vRm9sZGVyc0ZvdW5kOiBzdHJpbmc7XG4gIC8qKiBTaWRlYmFyIGZvbGRlci1yb3cgaG92ZXIgdG9vbHRpcCBjb3VudCBsaW5lLiBge259YCBpcyB0aGUgZGVzY2VuZGFudCB0b3RhbFxuICAgKiAgKEZvbGRlck5vZGUudG90YWxDb3VudCkuIFRoZSBob3N0IHN3YXBzIHRoZSBub3VuIGZvciBcInN0ZXAgZ3JvdXBcIiB3aGVuIGluXG4gICAqICBzdGVwLWdyb3VwIG1vZGUgYnkgb3ZlcnJpZGluZyB0aGVzZSB0d28ga2V5cy4gVGhlIGZ1bGwgdG9vbHRpcCBpcyBjb21wb3NlZFxuICAgKiAgYXMgYCR7bm9kZS5uYW1lfVxcbiR7dHBsLnJlcGxhY2UoJ3tufScsIHRvdGFsKX1gLiAqL1xuICBmb2xkZXJUb29sdGlwVG90YWxTaW5ndWxhcjogc3RyaW5nO1xuICBmb2xkZXJUb29sdGlwVG90YWxQbHVyYWw6IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfTU9EVUxBUl9MQUJFTFM6IE1vZHVsYXJMYWJlbHMgPSB7XG4gIGZvbGRlcnM6ICdGb2xkZXJzJyxcbiAgb3JnYW5pemVkOiAnT3JnYW5pemVkJyxcbiAgdW5vcmdhbml6ZWQ6ICdVbm9yZ2FuaXplZCcsXG4gIG5ld0ZvbGRlcjogJ05ldyBmb2xkZXInLFxuICBzZWFyY2hGb2xkZXJzUGxhY2Vob2xkZXI6ICdTZWFyY2ggZm9sZGVycy4uLicsXG4gIGFsbEZvbGRlcnM6ICdBbGwgZm9sZGVycycsXG4gIHN1YmZvbGRlcnNJbjogJ1N1YmZvbGRlcnMgaW4nLFxuICBtb3ZlVG9Gb2xkZXI6ICdNb3ZlIHRvIGZvbGRlcicsXG4gIGFkZFRhZzogJ0FkZCBUYWcnLFxuICBkZWxldGU6ICdEZWxldGUnLFxuICBzZWxlY3RBbGw6ICdTZWxlY3QgYWxsJyxcbiAgdGVzdHNDb3VudFNpbmd1bGFyOiAnMSB0ZXN0JyxcbiAgdGVzdHNDb3VudFBsdXJhbDogJ3tufSB0ZXN0cycsXG4gIGZvbGRlcnNDb3VudFNpbmd1bGFyOiAnMSBmb2xkZXInLFxuICBmb2xkZXJzQ291bnRQbHVyYWw6ICd7bn0gZm9sZGVycycsXG4gIHN1YmZvbGRlckNvdW50U2luZ3VsYXI6ICcxIHN1YmZvbGRlcicsXG4gIHN1YmZvbGRlckNvdW50UGx1cmFsOiAne259IHN1YmZvbGRlcnMnLFxuICBvbmVTdWJmb2xkZXI6ICcxIHN1YmZvbGRlcicsXG4gIHN1YmZvbGRlcnNDb3VudDogJ3tufSBzdWJmb2xkZXJzJyxcbiAgY2xlYXJGaWx0ZXI6ICdDbGVhciBmaWx0ZXInLFxuICBtb3ZlRGlhbG9nVGl0bGU6ICdNb3ZlIHRvIEZvbGRlcicsXG4gIG1vdmVEaWFsb2dDYW5jZWw6ICdDYW5jZWwnLFxuICBtb3ZlRGlhbG9nQ29uZmlybTogJ01vdmUgaGVyZScsXG4gIG1vdmVEaWFsb2dSb290OiAnVW5vcmdhbml6ZWQnLFxuICBtb3ZlRGlhbG9nRGVzY3JpcHRpb25TaW5ndWxhcjogJ01vdmluZyAxIHRlc3QgY2FzZSDigJQgc2VsZWN0IGRlc3RpbmF0aW9uJyxcbiAgbW92ZURpYWxvZ0Rlc2NyaXB0aW9uUGx1cmFsOiAnTW92aW5nIHtufSB0ZXN0IGNhc2VzIOKAlCBzZWxlY3QgZGVzdGluYXRpb24nLFxuXG4gIG5ld0ZvbGRlckRpYWxvZ1RpdGxlOiAnTmV3IEZvbGRlcicsXG4gIG5ld0ZvbGRlckRpYWxvZ0Rlc2NyaXB0aW9uOiAnUmVuYW1lIGFueSB0aW1lIGJ5IGRvdWJsZS1jbGlja2luZyBpbiB0aGUgdHJlZScsXG4gIG5ld0ZvbGRlckRpYWxvZ05hbWVMYWJlbDogJ0ZvbGRlciBuYW1lJyxcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZVBsYWNlaG9sZGVyOiAnZS5nLiBDaGVja291dCBGbG93LCBVc2VyIEF1dGgsIFBheW1lbnQgVGVzdHMnLFxuICBuZXdGb2xkZXJEaWFsb2dQYXJlbnRMYWJlbDogJ1BhcmVudCBmb2xkZXIgKG9wdGlvbmFsKScsXG4gIG5ld0ZvbGRlckRpYWxvZ1BhcmVudE5vbmU6ICdOb25lJyxcbiAgbmV3Rm9sZGVyRGlhbG9nQ29sb3JMYWJlbDogJ0ZvbGRlciBjb2xvciAob3B0aW9uYWwpJyxcbiAgbmV3Rm9sZGVyRGlhbG9nQ2FuY2VsOiAnQ2FuY2VsJyxcbiAgbmV3Rm9sZGVyRGlhbG9nQ29uZmlybTogJ0NyZWF0ZSBmb2xkZXInLFxuICBuZXdGb2xkZXJEaWFsb2dOYW1lUmVxdWlyZWRFcnJvcjogJ0ZvbGRlciBuYW1lIGlzIHJlcXVpcmVkJyxcbiAgbmV3Rm9sZGVyRGlhbG9nTmFtZU1heExlbmd0aEVycm9yOiAnRm9sZGVyIG5hbWUgY2Fubm90IGV4Y2VlZCAyMCBjaGFyYWN0ZXJzJyxcblxuICBmb2xkZXJNZW51Q3JlYXRlU3ViZm9sZGVyOiAnQ3JlYXRlIHN1YmZvbGRlcicsXG4gIGZvbGRlck1lbnVSZW5hbWU6ICdSZW5hbWUnLFxuICBmb2xkZXJNZW51TW92ZTogJ01vdmUgZm9sZGVyJyxcbiAgZm9sZGVyTWVudUR1cGxpY2F0ZTogJ0R1cGxpY2F0ZSBmb2xkZXInLFxuICBmb2xkZXJNZW51RGVsZXRlOiAnRGVsZXRlIGZvbGRlcicsXG5cbiAgZGVsZXRlRm9sZGVyRGlhbG9nVGl0bGU6ICdEZWxldGUgZm9sZGVyJyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVRlbXBsYXRlOiAnVGhpcyBmb2xkZXIgY29udGFpbnMge2l0ZW1zfS4gV2hhdCBzaG91bGQgaGFwcGVuIHRvIHRoZW0/JyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVRlc3RDYXNlU2luZ3VsYXI6ICcxIHRlc3QgY2FzZScsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlUZXN0Q2FzZVBsdXJhbDogJ3tufSB0ZXN0IGNhc2VzJyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVN0ZXBHcm91cFNpbmd1bGFyOiAnMSBzdGVwIGdyb3VwJyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nQm9keVN0ZXBHcm91cFBsdXJhbDogJ3tufSBzdGVwIGdyb3VwcycsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0JvZHlKb2luOiAnYW5kJyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvUGFyZW50VGl0bGU6ICdNb3ZlIHRvIHBhcmVudCBmb2xkZXInLFxuICBkZWxldGVGb2xkZXJEaWFsb2dNb3ZlVG9QYXJlbnREZXNjcmlwdGlvbjogJ01vdmUgdGhlbSBvbmUgbGV2ZWwgdXAg4oCUIG5vdGhpbmcgaXMgbG9zdCcsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ01vdmVUb1Vub3JnYW5pemVkVGl0bGU6ICdNb3ZlIHRvIFVub3JnYW5pemVkJyxcbiAgZGVsZXRlRm9sZGVyRGlhbG9nTW92ZVRvVW5vcmdhbml6ZWREZXNjcmlwdGlvbjogJ01vdmUgdGhlbSB0byB0aGUgVW5vcmdhbml6ZWQgc2VjdGlvbicsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0NhbmNlbDogJ0NhbmNlbCcsXG4gIGRlbGV0ZUZvbGRlckRpYWxvZ0NvbmZpcm06ICdEZWxldGUgZm9sZGVyJyxcblxuICBlbXB0eU5vVGVzdHNJbkZvbGRlclRpdGxlOiAnTm8gVGVzdCBDYXNlIEZvdW5kJyxcbiAgZW1wdHlOb1Rlc3RzSW5Gb2xkZXJEZXNjcmlwdGlvbjogJ1RoaXMgZm9sZGVyIGRvZXMgbm90IGNvbnRhaW4gYW55IHRlc3QgY2FzZXMgeWV0LicsXG5cbiAgZm9sZGVyQ29sdW1uTGFiZWw6ICdGb2xkZXInLFxuICB1bm9yZ2FuaXplZFJvd0xhYmVsOiAnVW5vcmdhbml6ZWQnLFxuICBub0ZvbGRlcnNGb3VuZDogJ05vIEZvbGRlcnMgRm91bmQnLFxuICBmb2xkZXJUb29sdGlwVG90YWxTaW5ndWxhcjogJzEgdG90YWwgdGVzdCBjYXNlIGluY2x1ZGluZyBzdWJmb2xkZXJzJyxcbiAgZm9sZGVyVG9vbHRpcFRvdGFsUGx1cmFsOiAne259IHRvdGFsIHRlc3QgY2FzZXMgaW5jbHVkaW5nIHN1YmZvbGRlcnMnLFxufTtcblxuLyoqXG4gKiBFbWl0dGVkIGFmdGVyIGEgc3VjY2Vzc2Z1bCBpbmxpbmUgZm9sZGVyIHJlbmFtZS4gQ2FycmllcyB0aGUgZnVsbCByZW5hbWVkIG5vZGVcbiAqICh3aXRoIHRoZSBuZXcgbmFtZSBhbHJlYWR5IGFwcGxpZWQpIHBsdXMgaXRzIHBhcmVudCBpZCwgc28gaG9zdHMgY2FuIGlzc3VlXG4gKiBhIGNvbXBsZXRlIHVwZGF0ZSByZXF1ZXN0IChlLmcuIGBQVVQgL3Rlc3RfY2FzZV9mb2xkZXJzL3tpZH1gKSB3aXRob3V0IGFcbiAqIHNlY29uZGFyeSBsb29rdXAgYWdhaW5zdCB0aGVpciBjYWNoZWQgdHJlZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJSZW5hbWVkUGF5bG9hZCB7XG4gIGZvbGRlcjogRm9sZGVyTm9kZTtcbiAgcGFyZW50SWQ6IG51bWJlciB8IG51bGw7XG4gIC8qKiBQcmV2aW91cyBuYW1lLCB1c2VmdWwgZm9yIHVuZG8gbWVzc2FnZXMgLyBhdWRpdCBsb2dzLiAqL1xuICBwcmV2aW91c05hbWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJDcmVhdGVkUGF5bG9hZCB7XG4gIHBhcmVudElkOiBudW1iZXIgfCBudWxsO1xuICBuYW1lOiBzdHJpbmc7XG4gIGNvbG9yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIERlbGV0ZSBzdHJhdGVnaWVzIG1hdGNoIHRoZSBiYWNrZW5kIGBzdHJhdGVneWAgcXVlcnkgcGFyYW0gdmFsdWVzIG9uXG4gKiBgREVMRVRFIC90ZXN0X2Nhc2VfZm9sZGVycy97aWR9P3N0cmF0ZWd5PeKApmAuIE9ubHkgdGhlIHR3byBtb3ZlIHN0cmF0ZWdpZXNcbiAqIGFyZSBjb3ZlcmVkIGJ5IHRoZSBsaWJyYXJ5J3MgaW50ZXJuYWwgZGlhbG9nOyBgREVMRVRFX0lGX0VNUFRZYCBpcyB0aGVcbiAqIGhvc3QncyByZXNwb25zaWJpbGl0eSAocHJlY2hlY2sgYGNvdW50ID09PSAwICYmIHRvdGFsQ291bnQgPT09IDBgKS5cbiAqL1xuZXhwb3J0IHR5cGUgRm9sZGVyRGVsZXRlU3RyYXRlZ3kgPSAnTU9WRV9UT19QQVJFTlQnIHwgJ01PVkVfVE9fVU5PUkdBTklTRUQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZvbGRlckRlbGV0ZVJlcXVlc3RlZFBheWxvYWQge1xuICBpZDogbnVtYmVyO1xuICBuYW1lOiBzdHJpbmc7XG4gIHRlc3RDb3VudDogbnVtYmVyO1xuICBoYXNQYXJlbnQ6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9sZGVyTW92ZVJlcXVlc3RlZFBheWxvYWQge1xuICBpZDogbnVtYmVyO1xuICBuYW1lOiBzdHJpbmc7XG4gIGhhc1BhcmVudDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJNb3ZlZFBheWxvYWQge1xuICBpZDogbnVtYmVyO1xuICBuZXdQYXJlbnRJZDogbnVtYmVyIHwgbnVsbDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGb2xkZXJEdXBsaWNhdGVSZXF1ZXN0ZWRQYXlsb2FkIHtcbiAgaWQ6IG51bWJlcjtcbiAgbmFtZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZvbGRlckRlbGV0ZWRQYXlsb2FkIHtcbiAgaWQ6IG51bWJlcjtcbiAgc3RyYXRlZ3k/OiBGb2xkZXJEZWxldGVTdHJhdGVneTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0c01vdmVkUGF5bG9hZCB7XG4gIHRlc3RJZHM6IEFycmF5PHN0cmluZyB8IG51bWJlcj47XG4gIHRhcmdldEZvbGRlcklkOiBudW1iZXIgfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1bGtBY3Rpb25JbnZva2VkUGF5bG9hZCB7XG4gIGlkOiBzdHJpbmc7XG4gIHNlbGVjdGVkOiBhbnlbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZW9yZGVyTGFiZWxzIHtcbiAgcmVvcmRlckJ1dHRvbjogc3RyaW5nO1xuICBjYW5jZWxCdXR0b246IHN0cmluZztcbiAgZG9uZUJ1dHRvbjogc3RyaW5nO1xuICBzYXZpbmdCdXR0b246IHN0cmluZztcbiAgYmFubmVyVGl0bGU6IHN0cmluZztcbiAgYmFubmVyRGVzY3JpcHRpb246IHN0cmluZztcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfUkVPUkRFUl9MQUJFTFM6IFJlb3JkZXJMYWJlbHMgPSB7XG4gIHJlb3JkZXJCdXR0b246ICdSZW9yZGVyJyxcbiAgY2FuY2VsQnV0dG9uOiAnQ2FuY2VsJyxcbiAgZG9uZUJ1dHRvbjogJ0RvbmUnLFxuICBzYXZpbmdCdXR0b246ICdTYXZpbmcuLi4nLFxuICBiYW5uZXJUaXRsZTogJ1Jlb3JkZXIgbW9kZScsXG4gIGJhbm5lckRlc2NyaXB0aW9uOiAnRHJhZyByb3dzIHVzaW5nIHRoZSBoYW5kbGUgdG8gcmVhcnJhbmdlLicsXG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlb3JkZXJTYXZlUGF5bG9hZCB7XG4gIG9yZGVyZWRJdGVtczogYW55W107XG59XG5cbmV4cG9ydCBjb25zdCBST1dfRFJBR19NSU1FID0gJ2FwcGxpY2F0aW9uL3gtY3FhLXRlc3QtaWRzJztcblxuLyoqIEN1c3RvbSBNSU1FIGZvciBmb2xkZXItcm93IGRyYWdzIGluIHRoZSBzaWRlYmFyLiBQYXlsb2FkIGlzIGEgSlNPTi1zdHJpbmdpZmllZCBmb2xkZXIgaWQuICovXG5leHBvcnQgY29uc3QgRk9MREVSX0RSQUdfTUlNRSA9ICdhcHBsaWNhdGlvbi94LWNxYS1mb2xkZXItaWQnO1xuIl19
@@ -7868,6 +7868,7 @@ const DEFAULT_MODULAR_CONFIG = {
7868
7868
  allowCreateFolder: true,
7869
7869
  allowRenameFolder: true,
7870
7870
  allowDeleteFolder: true,
7871
+ allowDuplicateFolder: false,
7871
7872
  allowNestedFolders: true,
7872
7873
  allowTestDragDrop: true,
7873
7874
  allowBulkSelection: true,
@@ -11335,10 +11336,10 @@ class ModularTableTemplateComponent {
11335
11336
  }
11336
11337
  ModularTableTemplateComponent.GRID_SCROLL_LOAD_THRESHOLD_PX = 96;
11337
11338
  ModularTableTemplateComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ModularTableTemplateComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: DialogService }], target: i0.ɵɵFactoryTarget.Component });
11338
- ModularTableTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ModularTableTemplateComponent, selector: "cqa-modular-table-template", inputs: { searchPlaceholder: "searchPlaceholder", searchValue: "searchValue", showClear: "showClear", showSearchBar: "showSearchBar", showExportButton: "showExportButton", isExporting: "isExporting", filterConfig: "filterConfig", filterModel: "filterModel", showFilterPanel: "showFilterPanel", showFilterButton: "showFilterButton", otherButtons: "otherButtons", otherDropDownButtons: "otherDropDownButtons", otherSelectDropDownButtons: "otherSelectDropDownButtons", otherButtonLabel: "otherButtonLabel", otherButtonVariant: "otherButtonVariant", showOtherButton: "showOtherButton", showActionButton: "showActionButton", showSettingsButton: "showSettingsButton", showAutoRefreshButton: "showAutoRefreshButton", showViewModeToggle: "showViewModeToggle", viewMode: "viewMode", viewModeLabels: "viewModeLabels", data: "data", isEmptyState: "isEmptyState", emptyStateConfig: "emptyStateConfig", actions: "actions", chips: "chips", filterApplied: "filterApplied", columns: "columns", rowSelectable: "rowSelectable", selectedAutoRefreshInterval: "selectedAutoRefreshInterval", pageIndex: "pageIndex", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions", pageSizeMenuDirection: "pageSizeMenuDirection", serverSidePagination: "serverSidePagination", totalElements: "totalElements", enableLocalSort: "enableLocalSort", isTableLoading: "isTableLoading", isTableDataLoading: "isTableDataLoading", cellJsonPathGetter: "cellJsonPathGetter", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", selectedItems: "selectedItems", showSelectAllInToolbar: "showSelectAllInToolbar", showDismissInToolbar: "showDismissInToolbar", allSelectedInToolbar: "allSelectedInToolbar", folders: "folders", rootFolders: "rootFolders", selectedFolderId: "selectedFolderId", expandedFolderIds: "expandedFolderIds", unorganizedCount: "unorganizedCount", folderIdAccessor: "folderIdAccessor", modularConfig: "modularConfig", modularLabels: "modularLabels", bulkActions: "bulkActions", sidebarCollapsed: "sidebarCollapsed", subfolderSectionExpanded: "subfolderSectionExpanded", organizedSectionExpanded: "organizedSectionExpanded", serverSideSearch: "serverSideSearch", rootTotal: "rootTotal", folderSearchLoading: "folderSearchLoading", folderSearchValue: "folderSearchValue", rootFoldersLoading: "rootFoldersLoading", savingFolderIds: "savingFolderIds", selectedFolderNode: "selectedFolderNode", selectedFolderTrail: "selectedFolderTrail", useInternalDialogs: "useInternalDialogs", showReorderButton: "showReorderButton", reorderSaving: "reorderSaving", reorderLabels: "reorderLabels", columnVisibility: "columnVisibility" }, outputs: { onSearchChange: "onSearchChange", onExportClick: "onExportClick", onApplyFilterClick: "onApplyFilterClick", onResetFilterClick: "onResetFilterClick", onClearAll: "onClearAll", removeChip: "removeChip", viewModeChange: "viewModeChange", pageChange: "pageChange", sortChange: "sortChange", folderSelected: "folderSelected", folderExpansionToggled: "folderExpansionToggled", folderChildrenRequested: "folderChildrenRequested", folderLoadMoreRequested: "folderLoadMoreRequested", rootLoadMoreRequested: "rootLoadMoreRequested", folderSearchChange: "folderSearchChange", folderCreated: "folderCreated", folderCreateRequested: "folderCreateRequested", folderRenamed: "folderRenamed", folderDeleted: "folderDeleted", testsMoved: "testsMoved", bulkActionClick: "bulkActionClick", bulkSelectAllChange: "bulkSelectAllChange", bulkDismiss: "bulkDismiss", bulkActionInvoked: "bulkActionInvoked", sidebarCollapsedChange: "sidebarCollapsedChange", subfolderSectionExpandedChange: "subfolderSectionExpandedChange", organizedSectionExpandedChange: "organizedSectionExpandedChange", reorderStart: "reorderStart", reorderCancel: "reorderCancel", reorderSave: "reorderSave", moveRequested: "moveRequested", selectedItemsChange: "selectedItemsChange", folderDeleteRequested: "folderDeleteRequested", folderMoveRequested: "folderMoveRequested", folderMoved: "folderMoved", folderDuplicateRequested: "folderDuplicateRequested", onReload: "onReload", onAutoRefreshClick: "onAutoRefreshClick", columnVisibilityChange: "columnVisibilityChange", autoRefreshIntervalChange: "autoRefreshIntervalChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "dynamicFilterComponent", first: true, predicate: DynamicFilterComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-flex cqa-flex-col cqa-relative\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 \" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n", components: [{ type: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: ExportCodeModalComponent, selector: "cqa-export-code-modal", inputs: ["isOpen", "cases", "disabled"], outputs: ["closeModal", "export"] }, { type: ColumnVisibilityComponent, selector: "cqa-column-visibility", inputs: ["isStepGroup", "columns", "columnVisibility", "selectedAutoRefreshInterval"], outputs: ["columnVisibilityChange", "autoRefreshChange"] }, { type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled", "containerBgColor", "fullWidth", "size"], outputs: ["valueChange"] }, { type: SelectedFiltersComponent, selector: "cqa-selected-filters", inputs: ["filterApplied", "chips", "defaultChips", "defaultChipClass"], outputs: ["removeChip", "clearAll", "onClearAll"] }, { type: DynamicFilterComponent, selector: "cqa-dynamic-filter", inputs: ["config", "model", "showFilterPanel", "buttonLayout"], outputs: ["filtersApplied", "filtersChanged", "resetAction", "onApplyFilterClick", "onResetFilterClick"] }, { type: FolderSidebarComponent, selector: "cqa-folder-sidebar", inputs: ["folders", "selectedFolderId", "expandedFolderIds", "unorganizedCount", "allowCreate", "allowRename", "allowDelete", "allowMove", "allowDuplicate", "allowDrop", "showCounts", "collapsed", "foldersAccordionExpanded", "labels", "serverSideSearch", "rootTotal", "folderSearchLoading", "rootFoldersLoading", "savingFolderIds", "searchValue"], outputs: ["folderSelected", "folderExpansionToggled", "folderChildrenRequested", "folderLoadMoreRequested", "searchChange", "rootLoadMoreRequested", "folderCreated", "folderCreateRequested", "folderRenamed", "folderDeleted", "folderMoveRequested", "folderDuplicateRequested", "testsDropped", "folderDropped", "collapsedChange", "foldersAccordionExpandedChange"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: DynamicTableComponent, selector: "app-dynamic-table", inputs: ["data", "columns", "emptyState", "gridTemplateColumns", "screenWidth", "enableSelectAll", "rowSelectable", "enableLocalSort", "isTableLoading", "isTableDataLoading", "cellJsonPathGetter", "onJsonPathCopiedHandler", "enableRowReorder", "reorderHandleTooltip"], outputs: ["sortChange", "rowReorder"] }, { type: EmptyStateComponent, selector: "cqa-empty-state", inputs: ["preset", "imageUrl", "title", "description", "actions"], outputs: ["actionClick"] }, { type: PaginationComponent, selector: "cqa-pagination", inputs: ["totalElements", "totalPages", "pageIndex", "pageSize", "pageItemCount", "pageSizeOptions", "pageSizeMenuDirection"], outputs: ["pageIndexChange", "pageSizeChange", "paginate"] }, { type: TableActionToolbarComponent, selector: "cqa-table-action-toolbar", inputs: ["selectedItems", "actions", "showSelectAll", "allSelected", "showDismiss"], outputs: ["actionClick", "selectAllChange", "dismiss"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: FolderDropDirective, selector: "[cqaFolderDrop]", inputs: ["cqaFolderDrop", "dropEnabled"], outputs: ["testsDropped", "folderDropped"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11339
+ ModularTableTemplateComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ModularTableTemplateComponent, selector: "cqa-modular-table-template", inputs: { searchPlaceholder: "searchPlaceholder", searchValue: "searchValue", showClear: "showClear", showSearchBar: "showSearchBar", showExportButton: "showExportButton", isExporting: "isExporting", filterConfig: "filterConfig", filterModel: "filterModel", showFilterPanel: "showFilterPanel", showFilterButton: "showFilterButton", otherButtons: "otherButtons", otherDropDownButtons: "otherDropDownButtons", otherSelectDropDownButtons: "otherSelectDropDownButtons", otherButtonLabel: "otherButtonLabel", otherButtonVariant: "otherButtonVariant", showOtherButton: "showOtherButton", showActionButton: "showActionButton", showSettingsButton: "showSettingsButton", showAutoRefreshButton: "showAutoRefreshButton", showViewModeToggle: "showViewModeToggle", viewMode: "viewMode", viewModeLabels: "viewModeLabels", data: "data", isEmptyState: "isEmptyState", emptyStateConfig: "emptyStateConfig", actions: "actions", chips: "chips", filterApplied: "filterApplied", columns: "columns", rowSelectable: "rowSelectable", selectedAutoRefreshInterval: "selectedAutoRefreshInterval", pageIndex: "pageIndex", pageSize: "pageSize", pageSizeOptions: "pageSizeOptions", pageSizeMenuDirection: "pageSizeMenuDirection", serverSidePagination: "serverSidePagination", totalElements: "totalElements", enableLocalSort: "enableLocalSort", isTableLoading: "isTableLoading", isTableDataLoading: "isTableDataLoading", cellJsonPathGetter: "cellJsonPathGetter", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", selectedItems: "selectedItems", showSelectAllInToolbar: "showSelectAllInToolbar", showDismissInToolbar: "showDismissInToolbar", allSelectedInToolbar: "allSelectedInToolbar", folders: "folders", rootFolders: "rootFolders", selectedFolderId: "selectedFolderId", expandedFolderIds: "expandedFolderIds", unorganizedCount: "unorganizedCount", folderIdAccessor: "folderIdAccessor", modularConfig: "modularConfig", modularLabels: "modularLabels", bulkActions: "bulkActions", sidebarCollapsed: "sidebarCollapsed", subfolderSectionExpanded: "subfolderSectionExpanded", organizedSectionExpanded: "organizedSectionExpanded", serverSideSearch: "serverSideSearch", rootTotal: "rootTotal", folderSearchLoading: "folderSearchLoading", folderSearchValue: "folderSearchValue", rootFoldersLoading: "rootFoldersLoading", savingFolderIds: "savingFolderIds", selectedFolderNode: "selectedFolderNode", selectedFolderTrail: "selectedFolderTrail", useInternalDialogs: "useInternalDialogs", showReorderButton: "showReorderButton", reorderSaving: "reorderSaving", reorderLabels: "reorderLabels", columnVisibility: "columnVisibility" }, outputs: { onSearchChange: "onSearchChange", onExportClick: "onExportClick", onApplyFilterClick: "onApplyFilterClick", onResetFilterClick: "onResetFilterClick", onClearAll: "onClearAll", removeChip: "removeChip", viewModeChange: "viewModeChange", pageChange: "pageChange", sortChange: "sortChange", folderSelected: "folderSelected", folderExpansionToggled: "folderExpansionToggled", folderChildrenRequested: "folderChildrenRequested", folderLoadMoreRequested: "folderLoadMoreRequested", rootLoadMoreRequested: "rootLoadMoreRequested", folderSearchChange: "folderSearchChange", folderCreated: "folderCreated", folderCreateRequested: "folderCreateRequested", folderRenamed: "folderRenamed", folderDeleted: "folderDeleted", testsMoved: "testsMoved", bulkActionClick: "bulkActionClick", bulkSelectAllChange: "bulkSelectAllChange", bulkDismiss: "bulkDismiss", bulkActionInvoked: "bulkActionInvoked", sidebarCollapsedChange: "sidebarCollapsedChange", subfolderSectionExpandedChange: "subfolderSectionExpandedChange", organizedSectionExpandedChange: "organizedSectionExpandedChange", reorderStart: "reorderStart", reorderCancel: "reorderCancel", reorderSave: "reorderSave", moveRequested: "moveRequested", selectedItemsChange: "selectedItemsChange", folderDeleteRequested: "folderDeleteRequested", folderMoveRequested: "folderMoveRequested", folderMoved: "folderMoved", folderDuplicateRequested: "folderDuplicateRequested", onReload: "onReload", onAutoRefreshClick: "onAutoRefreshClick", columnVisibilityChange: "columnVisibilityChange", autoRefreshIntervalChange: "autoRefreshIntervalChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "dynamicFilterComponent", first: true, predicate: DynamicFilterComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-flex cqa-flex-col cqa-relative\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 \" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [allowDuplicate]=\"modularConfig.allowDuplicateFolder\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n", components: [{ type: SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }, { type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "loading", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: ExportCodeModalComponent, selector: "cqa-export-code-modal", inputs: ["isOpen", "cases", "disabled"], outputs: ["closeModal", "export"] }, { type: ColumnVisibilityComponent, selector: "cqa-column-visibility", inputs: ["isStepGroup", "columns", "columnVisibility", "selectedAutoRefreshInterval"], outputs: ["columnVisibilityChange", "autoRefreshChange"] }, { type: SegmentControlComponent, selector: "cqa-segment-control", inputs: ["segments", "value", "disabled", "containerBgColor", "fullWidth", "size"], outputs: ["valueChange"] }, { type: SelectedFiltersComponent, selector: "cqa-selected-filters", inputs: ["filterApplied", "chips", "defaultChips", "defaultChipClass"], outputs: ["removeChip", "clearAll", "onClearAll"] }, { type: DynamicFilterComponent, selector: "cqa-dynamic-filter", inputs: ["config", "model", "showFilterPanel", "buttonLayout"], outputs: ["filtersApplied", "filtersChanged", "resetAction", "onApplyFilterClick", "onResetFilterClick"] }, { type: FolderSidebarComponent, selector: "cqa-folder-sidebar", inputs: ["folders", "selectedFolderId", "expandedFolderIds", "unorganizedCount", "allowCreate", "allowRename", "allowDelete", "allowMove", "allowDuplicate", "allowDrop", "showCounts", "collapsed", "foldersAccordionExpanded", "labels", "serverSideSearch", "rootTotal", "folderSearchLoading", "rootFoldersLoading", "savingFolderIds", "searchValue"], outputs: ["folderSelected", "folderExpansionToggled", "folderChildrenRequested", "folderLoadMoreRequested", "searchChange", "rootLoadMoreRequested", "folderCreated", "folderCreateRequested", "folderRenamed", "folderDeleted", "folderMoveRequested", "folderDuplicateRequested", "testsDropped", "folderDropped", "collapsedChange", "foldersAccordionExpandedChange"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: DynamicTableComponent, selector: "app-dynamic-table", inputs: ["data", "columns", "emptyState", "gridTemplateColumns", "screenWidth", "enableSelectAll", "rowSelectable", "enableLocalSort", "isTableLoading", "isTableDataLoading", "cellJsonPathGetter", "onJsonPathCopiedHandler", "enableRowReorder", "reorderHandleTooltip"], outputs: ["sortChange", "rowReorder"] }, { type: EmptyStateComponent, selector: "cqa-empty-state", inputs: ["preset", "imageUrl", "title", "description", "actions"], outputs: ["actionClick"] }, { type: PaginationComponent, selector: "cqa-pagination", inputs: ["totalElements", "totalPages", "pageIndex", "pageSize", "pageItemCount", "pageSizeOptions", "pageSizeMenuDirection"], outputs: ["pageIndexChange", "pageSizeChange", "paginate"] }, { type: TableActionToolbarComponent, selector: "cqa-table-action-toolbar", inputs: ["selectedItems", "actions", "showSelectAll", "allSelected", "showDismiss"], outputs: ["actionClick", "selectAllChange", "dismiss"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: FolderDropDirective, selector: "[cqaFolderDrop]", inputs: ["cqaFolderDrop", "dropEnabled"], outputs: ["testsDropped", "folderDropped"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11339
11340
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ModularTableTemplateComponent, decorators: [{
11340
11341
  type: Component,
11341
- args: [{ selector: 'cqa-modular-table-template', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-flex cqa-flex-col cqa-relative\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 \" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n", styles: [] }]
11342
+ args: [{ selector: 'cqa-modular-table-template', host: { class: 'cqa-ui-root' }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Reusable folder-icon chip. Render via <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>. -->\n<ng-template #folderIconChip let-color=\"color\">\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" [attr.stroke]=\"color || 'currentColor'\" stroke-width=\"0.916667\"/>\n </svg>\n </span>\n</ng-template>\n\n<!-- Reusable indeterminate loading spinner. Render via\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>. -->\n<ng-template #loadingSpinner let-size=\"size\">\n <svg [attr.width]=\"size || 20\" [attr.height]=\"size || 20\" viewBox=\"0 0 50 50\" aria-label=\"loading\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" stroke=\"#E5E7EB\" stroke-width=\"6\" fill=\"none\"></circle>\n <path d=\"M45 25a20 20 0 0 0-20-20\" stroke=\"#4F46E5\" stroke-width=\"6\" fill=\"none\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 25 25\" to=\"360 25 25\" dur=\"0.8s\" repeatCount=\"indefinite\"></animateTransform>\n </path>\n </svg>\n</ng-template>\n\n<!-- Reusable \"+\" chip used by the \"New folder\" tile. -->\n<ng-template #addIconChip>\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-w-10 cqa-h-10 cqa-rounded-lg cqa-bg-[#F0F0F1] cqa-text-[#6D6D74] cqa-flex-shrink-0 group-hover:cqa-bg-indigo-50 group-hover:cqa-text-[#3F43EE]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 3V13M3 8H13\" stroke=\"currentColor\" stroke-width=\"1.275\" stroke-linecap=\"round\"/>\n </svg>\n </span>\n</ng-template>\n\n<div class=\"cqa-ui-root\">\n <div class=\"cqa-w-full cqa-flex cqa-flex-col cqa-relative\">\n <div [class]=\"!showSearchBar ? 'cqa-justify-end' : 'cqa-justify-between'\" class=\"cqa-w-full cqa-flex cqa-items-center cqa-gap-3 cqa-flex-wrap cqa-mb-3\">\n <cqa-search-bar\n *ngIf=\"showSearchBar\"\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [showClear]=\"showClear\"\n (valueChange)=\"valueChange($event)\"\n (search)=\"search($event)\"\n (cleared)=\"cleared()\"\n ></cqa-search-bar>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-flex-wrap\">\n <cqa-button\n *ngIf=\"showExportButton\"\n variant=\"grey-solid\"\n icon=\"open_in_new\"\n [text]=\"isExporting ? 'Exporting...' : 'Export'\"\n [disabled]=\"isExporting\"\n (clicked)=\"exportCodeClick()\"\n >\n <span>{{ isExporting ? 'Exporting...' : 'Export' }}</span>\n </cqa-button>\n \n <!-- Export Code Modal -->\n <cqa-export-code-modal\n *ngIf=\"showExportButton\"\n [isOpen]=\"isExportModalOpen\"\n [cases]=\"selectedCasesForExport\"\n [disabled]=\"false\"\n (closeModal)=\"closeExportModal()\"\n (export)=\"onExportModalExport($event)\">\n </cqa-export-code-modal>\n <ng-container *ngFor=\"let dropdownTemplate of otherDropDownButtons; trackBy: trackByDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"dropdownTemplate\"></ng-container>\n </ng-container>\n\n <ng-container *ngFor=\"let selectDropdownTemplate of otherSelectDropDownButtons; trackBy: trackBySelectDropdownTemplateRef\">\n <ng-container *ngTemplateOutlet=\"selectDropdownTemplate\"></ng-container>\n </ng-container>\n \n <cqa-button\n *ngIf=\"showFilterButton\"\n variant=\"grey-solid\"\n icon=\"add\"\n [disabled]=\"isReordering\"\n (clicked)=\"toggleFilter()\"\n >\n <span class=\"cqa-flex cqa-items-center cqa-gap-1\">\n Filter \n <div [class]=\"arrowClasses\">\n <svg\n class=\"cqa-w-2 cqa-h-1 cqa-absolute cqa-left-[4px] cqa-top-[6px]\"\n viewBox=\"0 0 8 4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M0 0L4 4L8 0\"\n stroke=\"#0B0B0C\"\n stroke-width=\"1.33\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n </span>\n </cqa-button>\n <cqa-column-visibility\n *ngIf=\"showSettingsButton\"\n [columns]=\"visibilityColumns\"\n [columnVisibility]=\"columnVisibility\"\n [selectedAutoRefreshInterval]=\"selectedAutoRefreshInterval\"\n (columnVisibilityChange)=\"onColumnVisibilityChange($event)\"\n (autoRefreshChange)=\"onAutoRefreshChange($event)\"\n ></cqa-column-visibility>\n <cqa-button\n *ngIf=\"showAutoRefreshButton\"\n variant=\"grey-solid\"\n icon=\"refresh\"\n (clicked)=\"handleRefreshClick()\"\n [tooltip]=\"'Refresh'\"\n tooltipPosition=\"below\"\n [disabled]=\"isReordering\"\n ></cqa-button>\n <ng-container *ngFor=\"let buttonTemplate of otherButtons; trackBy: trackByTemplateRef\">\n <ng-container *ngTemplateOutlet=\"buttonTemplate\"></ng-container>\n </ng-container>\n <cqa-segment-control\n *ngIf=\"showViewModeToggle\"\n size=\"lg\"\n [segments]=\"viewModeSegments\"\n [value]=\"viewMode\"\n (valueChange)=\"onViewModeChange($event)\"\n ></cqa-segment-control>\n <cqa-button\n *ngIf=\"showReorderButton && !isReordering\"\n variant=\"outlined\"\n icon=\"drag_indicator\"\n [text]=\"reorderLabels.reorderButton\"\n [disabled]=\"!pagedRows || pagedRows.length === 0 || isTableLoading || isTableDataLoading\"\n (clicked)=\"startReorder()\"\n ></cqa-button>\n <ng-container *ngIf=\"showReorderButton && isReordering\">\n <cqa-button\n variant=\"outlined\"\n [text]=\"reorderLabels.cancelButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"cancelReorder()\"\n ></cqa-button>\n <cqa-button\n variant=\"filled\"\n [icon]=\"reorderSaving ? 'hourglass_empty' : ''\"\n [text]=\"reorderSaving ? reorderLabels.savingButton : reorderLabels.doneButton\"\n [disabled]=\"reorderSaving\"\n (clicked)=\"saveReorder()\"\n ></cqa-button>\n </ng-container>\n </div>\n </div>\n\n <!-- Reorder mode banner -->\n <div *ngIf=\"isReordering\" class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-3 cqa-px-3 cqa-py-2 cqa-rounded-md cqa-bg-[#FFFBEB] cqa-border cqa-border-[#FDE68A]\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <circle cx=\"3\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"3\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"8\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"3\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"8\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n <circle cx=\"13\" cy=\"13\" r=\"1.5\" fill=\"#92400E\"></circle>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold cqa-text-[#92400E]\">{{ reorderLabels.bannerTitle }}</span>\n <span class=\"cqa-text-sm cqa-text-[#92400E]\">{{ reorderLabels.bannerDescription }}</span>\n </div>\n\n <cqa-selected-filters\n [filterApplied]=\"filterApplied\"\n [chips]=\"chips\"\n (removeChip)=\"onRemoveChip($event)\"\n (clearAll)=\"onClearAllChips()\"\n (onClearAll)=\"onClearAll.emit()\"\n >\n </cqa-selected-filters>\n\n <cqa-dynamic-filter\n *ngIf=\"showFilterPanel\"\n [config]=\"filterConfig\"\n [model]=\"filterModel\"\n [showFilterPanel]=\"showFilterPanel\"\n (filtersChanged)=\"onFiltersChanged($event)\"\n (filtersApplied)=\"onFiltersApplied($event)\"\n (onApplyFilterClick)=\"onApplyFilterClick.emit($event)\"\n (onResetFilterClick)=\"handleResetFilterClick()\"\n >\n </cqa-dynamic-filter>\n\n <div class=\"cqa-flex cqa-items-stretch cqa-gap-2 cqa-min-h-0 \" style=\"border-bottom: 1px solid rgb(226, 226, 227);\">\n <!-- Sidebar (only shown in modular view) -->\n <cqa-folder-sidebar\n *ngIf=\"isModularView && modularConfig.showSidebar\"\n [folders]=\"folders\"\n [selectedFolderId]=\"selectedFolderId\"\n [expandedFolderIds]=\"expandedFolderIds\"\n [unorganizedCount]=\"unorganizedCount\"\n [allowCreate]=\"modularConfig.allowCreateFolder\"\n [allowRename]=\"modularConfig.allowRenameFolder\"\n [allowDelete]=\"modularConfig.allowDeleteFolder\"\n [allowDrop]=\"modularConfig.allowTestDragDrop\"\n [allowDuplicate]=\"modularConfig.allowDuplicateFolder\"\n [showCounts]=\"modularConfig.showCounts\"\n [collapsed]=\"sidebarCollapsed\"\n [labels]=\"modularLabels\"\n [serverSideSearch]=\"serverSideSearch\"\n [rootTotal]=\"rootTotal\"\n [folderSearchLoading]=\"folderSearchLoading\"\n [rootFoldersLoading]=\"rootFoldersLoading\"\n [savingFolderIds]=\"savingFolderIds\"\n [searchValue]=\"folderSearchValue\"\n (folderSelected)=\"onFolderSelected($event)\"\n (folderExpansionToggled)=\"onFolderExpansionToggled($event)\"\n (folderChildrenRequested)=\"folderChildrenRequested.emit($event)\"\n (folderLoadMoreRequested)=\"folderLoadMoreRequested.emit($event)\"\n (rootLoadMoreRequested)=\"rootLoadMoreRequested.emit()\"\n (searchChange)=\"folderSearchChange.emit($event)\"\n (folderCreated)=\"onFolderCreated($event)\"\n (folderCreateRequested)=\"onFolderCreateRequested($event)\"\n (folderRenamed)=\"onFolderRenamed($event)\"\n (folderDeleted)=\"onFolderDeleted($event)\"\n (folderMoveRequested)=\"onFolderMoveRequested($event)\"\n (folderDuplicateRequested)=\"onFolderDuplicateRequested($event)\"\n (testsDropped)=\"onTestsDropped($event)\"\n (folderDropped)=\"onFolderDropped($event)\"\n (collapsedChange)=\"onSidebarCollapsedChange($event)\"\n ></cqa-folder-sidebar>\n\n <!-- Right pane -->\n <div\n class=\"cqa-flex-1 cqa-flex cqa-flex-col cqa-min-w-0\"\n [style.border-top]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-left]=\"isModularView ? '1px solid #E2E2E3' : null\"\n [style.border-right]=\"isModularView ? '1px solid #E2E2E3' : null\"\n >\n <!-- Breadcrumb (modular view, folder drilled-in) -->\n <nav\n *ngIf=\"isModularView && modularConfig.showBreadcrumb && !isRootView\"\n aria-label=\"Folder path\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-sm cqa-px-3 cqa-py-2 cqa-rounded-none cqa-min-w-0\"\n style=\"color: #6D6D74; border-bottom: 1px solid #E2E2E3;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-flex-1 cqa-min-w-0 cqa-overflow-x-auto cqa-scrollbar-thin cqa-whitespace-nowrap\">\n <button type=\"button\" class=\"hover:cqa-text-[#3F43EE] cqa-inline-flex cqa-items-center cqa-gap-1 cqa-flex-shrink-0\" (click)=\"onFolderSelected(null)\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"currentColor\" stroke-width=\"0.916667\"/>\n </svg>\n <span>{{ modularLabels.allFolders }}</span>\n </button>\n <ng-container *ngFor=\"let crumb of breadcrumbTrail; let last = last\">\n <mat-icon class=\"cqa-align-middle cqa-flex-shrink-0\" style=\"font-size:16px;width:16px;height:16px;color:#6D6D74;\">chevron_right</mat-icon>\n <button\n type=\"button\"\n class=\"cqa-flex-shrink-0\"\n [ngClass]=\"last\n ? 'cqa-text-[#161617] cqa-font-semibold'\n : 'cqa-text-[#6D6D74] hover:cqa-text-[#3F43EE]'\"\n [disabled]=\"last\"\n (click)=\"!last && onFolderSelected(crumb.id)\"\n >{{ crumb.name }}</button>\n </ng-container>\n </div>\n <cqa-button\n *ngIf=\"modularConfig.showSubfolderSection && subfolderTiles.length\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n [icon]=\"subfolderSectionExpanded ? 'expand_less' : 'expand_more'\"\n [text]=\"(subfolderSectionExpanded ? 'Hide' : 'Show') + ' subfolders'\"\n [attr.aria-expanded]=\"subfolderSectionExpanded\"\n (clicked)=\"toggleSubfolderSection()\"\n ></cqa-button>\n <cqa-button\n *ngIf=\"modularConfig.allowCreateFolder\"\n class=\"cqa-flex-shrink-0\"\n variant=\"text\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px] !cqa-leading-[18px]\"\n icon=\"add\"\n [text]=\"modularLabels.newFolder\"\n (clicked)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n ></cqa-button>\n </nav>\n\n <!-- Folder grid: modular + root view -->\n <section\n *ngIf=\"isModularView && isRootView && modularConfig.showFolderGrid && rootFolderTiles.length\"\n class=\"cqa-px-5 cqa-pt-2\"\n style=\"border-bottom: 1px solid #F0F0F1;\"\n >\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-w-full cqa-text-left\"\n [attr.aria-expanded]=\"organizedSectionExpanded\"\n (click)=\"toggleOrganizedSection()\"\n >\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9583 10.4585C12.9583 10.79 12.8266 11.108 12.5921 11.3424C12.3577 11.5768 12.0398 11.7085 11.7083 11.7085H1.70825C1.37673 11.7085 1.05879 11.5768 0.824368 11.3424C0.589948 11.108 0.458252 10.79 0.458252 10.4585V1.7085C0.458252 1.37698 0.589948 1.05903 0.824368 0.824613C1.05879 0.590192 1.37673 0.458496 1.70825 0.458496H4.83325L6.08325 2.3335H11.7083C12.0398 2.3335 12.3577 2.46519 12.5921 2.69961C12.8266 2.93403 12.9583 3.25198 12.9583 3.5835V10.4585Z\" stroke=\"#6D6D74\" stroke-width=\"0.916667\"/>\n </svg>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.organized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ rootFolderTiles.length === 1 ? modularLabels.foldersCountSingular : modularLabels.foldersCountPlural.replace('{n}', '' + rootFolderTiles.length) }}\n </span>\n <mat-icon class=\"cqa-text-[#6D6D74] cqa-ml-auto\" style=\"font-size:18px;width:18px;height:18px\">\n {{ organizedSectionExpanded ? 'expand_less' : 'expand_more' }}\n </mat-icon>\n </button>\n <div\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"organizedSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin cqa-pb-1\"\n (scroll)=\"onRootGridScroll($event)\">\n <button\n *ngFor=\"let f of rootFolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}<ng-container *ngIf=\"f.children?.length\"> \u00B7 {{ f.children!.length === 1 ? modularLabels.oneSubfolder : modularLabels.subfoldersCount.replace('{n}', '' + f.children!.length) }}</ng-container>\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: null })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Pagination spinner anchored at the right edge of the Organized\n row. Only renders during an in-flight root fetch (initial OR\n scroll-driven \"load more\"), and is filtered to suppress when\n the section is empty so we don't show a spinner inside an\n otherwise-blank row. -->\n <div\n *ngIf=\"rootFoldersLoading && rootFolderTiles.length > 0\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading more folders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </div>\n </section>\n\n <!-- Subfolder section: modular + folder view. Shown whenever drilled in\n (even if no subfolders, so the \"+ New folder\" tile remains\n reachable, and so we can render a loading state during the\n drill-in fetch before children arrive). -->\n <section\n *ngIf=\"isModularView && !isRootView && modularConfig.showSubfolderSection && (subfolderTiles.length || currentFolderNode?.childrenLoading)\"\n class=\"cqa-grid\"\n style=\"transition: grid-template-rows 300ms cubic-bezier(0.4, 0, 0.2, 1);\"\n [style.grid-template-rows]=\"subfolderSectionExpanded ? '1fr' : '0fr'\"\n >\n <div class=\"cqa-min-h-0\" style=\"overflow: hidden;\">\n <div class=\"cqa-px-3 cqa-py-2 cqa-flex cqa-flex-nowrap cqa-gap-3 cqa-overflow-x-auto cqa-scrollbar-thin\"\n (scroll)=\"onSubfolderGridScroll($event)\">\n <button\n *ngFor=\"let f of subfolderTiles\"\n type=\"button\"\n [cqaFolderDrop]=\"f.id\"\n [dropEnabled]=\"modularConfig.allowTestDragDrop\"\n (testsDropped)=\"onTestsDropped($event)\"\n (click)=\"onFolderSelected(f.id)\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-solid cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-white hover:cqa-border-[#3F43EE] hover:cqa-shadow-sm cqa-transition-colors\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-min-w-0\">\n <ng-container *ngTemplateOutlet=\"folderIconChip; context: { color: f.color }\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ f.name }}</span>\n <span *ngIf=\"modularConfig.showCounts\" class=\"cqa-text-sm cqa-text-neutral-500 cqa-truncate\">\n {{ (f.count ?? 0) === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + (f.count ?? 0)) }}\n </span>\n </div>\n </div>\n <mat-icon class=\"cqa-text-neutral-400 cqa-flex-shrink-0\" style=\"font-size:20px;width:20px;height:20px\">chevron_right</mat-icon>\n </button>\n\n <!-- \"+ New folder\" tile -->\n <button\n *ngIf=\"modularConfig.allowCreateFolder\"\n type=\"button\"\n (click)=\"onFolderCreateRequested({ parentId: selectedFolderId })\"\n class=\"cqa-group cqa-flex-shrink-0 cqa-w-[240px] cqa-flex cqa-items-center cqa-gap-3 cqa-text-left cqa-p-3 cqa-rounded-[10px] cqa-border-dashed cqa-border-[0.5px] cqa-border-[#E2E2E3] cqa-bg-[#FAFAFA] hover:cqa-border-[#3F43EE] hover:cqa-bg-white cqa-transition-colors\"\n >\n <ng-container *ngTemplateOutlet=\"addIconChip\"></ng-container>\n <div class=\"cqa-flex cqa-flex-col cqa-min-w-0\">\n <span class=\"cqa-text-[15px] cqa-text-[#161617] cqa-truncate cqa-leading-tight group-hover:cqa-text-[#3F43EE]\">{{ modularLabels.newFolder }}</span>\n <span class=\"cqa-text-sm cqa-text-neutral-400\">{{ modularLabels.testsCountPlural.replace('{n}', '0') }}</span>\n </div>\n </button>\n\n <!-- Subfolder fetch indicator. Two cases:\n - Drill-in fetch: no subfolderTiles yet, render a centered\n row spinner so the section isn't empty during the fetch.\n - Pagination fetch: tiles exist, anchor a small spinner at\n the right edge so the user knows the next page is loading. -->\n <div\n *ngIf=\"currentFolderNode?.childrenLoading\"\n class=\"cqa-flex-shrink-0 cqa-flex cqa-items-center cqa-justify-center cqa-w-[80px]\"\n aria-live=\"polite\"\n [attr.aria-label]=\"'Loading subfolders'\"\n >\n <ng-container *ngTemplateOutlet=\"loadingSpinner; context: { size: 20 }\"></ng-container>\n </div>\n </div>\n </div>\n </section>\n\n <div\n *ngIf=\"isModularView && !isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-4 cqa-py-3 cqa-border cqa-border-indigo-100\"\n style=\"background-color: #D8D9FC;\"\n >\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <svg width=\"14\" height=\"13\" viewBox=\"0 0 14 13\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M12.9585 10.4585C12.9585 10.79 12.8268 11.108 12.5924 11.3424C12.358 11.5768 12.04 11.7085 11.7085 11.7085H1.7085C1.37698 11.7085 1.05903 11.5768 0.824613 11.3424C0.590192 11.108 0.458496 10.79 0.458496 10.4585V1.7085C0.458496 1.37698 0.590192 1.05903 0.824613 0.824613C1.05903 0.590192 1.37698 0.458496 1.7085 0.458496H4.8335L6.0835 2.3335H11.7085C12.04 2.3335 12.358 2.46519 12.5924 2.69961C12.8268 2.93403 12.9585 3.25198 12.9585 3.5835V10.4585Z\" stroke=\"#3F43EE\" stroke-width=\"0.916667\"/>\n </svg>\n <span class=\"cqa-text-sm cqa-font-semibold\" style=\"color: #3F43EE;\">\n {{ currentFolderNode?.name }} ({{ currentFolderDirectCount }})\n </span>\n </div>\n <cqa-button\n variant=\"outlined\"\n btnSize=\"sm\"\n customClass=\"!cqa-text-[13px]\"\n inlineStyles=\"border-color: #3F43EE; color: #3F43EE;\"\n [text]=\"modularLabels.clearFilter\"\n (clicked)=\"onFolderSelected(null)\"\n ></cqa-button>\n </div>\n\n <!-- Unorganized section header at root view -->\n <div\n *ngIf=\"isModularView && isRootView && modularConfig.showUnorganizedSection\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2 cqa-mt-2\" style=\"margin-left: 20px;\"\n >\n <mat-icon class=\"cqa-text-[#6D6D74]\" style=\"font-size:16px;width:16px;height:16px\">inbox</mat-icon>\n <h3 class=\"cqa-text-sm cqa-font-semibold cqa-text-[#6D6D74]\">{{ modularLabels.unorganized }}</h3>\n <span class=\"cqa-text-xs cqa-text-[#6D6D74]\">\n {{ unorganizedCount === 1 ? modularLabels.testsCountSingular : modularLabels.testsCountPlural.replace('{n}', '' + unorganizedCount) }}\n </span>\n </div>\n\n <div class=\"cqa-overflow-hidden cqa-border-t cqa-border-l cqa-border-r cqa-border-grey-200 cqa-relative cqa-overflow-x-auto\"\n [class.cqa-modular-table-flush]=\"isModularView\"\n [attr.style]=\"(!isModularView ? 'border-radius: 7px;' : '') + ((pagedRows && pagedRows.length > 0) ? '' : ' border-bottom: none !important;')\">\n <ng-container *ngIf=\"(isTableLoading || isTableDataLoading) || (!effectiveIsEmptyState && pagedRows && pagedRows.length > 0); else storyEmptyTpl\">\n <app-dynamic-table\n [style.border-bottom]=\"pagedRows && pagedRows.length > 0 ? '1px solid rgb(226, 226, 227)' : null\"\n [columns]=\"computedColumns\"\n [data]=\"pagedRows\"\n [rowSelectable]=\"rowSelectable\"\n [enableLocalSort]=\"enableLocalSort && !isReordering\"\n [isTableLoading]=\"isTableLoading\"\n [isTableDataLoading]=\"isTableDataLoading\"\n [cellJsonPathGetter]=\"cellJsonPathGetter\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [enableRowReorder]=\"isReordering\"\n (rowReorder)=\"onRowReorder($event)\"\n (sortChange)=\"sortChange.emit($event)\">\n <ng-template #emptyTableTpl>\n <div class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8\">\n <img src=\"/assets/illustrations/empty-state.svg\" alt=\"No data\" class=\"cqa-w-32 cqa-h-32 cqa-mb-4\" />\n <h3 class=\"cqa-text-lg cqa-font-semibold cqa-mb-2\">No test cases</h3>\n <p class=\"cqa-text-sm cqa-text-neutral-500 cqa-mb-4\">Try adjusting filters or create a new test case.</p>\n <cqa-button variant=\"filled\" (clicked)=\"toggleFilter()\">Show Filters</cqa-button>\n </div>\n </ng-template>\n </app-dynamic-table>\n </ng-container>\n\n <ng-template #storyEmptyTpl>\n <div class=\"cqa-p-6 cqa-flex cqa-flex-col cqa-items-center cqa-justify-center\">\n <cqa-empty-state\n *ngIf=\"effectiveIsEmptyState\"\n [title]=\"effectiveEmptyStateConfig.title\"\n [description]=\"effectiveEmptyStateConfig.description\"\n [imageUrl]=\"effectiveEmptyStateConfig.imageUrl\"\n [actions]=\"effectiveEmptyStateConfig.actions\"\n (actionClick)=\"onEmptyAction($event)\"\n >\n </cqa-empty-state>\n </div>\n </ng-template>\n </div>\n\n <cqa-pagination\n [totalElements]=\"serverSidePagination ? totalElements : filteredRows.length\"\n [pageIndex]=\"pageIndex\"\n [pageSize]=\"pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n [pageSizeMenuDirection]=\"pageSizeMenuDirection\"\n [pageItemCount]=\"pagedRows.length\"\n (paginate)=\"onPaginate($event)\"\n (pageSizeChange)=\"onPageSizeChange($event)\"\n >\n </cqa-pagination>\n </div>\n </div>\n\n <!-- Reused bulk action toolbar -->\n <div *ngIf=\"anyRowSelected && modularConfig.allowBulkSelection && !isReordering\" class=\"cqa-absolute cqa-bottom-[18.75px] cqa-left-[50%] cqa-translate-x-[-50%] cqa-w-full lg:cqa-max-w-[68%] cqa-sm:max-w-[75%] cqa-max-w-[90%] cqa-z-[1]\">\n <cqa-table-action-toolbar\n [selectedItems]=\"selectedItems && selectedItems.length > 0 ? selectedItems : currentSelectedItems\"\n [actions]=\"effectiveBulkActions\"\n [showSelectAll]=\"showSelectAllInToolbar\"\n [allSelected]=\"allSelectedInToolbar\"\n [showDismiss]=\"showDismissInToolbar\"\n (actionClick)=\"onBulkAction($event)\"\n (selectAllChange)=\"onBulkSelectAll($event)\"\n (dismiss)=\"onBulkDismiss()\"\n ></cqa-table-action-toolbar>\n </div>\n\n </div>\n</div>\n\n", styles: [] }]
11342
11343
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: DialogService }]; }, propDecorators: { searchPlaceholder: [{
11343
11344
  type: Input
11344
11345
  }], searchValue: [{