├── source ├── style │ ├── ils.css │ ├── map.css │ ├── externaldist.css │ ├── button.css │ ├── route.css │ ├── main.js │ ├── load.css │ ├── dep-arr.css │ ├── log.css │ ├── progress.css │ ├── legs.css │ ├── waypoints.css │ ├── vnav.css │ └── modal.css ├── html │ ├── button.html │ ├── tab-contents │ │ ├── map.html │ │ ├── main.js │ │ ├── load.html │ │ ├── log.html │ │ ├── dep-arr.html │ │ ├── legs.html │ │ ├── vnav.html │ │ ├── progress.html │ │ ├── ils.html │ │ └── route.html │ ├── externaldist.html │ └── modal.html ├── get.js ├── config.js ├── ui │ ├── elements.js │ ├── position.js │ ├── main.js │ └── ViewModel.js ├── userscript.js ├── get │ ├── ATS.js │ ├── STAR.js │ ├── runway.js │ ├── waypoint.js │ └── SID.js ├── .jshintrc ├── debug.js ├── nav │ ├── LNAV.js │ ├── progress.js │ ├── VNAV.js │ └── ILS.js ├── data.js ├── path.js ├── init.js ├── log.js ├── redefine.js ├── vnav-profile.js ├── minify.js ├── distance.js ├── utils.js ├── flight.js └── waypoints.js ├── images ├── waypoint.ai ├── waypoint.png ├── ils-markers.png ├── attitude-jet-ils.png ├── waypoint-active.png ├── localizer-indicator.png └── glideslope-indicator.png ├── .jshintignore ├── gefs-build-config.toml ├── .gitignore ├── compile ├── utils.js ├── index.js ├── navaids.js ├── waypoints.js ├── ATS.js ├── runways.js ├── SID.js ├── STAR.js └── approaches.js ├── .jshintrc ├── package.json ├── testing ├── script.js └── index.js ├── README.md └── LICENSE.md /source/style/ils.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/waypoint.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/waypoint.ai -------------------------------------------------------------------------------- /images/waypoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/waypoint.png -------------------------------------------------------------------------------- /source/style/map.css: -------------------------------------------------------------------------------- 1 | div.fmc-map-container { 2 | height: 405px; 3 | width: 700px; 4 | } 5 | -------------------------------------------------------------------------------- /images/ils-markers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/ils-markers.png -------------------------------------------------------------------------------- /images/attitude-jet-ils.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/attitude-jet-ils.png -------------------------------------------------------------------------------- /images/waypoint-active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/waypoint-active.png -------------------------------------------------------------------------------- /images/localizer-indicator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/localizer-indicator.png -------------------------------------------------------------------------------- /images/glideslope-indicator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gefs-plugins/fmc-requirejs/HEAD/images/glideslope-indicator.png -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | LICENSE 2 | .gitignore 3 | .jshintrc 4 | *.json 5 | *.md 6 | *.html 7 | *.css 8 | *.log 9 | node_modules/* 10 | build/* 11 | package/* 12 | -------------------------------------------------------------------------------- /gefs-build-config.toml: -------------------------------------------------------------------------------- 1 | globalVariableName = "fmc" 2 | shortName = "fmc" 3 | crxName = "fmc_requirejs" 4 | 5 | [requirejs] 6 | mainConfigFile = "./build.json" 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | build 4 | compile/data 5 | compile/compiled-data 6 | testing/imagery.js 7 | package 8 | *.pem 9 | ._* 10 | .idea 11 | *.log 12 | package-lock.json 13 | -------------------------------------------------------------------------------- /source/html/button.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /source/html/tab-contents/map.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /source/style/externaldist.css: -------------------------------------------------------------------------------- 1 | div.fmc-prog-info.geofs-f-standard-ui { 2 | position: absolute; 3 | margin-left: 5px; 4 | margin-top: -2px; 5 | } 6 | 7 | div.fmc-prog-info.geofs-f-standard-ui span.mdl-chip.mdl-chip--contact { 8 | padding-right: 12px; 9 | } 10 | -------------------------------------------------------------------------------- /source/get.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define(['get/waypoint', 'get/ATS', 'get/SID', 'get/STAR', 'get/runway', 'exports'], function (a, b, c, d, e, exports) { 4 | exports.waypoint = a; 5 | exports.ATS = b; 6 | exports.SID = c; 7 | exports.STAR = d; 8 | exports.runway = e; 9 | }); 10 | -------------------------------------------------------------------------------- /compile/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | ROOT_FOLDER: 'data/', 5 | readDir: dir => { 6 | let list = []; 7 | require('fs').readdirSync(dir).forEach(function (file) { 8 | if (/\.txt/.test(file)) list.push(file); 9 | }); 10 | 11 | return list; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /source/html/externaldist.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | Dest 4 |  nm 5 | 6 |
7 | -------------------------------------------------------------------------------- /source/config.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | "use strict"; 3 | 4 | requirejs.config({ 5 | urlArgs: '_=' + Date.now(), // Cache bust 6 | paths: { 7 | geodesic: '../node_modules/Leaflet.Geodesic/Leaflet.Geodesic', 8 | knockout: '../node_modules/knockout/build/output/knockout-latest', 9 | text: '../node_modules/text/text' 10 | } 11 | }); 12 | })(); 13 | -------------------------------------------------------------------------------- /source/ui/elements.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define({ 4 | modal: '.fmc-modal', 5 | container: { 6 | tabBar: '.fmc-modal .fmc-modal__tab-bar', 7 | modalContent: '.fmc-modal .fmc-modal__content main', 8 | uiBottomProgInfo: '.geofs-ui-bottom .fmc-prog-info' 9 | }, 10 | btn: { 11 | fmcBtn: 'button.fmc-btn', 12 | interactive: '.interactive' 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /source/style/button.css: -------------------------------------------------------------------------------- 1 | button.fmc-btn, 2 | button.fmc-btn:hover, 3 | button.fmc-btn:active, 4 | button.fmc-btn:focus:not(:active) { 5 | color: white; 6 | background: green; 7 | } 8 | 9 | button.fmc-btn__fade { 10 | transition: opacity 0.2s ease-in-out; 11 | -moz-transition: opacity 0.2s ease-in-out; 12 | -webkit-transition: opacity 0.2s ease-in-out; 13 | } 14 | 15 | button.fmc-btn__fade:hover { 16 | opacity: 0.8; 17 | } 18 | -------------------------------------------------------------------------------- /source/userscript.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Flight Management Computer for GeoFS 3 | // @description This extension adds an FMC which controls features such as VNAV, LNAV, route, progress information, etc. 4 | // @author Harry Xue and Ethan Shields 5 | // @namespace GeoFS-Plugins 6 | // @match http://*/geofs.php* 7 | // @match https://*/geofs.php* 8 | // @run-at document-end 9 | // @version 0.5.5r2 10 | // @grant none 11 | // ==/UserScript== 12 | -------------------------------------------------------------------------------- /source/html/tab-contents/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define([ 4 | 'minify!./route.html', 'minify!./dep-arr.html', 'minify!./legs.html', 5 | 'minify!./vnav.html', 'minify!./ils.html', 'minify!./progress.html', 6 | 'minify!./map.html', 'minify!./load.html', 'minify!./log.html' 7 | ], function (route, depArr, legs, vnav, ils, progress, map, load, log) { 8 | return [route, depArr, legs, vnav, ils, progress, map, load, log].join(''); 9 | }); 10 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { "globals": { "module": true } 2 | , "node": true 3 | , "predef": [ "-Promise" ] 4 | , "varstmt": true 5 | , "esnext": 6 6 | , "laxcomma": true 7 | , "laxbreak": true 8 | , "multistr": true 9 | , "eqeqeq": true 10 | , "smarttabs": true 11 | , "curly": false 12 | , "expr": true 13 | , "devel": true 14 | , "debug": true 15 | , "funcscope": false 16 | , "unused": true 17 | , "bitwise": true 18 | , "-W058": false 19 | , "-W002": false 20 | , "-W004": false 21 | } 22 | -------------------------------------------------------------------------------- /source/get/ATS.js: -------------------------------------------------------------------------------- 1 | "use strict"; // TODO Properly implement 2 | 3 | define(['data', 'log'], function (data, log) { 4 | 5 | function getAirway (startFix, airway, endFix) { 6 | if (!startFix || !endFix) log.warn('There must be one waypoint before and after the airway.'); 7 | 8 | var airwayList = data.ATS[airway]; // jshint unused: false 9 | 10 | var validList; 11 | } 12 | 13 | return function (startFix, airway, endFix) { 14 | return getAirway(startFix, airway, endFix); 15 | }; 16 | 17 | }); 18 | -------------------------------------------------------------------------------- /source/style/route.css: -------------------------------------------------------------------------------- 1 | div.fmc-dep-arr-table-container { 2 | margin-top: -10px; 3 | } 4 | 5 | div.fmc-dep-arr-table-container table { 6 | width: 100%; 7 | } 8 | 9 | div.fmc-dep-arr-table-container .material-icons { 10 | vertical-align: middle; 11 | margin-right: 5px; 12 | } 13 | 14 | div.fmc-dep-arr-table-container div { 15 | width: 80%; 16 | } 17 | 18 | div.fmc-wpt-add-container { 19 | float: right; 20 | } 21 | 22 | div.fmc-modal__actions button[action="add-wpt"] { 23 | min-width: 35px; 24 | width: 35px; height: 35px; 25 | float: right; 26 | } 27 | -------------------------------------------------------------------------------- /compile/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Promise = require('bluebird'); 4 | 5 | const fs = Promise.promisifyAll(require('fs')); 6 | const path = require('path'); 7 | 8 | const waypoints = require('./waypoints'); 9 | const navaids = require('./navaids'); 10 | const airways = require('./ATS'); 11 | const runways = require('./runways'); 12 | 13 | fs.existsAsync(path.join(__dirname, 'compiled-data')).then(exists => { 14 | if (!exists) fs.mkdir('compiled-data'); 15 | 16 | Promise.all([ waypoints, navaids, airways, runways ]) 17 | .then(() => console.log('\nDone!')); 18 | }).catch(console.error); 19 | -------------------------------------------------------------------------------- /source/style/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define([ 4 | 'minify!./button.css', 'minify!./externaldist.css', 'minify!./modal.css', 5 | 'minify!./route.css', 'minify!./waypoints.css', 'minify!./dep-arr.css', 6 | 'minify!./legs.css', 'minify!./vnav.css', 'minify!./ils.css', 7 | 'minify!./progress.css', 'minify!./map.css', 'minify!./load.css', 'minify!./log.css' 8 | ], function ( 9 | button, externalDist, modal, route, waypoints, 10 | depArr, legs, vnav, ils, progress, map, load, log 11 | ) { 12 | return [ 13 | button, externalDist, modal, route, waypoints, 14 | depArr, legs, vnav, ils, progress, map, load, log 15 | ].join(''); 16 | }); 17 | -------------------------------------------------------------------------------- /source/.jshintrc: -------------------------------------------------------------------------------- 1 | { "globals": 2 | { "geofs": true 3 | , "controls": true 4 | , "METERS_TO_FEET": true 5 | , "PAGE_PATH": true 6 | , "autopilot_pp": true 7 | , "componentHandler": true 8 | , "L": true 9 | , "ui": true 10 | , "define": true 11 | , "require": true 12 | , "requirejs": true 13 | , "Promise": true 14 | } 15 | , "laxcomma": true 16 | , "laxbreak": true 17 | , "multistr": true 18 | , "eqeqeq": true 19 | , "smarttabs": true 20 | , "globalstrict": true 21 | , "jquery": true 22 | , "curly": false 23 | , "browser": true 24 | , "expr": true 25 | , "devel": true 26 | , "debug": true 27 | , "funcscope": false 28 | , "unused": true 29 | , "bitwise": true 30 | , "-W004": false 31 | } 32 | -------------------------------------------------------------------------------- /source/get/STAR.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define(['data'], function (data) { 4 | 5 | /** 6 | * Get all STAR info for airport and arrival runway 7 | * 8 | * @param {String} airport 9 | * @returns {Array} The array of STAR 10 | */ 11 | return function (airport, runway) { 12 | if (!airport || !runway) return []; 13 | // FIXME: there still can be a STAR even if there is no arrival runway 14 | 15 | var allSTAR = data.STAR[airport]; 16 | var validSTAR = []; 17 | 18 | if (Array.isArray(allSTAR)) 19 | allSTAR.forEach(function (obj) { 20 | if (obj.runway === runway) validSTAR.push(obj); 21 | }); 22 | 23 | return validSTAR; 24 | }; 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /source/style/load.css: -------------------------------------------------------------------------------- 1 | div.fmc-load-container .mdl-textfield { 2 | width: 420px; 3 | overflow: hidden; 4 | } 5 | 6 | div.fmc-load-container .fmc-load-wpt__label { 7 | font-size: 16px; 8 | font-family: "Helvetica", "Arial", sans-serif; 9 | float: left; 10 | padding: 21px 10px; 11 | } 12 | 13 | div.fmc-load-container .fmc-load-wpt__label .material-icons { 14 | vertical-align: middle; 15 | } 16 | 17 | div.fmc-load-container button.load-wpt { 18 | margin-top: -60px; 19 | } 20 | 21 | div.fmc-load-container .fmc-generate-rte-container { 22 | margin-left: 10px; 23 | } 24 | 25 | div.fmc-load-container .fmc-generate-rte-container textarea { 26 | resize: none; 27 | font-family: monospace; 28 | } 29 | 30 | button.interactive.load-tab { 31 | float: right; 32 | } 33 | -------------------------------------------------------------------------------- /source/debug.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define(['ui/elements'], function (E) { 4 | 5 | // If FMC is production 6 | var PRODUCTION = false; 7 | 8 | // Stops event propagation 9 | function stopPropagation (event) { 10 | event.stopImmediatePropagation(); 11 | } 12 | 13 | return { 14 | /** 15 | * Stops input key propagation 16 | */ 17 | stopPropagation: function () { 18 | $(E.modal) 19 | .keyup(stopPropagation) 20 | .keydown(stopPropagation) 21 | .keypress(stopPropagation); 22 | }, 23 | 24 | /** 25 | * Logs debug statement into console when needed if not PRODUCTION 26 | */ 27 | log: function (text) { 28 | if (!PRODUCTION) console.log(text); 29 | } 30 | }; 31 | }); 32 | -------------------------------------------------------------------------------- /source/style/dep-arr.css: -------------------------------------------------------------------------------- 1 | div.fmc-dep-arr-container { 2 | overflow: hidden; 3 | } 4 | 5 | div.fmc-dep-arr-container .fmc-dep-arr__input-label { 6 | margin-left: 50px; 7 | font-size: 16px; 8 | font-weight: bold; 9 | color: rgba(0, 0, 0, 0.26); 10 | cursor: default; 11 | } 12 | 13 | div.fmc-dep-arr-container td div { 14 | width: 140px; 15 | margin-left: 10px; 16 | position: relative; 17 | } 18 | 19 | div.fmc-dep-arr-container .mdl-textfield__input, 20 | div.fmc-dep-arr-container label { 21 | width: 137px; 22 | } 23 | 24 | div.fmc-auto-tod-container { 25 | position: relative; 26 | left: 28%; 27 | } 28 | 29 | div.fmc-auto-tod-container .mdl-switch { 30 | width: 280px; 31 | } 32 | 33 | div.fmc-auto-tod-container .mdl-switch__label { 34 | font-weight: bold; 35 | cursor: default !important; 36 | } 37 | -------------------------------------------------------------------------------- /source/ui/position.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | define([ 4 | './elements', 'minify!html/button.html', 'minify!html/externaldist.html', 5 | 'minify!html/modal.html', 'html/tab-contents/main', 'style/main' 6 | ], function (E, button, externalDist, modal, tabContents, mainCSS) { 7 | 8 | return new Promise(function (resolve) { 9 | // Main FMC stylesheet 10 | $('