text: import { ENTER } from '@angular/cdk/keycodes';
  import { HttpClient, HttpEventType, HttpHeaders, HttpRequest, HttpResponse } from '@angular/common/http';
  import { animate, style, transition, trigger } from '@angular/animations';
  import { Platform } from '@angular/cdk/platform';
  import { __decorate, __metadata } from 'tslib';
  import { of, Observable, Subscription } from 'rxjs';
  import { switchMap, filter } from 'rxjs/operators';
  import { NzUpdateHostClassService, toBoolean, InputBoolean, InputNumber } from 'ng-zorro-antd/core';
  import { CommonModule } from '@angular/common';
  import { Component, ElementRef, HostListener, Input, Optional, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, EventEmitter, Output, NgModule } from '@angular/core';
  import { FormsModule } from '@angular/forms';
  import { NzI18nService, NzI18nModule } from 'ng-zorro-antd/i18n';
  import { NzIconModule } from 'ng-zorro-antd/icon';
  import { NzProgressModule } from 'ng-zorro-antd/progress';
  import { NzToolTipModule } from 'ng-zorro-antd/tooltip';
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  class NzUploadBtnComponent {
      // #endregion
      /**
       * @param {?} http
       * @param {?} el
       * @param {?} updateHostClassService
       */
      constructor(http, el, updateHostClassService) {
          this.http = http;
          this.el = el;
          this.updateHostClassService = updateHostClassService;
          this.reqs = {};
          this.inited = false;
          this.destroy = false;
          // #region fields
          this.classes = {};
          // #region styles
          this.prefixCls = 'ant-upload';
          if (!http) {
              throw new Error(`Not found 'HttpClient', You can import 'HttpClientModule' in your root module.`);
          }
      }
      // #endregion
      /**
       * @return {?}
       */
      onClick() {
          if (this.options.disabled || !this.options.openFileDialogOnClick) {
              return;
          }
          ((/** @type {?} */ (this.file.nativeElement))).click();
      }
      /**
       * @param {?} e
       * @return {?}
       */
      onKeyDown(e) {
          if (this.options.disabled) {
              return;
          }
          if (e.key === 'Enter' || e.keyCode === ENTER) {
              this.onClick();
          }
      }
      /**
       * @param {?} e
       * @return {?}
       */
      onFileDrop(e) {
          if (this.options.disabled || e.type === 'dragover') {
              e.preventDefault();
              return;
          }
          if (this.options.directory) {
              this.traverseFileTree((/** @type {?} */ (e.dataTransfer)).items);
          }
          else {
              /** @type {?} */
              const files = Array.prototype.slice
                  .call((/** @type {?} */ (e.dataTransfer)).files)
                  .filter((/**
               * @param {?} file
               * @return {?}
               */
              (file) => this.attrAccept(file, this.options.accept)));
              if (files.length) {
                  this.uploadFiles(files);
              }
          }
          e.preventDefault();
      }
      /**
       * @param {?} e
       * @return {?}
       */
      onChange(e) {
          if (this.options.disabled) {
              return;
          }
          /** @type {?} */
          const hie = (/** @type {?} */ (e.target));
          this.uploadFiles((/** @type {?} */ (hie.files)));
          hie.value = '';
      }
      /**
       * @private
       * @param {?} files
       * @return {?}
       */
      traverseFileTree(files) {
          // tslint:disable-next-line:no-any
          /** @type {?} */
          const _traverseFileTree = (/**
           * @param {?} item
           * @param {?} path
           * @return {?}
           */
          (item, path) => {
              if (item.isFile) {
                  item.file((/**
                   * @param {?} file
                   * @return {?}
                   */
                  (file) => {
                      if (this.attrAccept(file, this.options.accept)) {
                          this.uploadFiles([file]);
                      }
                  }));
              }
              else if (item.isDirectory) {
                  /** @type {?} */
                  const dirReader = item.createReader();
                  // tslint:disable-next-line:no-any
                  dirReader.readEntries((/**
                   * @param {?} entries
                   * @return {?}
                   */
                  (entries) => {
                      for (const entrieItem of entries) {
                          _traverseFileTree(entrieItem, `${path}${item.name}/`);
                      }
                  }));
              }
          });
          // tslint:disable-next-line:no-any
          for (const file of (/** @type {?} */ (files))) {
              _traverseFileTree(file.webkitGetAsEntry(), '');
          }
      }
      /**
       * @private
       * @param {?} file
       * @param {?=} acceptedFiles
       * @return {?}
       */
      attrAccept(file, acceptedFiles) {
          if (file && acceptedFiles) {
              /** @type {?} */
              const acceptedFilesArray = Array.isArray(acceptedFiles) ? acceptedFiles : acceptedFiles.split(',');
              /** @type {?} */
              const fileName = '' + file.name;
              /** @type {?} */
              const mimeType = '' + file.type;
              /** @type {?} */
              const baseMimeType = mimeType.replace(/\/.*$/, '');
              return acceptedFilesArray.some((/**
               * @param {?} type
               * @return {?}
               */
              type => {
                  /** @type {?} */
                  const validType = type.trim();
                  if (validType.charAt(0) === '.') {
                      return (fileName
                          .toLowerCase()
                          .indexOf(validType.toLowerCase(), fileName.toLowerCase().length - validType.toLowerCase().length) !== -1);
                  }
                  else if (/\/\*$/.test(validType)) {
                      // This is something like a image/* mime type
                      return baseMimeType === validType.replace(/\/.*$/, '');
                  }
                  return mimeType === validType;
              }));
          }
          return true;
      }
      /**
       * @private
       * @param {?} file
       * @return {?}
       */
      attachUid(file) {
          if (!file.uid) {
              file.uid = Math.random()
                  .toString(36)
                  .substring(2);
          }
          return file;
      }
      /**
       * @param {?} fileList
       * @return {?}
       */
      uploadFiles(fileList) {
          /** @type {?} */
          let filters$ = of(Array.prototype.slice.call(fileList));
          if (this.options.filters) {
              this.options.filters.forEach((/**
               * @param {?} f
               * @return {?}
               */
              f => {
                  filters$ = filters$.pipe(switchMap((/**
                   * @param {?} list
                   * @return {?}
                   */
                  list => {
                      /** @type {?} */
                      const fnRes = f.fn(list);
                      return fnRes instanceof Observable ? fnRes : of(fnRes);
                  })));
              }));
          }
          filters$.subscribe((/**
           * @param {?} list
           * @return {?}
           */
          list => {
              list.forEach((/**
               * @param {?} file
               * @return {?}
               */
              (file) => {
                  this.attachUid(file);
                  this.upload(file, list);
              }));
          }), (/**
           * @param {?} e
           * @return {?}
           */
          e => {
              console.warn(`Unhandled upload filter error`, e);
          }));
      }
      /**
       * @private
       * @param {?} file
       * @param {?} fileList
       * @return {?}
       */
      upload(file, fileList) {
          if (!this.options.beforeUpload) {
              return this.post(file);
          }
          /** @type {?} */
          const before = this.options.beforeUpload(file, fileList);
          if (before instanceof Observable) {
              before.subscribe((/**
               * @param {?} processedFile
               * @return {?}
               */
              (processedFile) => {
                  /** @type {?} */
                  const processedFileType = Object.prototype.toString.call(processedFile);
                  if (processedFileType === '[object File]' || processedFileType === '[object Blob]') {
                      this.attachUid(processedFile);
                      this.post(processedFile);
                  }
                  else if (typeof processedFile === 'boolean' && processedFile !== false) {
                      this.post(file);
                  }
              }), (/**
               * @param {?} e
               * @return {?}
               */
              e => {
                  console.warn(`Unhandled upload beforeUpload error`, e);
              }));
          }
          else if (before !== false) {
              return this.post(file);
          }
      }
      /**
       * @private
       * @param {?} file
       * @return {?}
       */
      post(file) {
          if (this.destroy) {
              return;
          }
          /** @type {?} */
          const opt = this.options;
          const { uid } = file;
          let { data, headers } = opt;
          if (typeof data === 'function') {
              data = ((/** @type {?} */ (data)))(file);
          }
          if (typeof headers === 'function') {
              headers = ((/** @type {?} */ (headers)))(file);
          }
          /** @type {?} */
          const args = {
              action: opt.action,
              name: opt.name,
              headers,
              file,
              data,
              withCredentials: opt.withCredentials,
              onProgress: opt.onProgress
                  ? (/**
                   * @param {?} e
                   * @return {?}
                   */
                  e => {
                      (/** @type {?} */ (opt.onProgress))(e, file);
                  })
                  : undefined,
              onSuccess: (/**
               * @param {?} ret
               * @param {?} xhr
               * @return {?}
               */
              (ret, xhr) => {
                  this.clean(uid);
                  (/** @type {?} */ (opt.onSuccess))(ret, file, xhr);
              }),
              onError: (/**
               * @param {?} xhr
               * @return {?}
               */
              xhr => {
                  this.clean(uid);
                  (/** @type {?} */ (opt.onError))(xhr, file);
              })
          };
          /** @type {?} */
          const req$ = (opt.customRequest || this.xhr).call(this, args);
          if (!(req$ instanceof Subscription)) {
              console.warn(`Must return Subscription type in '[nzCustomRequest]' property`);
          }
          this.reqs[uid] = req$;
          (/** @type {?} */ (opt.onStart))(file);
      }
      /**
       * @private
       * @param {?} args
       * @return {?}
       */
      xhr(args) {
          /** @type {?} */
          const formData = new FormData();
          // tslint:disable-next-line:no-any
          formData.append((/** @type {?} */ (args.name)), (/** @type {?} */ (args.file)));
          if (args.data) {
              Object.keys(args.data).map((/**
               * @param {?} key
               * @return {?}
               */
              key => {
                  formData.append(key, (/** @type {?} */ (args.data))[key]);
              }));
          }
          if (!args.headers) {
              args.headers = {};
          }
          if (args.headers['X-Requested-With'] !== null) {
              args.headers['X-Requested-With'] = `XMLHttpRequest`;
          }
          else {
              delete args.headers['X-Requested-With'];
          }
          /** @type {?} */
          const req = new HttpRequest('POST', (/** @type {?} */ (args.action)), formData, {
              reportProgress: true,
              withCredentials: args.withCredentials,
              headers: new HttpHeaders(args.headers)
          });
          return this.http.request(req).subscribe((/**
           * @param {?} event
           * @return {?}
           */
          (event) => {
              if (event.type === HttpEventType.UploadProgress) {
                  if ((/** @type {?} */ (event.total)) > 0) {
                      // tslint:disable-next-line:no-any
                      ((/** @type {?} */ (event))).percent = (event.loaded / (/** @type {?} */ (event.total))) * 100;
                  }
                  (/** @type {?} */ (args.onProgress))(event, args.file);
              }
              else if (event instanceof HttpResponse) {
                  (/** @type {?} */ (args.onSuccess))(event.body, args.file, event);
              }
          }), (/**
           * @param {?} err
           * @return {?}
           */
          err => {
              this.abort(args.file);
              (/** @type {?} */ (args.onError))(err, args.file);
          }));
      }
      /**
       * @private
       * @param {?} uid
       * @return {?}
       */
      clean(uid) {
          /** @type {?} */
          const req$ = this.reqs[uid];
          if (req$ instanceof Subscription) {
              req$.unsubscribe();
          }
          delete this.reqs[uid];
      }
      /**
       * @param {?=} file
       * @return {?}
       */
      abort(file) {
          if (file) {
              this.clean(file && file.uid);
          }
          else {
              Object.keys(this.reqs).forEach((/**
               * @param {?} uid
               * @return {?}
               */
              uid => this.clean(uid)));
          }
      }
      /**
       * @private
       * @return {?}
       */
      setClassMap() {
          /** @type {?} */
          const classMap = Object.assign({ [this.prefixCls]: true, [`${this.prefixCls}-disabled`]: this.options.disabled }, this.classes);
          this.updateHostClassService.updateHostClass(this.el.nativeElement, classMap);
      }
      /**
       * @return {?}
       */
      ngOnInit() {
          this.inited = true;
          this.setClassMap();
      }
      /**
       * @return {?}
       */
      ngOnChanges() {
          if (this.inited) {
              this.setClassMap();
          }
      }
      /**
       * @return {?}
       */
      ngOnDestroy() {
          this.destroy = true;
          this.abort();
      }
  }
  NzUploadBtnComponent.decorators = [
      { type: Component, args: [{
                  selector: '[nz-upload-btn]',
                  exportAs: 'nzUploadBtn',
                  template: "<input type=\"file\" #file (change)=\"onChange($event)\"\n  [attr.accept]=\"options.accept\"\n  [attr.directory]=\"options.directory ? 'directory': null\"\n  [attr.webkitdirectory]=\"options.directory ? 'webkitdirectory': null\"\n  [multiple]=\"options.multiple\" style=\"display: none;\">\n<ng-content></ng-content>",
                  host: {
                      '[attr.tabindex]': '"0"',
                      '[attr.role]': '"button"'
                  },
                  providers: [NzUpdateHostClassService],
                  preserveWhitespaces: false,
                  encapsulation: ViewEncapsulation.None
              }] }
  ];
  /** @nocollapse */
  NzUploadBtnComponent.ctorParameters = () => [
      { type: HttpClient, decorators: [{ type: Optional }] },
      { type: ElementRef },
      { type: NzUpdateHostClassService }
  ];
  NzUploadBtnComponent.propDecorators = {
      file: [{ type: ViewChild, args: ['file',] }],
      classes: [{ type: Input }],
      options: [{ type: Input }],
      onClick: [{ type: HostListener, args: ['click',] }],
      onKeyDown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
      onFileDrop: [{ type: HostListener, args: ['drop', ['$event'],] }, { type: HostListener, args: ['dragover', ['$event'],] }]
  };
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  class NzUploadListComponent {
      // #endregion
      /**
       * @param {?} el
       * @param {?} cdr
       * @param {?} updateHostClassService
       * @param {?} platform
       */
      constructor(el, cdr, updateHostClassService, platform) {
          this.el = el;
          this.cdr = cdr;
          this.updateHostClassService = updateHostClassService;
          this.platform = platform;
          this.imageTypes = ['image', 'webp', 'png', 'svg', 'gif', 'jpg', 'jpeg', 'bmp'];
          // #region fields
          // tslint:disable-next-line:no-any
          this.locale = {};
          // #endregion
          // #region styles
          this.prefixCls = 'ant-upload-list';
      }
      /**
       * @return {?}
       */
      get showPic() {
          return this.listType === 'picture' || this.listType === 'picture-card';
      }
      /**
       * @param {?} list
       * @return {?}
       */
      set items(list) {
          list.forEach((/**
           * @param {?} file
           * @return {?}
           */
          file => {
              file.linkProps = typeof file.linkProps === 'string' ? JSON.parse(file.linkProps) : file.linkProps;
          }));
          this._items = list;
      }
      /**
       * @return {?}
       */
      get items() {
          return this._items;
      }
      /**
       * @private
       * @return {?}
       */
      setClassMap() {
          /** @type {?} */
          const classMap = {
              [this.prefixCls]: true,
              [`${this.prefixCls}-${this.listType}`]: true
          };
          this.updateHostClassService.updateHostClass(this.el.nativeElement, classMap);
      }
      // #endregion
      // #region render
      /**
       * @private
       * @param {?} url
       * @return {?}
       */
      extname(url) {
          /** @type {?} */
          const temp = url.split('/');
          /** @type {?} */
          const filename = temp[temp.length - 1];
          /** @type {?} */
          const filenameWithoutSuffix = filename.split(/#|\?/)[0];
          return (/\.[^./\\]*$/.exec(filenameWithoutSuffix) || [''])[0];
      }
      /**
       * @param {?} file
       * @return {?}
       */
      isImageUrl(file) {
          if (~this.imageTypes.indexOf(file.type)) {
              return true;
          }
          /** @type {?} */
          const url = (/** @type {?} */ ((file.thumbUrl || file.url || '')));
          if (!url) {
              return false;
          }
          /** @type {?} */
          const extension = this.extname(url);
          if (/^data:image\//.test(url) || /(webp|svg|png|gif|jpg|jpeg|bmp)$/i.test(extension)) {
              return true;
          }
          else if (/^data:/.test(url)) {
              // other file types of base64
              return false;
          }
          else if (extension) {
              // other file types which have extension
              return false;
          }
          return true;
      }
      /**
       * @private
       * @param {?} file
       * @param {?} callback
       * @return {?}
       */
      previewFile(file, callback) {
          if (file.type && this.imageTypes.indexOf(file.type) === -1) {
              callback('');
          }
          /** @type {?} */
          const reader = new FileReader();
          // https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsDataURL
          reader.onloadend = (/**
           * @return {?}
           */
          () => callback((/** @type {?} */ (reader.result))));
          reader.readAsDataURL(file);
      }
      /**
       * @private
       * @return {?}
       */
      genThumb() {
          if (!this.platform.isBrowser) {
              return;
          }
          // tslint:disable-next-line:no-any
          /** @type {?} */
          const win = (/** @type {?} */ (window));
          if (!this.showPic ||
              typeof document === 'undefined' ||
              typeof win === 'undefined' ||
              !win.FileReader ||
              !win.File) {
              return;
          }
          this.items
              .filter((/**
           * @param {?} file
           * @return {?}
           */
          file => file.originFileObj instanceof File && file.thumbUrl === undefined))
              .forEach((/**
           * @param {?} file
           * @return {?}
           */
          file => {
              file.thumbUrl = '';
              this.previewFile((/** @type {?} */ (file.originFileObj)), (/**
               * @param {?} previewDataUrl
               * @return {?}
               */
              (previewDataUrl) => {
                  file.thumbUrl = previewDataUrl;
                  this.detectChanges();
              }));
          }));
      }
      /**
       * @param {?} file
       * @return {?}
       */
      showPreview(file) {
          const { showPreviewIcon, hidePreviewIconInNonImage } = this.icons;
          if (!showPreviewIcon) {
              return false;
          }
          return this.isImageUrl(file) ? true : !hidePreviewIconInNonImage;
      }
      /**
       * @param {?} file
       * @param {?} e
       * @return {?}
       */
      handlePreview(file, e) {
          if (!this.onPreview) {
              return;
          }
          e.preventDefault();
          return this.onPreview(file);
      }
      /**
       * @param {?} file
       * @param {?} e
       * @return {?}
       */
      handleRemove(file, e) {
          e.preventDefault();
          if (this.onRemove) {
              this.onRemove(file);
          }
          return;
      }
      /**
       * @return {?}
       */
      detectChanges() {
          this.cdr.detectChanges();
      }
      /**
       * @return {?}
       */
      ngOnChanges() {
          this.setClassMap();
          this.genThumb();
      }
  }
  NzUploadListComponent.decorators = [
      { type: Component, args: [{
                  selector: 'nz-upload-list',
                  exportAs: 'nzUploadList',
                  template: "<div *ngFor=\"let file of items\" class=\"ant-upload-list-item ant-upload-list-item-{{file.status}}\" @itemState>\n  <ng-template #icon>\n    <ng-container *ngIf=\"showPic; else noPicTpl\">\n      <div *ngIf=\"listType === 'picture-card' && file.status === 'uploading'; else thumbUrlCheck\" class=\"ant-upload-list-item-uploading-text\">{{ locale.uploading }}</div>\n    </ng-container>\n    <ng-template #thumbUrlCheck>\n      <i *ngIf=\"!file.thumbUrl && !file.url; else thumbTpl\"\n        class=\"ant-upload-list-item-thumbnail\" nz-icon nzType=\"picture\" theme=\"twotone\"></i>\n    </ng-template>\n    <ng-template #thumbTpl>\n      <a class=\"ant-upload-list-item-thumbnail\" target=\"_blank\" rel=\"noopener noreferrer\"\n        [href]=\"file.thumbUrl || file.url\"\n        (click)=\"handlePreview(file, $event)\">\n        <img *ngIf=\"isImageUrl(file); else noThumbTpl\" [src]=\"file.thumbUrl || file.url\" [attr.alt]=\"file.name\" />\n      </a>\n    </ng-template>\n    <ng-template #noThumbTpl><i class=\"ant-upload-list-item-icon\" nz-icon nzType=\"file\" theme=\"twotone\"></i></ng-template>\n    <ng-template #noPicTpl><i nz-icon [nzType]=\"file.status === 'uploading' ? 'loading' : 'paper-clip'\"></i></ng-template>\n  </ng-template>\n  <ng-template #preview>\n    <ng-container *ngIf=\"file.url; else prevText\">\n      <a [href]=\"file.thumbUrl || file.url\" target=\"_blank\" rel=\"noopener noreferrer\" [attr.download]=\"file.linkProps && file.linkProps.download\"\n        (click)=\"handlePreview(file, $event)\" class=\"ant-upload-list-item-name\" title=\"{{ file.name }}\">{{ file.name }}</a>\n    </ng-container>\n    <ng-template #prevText>\n      <span (click)=\"handlePreview(file, $event)\" class=\"ant-upload-list-item-name\" title=\"{{ file.name }}\">{{ file.name }}</span>\n    </ng-template>\n  </ng-template>\n  <div class=\"ant-upload-list-item-info\">\n    <span *ngIf=\"file.status === 'error'\" nz-tooltip [nzTitle]=\"file.message\">\n      <ng-template [ngTemplateOutlet]=\"icon\"></ng-template>\n      <ng-template [ngTemplateOutlet]=\"preview\"></ng-template>\n    </span>\n    <span *ngIf=\"file.status !== 'error'\">\n      <ng-template [ngTemplateOutlet]=\"icon\"></ng-template>\n      <ng-template [ngTemplateOutlet]=\"preview\"></ng-template>\n    </span>\n  </div>\n  <ng-container *ngIf=\"listType === 'picture-card' && file.status !== 'uploading'; else close\">\n    <span class=\"ant-upload-list-item-actions\">\n      <a *ngIf=\"showPreview(file)\" [href]=\"file.thumbUrl || file.url\"\n        target=\"_blank\" rel=\"noopener noreferrer\"\n        title=\"{{ locale.previewFile }}\"\n        [ngStyle]=\"!(file.url || file.thumbUrl) && {'opacity': .5, 'pointer-events': 'none'}\"\n        (click)=\"handlePreview(file, $event)\">\n          <i nz-icon nzType=\"eye-o\"></i>\n      </a>\n      <i *ngIf=\"icons.showRemoveIcon\" (click)=\"handleRemove(file, $event)\" nz-icon nzType=\"delete\" title=\"{{ locale.removeFile }}\"></i>\n    </span>\n  </ng-container>\n  <ng-template #close>\n    <i *ngIf=\"icons.showRemoveIcon\" (click)=\"handleRemove(file, $event)\" nz-icon nzType=\"close\" title=\"{{ locale.removeFile }}\"></i>\n  </ng-template>\n  <div *ngIf=\"file.status === 'uploading'\" class=\"ant-upload-list-item-progress\">\n    <nz-progress [nzPercent]=\"file.percent\" [nzShowInfo]=\"false\" [nzStrokeWidth]=\"2\"></nz-progress>\n  </div>\n</div>",
                  providers: [NzUpdateHostClassService],
                  animations: [
                      trigger('itemState', [
                          transition(':enter', [
                              style({ height: '0', width: '0', opacity: 0 }),
                              animate(150, style({ height: '*', width: '*', opacity: 1 }))
                          ]),
                          transition(':leave', [animate(150, style({ height: '0', width: '0', opacity: 0 }))])
                      ])
                  ],
                  preserveWhitespaces: false,
                  encapsulation: ViewEncapsulation.None,
                  changeDetection: ChangeDetectionStrategy.OnPush
              }] }
  ];
  /** @nocollapse */
  NzUploadListComponent.ctorParameters = () => [
      { type: ElementRef },
      { type: ChangeDetectorRef },
      { type: NzUpdateHostClassService },
      { type: Platform }
  ];
  NzUploadListComponent.propDecorators = {
      locale: [{ type: Input }],
      listType: [{ type: Input }],
      items: [{ type: Input }],
      icons: [{ type: Input }],
      onPreview: [{ type: Input }],
      onRemove: [{ type: Input }]
  };
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  class NzUploadComponent {
      // #endregion
      /**
       * @param {?} cdr
       * @param {?} i18n
       */
      constructor(cdr, i18n) {
          this.cdr = cdr;
          this.i18n = i18n;
          // tslint:disable-next-line:no-any
          this.locale = {};
          // #region fields
          this.nzType = 'select';
          this.nzLimit = 0;
          this.nzSize = 0;
          this.nzDirectory = false;
          this.nzOpenFileDialogOnClick = true;
          this.nzFilter = [];
          this.nzFileList = [];
          this.nzDisabled = false;
          this.nzListType = 'text';
          this.nzMultiple = false;
          this.nzName = 'file';
          this._showUploadList = true;
          this.nzShowButton = true;
          this.nzWithCredentials = false;
          this.nzChange = new EventEmitter();
          this.nzFileListChange = new EventEmitter();
          this.onStart = (/**
           * @param {?} file
           * @return {?}
           */
          (file) => {
              if (!this.nzFileList) {
                  this.nzFileList = [];
              }
              /** @type {?} */
              const targetItem = this.fileToObject(file);
              targetItem.status = 'uploading';
              this.nzFileList = this.nzFileList.concat(targetItem);
              this.nzFileListChange.emit(this.nzFileList);
              this.nzChange.emit({ file: targetItem, fileList: this.nzFileList, type: 'start' });
              this.detectChangesList();
          });
          this.onProgress = (/**
           * @param {?} e
           * @param {?} file
           * @return {?}
           */
          (e, file) => {
              /** @type {?} */
              const fileList = this.nzFileList;
              /** @type {?} */
              const targetItem = this.getFileItem(file, fileList);
              targetItem.percent = e.percent;
              this.nzChange.emit({
                  event: e,
                  file: Object.assign({}, targetItem),
                  fileList: this.nzFileList,
                  type: 'progress'
              });
              this.detectChangesList();
          });
          this.onSuccess = (/**
           * @param {?} res
           * @param {?} file
           * @return {?}
           */
          (res, file) => {
              /** @type {?} */
              const fileList = this.nzFileList;
              /** @type {?} */
              const targetItem = this.getFileItem(file, fileList);
              targetItem.status = 'done';
              targetItem.response = res;
              this.nzChange.emit({
                  file: Object.assign({}, targetItem),
                  fileList,
                  type: 'success'
              });
              this.detectChangesList();
          });
          this.onError = (/**
           * @param {?} err
           * @param {?} file
           * @return {?}
           */
          (err, file) => {
              /** @type {?} */
              const fileList = this.nzFileList;
              /** @type {?} */
              const targetItem = this.getFileItem(file, fileList);
              targetItem.error = err;
              targetItem.status = 'error';
              targetItem.message = this.genErr(targetItem);
              this.nzChange.emit({
                  file: Object.assign({}, targetItem),
                  fileList,
                  type: 'error'
              });
              this.detectChangesList();
          });
          this.onRemove = (/**
           * @param {?} file
           * @return {?}
           */
          (file) => {
              this.uploadComp.abort(file);
              file.status = 'removed';
              /** @type {?} */
              const fnRes = typeof this.nzRemove === 'function' ? this.nzRemove(file) : this.nzRemove == null ? true : this.nzRemove;
              (fnRes instanceof Observable ? fnRes : of(fnRes)).pipe(filter((/**
               * @param {?} res
               * @return {?}
               */
              (res) => res))).subscribe((/**
               * @return {?}
               */
              () => {
                  this.nzFileList = this.removeFileItem(file, this.nzFileList);
                  this.nzChange.emit({
                      file,
                      fileList: this.nzFileList,
                      type: 'removed'
                  });
                  this.nzFileListChange.emit(this.nzFileList);
                  this.cdr.detectChanges();
              }));
          });
          // #endregion
          // #region styles
          this.prefixCls = 'ant-upload';
          this.classList = [];
      }
      /**
       * @param {?} value
       * @return {?}
       */
      set nzShowUploadList(value) {
          this._showUploadList = typeof value === 'boolean' ? toBoolean(value) : value;
      }
      /**
       * @return {?}
       */
      get nzShowUploadList() {
          return this._showUploadList;
      }
      /**
       * @private
       * @template THIS
       * @this {THIS}
       * @return {THIS}
       */
      zipOptions() {
          if (typeof (/** @type {?} */ (this)).nzShowUploadList === 'boolean' && (/** @type {?} */ (this)).nzShowUploadList) {
              (/** @type {?} */ (this)).nzShowUploadList = {
                  showPreviewIcon: true,
                  showRemoveIcon: true,
                  hidePreviewIconInNonImage: false
              };
          }
          // filters
          /** @type {?} */
          const filters = (/** @type {?} */ (this)).nzFilter.slice();
          if ((/** @type {?} */ (this)).nzMultiple && (/** @type {?} */ (this)).nzLimit > 0 && filters.findIndex((/**
           * @param {?} w
           * @return {?}
           */
          w => w.name === 'limit')) === -1) {
              filters.push({
                  name: 'limit',
                  fn: (/**
                   * @param {?} fileList
                   * @return {?}
                   */
                  (fileList) => fileList.slice(-(/** @type {?} */ (this)).nzLimit))
              });
          }
          if ((/** @type {?} */ (this)).nzSize > 0 && filters.findIndex((/**
           * @param {?} w
           * @return {?}
           */
          w => w.name === 'size')) === -1) {
              filters.push({
                  name: 'size',
                  fn: (/**
                   * @param {?} fileList
                   * @return {?}
                   */
                  (fileList) => fileList.filter((/**
                   * @param {?} w
                   * @return {?}
                   */
                  w => w.size / 1024 <= (/** @type {?} */ (this)).nzSize)))
              });
          }
          if ((/** @type {?} */ (this)).nzFileType && (/** @type {?} */ (this)).nzFileType.length > 0 && filters.findIndex((/**
           * @param {?} w
           * @return {?}
           */
          w => w.name === 'type')) === -1) {
              /** @type {?} */
              const types = (/** @type {?} */ (this)).nzFileType.split(',');
              filters.push({
                  name: 'type',
                  fn: (/**
                   * @param {?} fileList
                   * @return {?}
                   */
                  (fileList) => fileList.filter((/**
                   * @param {?} w
                   * @return {?}
                   */
                  w => ~types.indexOf(w.type))))
              });
          }
          (/** @type {?} */ (this))._btnOptions = {
              disabled: (/** @type {?} */ (this)).nzDisabled,
              accept: (/** @type {?} */ (this)).nzAccept,
              action: (/** @type {?} */ (this)).nzAction,
              directory: (/** @type {?} */ (this)).nzDirectory,
              openFileDialogOnClick: (/** @type {?} */ (this)).nzOpenFileDialogOnClick,
              beforeUpload: (/** @type {?} */ (this)).nzBeforeUpload,
              customRequest: (/** @type {?} */ (this)).nzCustomRequest,
              data: (/** @type {?} */ (this)).nzData,
              headers: (/** @type {?} */ (this)).nzHeaders,
              name: (/** @type {?} */ (this)).nzName,
              multiple: (/** @type {?} */ (this)).nzMultiple,
              withCredentials: (/** @type {?} */ (this)).nzWithCredentials,
              filters,
              onStart: (/** @type {?} */ (this)).onStart,
              onProgress: (/** @type {?} */ (this)).onProgress,
              onSuccess: (/** @type {?} */ (this)).onSuccess,
              onError: (/** @type {?} */ (this)).onError
          };
          return (/** @type {?} */ (this));
      }
      // #region upload
      /**
       * @private
       * @param {?} file
       * @return {?}
       */
      fileToObject(file) {
          return {
              lastModified: file.lastModified,
              lastModifiedDate: file.lastModifiedDate,
              name: file.filename || file.name,
              size: file.size,
              type: file.type,
              uid: file.uid,
              response: file.response,
              error: file.error,
              percent: 0,
              // tslint:disable-next-line:no-any
              originFileObj: (/** @type {?} */ (file))
          };
      }
      /**
       * @private
       * @param {?} file
       * @param {?} fileList
       * @return {?}
       */
      getFileItem(file, fileList) {
          return fileList.filter((/**
           * @param {?} item
           * @return {?}
           */
          item => item.uid === file.uid))[0];
      }
      /**
       * @private
       * @param {?} file
       * @param {?} fileList
       * @return {?}
       */
      removeFileItem(file, fileList) {
          return fileList.filter((/**
           * @param {?} item
           * @return {?}
           */
          item => item.uid !== file.uid));
      }
      /**
       * @private
       * @param {?} file
       * @return {?}
       */
      genErr(file) {
          return file.response && typeof file.response === 'string'
              ? file.response
              : (file.error && file.error.statusText) || this.locale.uploadError;
      }
      /**
       * @param {?} e
       * @return {?}
       */
      fileDrop(e) {
          if (e.type === this.dragState) {
              return;
          }
          this.dragState = e.type;
          this.setClassMap();
      }
      // #endregion
      // #region list
      /**
       * @private
       * @return {?}
       */
      detectChangesList() {
          this.cdr.detectChanges();
          this.listComp.detectChanges();
      }
      /**
       * @private
       * @return {?}
       */
      setClassMap() {
          /** @type {?} */
          let subCls = [];
          if (this.nzType === 'drag') {
              if (this.nzFileList.some((/**
               * @param {?} file
               * @return {?}
               */
              file => file.status === 'uploading'))) {
                  subCls.push(`${this.prefixCls}-drag-uploading`);
              }
              if (this.dragState === 'dragover') {
                  subCls.push(`${this.prefixCls}-drag-hover`);
              }
          }
          else {
              subCls = [`${this.prefixCls}-select-${this.nzListType}`];
          }
          this.classList = [
              this.prefixCls,
              `${this.prefixCls}-${this.nzType}`,
              ...subCls,
              (this.nzDisabled && `${this.prefixCls}-disabled`) || ''
          ].filter((/**
           * @param {?} item
           * @return {?}
           */
          item => !!item));
          this.cdr.detectChanges();
      }
      // #endregion
      /**
       * @return {?}
       */
      ngOnInit() {
          this.i18n$ = this.i18n.localeChange.subscribe((/**
           * @return {?}
           */
          () => {
              this.locale = this.i18n.getLocaleData('Upload');
              this.detectChangesList();
          }));
      }
      /**
       * @param {?} changes
       * @return {?}
       */
      ngOnChanges(changes) {
          if (changes.nzFileList) {
              (this.nzFileList || []).forEach((/**
               * @param {?} file
               * @return {?}
               */
              file => (file.message = this.genErr(file))));
          }
          this.zipOptions().setClassMap();
      }
      /**
       * @return {?}
       */
      ngOnDestroy() {
          this.i18n$.unsubscribe();
      }
  }
  NzUploadComponent.decorators = [
      { type: Component, args: [{
                  selector: 'nz-upload',
                  exportAs: 'nzUpload',
                  template: "<ng-template #list>\n  <nz-upload-list #listComp [style.display]=\"nzShowUploadList ? '' : 'none'\"\n    [locale]=\"locale\"\n    [listType]=\"nzListType\"\n    [items]=\"nzFileList || []\"\n    [icons]=\"nzShowUploadList\"\n    [onPreview]=\"nzPreview\"\n    [onRemove]=\"onRemove\"></nz-upload-list>\n</ng-template>\n<ng-template #con><ng-content></ng-content></ng-template>\n<ng-template #btn>\n  <div [ngClass]=\"classList\" [style.display]=\"nzShowButton ? '' : 'none'\">\n    <div nz-upload-btn #uploadComp [options]=\"_btnOptions\">\n      <ng-template [ngTemplateOutlet]=\"con\"></ng-template>\n    </div>\n  </div>\n</ng-template>\n<ng-container *ngIf=\"nzType === 'drag'; else select\">\n  <div [ngClass]=\"classList\"\n    (drop)=\"fileDrop($event)\"\n    (dragover)=\"fileDrop($event)\"\n    (dragleave)=\"fileDrop($event)\">\n    <div nz-upload-btn #uploadComp [options]=\"_btnOptions\" [classes]=\"{'ant-upload-btn': true}\">\n      <div class=\"ant-upload-drag-container\">\n        <ng-template [ngTemplateOutlet]=\"con\"></ng-template>\n      </div>\n    </div>\n  </div>\n  <ng-template [ngTemplateOutlet]=\"list\"></ng-template>\n</ng-container>\n<ng-template #select>\n  <ng-container *ngIf=\"nzListType === 'picture-card'; else pic\">\n    <ng-template [ngTemplateOutlet]=\"list\"></ng-template>\n    <ng-template [ngTemplateOutlet]=\"btn\"></ng-template>\n  </ng-container>\n</ng-template>\n<ng-template #pic>\n  <ng-template [ngTemplateOutlet]=\"btn\"></ng-template>\n  <ng-template [ngTemplateOutlet]=\"list\"></ng-template>\n</ng-template>",
                  preserveWhitespaces: false,
                  encapsulation: ViewEncapsulation.None,
                  changeDetection: ChangeDetectionStrategy.OnPush
              }] }
  ];
  /** @nocollapse */
  NzUploadComponent.ctorParameters = () => [
      { type: ChangeDetectorRef },
      { type: NzI18nService }
  ];
  NzUploadComponent.propDecorators = {
      uploadComp: [{ type: ViewChild, args: ['uploadComp',] }],
      listComp: [{ type: ViewChild, args: ['listComp',] }],
      nzType: [{ type: Input }],
      nzLimit: [{ type: Input }],
      nzSize: [{ type: Input }],
      nzFileType: [{ type: Input }],
      nzAccept: [{ type: Input }],
      nzAction: [{ type: Input }],
      nzDirectory: [{ type: Input }],
      nzOpenFileDialogOnClick: [{ type: Input }],
      nzBeforeUpload: [{ type: Input }],
      nzCustomRequest: [{ type: Input }],
      nzData: [{ type: Input }],
      nzFilter: [{ type: Input }],
      nzFileList: [{ type: Input }],
      nzDisabled: [{ type: Input }],
      nzHeaders: [{ type: Input }],
      nzListType: [{ type: Input }],
      nzMultiple: [{ type: Input }],
      nzName: [{ type: Input }],
      nzShowUploadList: [{ type: Input }],
      nzShowButton: [{ type: Input }],
      nzWithCredentials: [{ type: Input }],
      nzRemove: [{ type: Input }],
      nzPreview: [{ type: Input }],
      nzChange: [{ type: Output }],
      nzFileListChange: [{ type: Output }]
  };
  __decorate([
      InputNumber(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzLimit", void 0);
  __decorate([
      InputNumber(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzSize", void 0);
  __decorate([
      InputBoolean(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzDirectory", void 0);
  __decorate([
      InputBoolean(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzOpenFileDialogOnClick", void 0);
  __decorate([
      InputBoolean(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzDisabled", void 0);
  __decorate([
      InputBoolean(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzMultiple", void 0);
  __decorate([
      InputBoolean(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzShowButton", void 0);
  __decorate([
      InputBoolean(),
      __metadata("design:type", Object)
  ], NzUploadComponent.prototype, "nzWithCredentials", void 0);
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  class NzUploadModule {
  }
  NzUploadModule.decorators = [
      { type: NgModule, args: [{
                  imports: [CommonModule, FormsModule, NzToolTipModule, NzProgressModule, NzI18nModule, NzIconModule],
                  declarations: [NzUploadComponent, NzUploadBtnComponent, NzUploadListComponent],
                  exports: [NzUploadComponent]
              },] }
  ];
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  
  /**
   * @fileoverview added by tsickle
   * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
   */
  
  export { NzUploadBtnComponent, NzUploadListComponent, NzUploadComponent, NzUploadModule };
  
  //# sourceMappingURL=ng-zorro-antd-upload.js.map