diff --git a/.gitignore b/.gitignore
index 7404c57..03b8502 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
 atlassian-ide-plugin.xml
 node_modules/
 typings/
-app/**/*.js
-app/**/*.js.map
+src/**/*.js
+src/**/*.js.map
 npm-debug.log
+dist/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index de552cc..58779de 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,93 +2,55 @@ stages:
   - build
   - cleanup_build
   - deploy
-#  - cleanup
-
-.run_deploy: &run_deploy
-  script:
-    - chmod +x ./deploy.sh
-    - ./deploy.sh
-  dependencies:
-    - build_job
+  - cleanup
 
 build_job:
   stage: build
   script:
     - npm install
-    - npm run tsc
+    - npm run build
   tags:
     - javascript
   except:
     - tags
   artifacts:
     paths:
-      - app/*.css
-      - app/*.html
-      - app/*.js
-      - app/*.js.map
-      - app/converter/*.js
-      - app/converter/*.js.map
-      - node_modules/@angular/
-      - node_modules/core-js/client/shim.js
-      - node_modules/zone.js/dist/zone.js
-      - node_modules/reflect-metadata/Reflect.js
-      - node_modules/rxjs/
-      - node_modules/systemjs/dist/system.src.js
-      - node_modules/utf8/utf8.js
-      - node_modules/quoted-printable/quoted-printable.js
-      - node_modules/punycode/punycode.js
-      - abeezee-regular.woff
-      - freemono.eot
-      - freemono.svg
-      - freemono.ttf
-      - freemono.woff
-      - index.html
-      - package.json
-      - systemjs.config.js
+      - dist
     expire_in: 30 min
 
 cleanup_build_job:
   stage: cleanup_build
   script:
     - rm -rf node_modules
-    - rm -rf typings
+    - rm -rf dist
   when: on_failure
 
-develop:
+pages:
   stage: deploy
-  <<: *run_deploy
-  environment: develop
+  environment: staging
   except:
     - tags
     - master
-    - develop
-  variables:
-    ENVIRON: develop
-    TARGET: $WWW_DEPLOY_ROOT_DEVELOP
-
-staging:
-  stage: deploy
-  <<: *run_deploy
-  environment: staging
-  only:
-    - develop
-  variables:
-    ENVIRON: staging
-    TARGET: $WWW_DEPLOY_ROOT_STAGING
+  script:
+    - mv dist public
+  artifacts:
+    paths:
+      - public
+  dependencies:
+    - build_job
 
 production:
   stage: deploy
-  <<: *run_deploy
   environment: production
   only:
     - master
-  variables:
-    ENVIRON: production
-    TARGET: $WWW_DEPLOY_ROOT_PRODUCTION
+  script:
+    - if [[ -z "${WWW_DEPLOY_ROOT_PRODUCTION}" ]] ; then echo "WWW_DEPLOY_ROOT_PRODUCTION is not set" ; exit 1 ; fi
+    - if [[ ! -d "${WWW_DEPLOY_ROOT_PRODUCTION}" ]] ; then mkdir -p "${WWW_DEPLOY_ROOT_PRODUCTION}" || die "Failed to create target directory for deployment!" ; fi
+    - cp dist/* "${WWW_DEPLOY_ROOT_PRODUCTION}"
 
-#cleanup_job:
-#  stage: cleanup
-#  script:
-#    - rm -rf node_modules
-#    - rm -rf typings
-#  when: always
+cleanup_job:
+  stage: cleanup
+  script:
+    - rm -rf node_modules
+  when: always
diff --git a/app/nativelibrarywrapper.service.ts b/app/nativelibrarywrapper.service.ts
deleted file mode 100644
index 2a905b9..0000000
--- a/app/nativelibrarywrapper.service.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {Injectable} from "@angular/core";
-
-declare var utf8:any;
-declare var quotedPrintable:any;
-declare var punycode:any;
-
-@Injectable()
-export class NativeLibraryWrapperService {
-    public utf8:any;
-    public quotedPrintable:any;
-    public punycode:any;
-
-    constructor() {
-        this.utf8 = utf8;
-        this.quotedPrintable = quotedPrintable;
-        this.punycode = punycode;
-    }
-}
diff --git a/config/helpers.js b/config/helpers.js
new file mode 100644
index 0000000..adfb603
--- /dev/null
+++ b/config/helpers.js
@@ -0,0 +1,7 @@
+var path = require('path');
+var _root = path.resolve(__dirname, '..');
+function root(args) {
+    args = Array.prototype.slice.call(arguments, 0);
+    return path.join.apply(path, [_root].concat(args));
+}
+exports.root = root;
diff --git a/config/webpack.common.js b/config/webpack.common.js
new file mode 100644
index 0000000..58d407b
--- /dev/null
+++ b/config/webpack.common.js
@@ -0,0 +1,76 @@
+var webpack = require('webpack');
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
+var helpers = require('./helpers');
+
+module.exports = {
+    entry: {
+        'polyfills': './src/polyfills.ts',
+        'vendor': './src/vendor.ts',
+        'app': './src/main.ts'
+    },
+
+    resolve: {
+        extensions: ['.ts', '.js']
+    },
+
+    module: {
+        rules: [
+            {
+                test: /\.ts$/,
+                loaders: [
+                    {
+                        loader: 'awesome-typescript-loader',
+                        options: {
+                            configFileName: helpers.root('src', 'tsconfig.json')
+                        }
+                    },
+                    'angular2-template-loader'
+                ]
+            },
+            {
+                test: /\.html$/,
+                use: 'html-loader'
+            },
+            {
+                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
+                use: 'file-loader?name=assets/[name].[hash].[ext]'
+            },
+            {
+                test: /\.css$/,
+                exclude: helpers.root('src', 'app'),
+                use: ExtractTextPlugin.extract({
+                    fallback: 'style-loader',
+                    use: 'css-loader?sourceMap'
+                })
+            },
+            {
+                test: /\.css$/,
+                include: helpers.root('src', 'app'),
+                use: 'raw-loader'
+            }
+        ]
+    },
+
+    plugins: [
+        // Workaround for angular/angular#11580
+        new webpack.ContextReplacementPlugin(
+            // The (\\|\/) piece accounts for path separators in *nix and Windows
+            /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
+            helpers.root('./src'), // location of your src
+            {} // a map of your routes
+        ),
+
+        new webpack.optimize.CommonsChunkPlugin({
+            name: ['app', 'vendor', 'polyfills']
+        }),
+
+        new HtmlWebpackPlugin({
+            template: 'src/index.html'
+        }),
+
+        new webpack.optimize.UglifyJsPlugin({
+            comments: false
+        })
+    ]
+};
diff --git a/config/webpack.dev.js b/config/webpack.dev.js
new file mode 100644
index 0000000..7f3c504
--- /dev/null
+++ b/config/webpack.dev.js
@@ -0,0 +1,24 @@
+var webpackMerge = require('webpack-merge');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
+var commonConfig = require('./webpack.common.js');
+var helpers = require('./helpers');
+
+module.exports = webpackMerge(commonConfig, {
+    devtool: 'cheap-module-eval-source-map',
+
+    output: {
+        path: helpers.root('dist'),
+        publicPath: 'http://localhost:8080/',
+        filename: '[name].js',
+        chunkFilename: '[id].chunk.js'
+    },
+
+    plugins: [
+        new ExtractTextPlugin('[name].css')
+    ],
+
+    devServer: {
+        historyApiFallback: true,
+        stats: 'minimal'
+    }
+});
diff --git a/config/webpack.prod.js b/config/webpack.prod.js
new file mode 100644
index 0000000..a5fb526
--- /dev/null
+++ b/config/webpack.prod.js
@@ -0,0 +1,38 @@
+var webpack = require('webpack');
+var webpackMerge = require('webpack-merge');
+var ExtractTextPlugin = require('extract-text-webpack-plugin');
+var commonConfig = require('./webpack.common.js');
+var helpers = require('./helpers');
+
+const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
+
+module.exports = webpackMerge(commonConfig, {
+    devtool: 'source-map',
+
+    output: {
+        path: helpers.root('dist'),
+        publicPath: '',
+        filename: '[name].[hash].js',
+        chunkFilename: '[id].[hash].chunk.js'
+    },
+
+    plugins: [
+        new webpack.NoEmitOnErrorsPlugin(),
+        new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
+            mangle: {
+                keep_fnames: true
+            }
+        }),
+        new ExtractTextPlugin('[name].[hash].css'),
+        new webpack.DefinePlugin({
+            'process.env': {
+                'ENV': JSON.stringify(ENV)
+            }
+        }),
+        new webpack.LoaderOptionsPlugin({
+            htmlLoader: {
+                minimize: false // workaround for ng2
+            }
+        })
+    ]
+});
diff --git a/deploy.sh b/deploy.sh
deleted file mode 100755
index c21a4f3..0000000
--- a/deploy.sh
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/sh
-
-function die() {
-    echo $*
-    exit 1
-}
-
-declare destination
-case "${TARGET}" in
-	"${WWW_DEPLOY_ROOT_DEVELOP}")
-		destination="${TARGET}/${CI_BUILD_REF_NAME}"
-		;;
-	"${WWW_DEPLOY_ROOT_STAGING}"|"${WWW_DEPLOY_ROOT_PRODUCTION}")
-		destination="${TARGET}"
-		;;
-	*)
-		die "Invalid TARGET specified. Aborting deployment."
-		;;
-esac
-
-if [[ ! -d "${destination}" ]] ; then
-    mkdir -p "${destination}" || die "Failed to create target directory for deployment!"
-fi
-
-rm -rf "${destination}"/* || die "Failed to clean destination directory (step 1)"
-rm -rf "${destination}"/.??* || die "Failed to clean destination directory (step 2)"
-
-cp -a index.html abeezee-regular.woff freemono.* package.json systemjs.config.js "${destination}" || die "Failed to copy resources to dest/"
-
-mkdir -p "${destination}/app/converter" || die "Failed to create dest/app/converter directory"
-cp -a app/*.css app/*.html app/*.js app/*.js.map "${destination}/app" || die "Failed to copy resources to dest/app"
-cp -a app/converter/*.js app/converter/*.js.map "${destination}/app/converter" || die "Failed to copy resources to dest/app/converter"
-
-mkdir -p "${destination}/node_modules/@angular" || die "Failed to create dest/node_modules/@angular"
-cp -a node_modules/@angular/* "${destination}/node_modules/@angular/" || die "Failed to copy @angular"
-
-mkdir -p "${destination}/node_modules/core-js/client" || die "Failed to create dest/node_modules/core-js"
-cp -a node_modules/core-js/client/shim.js "${destination}/node_modules/core-js/client/" || die "Failed to copy core-js"
-
-mkdir -p "${destination}/node_modules/zone.js/dist" || die "Failed to create dest/node_modules/zone.js"
-cp -a node_modules/zone.js/dist/zone.js "${destination}/node_modules/zone.js/dist/" || die "Failed to copy zone.js"
-
-mkdir -p "${destination}/node_modules/reflect-metadata" || die "Failed to create dest/node_modules/reflect-metadata"
-cp -a node_modules/reflect-metadata/Reflect.js "${destination}/node_modules/reflect-metadata/" || die "Failed to copy Reflect.js"
-
-mkdir -p "${destination}/node_modules/rxjs" || die "Failed to create dest/node_modules/rxjs"
-cp -a node_modules/rxjs/* "${destination}/node_modules/rxjs/" || die "Failed to copy rxjs"
-
-mkdir -p "${destination}/node_modules/systemjs/dist" || die "Failed to create dest/node_modules/systemjs"
-cp -a node_modules/systemjs/dist/system.src.js "${destination}/node_modules/systemjs/dist/" || die "Failed to copy system.src.js"
-
-mkdir -p "${destination}/node_modules/utf8" || die "Failed to create dest/node_modules/utf8"
-cp -a node_modules/utf8/utf8.js "${destination}/node_modules/utf8/" || die "Failed to copy utf8.js"
-
-mkdir -p "${destination}/node_modules/quoted-printable" || die "Failed to create dest/node_modules/quoted-printable"
-cp -a node_modules/quoted-printable/quoted-printable.js "${destination}/node_modules/quoted-printable/" || die "Failed to copy quoted-printable.js"
-
-mkdir -p "${destination}/node_modules/punycode" || die "Failed to create dest/node_modules/punycode"
-cp -a node_modules/punycode/punycode.js "${destination}/node_modules/punycode/" || die "Failed to copy punycode.js"
-
-echo "Deployment successful."
diff --git a/index.html b/index.html
deleted file mode 100644
index f12af09..0000000
--- a/index.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="UTF-8"/>
-    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>
-    <title>Decode? Encode? DENcode!</title>
-    <script type="text/javascript" src="node_modules/core-js/client/shim.js"></script>
-    <script type="text/javascript" src="node_modules/zone.js/dist/zone.js"></script>
-    <script type="text/javascript" src="node_modules/reflect-metadata/Reflect.js"></script>
-    <script type="text/javascript" src="node_modules/systemjs/dist/system.src.js"></script>
-    <script type="text/javascript" src="node_modules/utf8/utf8.js"></script>
-    <script type="text/javascript" src="node_modules/quoted-printable/quoted-printable.js"></script>
-    <script type="text/javascript" src="node_modules/punycode/punycode.js"></script>
-
-    <script type="text/javascript" src="systemjs.config.js"></script>
-    <script type="text/javascript">
-        System.import("app").catch(function (err) {
-            console.log(err);
-        });
-    </script>
-    <style>
-        @font-face {
-            font-family: "ABeeZee";
-            font-stretch: normal;
-            font-style: normal;
-            font-variant: normal;
-            font-weight: normal;
-            src: local("ABeeZee Regular"),
-            local("ABeeZee-Regular"),
-            local("ABeeZee"),
-            url("abeezee-regular.woff") format("woff");
-        }
-
-        body {
-            font-family: "ABeeZee", sans-serif;
-            margin: 0;
-            padding: 1em 0 0 0;
-        }
-
-        h1 {
-            text-align: center;
-        }
-    </style>
-</head>
-<body>
-<h1>Decode? Encode? DENcode!</h1>
-<noscript>This webpage lets you decode and encode data and text to and from various formats. But
-    it requires you to <strong>enable Javascript</strong> to do so. So please turn it on in your
-    Browser. You won't regret it!
-</noscript>
-<den-app>
-    <div style="text-align:center;">Please hold on, we're starting the turbines ...</div>
-</den-app>
-</body>
-</html>
diff --git a/karma.conf.js b/karma.conf.js
new file mode 100644
index 0000000..9649b15
--- /dev/null
+++ b/karma.conf.js
@@ -0,0 +1 @@
+module.exports = require('./config/karma.conf.js');
diff --git a/package.json b/package.json
index 39d3c79..3caf487 100644
--- a/package.json
+++ b/package.json
@@ -1,47 +1,66 @@
 {
   "name": "dencode.org",
-  "version": "1.0.0-alpha.1",
+  "version": "1.0.0-alpha.2",
   "description": "Convert to and fro!",
   "keywords": [
-    "dencode", "conversion", "converter", "convert"
+    "dencode",
+    "conversion",
+    "converter",
+    "convert"
   ],
   "author": {
     "name": "Manuel Friedli",
     "email": "manuel@fritteli.ch"
   },
   "license": "MIT",
-  "homepage": "https://test.friedli.info/~manuel/dencode",
-  "repository": "https://gittr.ch/manuel/dencode.org.git",
+  "homepage": "https://manuel.pages.gittr.ch/dencode.org",
+  "repository": {
+    "type": "git",
+    "url": "https://gittr.ch/manuel/dencode.org.git"
+  },
   "dependencies": {
-    "@angular/common": "2.0.0",
-    "@angular/compiler": "2.0.0",
-    "@angular/core": "2.0.0",
-    "@angular/forms": "2.0.0",
-    "@angular/platform-browser": "2.0.0",
-    "@angular/platform-browser-dynamic": "2.0.0",
-    "@angular/upgrade": "2.0.0",
-    "bootstrap": "^3.3.6",
-    "core-js": "^2.4.0",
-    "reflect-metadata": "^0.1.3",
-    "rxjs": "5.0.0-beta.12",
-    "systemjs": "^0.19.27",
-    "zone.js": "^0.6.12",
+    "@angular/common": "^2.4.0",
+    "@angular/compiler": "^2.4.0",
+    "@angular/core": "^2.4.0",
+    "@angular/forms": "^2.4.0",
+    "@angular/platform-browser": "^2.4.0",
+    "@angular/platform-browser-dynamic": "^2.4.0",
+    "core-js": "^2.4.1",
+    "rxjs": "^5.0.1",
+    "zone.js": "^0.7.4",
+    "bootstrap": "^3.3.0",
     "quoted-printable": "^1.0.0",
-    "utf8": "^2.1.1",
-    "punycode": "1.4.1"
+    "utf8": "^2.1.0",
+    "punycode": "^1.4.0"
   },
   "devDependencies": {
-    "concurrently": "^2.2.0",
-    "lite-server": "^2.2.0",
-    "typescript": "^2.0.2",
-    "typings": "^1.3.2"
+    "@types/node": "^6.0.45",
+    "@types/jasmine": "2.5.36",
+    "angular2-template-loader": "^0.6.0",
+    "awesome-typescript-loader": "^3.0.4",
+    "css-loader": "^0.26.1",
+    "extract-text-webpack-plugin": "^2.0.0",
+    "file-loader": "^0.9.0",
+    "html-loader": "^0.4.3",
+    "html-webpack-plugin": "^2.16.1",
+    "jasmine-core": "^2.4.1",
+    "karma": "^1.2.0",
+    "karma-chrome-launcher": "^2.0.0",
+    "karma-jasmine": "^1.0.2",
+    "karma-sourcemap-loader": "^0.3.7",
+    "karma-webpack": "^2.0.1",
+    "null-loader": "^0.1.1",
+    "raw-loader": "^0.5.1",
+    "rimraf": "^2.5.2",
+    "style-loader": "^0.13.1",
+    "typescript": "^2.0.10",
+    "webpack": "^2.2.1",
+    "webpack-dev-server": "^2.4.1",
+    "webpack-merge": "^3.0.0"
   },
   "scripts": {
-    "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\"",
-    "lite": "lite-server",
-    "postinstall": "typings install",
-    "tsc": "tsc",
-    "tsc:w": "tsc -w",
-    "typings": "typings"
+    "start": "webpack-dev-server --inline --progress --port 8080",
+    "test": "karma start",
+    "build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
   }
 }
diff --git a/app/app.component.css b/src/app/app.component.css
similarity index 75%
rename from app/app.component.css
rename to src/app/app.component.css
index a1f448b..6a42d9d 100644
--- a/app/app.component.css
+++ b/src/app/app.component.css
@@ -1,25 +1,3 @@
-@font-face {
-    font-family: "ABeeZee";
-    font-stretch: normal;
-    font-style: normal;
-    font-variant: normal;
-    font-weight: normal;
-    src: local("ABeeZee Regular"),
-    local("ABeeZee-Regular"),
-    local("ABeeZee"),
-    url("../abeezee-regular.woff") format("woff");
-}
-
-@font-face {
-    font-family: "Free Monospaced";
-    src: url("../freemono.eot?") format("eot"),
-    url("../freemono.woff") format("woff"),
-    url("../freemono.ttf") format("truetype"),
-    url("../freemono.svg#FreeMono") format("svg");
-    font-weight: normal;
-    font-style: normal;
-}
-
 .inputwrapper {
     font-family: "ABeeZee", sans-serif;
     margin: 0 1em 1em 1em;
diff --git a/app/app.component.html b/src/app/app.component.html
similarity index 100%
rename from app/app.component.html
rename to src/app/app.component.html
diff --git a/app/app.component.ts b/src/app/app.component.ts
similarity index 94%
rename from app/app.component.ts
rename to src/app/app.component.ts
index 97a015e..6755491 100644
--- a/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -5,11 +5,12 @@ import {Converter} from "./converter/converter";
 import {NativeLibraryWrapperService} from "./nativelibrarywrapper.service";
 import {Step} from "./step";
 
+import "../assets/css/style.css";
+
 @Component({
-    moduleId: module.id,
     selector: "den-app",
-    templateUrl: "app.component.html",
-    styleUrls: ["app.component.css"],
+    templateUrl: "./app.component.html",
+    styleUrls: ["./app.component.css"],
     providers: [ConverterRegistryService, InputComponentManagerService, NativeLibraryWrapperService]
 })
 export class AppComponent extends OnInit {
diff --git a/app/app.module.ts b/src/app/app.module.ts
similarity index 100%
rename from app/app.module.ts
rename to src/app/app.module.ts
diff --git a/app/converter/base64decoder.ts b/src/app/converter/base64decoder.ts
similarity index 100%
rename from app/converter/base64decoder.ts
rename to src/app/converter/base64decoder.ts
diff --git a/app/converter/base64encoder.ts b/src/app/converter/base64encoder.ts
similarity index 100%
rename from app/converter/base64encoder.ts
rename to src/app/converter/base64encoder.ts
diff --git a/app/converter/bintodecconverter.ts b/src/app/converter/bintodecconverter.ts
similarity index 99%
rename from app/converter/bintodecconverter.ts
rename to src/app/converter/bintodecconverter.ts
index 0b4cbd7..33d73ba 100644
--- a/app/converter/bintodecconverter.ts
+++ b/src/app/converter/bintodecconverter.ts
@@ -1,4 +1,5 @@
 import {Converter} from "./converter";
+
 export class BinToDecConverter implements Converter {
     getDisplayname():string {
         return "Convert binary to decimal";
diff --git a/app/converter/converter.ts b/src/app/converter/converter.ts
similarity index 100%
rename from app/converter/converter.ts
rename to src/app/converter/converter.ts
diff --git a/app/converter/dectobinconverter.ts b/src/app/converter/dectobinconverter.ts
similarity index 99%
rename from app/converter/dectobinconverter.ts
rename to src/app/converter/dectobinconverter.ts
index b64a310..c457d4c 100644
--- a/app/converter/dectobinconverter.ts
+++ b/src/app/converter/dectobinconverter.ts
@@ -1,4 +1,5 @@
 import {Converter} from "./converter";
+
 export class DecToBinConverter implements Converter {
     getDisplayname():string {
         return "Convert decimal to binary";
diff --git a/app/converter/dectohexconverter.ts b/src/app/converter/dectohexconverter.ts
similarity index 99%
rename from app/converter/dectohexconverter.ts
rename to src/app/converter/dectohexconverter.ts
index b033792..4050643 100644
--- a/app/converter/dectohexconverter.ts
+++ b/src/app/converter/dectohexconverter.ts
@@ -1,4 +1,5 @@
 import {Converter} from "./converter";
+
 export class DecToHexConverter implements Converter {
     getDisplayname():string {
         return "Convert decimal to hexadecimal";
diff --git a/app/converter/hextodecconverter.ts b/src/app/converter/hextodecconverter.ts
similarity index 99%
rename from app/converter/hextodecconverter.ts
rename to src/app/converter/hextodecconverter.ts
index 2dcdad2..68b8c27 100644
--- a/app/converter/hextodecconverter.ts
+++ b/src/app/converter/hextodecconverter.ts
@@ -1,4 +1,5 @@
 import {Converter} from "./converter";
+
 export class HexToDecConverter implements Converter {
     getDisplayname():string {
         return "Convert hexadecimal to decimal";
diff --git a/app/converter/htmlentitiesdecoder.ts b/src/app/converter/htmlentitiesdecoder.ts
similarity index 100%
rename from app/converter/htmlentitiesdecoder.ts
rename to src/app/converter/htmlentitiesdecoder.ts
diff --git a/app/converter/htmlentitiesencoder.ts b/src/app/converter/htmlentitiesencoder.ts
similarity index 100%
rename from app/converter/htmlentitiesencoder.ts
rename to src/app/converter/htmlentitiesencoder.ts
diff --git a/app/converter/punycodedecoder.ts b/src/app/converter/punycodedecoder.ts
similarity index 100%
rename from app/converter/punycodedecoder.ts
rename to src/app/converter/punycodedecoder.ts
diff --git a/app/converter/punycodeencoder.ts b/src/app/converter/punycodeencoder.ts
similarity index 100%
rename from app/converter/punycodeencoder.ts
rename to src/app/converter/punycodeencoder.ts
diff --git a/app/converter/quotedprintabledecoder.ts b/src/app/converter/quotedprintabledecoder.ts
similarity index 100%
rename from app/converter/quotedprintabledecoder.ts
rename to src/app/converter/quotedprintabledecoder.ts
diff --git a/app/converter/quotedprintableencoder.ts b/src/app/converter/quotedprintableencoder.ts
similarity index 100%
rename from app/converter/quotedprintableencoder.ts
rename to src/app/converter/quotedprintableencoder.ts
diff --git a/app/converter/uricomponentdecoder.ts b/src/app/converter/uricomponentdecoder.ts
similarity index 100%
rename from app/converter/uricomponentdecoder.ts
rename to src/app/converter/uricomponentdecoder.ts
diff --git a/app/converter/uricomponentencoder.ts b/src/app/converter/uricomponentencoder.ts
similarity index 100%
rename from app/converter/uricomponentencoder.ts
rename to src/app/converter/uricomponentencoder.ts
diff --git a/app/converter/uridecoder.ts b/src/app/converter/uridecoder.ts
similarity index 100%
rename from app/converter/uridecoder.ts
rename to src/app/converter/uridecoder.ts
diff --git a/app/converter/uriencoder.ts b/src/app/converter/uriencoder.ts
similarity index 100%
rename from app/converter/uriencoder.ts
rename to src/app/converter/uriencoder.ts
diff --git a/app/converterregistry.service.ts b/src/app/converterregistry.service.ts
similarity index 100%
rename from app/converterregistry.service.ts
rename to src/app/converterregistry.service.ts
diff --git a/app/inputcomponentmanager.service.ts b/src/app/inputcomponentmanager.service.ts
similarity index 100%
rename from app/inputcomponentmanager.service.ts
rename to src/app/inputcomponentmanager.service.ts
diff --git a/src/app/nativelibrarywrapper.service.ts b/src/app/nativelibrarywrapper.service.ts
new file mode 100644
index 0000000..468b21d
--- /dev/null
+++ b/src/app/nativelibrarywrapper.service.ts
@@ -0,0 +1,17 @@
+import {Injectable} from "@angular/core";
+import {Punycode} from "./punycode";
+import {Utf8} from "./utf8";
+import {QuotedPrintable} from "./quotedprintable";
+
+@Injectable()
+export class NativeLibraryWrapperService {
+    public utf8:Utf8;
+    public quotedPrintable:QuotedPrintable;
+    public punycode:Punycode;
+
+    constructor() {
+        this.utf8 = require("utf8");
+        this.quotedPrintable = require("quoted-printable");
+        this.punycode = require("punycode");
+    }
+}
diff --git a/src/app/punycode.ts b/src/app/punycode.ts
new file mode 100644
index 0000000..a141d24
--- /dev/null
+++ b/src/app/punycode.ts
@@ -0,0 +1,4 @@
+export interface Punycode {
+    encode(input:string):string;
+    decode(input:string):string;
+}
diff --git a/src/app/quotedprintable.ts b/src/app/quotedprintable.ts
new file mode 100644
index 0000000..2cfb171
--- /dev/null
+++ b/src/app/quotedprintable.ts
@@ -0,0 +1,4 @@
+export interface QuotedPrintable {
+    encode(input:string):string;
+    decode(input:string):string;
+}
diff --git a/app/step.ts b/src/app/step.ts
similarity index 99%
rename from app/step.ts
rename to src/app/step.ts
index fb4d584..d86c68f 100644
--- a/app/step.ts
+++ b/src/app/step.ts
@@ -1,4 +1,5 @@
 import {Converter} from "./converter/converter";
+
 export class Step {
     public content:string = "";
     public selectedConverter:Converter = undefined;
diff --git a/src/app/utf8.ts b/src/app/utf8.ts
new file mode 100644
index 0000000..cce1ba8
--- /dev/null
+++ b/src/app/utf8.ts
@@ -0,0 +1,4 @@
+export interface Utf8 {
+    encode(input:any):string;
+    decode(input:string):any;
+}
diff --git a/src/assets/css/style.css b/src/assets/css/style.css
new file mode 100644
index 0000000..323ad97
--- /dev/null
+++ b/src/assets/css/style.css
@@ -0,0 +1,35 @@
+@font-face {
+    font-family: "ABeeZee";
+    font-stretch: normal;
+    font-style: normal;
+    font-variant: normal;
+    font-weight: normal;
+    src: local("ABeeZee Regular"),
+    local("ABeeZee-Regular"),
+    local("ABeeZee"),
+    url("../fonts/abeezee-regular.woff") format("woff");
+}
+
+@font-face {
+    font-family: "Free Monospaced";
+    src: url("../fonts/freemono.eot?") format("eot"),
+    url("../fonts/freemono.woff") format("woff"),
+    url("../fonts/freemono.ttf") format("truetype"),
+    url("../fonts/freemono.svg#FreeMono") format("svg");
+    font-weight: normal;
+    font-style: normal;
+}
+
+body {
+    font-family: "ABeeZee", sans-serif;
+    margin: 0;
+    padding: 1em 0 0 0;
+}
+
+h1 {
+    text-align: center;
+}
+
+.apploader {
+    text-align: center;
+}
diff --git a/abeezee-regular.woff b/src/assets/fonts/abeezee-regular.woff
similarity index 100%
rename from abeezee-regular.woff
rename to src/assets/fonts/abeezee-regular.woff
diff --git a/freemono.eot b/src/assets/fonts/freemono.eot
similarity index 100%
rename from freemono.eot
rename to src/assets/fonts/freemono.eot
diff --git a/freemono.svg b/src/assets/fonts/freemono.svg
similarity index 100%
rename from freemono.svg
rename to src/assets/fonts/freemono.svg
diff --git a/freemono.ttf b/src/assets/fonts/freemono.ttf
similarity index 100%
rename from freemono.ttf
rename to src/assets/fonts/freemono.ttf
diff --git a/freemono.woff b/src/assets/fonts/freemono.woff
similarity index 100%
rename from freemono.woff
rename to src/assets/fonts/freemono.woff
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..962167d
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8"/>
+    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>
+    <title>Decode? Encode? DENcode!</title>
+</head>
+<body>
+<h1>Decode? Encode? DENcode!</h1>
+<noscript>This webpage lets you decode and encode data and text to and from various formats. But
+    it requires you to <strong>enable Javascript</strong> to do so. So please turn it on in your
+    Browser. You won't regret it!
+</noscript>
+<den-app>
+    <div class="apploader">Please hold on, we're starting the turbines ...</div>
+</den-app>
+</body>
+</html>
diff --git a/app/main.ts b/src/main.ts
similarity index 74%
rename from app/main.ts
rename to src/main.ts
index c31c26f..1a7052b 100644
--- a/app/main.ts
+++ b/src/main.ts
@@ -1,4 +1,4 @@
 import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
-import {AppModule} from "./app.module";
+import {AppModule} from "./app/app.module";
 
 platformBrowserDynamic().bootstrapModule(AppModule);
diff --git a/src/polyfills.ts b/src/polyfills.ts
new file mode 100644
index 0000000..1a7f5df
--- /dev/null
+++ b/src/polyfills.ts
@@ -0,0 +1,11 @@
+import "core-js/es6";
+import "core-js/es7/reflect";
+require("zone.js/dist/zone");
+
+if (process.env.ENV === 'production') {
+    // Production
+} else {
+    // Development and test
+    Error['stackTraceLimit'] = Infinity;
+    require('zone.js/dist/long-stack-trace-zone');
+}
diff --git a/tsconfig.json b/src/tsconfig.json
similarity index 50%
rename from tsconfig.json
rename to src/tsconfig.json
index e6a6eac..da26a70 100644
--- a/tsconfig.json
+++ b/src/tsconfig.json
@@ -1,12 +1,20 @@
 {
   "compilerOptions": {
+    "alwaysStrict": true,
     "target": "es5",
     "module": "commonjs",
     "moduleResolution": "node",
     "sourceMap": true,
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
-    "removeComments": false,
-    "noImplicitAny": false
+    "lib": [
+      "es2015",
+      "dom"
+    ],
+    "noImplicitAny": true,
+    "suppressImplicitAnyIndexErrors": true,
+    "typeRoots": [
+      "../node_modules/@types/"
+    ]
   }
 }
diff --git a/src/vendor.ts b/src/vendor.ts
new file mode 100644
index 0000000..bae9e0f
--- /dev/null
+++ b/src/vendor.ts
@@ -0,0 +1,5 @@
+import "@angular/core";
+import "@angular/platform-browser";
+import "@angular/platform-browser-dynamic";
+import "@angular/forms";
+import "rxjs";
diff --git a/systemjs.config.js b/systemjs.config.js
deleted file mode 100644
index 5ac6290..0000000
--- a/systemjs.config.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * System configuration for Angular 2 samples
- * Adjust as necessary for your application needs.
- */
-(function (global) {
-    System.config({
-        paths: {
-            // paths serve as alias
-            'npm:': 'node_modules/'
-        },
-        // map tells the System loader where to look for things
-        map: {
-            // our app is within the app folder
-            app: 'app',
-            // angular bundles
-            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
-            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
-            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
-            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
-            '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
-//            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
-//            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
-           '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
-            // other libraries
-            'rxjs': 'npm:rxjs'//,
-//            'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
-        },
-        // packages tells the System loader how to load when no filename and/or no extension
-        packages: {
-            app: {
-                main: './main.js',
-                defaultExtension: 'js'
-            },
-            rxjs: {
-                defaultExtension: 'js'
-            },
-            'angular2-in-memory-web-api': {
-                main: './index.js',
-                defaultExtension: 'js'
-            }
-        }
-    });
-})(this);
\ No newline at end of file
diff --git a/typings.json b/typings.json
deleted file mode 100644
index c43d8b7..0000000
--- a/typings.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "name": "dencode.org",
-  "dependencies": {},
-  "globalDependencies": {
-    "core-js": "registry:dt/core-js#0.0.0+20160914114559",
-    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
-    "node": "registry:dt/node#6.0.0+20160915134512"
-  }
-}
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..26df33c
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1 @@
+module.exports = require('./config/webpack.dev.js');