diff --git a/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
new file mode 100644
index 0000000..ac68c1a
--- /dev/null
+++ b/web/gui2-fw-lib/projects/gui2-fw-lib/src/lib/util/keys.service.ts
@@ -0,0 +1,407 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { Injectable } from '@angular/core';
+import * as d3 from 'd3';
+import { LogService } from '../log.service';
+import { FnService } from '../util/fn.service';
+import { LionService } from './lion.service';
+import { NavService } from '../nav/nav.service';
+
+export interface KeyHandler {
+    globalKeys: Object;
+    maskedKeys: Object;
+    dialogKeys: Object;
+    viewKeys: any;
+    viewFn: any;
+    viewGestures: string[][];
+}
+
+export enum KeysToken {
+    KEYEV = 'keyev'
+}
+
+/**
+ * ONOS GUI -- Keys Service Module.
+ */
+@Injectable({
+    providedIn: 'root',
+})
+export class KeysService {
+    enabled: boolean = true;
+    globalEnabled: boolean = true;
+    keyHandler: KeyHandler = <KeyHandler>{
+        globalKeys: {},
+        maskedKeys: {},
+        dialogKeys: {},
+        viewKeys: {},
+        viewFn: null,
+        viewGestures: [],
+    };
+
+    seq: any = {};
+    matching: boolean = false;
+    matched: string = '';
+    lookup: any;
+    textFieldDoesNotBlock: any = {
+        enter: 1,
+        esc: 1,
+    };
+    qhs: any; // Quick Help Service ??
+
+    constructor(
+        protected log: LogService,
+        protected fs: FnService,
+        protected ls: LionService,
+        protected ns: NavService
+    ) {
+        this.log.debug('KeyService constructed');
+    }
+
+    bindQhs(_qhs_) {
+        this.qhs = _qhs_;
+    }
+
+    installOn(elem) {
+        this.log.debug('Installing keys handler');
+        elem.on('keydown', () => { this.keyIn(); });
+        this.setupGlobalKeys();
+    }
+
+    keyBindings(x) {
+        if (x === undefined) {
+            return this.getKeyBindings();
+        } else {
+            this.setKeyBindings(x);
+        }
+    }
+
+    unbindKeys() {
+        this.keyHandler.viewKeys = {};
+        this.keyHandler.viewFn = null;
+        this.keyHandler.viewGestures = [];
+    }
+
+    dialogKeys(x) {
+        if (x === undefined) {
+            this.unbindDialogKeys();
+        } else {
+            this.bindDialogKeys(x);
+        }
+    }
+
+    addSeq(word, data) {
+        this.fs.addToTrie(this.seq, word, data);
+    }
+
+    remSeq(word) {
+        this.fs.removeFromTrie(this.seq, word);
+    }
+
+    gestureNotes(g?) {
+        if (g === undefined) {
+            return this.keyHandler.viewGestures;
+        } else {
+            this.keyHandler.viewGestures = this.fs.isA(g) || [];
+        }
+    }
+
+    enableKeys(b) {
+        this.enabled = b;
+    }
+
+    enableGlobalKeys(b) {
+        this.globalEnabled = b;
+    }
+
+    checkNotGlobal(o) {
+        const oops = [];
+        if (this.fs.isO(o)) {
+            o.forEach((val, key) => {
+                if (this.keyHandler.globalKeys[key]) {
+                    oops.push(key);
+                }
+            });
+            if (oops.length) {
+                this.log.warn('Ignoring reserved global key(s):', oops.join(','));
+                oops.forEach((key) => {
+                    delete o[key];
+                });
+            }
+        }
+    }
+
+    protected matchSeq(key) {
+        if (!this.matching && key === 'shift-shift') {
+            this.matching = true;
+            return true;
+        }
+        if (this.matching) {
+            this.matched += key;
+            this.lookup = this.fs.trieLookup(this.seq, this.matched);
+            if (this.lookup === -1) {
+                return true;
+            }
+            this.matching = false;
+            this.matched = '';
+            if (!this.lookup) {
+                return;
+            }
+            // ee.cluck(lookup);
+            return true;
+        }
+    }
+
+    protected whatKey(code: number): string {
+        switch (code) {
+            case 8: return 'delete';
+            case 9: return 'tab';
+            case 13: return 'enter';
+            case 16: return 'shift';
+            case 27: return 'esc';
+            case 32: return 'space';
+            case 37: return 'leftArrow';
+            case 38: return 'upArrow';
+            case 39: return 'rightArrow';
+            case 40: return 'downArrow';
+            case 186: return 'semicolon';
+            case 187: return 'equals';
+            case 188: return 'comma';
+            case 189: return 'dash';
+            case 190: return 'dot';
+            case 191: return 'slash';
+            case 192: return 'backQuote';
+            case 219: return 'openBracket';
+            case 220: return 'backSlash';
+            case 221: return 'closeBracket';
+            case 222: return 'quote';
+            default:
+                if ((code >= 48 && code <= 57) ||
+                    (code >= 65 && code <= 90)) {
+                    return String.fromCharCode(code);
+                } else if (code >= 112 && code <= 123) {
+                    return 'F' + (code - 111);
+                }
+                return null;
+        }
+    }
+
+    protected textFieldInput() {
+        const t = d3.event.target.tagName.toLowerCase();
+        return t === 'input' || t === 'textarea';
+    }
+
+    protected keyIn() {
+        const event = d3.event;
+        // d3.events can set the keyCode, but unit tests based on KeyboardEvent
+        // cannot set keyCode since the attribute has been deprecated
+        const code = event.keyCode ? event.keyCode : event.code;
+        let key = this.whatKey(Number.parseInt(code));
+        this.log.debug('Key detected', event, key, event.code, event.keyCode);
+        const textBlockable = !this.textFieldDoesNotBlock[key];
+        const modifiers = [];
+
+        if (event.metaKey) {
+            modifiers.push('cmd');
+        }
+        if (event.altKey) {
+            modifiers.push('alt');
+        }
+        if (event.shiftKey) {
+            modifiers.push('shift');
+        }
+
+        if (!key) {
+            return;
+        }
+
+        modifiers.push(key);
+        key = modifiers.join('-');
+
+        if (textBlockable && this.textFieldInput()) {
+            return;
+        }
+
+        const kh: KeyHandler = this.keyHandler;
+        const gk = kh.globalKeys[key];
+        const gcb = this.fs.isF(gk) || (this.fs.isA(gk) && this.fs.isF(gk[0]));
+        const dk = kh.dialogKeys[key];
+        const dcb = this.fs.isF(dk);
+        const vk = kh.viewKeys[key];
+        const kl = this.fs.isF(kh.viewKeys._keyListener);
+        const vcb = this.fs.isF(vk) || (this.fs.isA(vk) && this.fs.isF(vk[0])) || this.fs.isF(kh.viewFn);
+        const token: KeysToken = KeysToken.KEYEV; // indicate this was a key-pressed event
+
+        event.stopPropagation();
+
+        if (this.enabled) {
+            if (this.matchSeq(key)) {
+                return;
+            }
+
+            // global callback?
+            if (gcb && gcb(token, key, code, event)) {
+                // if the event was 'handled', we are done
+                return;
+            }
+            // dialog callback?
+            if (dcb) {
+                dcb(token, key, code, event);
+                // assume dialog handled the event
+                return;
+            }
+            // otherwise, let the view callback have a shot
+            if (vcb) {
+                this.log.debug('Letting view callback have a shot', vcb, token, key, code, event );
+                vcb(token, key, code, event);
+            }
+            if (kl) {
+                kl(key);
+            }
+        }
+    }
+
+    // functions to obtain localized strings deferred from the setup of the
+    //  global key data structures.
+    protected qhlion() {
+        return this.ls.bundle('core.fw.QuickHelp');
+    }
+    protected qhlionShowHide() {
+        return this.qhlion()('qh_hint_show_hide_qh');
+    }
+
+    protected qhlionHintEsc() {
+        return this.qhlion()('qh_hint_esc');
+    }
+
+    protected qhlionHintT() {
+        return this.qhlion()('qh_hint_t');
+    }
+
+    protected setupGlobalKeys() {
+        Object.assign(this.keyHandler, {
+            globalKeys: {
+                backSlash: [(view, key, code, ev) => this.quickHelp(view, key, code, ev), this.qhlionShowHide],
+                slash: [(view, key, code, ev) => this.quickHelp(view, key, code, ev), this.qhlionShowHide],
+                esc: [(view, key, code, ev) => this.escapeKey(view, key, code, ev), this.qhlionHintEsc],
+                T: [(view, key, code, ev) => this.toggleTheme(view, key, code, ev), this.qhlionHintT],
+            },
+            globalFormat: ['backSlash', 'slash', 'esc', 'T'],
+
+            // Masked keys are global key handlers that always return true.
+            // That is, the view will never see the event for that key.
+            maskedKeys: {
+                slash: 1,
+                backSlash: 1,
+                T: 1,
+            },
+        });
+    }
+
+    protected quickHelp(view, key, code, ev) {
+        if (!this.globalEnabled) {
+            return false;
+        }
+        this.qhs.showQuickHelp(this.keyHandler);
+        return true;
+    }
+
+    // returns true if we 'consumed' the ESC keypress, false otherwise
+    protected escapeKey(view, key, code, ev) {
+        return this.ns.hideNav() || this.qhs.hideQuickHelp();
+    }
+
+    protected toggleTheme(view, key, code, ev) {
+        if (!this.globalEnabled) {
+            return false;
+        }
+        // ts.toggleTheme();
+        return true;
+    }
+
+    protected filterMaskedKeys(map: any, caller: any, remove: boolean): any[] {
+        const masked = [];
+        const msgs = [];
+
+        d3.map(map).keys().forEach((key) => {
+            if (this.keyHandler.maskedKeys[key]) {
+                masked.push(key);
+                msgs.push(caller, ': Key "' + key + '" is reserved');
+            }
+        });
+
+        if (msgs.length) {
+            this.log.warn(msgs.join('\n'));
+        }
+
+        if (remove) {
+            masked.forEach((k) => {
+                delete map[k];
+            });
+        }
+        return masked;
+    }
+
+    protected unexParam(fname, x) {
+        this.log.warn(fname, ': unexpected parameter-- ', x);
+    }
+
+    protected setKeyBindings(keyArg) {
+        const fname = 'setKeyBindings()';
+        const kFunc = this.fs.isF(keyArg);
+        const kMap = this.fs.isO(keyArg);
+
+        if (kFunc) {
+            // set general key handler callback
+            this.keyHandler.viewFn = kFunc;
+        } else if (kMap) {
+            this.filterMaskedKeys(kMap, fname, true);
+            this.keyHandler.viewKeys = kMap;
+        } else {
+            this.unexParam(fname, keyArg);
+        }
+    }
+
+    getKeyBindings() {
+        const gkeys = d3.map(this.keyHandler.globalKeys).keys();
+        const masked = d3.map(this.keyHandler.maskedKeys).keys();
+        const vkeys = d3.map(this.keyHandler.viewKeys).keys();
+        const vfn = !!this.fs.isF(this.keyHandler.viewFn);
+
+        return {
+            globalKeys: gkeys,
+            maskedKeys: masked,
+            viewKeys: vkeys,
+            viewFunction: vfn,
+        };
+    }
+
+    protected bindDialogKeys(map) {
+        const fname = 'bindDialogKeys()';
+        const kMap = this.fs.isO(map);
+
+        if (kMap) {
+            this.filterMaskedKeys(map, fname, true);
+            this.keyHandler.dialogKeys = kMap;
+        } else {
+            this.unexParam(fname, map);
+        }
+    }
+
+    protected unbindDialogKeys() {
+        this.keyHandler.dialogKeys = {};
+    }
+
+}
