浏览代码

Upgrade tslint from 4.4 to 5.9

There are a few new lints, including checks for const correctness. This
resulted in many (mostly mechanical) changes.
Danilo Bargen 7 年之前
父节点
当前提交
bf2b860d72

+ 119 - 418
package-lock.json

@@ -198,15 +198,6 @@
       "resolved": "https://registry.npmjs.org/angularjs-scroll-glue/-/angularjs-scroll-glue-2.1.0.tgz",
       "integrity": "sha1-2aXo5QG7XkDL6yXzr2awxhM1wiY="
     },
-    "ansi-align": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz",
-      "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=",
-      "dev": true,
-      "requires": {
-        "string-width": "1.0.2"
-      }
-    },
     "ansi-regex": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
@@ -275,6 +266,15 @@
         }
       }
     },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
     "arr-diff": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
@@ -1105,23 +1105,6 @@
         "hoek": "2.16.3"
       }
     },
-    "boxen": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz",
-      "integrity": "sha1-g2TUJIrDT/DvGy8r9JpsYM4NgbY=",
-      "dev": true,
-      "requires": {
-        "ansi-align": "1.1.0",
-        "camelcase": "2.1.1",
-        "chalk": "1.1.3",
-        "cli-boxes": "1.0.0",
-        "filled-array": "1.1.0",
-        "object-assign": "4.1.1",
-        "repeating": "2.0.1",
-        "string-width": "1.0.2",
-        "widest-line": "1.0.0"
-      }
-    },
     "brace-expansion": {
       "version": "1.1.8",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
@@ -1450,12 +1433,6 @@
         "map-obj": "1.0.1"
       }
     },
-    "capture-stack-trace": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz",
-      "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=",
-      "dev": true
-    },
     "caseless": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
@@ -1499,12 +1476,6 @@
         "safe-buffer": "5.1.1"
       }
     },
-    "cli-boxes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
-      "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
-      "dev": true
-    },
     "cliui": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
@@ -1530,6 +1501,21 @@
       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
     },
+    "color-convert": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+      "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
     "colors": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
@@ -1737,31 +1723,6 @@
         }
       }
     },
-    "configstore": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz",
-      "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=",
-      "dev": true,
-      "requires": {
-        "dot-prop": "3.0.0",
-        "graceful-fs": "4.1.11",
-        "mkdirp": "0.5.1",
-        "object-assign": "4.1.1",
-        "os-tmpdir": "1.0.2",
-        "osenv": "0.1.4",
-        "uuid": "2.0.3",
-        "write-file-atomic": "1.3.4",
-        "xdg-basedir": "2.0.0"
-      },
-      "dependencies": {
-        "uuid": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
-          "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
-          "dev": true
-        }
-      }
-    },
     "connect": {
       "version": "3.6.3",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.3.tgz",
@@ -1834,15 +1795,6 @@
         "elliptic": "6.4.0"
       }
     },
-    "create-error-class": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
-      "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
-      "dev": true,
-      "requires": {
-        "capture-stack-trace": "1.0.0"
-      }
-    },
     "create-hash": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
@@ -1970,12 +1922,6 @@
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
       "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
     },
-    "deep-extend": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
-      "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=",
-      "dev": true
-    },
     "defined": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
@@ -2047,9 +1993,9 @@
       "dev": true
     },
     "diff": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.0.tgz",
-      "integrity": "sha512-w0XZubFWn0Adlsapj9EAWX0FqWdO4tz8kc3RiYdWLh4k/V8PTb6i0SMgXt0vRM3zyKnT8tKO7mUlieRQHIjMNg==",
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
+      "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
       "dev": true
     },
     "diffie-hellman": {
@@ -2079,15 +2025,6 @@
       "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
       "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw="
     },
-    "dot-prop": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz",
-      "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=",
-      "dev": true,
-      "requires": {
-        "is-obj": "1.0.1"
-      }
-    },
     "duplexer2": {
       "version": "0.0.2",
       "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
@@ -2407,12 +2344,6 @@
         "repeat-string": "1.6.1"
       }
     },
-    "filled-array": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz",
-      "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=",
-      "dev": true
-    },
     "finalhandler": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz",
@@ -2437,15 +2368,6 @@
         "pinkie-promise": "2.0.1"
       }
     },
-    "findup-sync": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
-      "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
-      "dev": true,
-      "requires": {
-        "glob": "5.0.15"
-      }
-    },
     "for-in": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -3675,70 +3597,6 @@
         "sparkles": "1.0.0"
       }
     },
-    "got": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz",
-      "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=",
-      "dev": true,
-      "requires": {
-        "create-error-class": "3.0.2",
-        "duplexer2": "0.1.4",
-        "is-redirect": "1.0.0",
-        "is-retry-allowed": "1.1.0",
-        "is-stream": "1.1.0",
-        "lowercase-keys": "1.0.0",
-        "node-status-codes": "1.0.0",
-        "object-assign": "4.1.1",
-        "parse-json": "2.2.0",
-        "pinkie-promise": "2.0.1",
-        "read-all-stream": "3.1.0",
-        "readable-stream": "2.3.3",
-        "timed-out": "3.1.3",
-        "unzip-response": "1.0.2",
-        "url-parse-lax": "1.0.0"
-      },
-      "dependencies": {
-        "duplexer2": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
-          "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
-          "dev": true,
-          "requires": {
-            "readable-stream": "2.3.3"
-          }
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "1.0.0",
-            "process-nextick-args": "1.0.7",
-            "safe-buffer": "5.1.1",
-            "string_decoder": "1.0.3",
-            "util-deprecate": "1.0.2"
-          }
-        },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "5.1.1"
-          }
-        }
-      }
-    },
     "graceful-fs": {
       "version": "4.1.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
@@ -3965,12 +3823,6 @@
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
       "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
     },
-    "imurmurhash": {
-      "version": "0.1.4",
-      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-      "dev": true
-    },
     "in-publish": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
@@ -4009,12 +3861,6 @@
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
       "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
     },
-    "ini": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
-      "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
-      "dev": true
-    },
     "inject-lr-script": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/inject-lr-script/-/inject-lr-script-2.1.0.tgz",
@@ -4164,12 +4010,6 @@
         "xtend": "4.0.1"
       }
     },
-    "is-npm": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
-      "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
-      "dev": true
-    },
     "is-number": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
@@ -4179,12 +4019,6 @@
         "kind-of": "3.2.2"
       }
     },
-    "is-obj": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
-      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
-      "dev": true
-    },
     "is-posix-bracket": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
@@ -4202,24 +4036,6 @@
       "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
       "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
     },
-    "is-redirect": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
-      "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
-      "dev": true
-    },
-    "is-retry-allowed": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
-      "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
-      "dev": true
-    },
-    "is-stream": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-      "dev": true
-    },
     "is-typedarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
@@ -4289,6 +4105,24 @@
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
       "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
     },
+    "js-yaml": {
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+      "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.10",
+        "esprima": "4.0.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+          "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+          "dev": true
+        }
+      }
+    },
     "jsbn": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
@@ -4516,21 +4350,6 @@
         "stream-splicer": "2.0.0"
       }
     },
-    "latest-version": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz",
-      "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=",
-      "dev": true,
-      "requires": {
-        "package-json": "2.4.0"
-      }
-    },
-    "lazy-req": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz",
-      "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=",
-      "dev": true
-    },
     "lcid": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
@@ -4740,12 +4559,6 @@
         "signal-exit": "3.0.2"
       }
     },
-    "lowercase-keys": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
-      "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
-      "dev": true
-    },
     "lru-cache": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
@@ -5112,12 +4925,6 @@
         }
       }
     },
-    "node-status-codes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz",
-      "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=",
-      "dev": true
-    },
     "nopt": {
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
@@ -5291,18 +5098,6 @@
         "shell-quote": "1.6.1"
       }
     },
-    "package-json": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz",
-      "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=",
-      "dev": true,
-      "requires": {
-        "got": "5.7.1",
-        "registry-auth-token": "3.3.1",
-        "registry-url": "3.1.0",
-        "semver": "5.4.1"
-      }
-    },
     "pad-left": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz",
@@ -5489,12 +5284,6 @@
       "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
       "dev": true
     },
-    "prepend-http": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
-      "dev": true
-    },
     "preserve": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
@@ -5665,60 +5454,6 @@
         }
       }
     },
-    "rc": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
-      "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
-      "dev": true,
-      "requires": {
-        "deep-extend": "0.4.2",
-        "ini": "1.3.4",
-        "minimist": "1.2.0",
-        "strip-json-comments": "2.0.1"
-      }
-    },
-    "read-all-stream": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
-      "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
-      "dev": true,
-      "requires": {
-        "pinkie-promise": "2.0.1",
-        "readable-stream": "2.3.3"
-      },
-      "dependencies": {
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "1.0.0",
-            "process-nextick-args": "1.0.7",
-            "safe-buffer": "5.1.1",
-            "string_decoder": "1.0.3",
-            "util-deprecate": "1.0.2"
-          }
-        },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "5.1.1"
-          }
-        }
-      }
-    },
     "read-only-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz",
@@ -5908,25 +5643,6 @@
         "regjsparser": "0.1.5"
       }
     },
-    "registry-auth-token": {
-      "version": "3.3.1",
-      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz",
-      "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=",
-      "dev": true,
-      "requires": {
-        "rc": "1.2.1",
-        "safe-buffer": "5.1.1"
-      }
-    },
-    "registry-url": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
-      "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
-      "dev": true,
-      "requires": {
-        "rc": "1.2.1"
-      }
-    },
     "regjsgen": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
@@ -6148,15 +5864,6 @@
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
       "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
     },
-    "semver-diff": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
-      "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
-      "dev": true,
-      "requires": {
-        "semver": "5.4.1"
-      }
-    },
     "send": {
       "version": "0.15.4",
       "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz",
@@ -6254,12 +5961,6 @@
       "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
       "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
     },
-    "slide": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
-      "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=",
-      "dev": true
-    },
     "sntp": {
       "version": "1.0.9",
       "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
@@ -6479,6 +6180,12 @@
         }
       }
     },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
     "sshpk": {
       "version": "1.13.1",
       "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
@@ -6871,12 +6578,6 @@
       "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
       "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM="
     },
-    "timed-out": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz",
-      "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=",
-      "dev": true
-    },
     "timers-browserify": {
       "version": "1.4.2",
       "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
@@ -7022,22 +6723,58 @@
         "tsconfig": "5.0.3"
       }
     },
+    "tslib": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
+      "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==",
+      "dev": true
+    },
     "tslint": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/tslint/-/tslint-4.4.2.tgz",
-      "integrity": "sha1-sUy3muA5xyRxq0wmJyJrlA3aGcY=",
+      "version": "5.9.1",
+      "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz",
+      "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=",
       "dev": true,
       "requires": {
         "babel-code-frame": "6.22.0",
-        "colors": "1.1.2",
-        "diff": "3.3.0",
-        "findup-sync": "0.3.0",
+        "builtin-modules": "1.1.1",
+        "chalk": "2.3.1",
+        "commander": "2.14.1",
+        "diff": "3.4.0",
         "glob": "7.1.2",
-        "optimist": "0.6.1",
+        "js-yaml": "3.10.0",
+        "minimatch": "3.0.4",
         "resolve": "1.4.0",
-        "update-notifier": "1.0.3"
+        "semver": "5.4.1",
+        "tslib": "1.9.0",
+        "tsutils": "2.21.1"
       },
       "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
+          }
+        },
+        "chalk": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz",
+          "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "5.2.0"
+          }
+        },
+        "commander": {
+          "version": "2.14.1",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz",
+          "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==",
+          "dev": true
+        },
         "glob": {
           "version": "7.1.2",
           "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
@@ -7051,9 +6788,33 @@
             "once": "1.4.0",
             "path-is-absolute": "1.0.1"
           }
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz",
+          "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==",
+          "dev": true,
+          "requires": {
+            "has-flag": "3.0.0"
+          }
         }
       }
     },
+    "tsutils": {
+      "version": "2.21.1",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.21.1.tgz",
+      "integrity": "sha512-heMkdeQ9iUc90ynfiNo5Y+GXrEEGy86KMvnSTfHO+Q40AuNQ1lZGXcv58fuU9XTUxI0V7YIN9xPN+CO9b1Gn3w==",
+      "dev": true,
+      "requires": {
+        "tslib": "1.9.0"
+      }
+    },
     "tty-browserify": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -7106,28 +6867,6 @@
       "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
       "dev": true
     },
-    "unzip-response": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
-      "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=",
-      "dev": true
-    },
-    "update-notifier": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz",
-      "integrity": "sha1-j5LFFUgr1oMbfJMBPnD4dVLHz1o=",
-      "dev": true,
-      "requires": {
-        "boxen": "0.6.0",
-        "chalk": "1.1.3",
-        "configstore": "2.1.0",
-        "is-npm": "1.0.0",
-        "latest-version": "2.0.0",
-        "lazy-req": "1.1.0",
-        "semver-diff": "2.1.0",
-        "xdg-basedir": "2.0.0"
-      }
-    },
     "url": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -7144,15 +6883,6 @@
         }
       }
     },
-    "url-parse-lax": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
-      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
-      "dev": true,
-      "requires": {
-        "prepend-http": "1.0.4"
-      }
-    },
     "url-trim": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/url-trim/-/url-trim-1.0.0.tgz",
@@ -7473,15 +7203,6 @@
         "string-width": "1.0.2"
       }
     },
-    "widest-line": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz",
-      "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=",
-      "dev": true,
-      "requires": {
-        "string-width": "1.0.2"
-      }
-    },
     "wordwrap": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -7502,17 +7223,6 @@
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
     },
-    "write-file-atomic": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz",
-      "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "4.1.11",
-        "imurmurhash": "0.1.4",
-        "slide": "1.1.6"
-      }
-    },
     "ws": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz",
@@ -7529,15 +7239,6 @@
       "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
       "dev": true
     },
-    "xdg-basedir": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz",
-      "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=",
-      "dev": true,
-      "requires": {
-        "os-homedir": "1.0.2"
-      }
-    },
     "xmlhttprequest-ssl": {
       "version": "1.5.3",
       "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",

+ 1 - 1
package.json

@@ -75,6 +75,6 @@
     "karma-chrome-launcher": "~2.0.0",
     "karma-firefox-launcher": "~1.0.0",
     "karma-jasmine": "^1.1.1",
-    "tslint": "~4.4.2"
+    "tslint": "~5.9"
   }
 }

+ 7 - 7
src/app.ts

@@ -121,14 +121,14 @@ angular.module('3ema', [
 .config(['$httpProvider', ($httpProvider: ng.IHttpProvider) => {
     $httpProvider.interceptors.push(['CACHE_BUST', (CACHE_BUST: string) => {
         return {
-            request: (config) => {
-                if (config.url.indexOf('partials/') !== -1 ||
-                    config.url.indexOf('directives/') !== -1 ||
-                    config.url.indexOf('i18n/') !== -1) {
-                    const separator = config.url.indexOf('?') === -1 ? '?' : '&';
-                    config.url = config.url + separator + CACHE_BUST;
+            request: (conf) => {
+                if (conf.url.indexOf('partials/') !== -1 ||
+                    conf.url.indexOf('directives/') !== -1 ||
+                    conf.url.indexOf('i18n/') !== -1) {
+                    const separator = conf.url.indexOf('?') === -1 ? '?' : '&';
+                    conf.url = conf.url + separator + CACHE_BUST;
                 }
-                return config;
+                return conf;
             },
         };
     }]);

+ 2 - 2
src/controller_model/contact.ts

@@ -43,7 +43,7 @@ export class ContactControllerModel implements threema.ControllerModel {
     constructor($log: ng.ILogService, $translate: ng.translate.ITranslateService, $mdDialog: ng.material.IDialogService,
                 webClientService: WebClientService,
                 mode: ControllerModelMode,
-                contact: threema.ContactReceiver = undefined) {
+                contact?: threema.ContactReceiver) {
         this.$log = $log;
         this.$translate = $translate;
         this.$mdDialog = $mdDialog;
@@ -116,7 +116,7 @@ export class ContactControllerModel implements threema.ControllerModel {
     }
 
     public clean(ev: any): any {
-        let confirm = this.$mdDialog.confirm()
+        const confirm = this.$mdDialog.confirm()
             .title(this.$translate.instant('messenger.DELETE_THREAD'))
             .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', {count: 1}))
             .targetEvent(ev)

+ 3 - 3
src/controller_model/distributionList.ts

@@ -37,7 +37,7 @@ export class DistributionListControllerModel implements threema.ControllerModel
     constructor($log: ng.ILogService, $translate: ng.translate.ITranslateService, $mdDialog: ng.material.IDialogService,
                 webClientService: WebClientService,
                 mode: ControllerModelMode,
-                distributionList: threema.DistributionListReceiver = undefined) {
+                distributionList?: threema.DistributionListReceiver) {
         this.$log = $log;
         this.$translate = $translate;
         this.$mdDialog = $mdDialog;
@@ -100,7 +100,7 @@ export class DistributionListControllerModel implements threema.ControllerModel
     }
 
     public clean(ev: any): any {
-        let confirm = this.$mdDialog.confirm()
+        const confirm = this.$mdDialog.confirm()
             .title(this.$translate.instant('messenger.DELETE_THREAD'))
             .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', {count: 1}))
             .targetEvent(ev)
@@ -132,7 +132,7 @@ export class DistributionListControllerModel implements threema.ControllerModel
 
     public delete(ev): void {
 
-        let confirm = this.$mdDialog.confirm()
+        const confirm = this.$mdDialog.confirm()
             .title(this.$translate.instant('messenger.DISTRIBUTION_LIST_DELETE'))
             .textContent(this.$translate.instant('messenger.DISTRIBUTION_LIST_DELETE_REALLY'))
             .targetEvent(ev)

+ 4 - 5
src/controller_model/group.ts

@@ -39,7 +39,7 @@ export class GroupControllerModel implements threema.ControllerModel {
     constructor($log: ng.ILogService, $translate: ng.translate.ITranslateService, $mdDialog: ng.material.IDialogService,
                 webClientService: WebClientService,
                 mode: ControllerModelMode,
-                group: threema.GroupReceiver = undefined) {
+                group?: threema.GroupReceiver) {
         this.$log = $log;
         this.$translate = $translate;
         this.$mdDialog = $mdDialog;
@@ -115,7 +115,7 @@ export class GroupControllerModel implements threema.ControllerModel {
     }
 
     public clean(ev: any): any {
-        let confirm = this.$mdDialog.confirm()
+        const confirm = this.$mdDialog.confirm()
             .title(this.$translate.instant('messenger.DELETE_THREAD'))
             .textContent(this.$translate.instant('messenger.DELETE_THREAD_MESSAGE', {count: 1}))
             .targetEvent(ev)
@@ -146,7 +146,7 @@ export class GroupControllerModel implements threema.ControllerModel {
     }
 
     public leave(ev): void {
-        let confirm = this.$mdDialog.confirm()
+        const confirm = this.$mdDialog.confirm()
             .title(this.$translate.instant('messenger.GROUP_LEAVE'))
             .textContent(this.$translate.instant(
                 this.group.administrator === this.webClientService.getMyIdentity().identity
@@ -180,8 +180,7 @@ export class GroupControllerModel implements threema.ControllerModel {
     }
 
     public delete(ev): void {
-
-        let confirm = this.$mdDialog.confirm()
+        const confirm = this.$mdDialog.confirm()
             .title(this.$translate.instant('messenger.GROUP_DELETE'))
             .textContent(this.$translate.instant('messenger.GROUP_DELETE_REALLY'))
             .targetEvent(ev)

+ 4 - 4
src/controllers/status.ts

@@ -142,8 +142,8 @@ export class StatusController {
         this.$log.warn(this.logTag, 'Connection lost. Attempting to reconnect...');
 
         // Get original keys
-        let originalKeyStore = this.webClientService.salty.keyStore;
-        let originalPeerPermanentKeyBytes = this.webClientService.salty.peerPermanentKeyBytes;
+        const originalKeyStore = this.webClientService.salty.keyStore;
+        const originalPeerPermanentKeyBytes = this.webClientService.salty.peerPermanentKeyBytes;
 
         // Timeout durations
         const TIMEOUT1 = 20 * 1000; // Duration per step for first reconnect
@@ -153,7 +153,7 @@ export class StatusController {
         let reconnectTry: 1 | 2 = 1;
 
         // Handler for failed reconnection attempts
-        let reconnectionFailed = () => {
+        const reconnectionFailed = () => {
             // Collapse status bar
             this.collapseStatusBar();
 
@@ -184,7 +184,7 @@ export class StatusController {
         };
 
         // Function to soft-reconnect. Does not reset the loaded data.
-        let doSoftReconnect = () => {
+        const doSoftReconnect = () => {
             const deleteStoredData = false;
             const resetPush = false;
             const redirect = false;

+ 1 - 1
src/directives/avatar.ts

@@ -73,7 +73,7 @@ export default [
                     if (inView) {
                         if (loadingPromise === null) {
                             // Do not wait on high resolution avatar
-                            let loadingTimeout = this.highResolution ? 0 : 500;
+                            const loadingTimeout = this.highResolution ? 0 : 500;
                             loadingPromise = $timeout(() => {
                                 // show loading only on high res images!
                                 webClientService.requestAvatar({

+ 10 - 11
src/directives/avatar_editor.ts

@@ -49,7 +49,7 @@ export default [
                 const enabled = scope.enabled === undefined || scope.enabled === true;
 
                 let croppieInstance = null;
-                let initCroppie = () => {
+                const initCroppie = () => {
                     if (croppieInstance !== null) {
                         return croppieInstance;
                     }
@@ -75,7 +75,7 @@ export default [
                                 })
                                     .then((blob: Blob) => {
                                         const fileReader = new FileReader();
-                                        fileReader.onload = function () {
+                                        fileReader.onload = function() {
                                             scope.onChange(this.result);
                                         };
                                         fileReader.readAsArrayBuffer(blob);
@@ -109,7 +109,7 @@ export default [
                             // set a null object
                             reject(ev);
                         };
-                        reader.onprogress = function (data) {
+                        reader.onprogress = function(data) {
                             if (data.lengthComputable) {
                                 // TODO implement progress?
                                 // let progress = ((data.loaded / data.total) * 100);
@@ -125,7 +125,7 @@ export default [
                     }
                     // get first
                     fetchFileContent(fileList[0]).then((data: ArrayBuffer) => {
-                        let image = $filter('bufferToUrl')(data, 'image/jpg', false);
+                        const image = $filter('bufferToUrl')(data, 'image/jpg', false);
                         setImage(image);
                     }).catch((ev: ErrorEvent) => {
                         $log.error(logTag, 'Could not load file:', ev.message);
@@ -188,17 +188,16 @@ export default [
 
                     loading(true);
                     // load image to calculate size
-                    let img = new Image();
-                    img.addEventListener('load', function () {
+                    const img = new Image();
+                    img.addEventListener('load', function() {
                         $log.debug(logTag, 'Image loaded');
 
-                        // hack to fix typescript undefined method (width) exception
-                        let w = (this as any).naturalWidth;
-                        let h = (this as any).naturalHeight;
-                        let size = Math.min(w, h);
+                        const w = this.naturalWidth;
+                        const h = this.naturalHeight;
+                        const size = Math.min(w, h);
 
                         // set to center
-                        let imageSize = [
+                        const imageSize = [
                             (w - size) / 2,
                             (h - size) / 2,
                             size,

+ 23 - 23
src/directives/compose_area.ts

@@ -92,7 +92,7 @@ export default [
                 /**
                  * Stop propagation of click events and hold htmlElement of the emojipicker
                  */
-                let EmojiPickerContainer = (function() {
+                const EmojiPickerContainer = (function() {
                     let instance;
 
                     function click(e) {
@@ -197,9 +197,9 @@ export default [
                     const text = getText();
 
                     return new Promise((resolve, reject) => {
-                        let submitTexts = (strings: string[]) => {
-                            let messages: threema.TextMessageData[] = [];
-                            for (let piece of strings) {
+                        const submitTexts = (strings: string[]) => {
+                            const messages: threema.TextMessageData[] = [];
+                            for (const piece of strings) {
                                 messages.push({
                                     text: piece,
                                 });
@@ -212,8 +212,8 @@ export default [
 
                         const fullText = text.trim().replace(/\r/g, '');
                         if (fullText.length > scope.maxTextLength) {
-                            let pieces: string[] = stringService.byteChunk(fullText, scope.maxTextLength, 50);
-                            let confirm = $mdDialog.confirm()
+                            const pieces: string[] = stringService.byteChunk(fullText, scope.maxTextLength, 50);
+                            const confirm = $mdDialog.confirm()
                                 .title($translate.instant('messenger.MESSAGE_TOO_LONG_SPLIT_SUBJECT'))
                                 .textContent($translate.instant('messenger.MESSAGE_TOO_LONG_SPLIT_BODY', {
                                     max: scope.maxTextLength,
@@ -222,7 +222,7 @@ export default [
                                 .ok($translate.instant('common.YES'))
                                 .cancel($translate.instant('common.NO'));
 
-                            $mdDialog.show(confirm).then(function () {
+                            $mdDialog.show(confirm).then(function() {
                                 submitTexts(pieces);
                             }, () => {
                                 reject();
@@ -291,15 +291,15 @@ export default [
 
                         // If the compose area contains only a single <br>, make it fully empty.
                         // See also: https://stackoverflow.com/q/14638887/284318
-                        let text = getText(false);
+                        const text = getText(false);
                         if (text === '\n') {
                             composeDiv[0].innerText = '';
                         } else if (ev.keyCode === 190) {
                             // A ':' is pressed, try to parse
-                            let currentWord = stringService.getWord(text, caretPosition.fromBytes, [':']);
+                            const currentWord = stringService.getWord(text, caretPosition.fromBytes, [':']);
                             if (currentWord.length > 2
                                 && currentWord.substr(0, 1) === ':') {
-                                let unicodeEmoji = emojione.shortnameToUnicode(currentWord);
+                                const unicodeEmoji = emojione.shortnameToUnicode(currentWord);
                                 if (unicodeEmoji && unicodeEmoji !== currentWord) {
                                     return insertEmoji(unicodeEmoji,
                                         caretPosition.from - currentWord.length,
@@ -325,9 +325,9 @@ export default [
                 // Resolve to ArrayBuffer or reject to ErrorEvent.
                 function fetchFileListContents(fileList: FileList): Promise<Map<File, ArrayBuffer>> {
                     return new Promise((resolve) => {
-                        let buffers = new Map<File, ArrayBuffer>();
+                        const buffers = new Map<File, ArrayBuffer>();
                         const fileCounter = fileList.length;
-                        let next = (file: File, res: ArrayBuffer | null, error: any) => {
+                        const next = (file: File, res: ArrayBuffer | null, error: any) => {
                             buffers.set(file, res);
                             if (buffers.size >= fileCounter) {
                                resolve(buffers);
@@ -345,7 +345,7 @@ export default [
                             };
                             reader.onprogress = function(data) {
                                 if (data.lengthComputable) {
-                                    let progress = ((data.loaded / data.total) * 100);
+                                    const progress = ((data.loaded / data.total) * 100);
                                     scope.onUploading(true, progress, 100 / fileCounter * n);
                                 }
                             };
@@ -357,7 +357,7 @@ export default [
                 function uploadFiles(fileList: FileList): void {
                     scope.onUploading(true, 0, 0);
                     fetchFileListContents(fileList).then((data: Map<File, ArrayBuffer>) => {
-                        let fileMessages = [];
+                        const fileMessages = [];
                         data.forEach((buffer, file) => {
                             const fileMessageData: threema.FileMessageData = {
                                 name: file.name,
@@ -417,7 +417,7 @@ export default [
                         // Convert blob to arraybuffer
                         const reader = new FileReader();
                         reader.onload = function() {
-                            let buffer: ArrayBuffer = this.result;
+                            const buffer: ArrayBuffer = this.result;
 
                             // Construct file name
                             let fileName: string;
@@ -556,7 +556,7 @@ export default [
                         if (node.nodeType === node.TEXT_NODE) {
                             currentHTML += node.textContent;
                         } else if (node.nodeType === node.ELEMENT_NODE) {
-                            let tag = node.tagName.toLowerCase();
+                            const tag = node.tagName.toLowerCase();
                             if (tag === 'img' || tag === 'span') {
                                 currentHTML += getOuterHtml(node);
                             } else if (tag === 'br') {
@@ -623,10 +623,10 @@ export default [
 
                 // Disable content editable and dragging for contained images (emoji)
                 function cleanupComposeContent() {
-                    for (let img of composeDiv[0].getElementsByTagName('img')) {
+                    for (const img of composeDiv[0].getElementsByTagName('img')) {
                         img.ondragstart = () => false;
                     }
-                    for (let span of composeDiv[0].getElementsByTagName('span')) {
+                    for (const span of composeDiv[0].getElementsByTagName('span')) {
                         span.setAttribute('contenteditable', false);
                     }
 
@@ -649,7 +649,7 @@ export default [
 
                 // return the outer html of a node element
                 function getOuterHtml(node: Node): string {
-                    let pseudoElement = document.createElement('pseudo');
+                    const pseudoElement = document.createElement('pseudo');
                     pseudoElement.appendChild(node.cloneNode(true));
                     return pseudoElement.innerHTML;
                 }
@@ -700,7 +700,7 @@ export default [
                         const selection = window.getSelection();
                         if (selection.rangeCount) {
                             const range = selection.getRangeAt(0);
-                            let from = getPositions(range.startOffset, range.startContainer);
+                            const from = getPositions(range.startOffset, range.startContainer);
                             if (from !== null && from.html >= 0) {
                                 const to = getPositions(range.endOffset, range.endContainer);
 
@@ -718,15 +718,15 @@ export default [
                 // set the correct cart position in the content editable div, position
                 // is the position in the html content (not plain text)
                 function setCaretPosition(pos: number) {
-                    let rangeAt = (node: Node, offset?: number) => {
-                        let range = document.createRange();
+                    const rangeAt = (node: Node, offset?: number) => {
+                        const range = document.createRange();
                         range.collapse(false);
                         if (offset !== undefined) {
                             range.setStart(node, offset);
                         } else {
                             range.setStartAfter(node);
                         }
-                        let sel = window.getSelection();
+                        const sel = window.getSelection();
                         sel.removeAllRanges();
                         sel.addRange(range);
                     };

+ 4 - 4
src/directives/drag_file.ts

@@ -46,8 +46,8 @@ export default [
                 // Resolve to ArrayBuffer or reject to ErrorEvent.
                 function fetchFileListContents(fileList: FileList): Promise<Map<File, ArrayBuffer>> {
                     return new Promise((resolve) => {
-                        let buffers = new Map<File, ArrayBuffer>();
-                        let next = (file: File, res: ArrayBuffer | null, error?: ErrorEvent) => {
+                        const buffers = new Map<File, ArrayBuffer>();
+                        const next = (file: File, res: ArrayBuffer | null, error?: ErrorEvent) => {
                             buffers.set(file, res);
                             if (buffers.size >= fileList.length) {
                                 resolve(buffers);
@@ -69,7 +69,7 @@ export default [
                             };
                             reader.onprogress = function(data) {
                                 if (data.lengthComputable) {
-                                    let progress = ((data.loaded / data.total) * 100);
+                                    const progress = ((data.loaded / data.total) * 100);
                                     scope.onUploading(true, progress, 100 / fileList.length * n);
                                 }
                             };
@@ -81,7 +81,7 @@ export default [
                 function uploadFiles(fileList: FileList): void {
                     scope.onUploading(true, 0, 0);
                     fetchFileListContents(fileList).then((data: Map<File, ArrayBuffer>) => {
-                        let fileMessages = [];
+                        const fileMessages = [];
                         data.forEach((buffer, file) => {
                             const fileMessageData: threema.FileMessageData = {
                                 name: file.name,

+ 1 - 1
src/directives/latest_message.ts

@@ -103,7 +103,7 @@ export default [
                         // Don't show draft if conversation is active
                         return false;
                     }
-                    let draft = this.getDraft();
+                    const draft = this.getDraft();
                     return draft !== undefined && draft !== null;
                 };
 

+ 3 - 3
src/directives/member_list_editor.ts

@@ -54,8 +54,8 @@ export default [
                         return [];
                     } else {
                         // search for contacts, do not show selected contacts
-                        let lowercaseQuery = angular.lowercase(query);
-                        let result = this.allContacts.filter((contactReceiver: threema.ContactReceiver) => {
+                        const lowercaseQuery = angular.lowercase(query);
+                        const result = this.allContacts.filter((contactReceiver: threema.ContactReceiver) => {
                             return this.members.filter((identity: string) => {
                                     return identity === contactReceiver.id;
                                 }).length === 0
@@ -77,7 +77,7 @@ export default [
                         return false;
                     }
 
-                    this.members = this.members.filter(function (i: string) {
+                    this.members = this.members.filter(function(i: string) {
                         return i !== contact.id;
                     });
                     return true;

+ 1 - 1
src/directives/message_media.ts

@@ -126,7 +126,7 @@ export default [
                 this.playAudio = (buffer: ArrayBuffer) => {
                     $mdDialog.show({
                         controllerAs: 'ctrl',
-                        controller: function () {
+                        controller: function() {
                             this.blobBuffer = buffer;
                             this.cancel = () => {
                                 $mdDialog.cancel();

+ 1 - 1
src/directives/message_text.ts

@@ -30,7 +30,7 @@ export default [
             controller: [function() {
                 // Get text depending on type
                 let rawText = null;
-                let message = this.message as threema.Message;
+                const message = this.message as threema.Message;
                 switch (message.type) {
                     case 'text':
                         rawText = message.body;

+ 1 - 1
src/directives/my_identity.ts

@@ -29,7 +29,7 @@ export default [
             controllerAs: 'ctrl',
             controller: [function() {
                 this.showQRCode = () => {
-                    let identity: threema.Identity = this.identity;
+                    const identity: threema.Identity = this.identity;
                     $mdDialog.show({
                         controllerAs: 'ctrl',
                         controller: [function() {

+ 15 - 10
src/filters.ts

@@ -129,16 +129,19 @@ angular.module('3ema.filters', [])
 /**
  * Convert mention elements to html elements
  */
-.filter('mentionify', ['WebClientService', '$translate', 'escapeHtmlFilter',
-    function (webClientService: WebClientService, $translate: ng.translate.ITranslateService, escapeHtmlFilter) {
+.filter('mentionify', [
+    'WebClientService',
+    '$translate',
+    'escapeHtmlFilter',
+    function(webClientService: WebClientService, $translate: ng.translate.ITranslateService, escapeHtmlFilter) {
         return(text) => {
             if (text !== null && text.length > 10) {
                 let result = text.match(/@\[([\*\@a-zA-Z0-9][\@a-zA-Z0-9]{7})\]/g);
                 if (result !== null) {
                     result = ([...new Set(result)]);
                     // Unique
-                    for (let possibleMention of result) {
-                        let identity = possibleMention.substr(2, 8);
+                    for (const possibleMention of result) {
+                        const identity = possibleMention.substr(2, 8);
                         let mentionName;
                         let cssClass;
                         if (identity === '@@@@@@@@') {
@@ -168,7 +171,9 @@ angular.module('3ema.filters', [])
             }
             return text;
         };
-}])
+    },
+])
+
 /**
  * Reverse an array.
  */
@@ -291,8 +296,8 @@ angular.module('3ema.filters', [])
         if (!size) {
             return '';
         }
-        let i = Math.floor( Math.log(size) / Math.log(1024) );
-        let x = (size / Math.pow(1024, i)).toFixed(2);
+        const i = Math.floor( Math.log(size) / Math.log(1024) );
+        const x = (size / Math.pow(1024, i)).toFixed(2);
         return (x + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]);
     };
 })
@@ -314,10 +319,10 @@ angular.module('3ema.filters', [])
 /**
  * Convert ID-Array to (Display-)Name-String, separated by ','
  */
-.filter('idsToNames', ['WebClientService', function (webClientService: WebClientService) {
+.filter('idsToNames', ['WebClientService', function(webClientService: WebClientService) {
     return(ids: string[]) => {
-        let names: string[] = [];
-        for (let id of ids) {
+        const names: string[] = [];
+        for (const id of ids) {
             this.contactReceiver = webClientService.contacts.get(id);
             names.push(this.contactReceiver.displayName);
         }

+ 7 - 7
src/helpers.ts

@@ -176,7 +176,7 @@ export function utf8aToString(bytes: Uint8Array): string {
 /**
  * Filter an array or object.
  */
-export function filter(obj: Object | any[], callback: (arg: any) => boolean) {
+export function filter(obj: object | any[], callback: (arg: any) => boolean) {
     if (obj instanceof Array) {
         // Filter arrays using Array.filter
         return (obj as any[]).filter(callback);
@@ -184,7 +184,7 @@ export function filter(obj: Object | any[], callback: (arg: any) => boolean) {
         // Filter objects by iterating over them
         // and selectively copying values
         const out = {};
-        for (let key in Object.keys(obj)) { // tslint:disable-line:forin
+        for (const key in Object.keys(obj)) { // tslint:disable-line:forin
             const value = obj[key];
             if (callback(value)) {
                 out[key] = value;
@@ -210,9 +210,9 @@ export function throttle(fn, threshold: number = 250, scope) {
     let last;
     let deferTimer;
     return function() {
-        let context = scope || this;
-        let now = +(new Date());
-        let args = arguments;
+        const context = scope || this;
+        const now = +(new Date());
+        const args = arguments;
         if (last && now < last + threshold) {
             // hold on to it
             clearTimeout(deferTimer);
@@ -234,10 +234,10 @@ export function throttle(fn, threshold: number = 250, scope) {
  */
 export function supportsPassive() {
     // Test via a getter in the options object to see if the passive property is accessed
-    let supportsPassive = false;
+    let support = false;
     try {
         const opts = Object.defineProperty({}, 'passive', {
-            get: () => supportsPassive = true,
+            get: () => support = true,
         });
         window.addEventListener('test', null, opts);
     } catch (e) { /* do nothing */ }

+ 13 - 9
src/partials/messenger.ts

@@ -222,9 +222,6 @@ class ConversationController {
     public currentMentions: threema.Mention[] = [];
     public currentMentionFilterWord = null;
     public selectedMention: number = null;
-    public showMentionSelector = (): boolean => this.type === 'group'
-        && this.currentMentionFilterWord != null
-        && this.currentMentions.length > 0;
 
     private uploading = {
         enabled: false,
@@ -458,7 +455,7 @@ class ConversationController {
                 return reject();
             }
             let success = true;
-            let nextCallback = (index: number) => {
+            const nextCallback = (index: number) => {
                 if (index === contents.length - 1) {
                     if (success) {
                         resolve();
@@ -473,7 +470,7 @@ class ConversationController {
                     // Determine file type
                     let showSendAsFileCheckbox = false;
                     let captionSupported = false;
-                    for (let msg of contents as threema.FileMessageData[]) {
+                    for (const msg of contents as threema.FileMessageData[]) {
                         if (!msg.fileType) {
                             msg.fileType = 'application/octet-stream';
                         }
@@ -593,7 +590,7 @@ class ConversationController {
         this.webClientService.setDraft(this.receiver, text);
         if (currentWord && currentWord.substr(0, 1) === '@') {
             this.currentMentionFilterWord = currentWord.substr(1);
-            let query = this.currentMentionFilterWord.toLowerCase().trim();
+            const query = this.currentMentionFilterWord.toLowerCase().trim();
             const selectedMentionObject = this.getSelectedMention();
             this.currentMentions = this.allMentions.filter((i) => {
                 if (query.length === 0) {
@@ -625,6 +622,13 @@ class ConversationController {
 
         return this.currentMentions[this.selectedMention];
     }
+
+    public showMentionSelector = (): boolean => {
+        return this.type === 'group'
+            && this.currentMentionFilterWord != null
+            && this.currentMentions.length > 0;
+    }
+
     /**
      * Handle mention selector navigation
      */
@@ -701,7 +705,7 @@ class ConversationController {
     }
 
     public requestMessages(): void {
-        let refMsgId = this.webClientService.requestMessages(this.$stateParams);
+        const refMsgId = this.webClientService.requestMessages(this.$stateParams);
 
         if (refMsgId !== null
             && refMsgId !== undefined) {
@@ -1081,7 +1085,7 @@ class ReceiverDetailController {
 
         // Append members
         if (this.receiver.type === 'contact') {
-            let contactReceiver = (<threema.ContactReceiver> this.receiver);
+            const contactReceiver = this.receiver as threema.ContactReceiver;
 
             this.contactService.requiredDetails(contactReceiver)
                 .then(() => {
@@ -1360,7 +1364,7 @@ class ReceiverCreateController {
         }
     }
 
-    private showAddError(errorCode: String): void {
+    private showAddError(errorCode: string): void {
         if (errorCode === undefined) {
             errorCode = 'invalid_entry';
         }

+ 3 - 3
src/services/browser.ts

@@ -29,7 +29,7 @@ export class BrowserService {
     }
 
     private initializePageVisibility() {
-        let onChange = (isVisible: any) => {
+        const onChange = (isVisible: any) => {
             if (this.isPageVisible !== isVisible) {
                 this.isPageVisible = isVisible;
             }
@@ -62,7 +62,7 @@ export class BrowserService {
             blur: false,
         };
 
-        for (let event in map) {
+        for (const event in map) {
             if (map[event] !== undefined) {
                 document.addEventListener(event, () => {
                     onChange(map[event]);
@@ -106,7 +106,7 @@ export class BrowserService {
                 this.browser.chrome = false;
             }
 
-            for (let x in this.browser) {
+            for (const x in this.browser) {
                 if (this.browser[x]) {
                     let b;
                     if (x === 'msie') {

+ 2 - 3
src/services/fingerprint.ts

@@ -24,9 +24,8 @@ export class FingerPrintService {
     }
 
     public generate(publicKey: ArrayBuffer): string {
-        if (publicKey !== undefined
-            && publicKey.byteLength === 32) {
-            let sha256PublicKey = sha256(publicKey);
+        if (publicKey !== undefined && publicKey.byteLength === 32) {
+            const sha256PublicKey = sha256(publicKey);
             if (sha256PublicKey !== undefined) {
                 return sha256PublicKey.toLowerCase().substr(0, 32);
             }

+ 5 - 6
src/services/message.ts

@@ -38,7 +38,7 @@ export class MessageService {
     }
 
     public getAccess(message: threema.Message, receiver: threema.Receiver): MessageAccess  {
-        let access = new MessageAccess();
+        const access = new MessageAccess();
 
         if (message !== undefined && receiver !== undefined && message.temporaryId === undefined) {
             access.quote =  (message.type === 'text')
@@ -74,8 +74,7 @@ export class MessageService {
     public showStatusIcon(message: threema.Message, receiver: threema.Receiver): boolean {
         if (message !== null && receiver !== null) {
 
-            let messageState = message.state;
-            // MessageState messageState = messageModel.getState();
+            const messageState = message.state;
 
             // group message/distribution list message icons only on pending or failing states
             switch (receiver.type) {
@@ -119,7 +118,7 @@ export class MessageService {
             return null;
         }
 
-        let getFileName = (prefix: string, postfix?: string): string => {
+        const getFileName = (prefix: string, postfix?: string): string => {
             if (message.id === undefined) {
                 this.$log.warn('missing id on message model');
                 return null;
@@ -155,8 +154,8 @@ export class MessageService {
      */
     public createTemporary(receiver: threema.Receiver, msgType: string,
                            messageData: threema.MessageData): threema.Message {
-        let now = new Date();
-        let message = {
+        const now = new Date();
+        const message = {
             temporaryId: receiver.type + receiver.id + Math.random(),
             type: msgType,
             isOutbox: true,

+ 3 - 3
src/services/notification.ts

@@ -134,9 +134,9 @@ export class NotificationService {
      */
     private fetchSettings(): void {
         this.$log.debug(this.logTag, 'Fetching settings...');
-        let notifications = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATIONS);
-        let preview = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATION_PREVIEW);
-        let sound = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATION_SOUND);
+        const notifications = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATIONS);
+        const preview = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATION_PREVIEW);
+        const sound = this.retrieveSetting(NotificationService.SETTINGS_NOTIFICATION_SOUND);
         if (notifications === 'true') {
             this.$log.debug(this.logTag, 'Desktop notifications:', notifications);
             this.desktopNotifications = true;

+ 5 - 5
src/services/peerconnection.ts

@@ -146,7 +146,7 @@ export class PeerConnectionHelper {
             this.$log.debug(this.logTag, 'ICE gathering state change:', this.pc.iceGatheringState);
         };
         this.webrtcTask.on('candidates', (e: saltyrtc.tasks.webrtc.CandidatesEvent) => {
-            for (let candidateInit of e.data) {
+            for (const candidateInit of e.data) {
                 if (candidateInit) {
                     this.$log.debug(this.logTag, 'Adding remote ICE candidate:',
                         this.censorCandidate(candidateInit.candidate));
@@ -160,20 +160,20 @@ export class PeerConnectionHelper {
 
     private async initiatorFlow(): Promise<void> {
         // Send offer
-        let offer: RTCSessionDescriptionInit = await this.pc.createOffer();
+        const offer: RTCSessionDescriptionInit = await this.pc.createOffer();
         await this.pc.setLocalDescription(offer);
         this.$log.debug(this.logTag, 'Created offer, set local description');
         this.webrtcTask.sendOffer(offer);
 
         // Receive answer
-        let receiveAnswer: () => Promise<saltyrtc.tasks.webrtc.Answer> = () => {
+        const receiveAnswer: () => Promise<saltyrtc.tasks.webrtc.Answer> = () => {
             return new Promise((resolve) => {
                 this.webrtcTask.once('answer', (e: saltyrtc.tasks.webrtc.AnswerEvent) => {
                     resolve(e.data);
                 });
             });
         };
-        let answer: RTCSessionDescriptionInit = await receiveAnswer();
+        const answer: RTCSessionDescriptionInit = await receiveAnswer();
         await this.pc.setRemoteDescription(answer);
         this.$log.debug(this.logTag, 'Received answer, set remote description');
     }
@@ -258,7 +258,7 @@ export class PeerConnectionHelper {
      * Return the censored ICE candidate.
      */
     private censorCandidate(candidateInit: string): string {
-        let candidate = SDPUtils.parseCandidate(candidateInit);
+        const candidate = SDPUtils.parseCandidate(candidateInit);
         if (this.censorCandidates) {
             if (candidate.type !== 'relay') {
                 candidate.ip = '***';

+ 1 - 1
src/services/push.ts

@@ -67,7 +67,7 @@ export class PushService {
         }
 
         // Prepare request
-        let request = {
+        const request = {
             method: 'POST',
             url: this.url,
             headers: {

+ 4 - 4
src/services/qrcode.ts

@@ -42,8 +42,8 @@ export class QrCodeService {
         // tslint:disable:no-bitwise
 
         // Allocate array buffer
-        let saltyRtcHostBytes = stringToUtf8a(host);
-        let buf = new ArrayBuffer(2 + 1 + 32 + 32 + 32 + 2 + saltyRtcHostBytes.byteLength);
+        const saltyRtcHostBytes = stringToUtf8a(host);
+        const buf = new ArrayBuffer(2 + 1 + 32 + 32 + 32 + 2 + saltyRtcHostBytes.byteLength);
 
         // Options bitfield
         let options = 0;
@@ -51,12 +51,12 @@ export class QrCodeService {
         options |= (persistent ? 1 : 0) << 1;
 
         // Write version and options
-        let dataView = new DataView(buf);
+        const dataView = new DataView(buf);
         dataView.setUint16(0, this.protocolVersion);
         dataView.setUint8(2, options);
 
         // Write initiator key, auth token and server key
-        let u8Array = new Uint8Array(buf);
+        const u8Array = new Uint8Array(buf);
         u8Array.set(initiatorKey, 3);
         u8Array.set(authToken, 35);
         if (serverKey === null) {

+ 8 - 8
src/services/string.ts

@@ -17,14 +17,14 @@
 
 export class StringService {
     public byteChunk(str: string, byteLength: number, offset: number = null): string[] {
-        let chars = [...str];
-        let chunks = [''];
+        const chars = [...str];
+        const chunks = [''];
         let currentChunkSize = 0;
         let chunkIndex = 0;
-        let offsetChars = [' ', '\r', '\n', '\t', '.'];
+        const offsetChars = [' ', '\r', '\n', '\t', '.'];
         let lastSeparator = -1;
         chars.forEach ((charString: string) => {
-            let length = Buffer.byteLength(charString, 'utf8');
+            const length = Buffer.byteLength(charString, 'utf8');
             if (offset !== null) {
                 if (offsetChars.indexOf(charString) > -1) {
                     lastSeparator = currentChunkSize + 1;
@@ -60,17 +60,17 @@ export class StringService {
     }
     public getWord(input: string, pos: number, additionalSeparators: string[] = null): string {
         if (input !== null && input.length > 0) {
-            let chars = [...input];
+            const chars = [...input];
             let charFound = false;
-            let realPos = Math.min(pos, chars.length) - 1;
+            const realPos = Math.min(pos, chars.length) - 1;
 
             if (realPos < 0) {
                 return '';
             }
 
-            let wordChars = new Array(realPos);
+            const wordChars = new Array(realPos);
             for (let n = realPos; n >= 0; n--) {
-                let realChar = chars[n].trim();
+                const realChar = chars[n].trim();
                 if (realChar === '') {
                     // Abort
                     if (charFound === false) {

+ 76 - 76
src/services/webclient.ts

@@ -54,7 +54,7 @@ class WebClientDefault {
      * If the avatar type is invalid, return null.
      */
     public getAvatar(type: string, highResolution: boolean): string {
-        let field: string = highResolution ? 'high' : 'low';
+        const field: string = highResolution ? 'high' : 'low';
         if (typeof this.avatar[type] === 'undefined') {
             return null;
         }
@@ -182,8 +182,8 @@ export class WebClientService {
     private trustedKeyStore: TrustedKeyStoreService;
     public version = null;
 
-    private blobCache = new Map<String, ArrayBuffer>();
-    private loadingMessages = new Map<String, boolean>();
+    private blobCache = new Map<string, ArrayBuffer>();
+    private loadingMessages = new Map<string, boolean>();
 
     public receiverListener: threema.ReceiverListener[] = [];
 
@@ -364,7 +364,7 @@ export class WebClientService {
         this.salty.on('state-change', (ev: saltyrtc.SaltyRTCEvent) => {
             // Wrap this in a $timeout to execute at the end of the event loop.
             this.$timeout(() => {
-                let state: saltyrtc.SignalingState = ev.data;
+                const state: saltyrtc.SignalingState = ev.data;
                 if (!this.startupDone) {
                     switch (state) {
                         case 'new':
@@ -638,7 +638,7 @@ export class WebClientService {
         const allUrls = [].concat(...this.config.ICE_SERVERS.map((conf) => conf.urls));
         if (allUrls.some((url) => url.startsWith('turn:') && url.endsWith('=tcp'))) {
             // There's at least one TURN server with TCP transport in the list
-            for (let server of this.config.ICE_SERVERS) {
+            for (const server of this.config.ICE_SERVERS) {
                 // Remove TLS entries
                 server.urls = server.urls.filter((url) => !url.startsWith('turns:'));
             }
@@ -662,7 +662,7 @@ export class WebClientService {
         // Check pending routines
         this.pendingInitializationStepRoutines = this.pendingInitializationStepRoutines.filter((routine) => {
             let isValid = true;
-            for (let requiredStep of routine.requiredSteps) {
+            for (const requiredStep of routine.requiredSteps) {
                 if (!this.initialized.has(requiredStep)) {
                     isValid = false;
                     break;
@@ -772,8 +772,8 @@ export class WebClientService {
      */
     public requestAvatar(receiver: threema.Receiver, highResolution: boolean): Promise<any> {
         // Check if the receiver has an avatar or the avatar already exists
-        let resolution = highResolution ? 'high' : 'low';
-        let receiverInfo = this.receivers.getData(receiver);
+        const resolution = highResolution ? 'high' : 'low';
+        const receiverInfo = this.receivers.getData(receiver);
         if (receiverInfo && receiverInfo.avatar && receiverInfo.avatar[resolution]) {
             // Avatar already exists
             // TODO: Do we get avatar changes via update?
@@ -783,7 +783,7 @@ export class WebClientService {
         }
 
         // Create arguments and send request
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
             [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
             [WebClientService.ARGUMENT_AVATAR_HIGH_RESOLUTION]: highResolution,
@@ -823,7 +823,7 @@ export class WebClientService {
      * Request a blob.
      */
     public requestBlob(msgId: number, receiver: threema.Receiver): Promise<ArrayBuffer> {
-        let cached = this.blobCache.get(msgId + receiver.type);
+        const cached = this.blobCache.get(msgId + receiver.type);
 
         if (cached !== undefined) {
 
@@ -855,7 +855,7 @@ export class WebClientService {
         // }
 
         // Create arguments and send request
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
             [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
             [WebClientService.ARGUMENT_MESSAGE_ID]: newestMessageId,
@@ -879,7 +879,7 @@ export class WebClientService {
         return new Promise<any> (
             (resolve, reject) => {
                 // Try to load receiver object
-                let receiverObject = this.receivers.getData(receiver);
+                const receiverObject = this.receivers.getData(receiver);
                 // Check blocked flag
                 if (receiverObject.type === 'contact'
                     && (receiverObject as threema.ContactReceiver).isBlocked) {
@@ -918,7 +918,7 @@ export class WebClientService {
                         let invalidFeatureLevelMessage = 'error.FILE_MESSAGES_NOT_SUPPORTED';
                         if ((message as threema.FileMessageData).sendAsFile !== true) {
                             // check mime type
-                            let mime = (message as threema.FileMessageData).fileType;
+                            const mime = (message as threema.FileMessageData).fileType;
 
                             if (this.mimeService.isAudio(mime)) {
                                 requiredFeatureLevel = 1;
@@ -938,16 +938,16 @@ export class WebClientService {
                                 return reject(this.$translate.instant(invalidFeatureLevelMessage, {
                                     receiverName: receiver.displayName}));
                             case 'group':
-                                let unsupportedMembers = [];
-                                let group = this.groups.get(receiver.id);
+                                const unsupportedMembers = [];
+                                const group = this.groups.get(receiver.id);
 
                                 if (group === undefined) {
                                     return reject();
                                 }
                                 group.members.forEach((identity: string) => {
                                     if (identity !== this.me.id) {
-                                        // ignore "me"
-                                        let contact = this.contacts.get(identity);
+                                        // tslint:disable-next-line: no-shadowed-variable
+                                        const contact = this.contacts.get(identity);
                                         if (contact !== undefined && contact.featureLevel < requiredFeatureLevel) {
                                             unsupportedMembers.push(contact.displayName);
                                         }
@@ -980,10 +980,10 @@ export class WebClientService {
                         return reject();
                 }
 
-                let temporaryMessage = this.messageService.createTemporary(receiver, type, message);
+                const temporaryMessage = this.messageService.createTemporary(receiver, type, message);
                 this.messages.addNewer(receiver, [temporaryMessage]);
 
-                let args = {
+                const args = {
                     [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
                     [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
                     [WebClientService.ARGUMENT_TEMPORARY_ID]: temporaryMessage.temporaryId,
@@ -1032,7 +1032,7 @@ export class WebClientService {
             return;
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
             [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
             [WebClientService.ARGUMENT_MESSAGE_ID]: message.id,
@@ -1050,7 +1050,7 @@ export class WebClientService {
             return;
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
             [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
             [WebClientService.ARGUMENT_MESSAGE_ID]: message.id,
@@ -1060,7 +1060,7 @@ export class WebClientService {
 
     public sendMeIsTyping(receiver, isTyping: boolean): void {
         // Create arguments and send create
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
             [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
             [WebClientService.ARGUMENT_CONTACT_IS_TYPING]: isTyping,
@@ -1075,7 +1075,7 @@ export class WebClientService {
     /**
      * Send a add Contact request
      */
-    public addContact(threemaId: String): Promise<threema.ContactReceiver> {
+    public addContact(threemaId: string): Promise<threema.ContactReceiver> {
         return this._sendCreatePromise(WebClientService.SUB_TYPE_CONTACT, {
             [WebClientService.ARGUMENT_IDENTITY]: threemaId,
         });
@@ -1084,11 +1084,11 @@ export class WebClientService {
     /**
      * Modify a contact name or a avatar
      */
-    public modifyContact(threemaId: String,
-                         firstName: String,
-                         lastName: String,
+    public modifyContact(threemaId: string,
+                         firstName: string,
+                         lastName: string,
                          avatar?: ArrayBuffer): Promise<threema.ContactReceiver> {
-        let promise = this._sendUpdatePromise(WebClientService.SUB_TYPE_CONTACT, {
+        const promise = this._sendUpdatePromise(WebClientService.SUB_TYPE_CONTACT, {
             [WebClientService.ARGUMENT_IDENTITY]: threemaId,
         }, {
             [WebClientService.ARGUMENT_FIRST_NAME]: firstName,
@@ -1109,10 +1109,10 @@ export class WebClientService {
     /**
      * Create a group receiver
      */
-    public createGroup(members: String[],
-                       name: String = null,
+    public createGroup(members: string[],
+                       name: string = null,
                        avatar?: ArrayBuffer): Promise<threema.GroupReceiver> {
-        let data = {
+        const data = {
             [WebClientService.ARGUMENT_MEMBERS]: members,
             [WebClientService.ARGUMENT_NAME]: name,
         } as any;
@@ -1125,10 +1125,10 @@ export class WebClientService {
     }
 
     public modifyGroup(id: string,
-                       members: String[],
-                       name: String = null,
+                       members: string[],
+                       name: string = null,
                        avatar?: ArrayBuffer): Promise<threema.GroupReceiver> {
-        let data = {
+        const data = {
             [WebClientService.ARGUMENT_MEMBERS]: members,
             [WebClientService.ARGUMENT_NAME]: name,
         } as any;
@@ -1136,7 +1136,7 @@ export class WebClientService {
         if (avatar !== undefined) {
             data[WebClientService.ARGUMENT_AVATAR_HIGH_RESOLUTION] = avatar;
         }
-        let promise = this._sendUpdatePromise(WebClientService.SUB_TYPE_GROUP, {
+        const promise = this._sendUpdatePromise(WebClientService.SUB_TYPE_GROUP, {
             [WebClientService.ARGUMENT_RECEIVER_ID]: id,
         }, data);
 
@@ -1155,7 +1155,7 @@ export class WebClientService {
             return new Promise((resolve, reject) => reject('not allowed'));
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_ID]: group.id,
             // TODO: delete type into const
             [WebClientService.ARGUMENT_DELETE_TYPE]: 'leave',
@@ -1172,7 +1172,7 @@ export class WebClientService {
                 });
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_ID]: group.id,
             // TODO: delete type into const
             [WebClientService.ARGUMENT_DELETE_TYPE]: 'delete',
@@ -1189,15 +1189,15 @@ export class WebClientService {
                 });
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_ID]: group.id,
         };
 
         return this._sendRequestPromise(WebClientService.SUB_TYPE_GROUP_SYNC, args);
     }
 
-    public createDistributionList(members: String[], name: String = null): Promise<threema.DistributionListReceiver> {
-        let data = {
+    public createDistributionList(members: string[], name: string = null): Promise<threema.DistributionListReceiver> {
+        const data = {
             [WebClientService.ARGUMENT_MEMBERS]: members,
             [WebClientService.ARGUMENT_NAME]: name,
         } as any;
@@ -1206,9 +1206,9 @@ export class WebClientService {
     }
 
     public modifyDistributionList(id: string,
-                                  members: String[],
-                                  name: String = null): Promise<threema.DistributionListReceiver> {
-        let data = {
+                                  members: string[],
+                                  name: string = null): Promise<threema.DistributionListReceiver> {
+        const data = {
             [WebClientService.ARGUMENT_MEMBERS]: members,
             [WebClientService.ARGUMENT_NAME]: name,
         } as any;
@@ -1223,7 +1223,7 @@ export class WebClientService {
             return new Promise((resolve, reject) => reject('not allowed'));
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_ID]: distributionList.id,
         };
 
@@ -1240,7 +1240,7 @@ export class WebClientService {
             return new Promise((resolve, reject) => reject('invalid receiver'));
         }
 
-        let args = {
+        const args = {
             [WebClientService.ARGUMENT_RECEIVER_TYPE]: receiver.type,
             [WebClientService.ARGUMENT_RECEIVER_ID]: receiver.id,
         };
@@ -1296,7 +1296,7 @@ export class WebClientService {
             }
 
             if (quoteText !== undefined) {
-                let quote = {
+                const quote = {
                     identity: message.isOutbox ? this.me.id : message.partnerId,
                     text: quoteText,
                 } as threema.Quote;
@@ -1397,7 +1397,7 @@ export class WebClientService {
         }
 
         if (data[WebClientService.ARGUMENT_SUCCESS]) {
-            let contactReceiver = this.receivers.contacts
+            const contactReceiver = this.receivers.contacts
                 .get(message.args[WebClientService.ARGUMENT_IDENTITY]) as threema.ContactReceiver;
 
             // get system contact
@@ -1449,7 +1449,7 @@ export class WebClientService {
 
         if (data[WebClientService.ARGUMENT_SUCCESS]
             && data[WebClientService.SUB_TYPE_RECEIVER] !== undefined) {
-            let receiver = data[WebClientService.SUB_TYPE_RECEIVER] as threema.ContactReceiver;
+            const receiver = data[WebClientService.SUB_TYPE_RECEIVER] as threema.ContactReceiver;
             // Add or update a certain receiver
             if (receiver.type === undefined) {
                 receiver.type = 'contact';
@@ -1488,7 +1488,7 @@ export class WebClientService {
 
         if (data[WebClientService.ARGUMENT_SUCCESS]
             && data[WebClientService.SUB_TYPE_RECEIVER] !== undefined) {
-            let receiver = data[WebClientService.SUB_TYPE_RECEIVER] as threema.GroupReceiver;
+            const receiver = data[WebClientService.SUB_TYPE_RECEIVER] as threema.GroupReceiver;
             // Add or update a certain receiver
             if (receiver.type === undefined) {
                 receiver.type = 'group';
@@ -1528,7 +1528,7 @@ export class WebClientService {
 
         if (data[WebClientService.ARGUMENT_SUCCESS]
             && data[WebClientService.SUB_TYPE_RECEIVER] !== undefined) {
-            let receiver = data[WebClientService.SUB_TYPE_RECEIVER] as threema.DistributionListReceiver;
+            const receiver = data[WebClientService.SUB_TYPE_RECEIVER] as threema.DistributionListReceiver;
             // Add or update a certain receiver
             if (receiver.type === undefined) {
                 receiver.type = 'distributionList';
@@ -1554,7 +1554,7 @@ export class WebClientService {
     }
 
     private _receiveResponseCreateMessage(message: threema.WireMessage):
-    threema.PromiseRequestResult<String> {
+    threema.PromiseRequestResult<string> {
         this.$log.debug('Received create message response');
         // Unpack data and arguments
         const args = message.args;
@@ -1598,15 +1598,15 @@ export class WebClientService {
 
     private _receiveResponseConversations(message: threema.WireMessage) {
         this.$log.debug('Received conversations response');
-        let data = message.data;
+        const data = message.data;
         if (data === undefined) {
             this.$log.warn('Invalid conversation response, data missing');
         } else {
             // if a avatar was set on a conversation
             // convert and copy to the receiver
-            for (let conversation of data) {
+            for (const conversation of data) {
                 if (conversation.avatar !== undefined) {
-                    let receiver = this.receivers.getData({
+                    const receiver = this.receivers.getData({
                         id: conversation.id,
                         type: conversation.type,
                     } as threema.Receiver);
@@ -1629,15 +1629,15 @@ export class WebClientService {
 
     private _receiveResponseConversation(message: threema.WireMessage) {
         this.$log.debug('Received conversation response');
-        let args = message.args;
-        let data = message.data;
+        const args = message.args;
+        const data = message.data;
         if (args === undefined || data === undefined) {
             this.$log.warn('Invalid conversation response, data or arguments missing');
             return;
         }
 
         // Unpack required argument fields
-        let type: string = args[WebClientService.ARGUMENT_MODE];
+        const type: string = args[WebClientService.ARGUMENT_MODE];
         switch (type) {
             case WebClientService.ARGUMENT_MODE_NEW:
                 this.conversations.add(data);
@@ -1721,7 +1721,7 @@ export class WebClientService {
         }
 
         // Check if the page was requested
-        let receiver = {type: type, id: id} as threema.Receiver;
+        const receiver = {type: type, id: id} as threema.Receiver;
 
         // Set as loaded
         this.loadingMessages.delete(receiver.type + receiver.id);
@@ -1778,13 +1778,13 @@ export class WebClientService {
         }
 
         // Set avatar for receiver according to resolution
-        let field: string = highResolution ? 'high' : 'low';
-        let receiverData = this.receivers.getData(args);
+        const field: string = highResolution ? 'high' : 'low';
+        const receiverData = this.receivers.getData(args);
         if (receiverData.avatar === null || receiverData.avatar === undefined) {
             receiverData.avatar = {};
         }
 
-        let avatar = this.$filter('bufferToUrl')(data, 'image/png');
+        const avatar = this.$filter('bufferToUrl')(data, 'image/png');
         receiverData.avatar[field] = avatar;
 
         return {
@@ -1897,7 +1897,7 @@ export class WebClientService {
             this.$log.warn('Invalid message update, argument field missing');
             return;
         }
-        let receiver = {type: type, id: id} as threema.Receiver;
+        const receiver = {type: type, id: id} as threema.Receiver;
 
         // React depending on mode
         switch (mode) {
@@ -1948,7 +1948,7 @@ export class WebClientService {
             case WebClientService.ARGUMENT_MODE_NEW:
             case WebClientService.ARGUMENT_MODE_MODIFIED:
                 // Add or update a certain receiver
-                let updatedReceiver = this.receivers.extend(type, data);
+                const updatedReceiver = this.receivers.extend(type, data);
 
                 // remove all cached messages if the receiver was moved to "locked" state
                 if (updatedReceiver !== undefined && updatedReceiver.locked) {
@@ -2123,20 +2123,20 @@ export class WebClientService {
             id: message.partnerId,
             type: 'contact',
         } as threema.Receiver) as threema.ContactReceiver;
-        let partnerName = partner.displayName || ('~' + partner.publicNickname);
+        const partnerName = partner.displayName || ('~' + partner.publicNickname);
 
         // Show notification
         this.$translate('messenger.MESSAGE_NOTIFICATION_SUBJECT', {messageCount: 1 + conversation.unreadCount})
             .then((titlePrefix) =>  {
                 const title = `${titlePrefix} ${senderName}`;
                 let body = '';
-                let messageType = message.type;
-                let caption = message.caption;
+                const messageType = message.type;
+                const caption = message.caption;
                 let captionString = '';
                 if (caption !== undefined) {
                     captionString = captionString + ': ' + caption;
                 }
-                let messageTypeString = this.$translate.instant('messageTypes.' + messageType);
+                const messageTypeString = this.$translate.instant('messageTypes.' + messageType);
                 switch (messageType as threema.MessageType) {
                     case 'text':
                         body = message.body;
@@ -2222,7 +2222,7 @@ export class WebClientService {
     }
 
     private _sendRequest(type, args = null): void {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_REQUEST,
             subType: type,
         };
@@ -2247,7 +2247,7 @@ export class WebClientService {
 
         return new Promise(
             (resolve, reject) => {
-                let p = {
+                const p = {
                     resolve: resolve,
                     reject: reject,
                 } as threema.PromiseCallbacks;
@@ -2266,7 +2266,7 @@ export class WebClientService {
     }
 
     private _sendRequestPromise(type, args = null, timeout: number = null): Promise<any> {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_REQUEST,
             subType: type,
             args: args,
@@ -2276,7 +2276,7 @@ export class WebClientService {
     }
 
     private _sendCreatePromise(type, args = null, data: any = null, timeout: number = null): Promise<any> {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_CREATE,
             subType: type,
             args: args,
@@ -2286,7 +2286,7 @@ export class WebClientService {
     }
 
     private _sendUpdatePromise(type, args = null, data: any = null, timeout: number = null): Promise<any> {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_UPDATE,
             subType: type,
             data: data,
@@ -2297,7 +2297,7 @@ export class WebClientService {
     }
 
     private _sendCreate(type, data, args = null): void {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_CREATE,
             subType: type,
             data: data,
@@ -2309,7 +2309,7 @@ export class WebClientService {
     }
 
     private _sendDelete(type, args, data = null): void {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_DELETE,
             subType: type,
             data: data,
@@ -2319,7 +2319,7 @@ export class WebClientService {
     }
 
     private _sendDeletePromise(type, args, data: any = null, timeout: number = null): Promise<any> {
-        let message: threema.WireMessage = {
+        const message: threema.WireMessage = {
             type: WebClientService.TYPE_DELETE,
             subType: type,
             data: data,
@@ -2338,7 +2338,7 @@ export class WebClientService {
             && message.args !== undefined
             && message.args[WebClientService.ARGUMENT_TEMPORARY_ID] !== undefined) {
             // find pending promise
-            let promiseId = message.args[WebClientService.ARGUMENT_TEMPORARY_ID];
+            const promiseId = message.args[WebClientService.ARGUMENT_TEMPORARY_ID];
 
             if (this.requestPromises.has(promiseId)) {
                 if (receiveResult.success) {
@@ -2530,7 +2530,7 @@ export class WebClientService {
     }
 
     private runAfterInitializationSteps(requiredSteps: threema.InitializationStep[], callback: any): void {
-        for (let requiredStep of requiredSteps) {
+        for (const requiredStep of requiredSteps) {
             if (!this.initialized.has(requiredStep)) {
                 this.$log.debug(this.logTag,
                     'Required initialization step', requiredStep, 'not completed, add pending routine');

+ 25 - 26
src/threema/container.ts

@@ -39,8 +39,8 @@ class StringHashSet {
     }
 
     public values() {
-        let values = [];
-        for (let i in this.setObj) {
+        const values = [];
+        for (const i in this.setObj) {
             if (this.setObj[i] === this.val) {
                 values.push(i);
             }
@@ -256,7 +256,7 @@ angular.module('3ema.container', [])
          * Comparison is done by type and id.
          */
         public find(pattern: threema.Conversation | threema.Receiver): threema.Conversation | null {
-            for (let conversation of this.get()) {
+            for (const conversation of this.get()) {
                 const a = pattern;
                 const b = conversation;
                 if (a !== undefined && b !== undefined && a.type === b.type && a.id === b.id) {
@@ -273,10 +273,10 @@ angular.module('3ema.container', [])
         public updateOrAdd(conversation: threema.Conversation): void {
             let moveDirection = 0;
             let updated = false;
-            for (let p of this.conversations.keys()) {
+            for (const p of this.conversations.keys()) {
                 if (receiverService.compare(this.conversations[p], conversation)) {
                     // ok, replace me and break
-                    let old = this.conversations[p];
+                    const old = this.conversations[p];
                     if (old.position !== conversation.position) {
                         // position also changed...
                         moveDirection = old.position > conversation.position ? -1 : 1;
@@ -290,7 +290,7 @@ angular.module('3ema.container', [])
             if (moveDirection !== 0) {
                 // reindex
                 let before = true;
-                for (let p in this.conversations) {
+                for (const p in this.conversations) {
                     if (receiverService.compare(this.conversations[p], conversation)) {
                         before = false;
                     } else if (before && moveDirection < 0) {
@@ -301,7 +301,7 @@ angular.module('3ema.container', [])
                 }
 
                 // sort by position field
-                this.conversations.sort(function (convA, convB) {
+                this.conversations.sort(function(convA, convB) {
                     return convA.position - convB.position;
                 });
             } else if (!updated) {
@@ -310,7 +310,7 @@ angular.module('3ema.container', [])
         }
 
         public remove(conversation: threema.Conversation): void {
-            for (let p of this.conversations.keys()) {
+            for (const p of this.conversations.keys()) {
                 if (receiverService.compare(this.conversations[p], conversation)) {
                     // remove conversation from array
                     this.conversations.splice(p, 1);
@@ -405,29 +405,28 @@ angular.module('3ema.container', [])
          * @param $scope
          */
         public clear($scope: ng.IScope): void {
-            this.messages.forEach ((messageMap: Map<string, ReceiverMessages>,
-                receiverType: threema.ReceiverType) => {
-               messageMap.forEach ((messages: ReceiverMessages, id: string) => {
-                   messages.requested = false;
-                   messages.referenceMsgId = null;
-                   messages.more = true;
-                   messages.list = [];
-
-                   this.notify({
-                       id: id,
-                       type: receiverType,
-                   } as threema.Receiver, $scope);
-               });
+            this.messages.forEach((messageMap: Map<string, ReceiverMessages>, receiverType: threema.ReceiverType) => {
+                messageMap.forEach((messages: ReceiverMessages, id: string) => {
+                    messages.requested = false;
+                    messages.referenceMsgId = null;
+                    messages.more = true;
+                    messages.list = [];
+
+                    this.notify({
+                        id: id,
+                        type: receiverType,
+                    } as threema.Receiver, $scope);
+                });
             });
         }
 
         /**
          * Reset the cached messages of a receiver (e.g. the receiver was locked by the mobile)
          */
-        public clearReceiverMessages(receiver: threema.Receiver): Number {
+        public clearReceiverMessages(receiver: threema.Receiver): number {
             let cachedMessageCount = 0;
             if (this.messages.has(receiver.type)) {
-                let typeMessages = this.messages.get(receiver.type);
+                const typeMessages = this.messages.get(receiver.type);
                 if (typeMessages.has(receiver.id)) {
                     cachedMessageCount = typeMessages.get(receiver.id).list.length;
                     typeMessages.delete(receiver.id);
@@ -579,7 +578,7 @@ angular.module('3ema.container', [])
          */
         public setThumbnail(receiver: threema.Receiver, messageId: number, thumbnailImage: string): boolean {
             const list = this.getList(receiver);
-            for (let message of list) {
+            for (const message of list) {
                 if (message.id === messageId) {
                     if (message.thumbnail === undefined) {
                         message.thumbnail = {img: thumbnailImage} as threema.Thumbnail;
@@ -628,7 +627,7 @@ angular.module('3ema.container', [])
 
         public bindTemporaryToMessageId(receiver: threema.Receiver, temporaryId: string, messageId: number): boolean {
             const list = this.getList(receiver);
-            for (let item of list) {
+            for (const item of list) {
                 if (item.temporaryId === temporaryId) {
                     if (item.id !== undefined) {
                         // do not bind to a new message id
@@ -762,7 +761,7 @@ angular.module('3ema.container', [])
      */
     class Drafts implements threema.Container.Drafts {
 
-        private quotes = new Map<String, threema.Quote>();
+        private quotes = new Map<string, threema.Quote>();
 
         // Use to implement draft texts!
         private texts = new Map<string, string>();

+ 0 - 5
tests/service/uri.js

@@ -29,9 +29,4 @@ describe('UriService', function() {
         expect(parsed).toEqual({});
     });
 
-    it('ignores invalid params', () => {
-        const parsed = $service.parseQueryParams(7);
-        expect(parsed).toEqual(null);
-    });
-
 });

+ 1 - 1
tslint.json

@@ -11,6 +11,6 @@
         "only-arrow-functions": false,
         "quotemark": [true, "single", "avoid-escape"],
         "indent": [true, "spaces"],
-        "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-module", "check-separator", "check-type", "check-typecast", "check-preblock"]
+        "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-rest-spread", "check-type", "check-typecast", "check-type-operator", "check-preblock"]
     }
 }