{"id":3351,"date":"2026-02-22T10:46:50","date_gmt":"2026-02-22T15:46:50","guid":{"rendered":"https:\/\/steely.org\/celnav\/?page_id=3351"},"modified":"2026-05-04T09:44:05","modified_gmt":"2026-05-04T13:44:05","slug":"assumed-position","status":"publish","type":"page","link":"https:\/\/steely.org\/celnav\/assumed-position\/","title":{"rendered":"Assumed Position"},"content":{"rendered":"<div style=\"text-align: justify;\">\n\n\n<p class=\"wp-block-paragraph\">The browser must support WebGL, and Javascript must be enabled. These are usually enabled by default. To improve performance, keep the data area turned off (default) using the &#8220;Data&#8221; button. The data area is a text pane at the bottom of the page that appears when data is turned on. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mobile users: finger drags are disabled on the rendering. To scroll-down, drag anywhere else on the page. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Scenario buttons setup various scenarios that are explained in the text.<\/p>\n\n\n\n<!-- Reload page when browser window width is changed so everything gets resized -->\n<script>\n\/\/ Reliable cross\u2011platform orientation detection for WordPress + GlowScript\n(function() {\n\n    function getOrientation() {\n        return window.matchMedia(\"(orientation: portrait)\").matches\n            ? \"portrait\"\n            : \"landscape\";\n    }\n\n    let lastOrientation = getOrientation();\n\n    \/\/ Debounced resize handler\n    let resizeTimer = null;\n\n    window.addEventListener(\"resize\", function() {\n        clearTimeout(resizeTimer);\n        resizeTimer = setTimeout(function() {\n            const current = getOrientation();\n            if (current !== lastOrientation) {\n                lastOrientation = current;\n                location.reload();\n            }\n        }, 150);\n    });\n\n})();\n<\/script>\n\n\n<div style=\"text-align: justify;\">\n\n\n<div id=\"glowscript\" class=\"glowscript\">\n<meta http-equiv=\"Content-Type\" content=\"text\/html; charset=utf-8\">\n<link type=\"text\/css\" href=\"https:\/\/www.glowscript.org\/css\/redmond\/2.1\/jquery-ui.custom.css\" rel=\"stylesheet\" \/>\n<link type=\"text\/css\" href=\"https:\/\/www.glowscript.org\/css\/ide.css\" rel=\"stylesheet\" \/>\n<script type=\"text\/javascript\" src=\"https:\/\/www.glowscript.org\/lib\/jquery\/2.1\/jquery.min.js\"><\/script>\n<script type=\"text\/javascript\" src=\"https:\/\/www.glowscript.org\/lib\/jquery\/2.1\/jquery-ui.custom.min.js\"><\/script>\n<script type=\"text\/javascript\" src=\"https:\/\/www.glowscript.org\/package\/glow.3.2.min.js\"><\/script>\n<script type=\"text\/javascript\" src=\"https:\/\/www.glowscript.org\/package\/RSrun.3.2.min.js\"><\/script>\n<script type=\"text\/javascript\"><!--\/\/--><![CDATA[\/\/><!--\n\n\/\/ START JAVASCRIPT\n;(function() {;\nvar \u03c1\u03c3_modules = {};\nvar log_buffer, preset_clicked, camera_rad, line_radius, marker_radius, damping, preset2_baseline_ptw, preset2_k, gp_slide_factor, ap_slide_degrees, anim_rate, paused, data_off, label_scale;\n\u03c1\u03c3_modules.pythonize = {};\n\n(function(){\n    function strings() {\n        var string_funcs, exclude, name;\n        string_funcs = set(\"capitalize strip lstrip rstrip islower isupper isspace lower upper swapcase center count endswith startswith find rfind index rindex format join ljust rjust partition rpartition replace split rsplit splitlines zfill\".split(\" \"));\n        if (!arguments.length) {\n            exclude = (function(){\n                var s = \u03c1\u03c3_set();\n                s.jsset.add(\"split\");\n                s.jsset.add(\"replace\");\n                return s;\n            })();\n        } else if (arguments[0]) {\n            exclude = Array.prototype.slice.call(arguments);\n        } else {\n            exclude = null;\n        }\n        if (exclude) {\n            string_funcs = string_funcs.difference(set(exclude));\n        }\n        var \u03c1\u03c3_Iter0 = string_funcs;\n        \u03c1\u03c3_Iter0 = ((typeof \u03c1\u03c3_Iter0[Symbol.iterator] === \"function\") ? (\u03c1\u03c3_Iter0 instanceof Map ? \u03c1\u03c3_Iter0.keys() : \u03c1\u03c3_Iter0) : Object.keys(\u03c1\u03c3_Iter0));\n        for (var \u03c1\u03c3_Index0 of \u03c1\u03c3_Iter0) {\n            name = \u03c1\u03c3_Index0;\n            (\u03c1\u03c3_expr_temp = String.prototype)[(typeof name === \"number\" && name < 0) ? \u03c1\u03c3_expr_temp.length + name : name] = (\u03c1\u03c3_expr_temp = \u03c1\u03c3_str.prototype)[(typeof name === \"number\" && name < 0) ? \u03c1\u03c3_expr_temp.length + name : name];\n        }\n    };\n    if (!strings.__module__) Object.defineProperties(strings, {\n        __module__ : {value: \"pythonize\"}\n    });\n\n    \u03c1\u03c3_modules.pythonize.strings = strings;\n})();\nasync function __main__() {\n\"use strict\";\n    var display = canvas;\n    var scene = canvas();\n\n    function round(num, n=0) {return Number(num.toFixed(n))}\n\n    var version, print, arange, __name__, type, \u03c1\u03c3_ls, debug, log_buffer, alat, alon, olat, olon, hsdeg, hadeg, hodeg, gp_dec, gp_gha, ll_vector, ob_vector, alat2, alon2, gp2_dec, gp2_gha, ll2_vector, base_line_radius, line_radius, base_marker_radius, marker_radius, line_radius_change_rate, marker_radius_change_rate, paused, data_off, scene_brightness, bg_color, globe_opacity, R, globe_shininess, globe_texture, globe_color, ua, isMobile, isPortrait, isLandscape, scene, offset, initial_camera_rad, txt, dev_lbl_height, dev_txt_height, all_labels, label_scale, earth, np_vec, gp_vec, gp_vec_original, gp2_vec, upbn, dnbn, lfbn, rtbn, zinbn, zoutbn, gp_slider, ap_slider, speed_slider, rsbn, pause_btn, ssbn, data_bn, mpbn, camera_rad, preset_clicked, uO, uGP, \u03c1\u03c3_unpack, Zn_dir, ob_Zn_curve, ob_lop_label, ob_lop_dir, ob_lop_curve, gp_marker, gp_label, gp2_marker, gp2_label, ap2_marker, ap2_label, fixed_zn2_curve, fixed_ap2_to_int_curve, fixed_lop2_curve, fixed_P2int_marker, lop2_label, Hc2, P2_int, t2_lop, lop2_plane_normal, U_obs, NP, N_obs, E_obs, observer_marker, observer_label, Pint_marker, aval_label_y_offset, aval_label, obea1_label, obea1_curve, obea2_label, obea2_curve, ap_Zn_curve, i, ap_to_int_curve, ap_marker, ap_label, lop_short, dist_label, intercept_label, lop_label, ob_Zn_vec, ob_zn_bearing, fix_marker_ring, fix_marker_point, fix_marker_point_label, t, theta, prev_gp_slider_val, prev_label_scale, not_zoomed, AP_distance_deg, r_AP, AP, P_int, Hc, Ho, lop_plane_normal, nm_distance, ap_zn_label, t_lop, lop_tangent, short_len, p1, p2, dt, ap_Zn_vec, ap_zn_bearing, ap2_Zn_vec, ap2_zn_bearing, ap_lat, ap_lon, fix_distance_nm, fix_marker_pos, L, leak_report, count, obj;\n    version = \u03c1\u03c3_list_decorate([ \"3.2\", \"glowscript\" ]);\n    Array.prototype['+'] = function(r) {return this.concat(r)}\n    Array.prototype['*'] = function(r) {return __array_times_number(this, r)}\n    window.__GSlang = \"vpython\";\n    print = GSprint;\n    arange = range;\n    __name__ = \"__main__\";\n    type = pytype;\n    var strings = \u03c1\u03c3_modules.pythonize.strings;\n\n    strings();\n    \"2\";\n    debug = false;\n    \"4\";\n    log_buffer = \"\";\n    \"6\";\n    async function log(msg) {\n        \"7\";\n        \"8\";\n        log_buffer=log_buffer[\"+\"](msg[\"+\"](\"\\n\"));\n    };\n    if (!log.__argnames__) Object.defineProperties(log, {\n        __argnames__ : {value: [\"msg\"]},\n        __module__ : {value: null}\n    });\n\n    \"11\";\n    async function save_log() {\n        var filename = (arguments[0] === undefined || ( 0 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true)) ? save_log.__defaults__.filename : arguments[0];\n        var \u03c1\u03c3_kwargs_obj = arguments[arguments.length[\"-\"](1)];\n        if (\u03c1\u03c3_kwargs_obj === null || typeof \u03c1\u03c3_kwargs_obj !== \"object\" || \u03c1\u03c3_kwargs_obj [\u03c1\u03c3_kwargs_symbol] !== true) \u03c1\u03c3_kwargs_obj = {};\n        if (Object.prototype.hasOwnProperty.call(\u03c1\u03c3_kwargs_obj, \"filename\")){\n            filename = \u03c1\u03c3_kwargs_obj.filename;\n        }\n        var \u03c1\u03c3_ls, js;\n        \"12\";\n        \"14\";\n        js = \"var blob = new Blob([`\"[\"+\"](log_buffer)[\"+\"](\"`], {type:'text\/plain'});\");\n        \"15\";\n        js=js[\"+\"](\"var url = URL.createObjectURL(blob);\");\n        \"16\";\n        js=js[\"+\"](\"var a = document.createElement('a');\");\n        \"17\";\n        js=js[\"+\"](\"a.href = url;\");\n        \"18\";\n        js=js[\"+\"](\"a.download = '\"[\"+\"](filename)[\"+\"](\"';\"));\n        \"19\";\n        js=js[\"+\"](\"document.body.appendChild(a);\");\n        \"20\";\n        js=js[\"+\"](\"a.click();\");\n        \"21\";\n        js=js[\"+\"](\"document.body.removeChild(a);\");\n        \"23\";\n        window.eval(js);\n    };\n    if (!save_log.__defaults__) Object.defineProperties(save_log, {\n        __defaults__ : {value: {filename:\"glowscript_log.txt\"}},\n        __handles_kwarg_interpolation__ : {value: true},\n        __argnames__ : {value: [\"filename\"]},\n        __module__ : {value: null}\n    });\n\n    \"25\";\n    async function scalar_is_nan(x) {\n        \"26\";\n        return (x !== x && (typeof x !== \"object\" || \u03c1\u03c3_not_equals(x, x)));\n    };\n    if (!scalar_is_nan.__argnames__) Object.defineProperties(scalar_is_nan, {\n        __argnames__ : {value: [\"x\"]},\n        __module__ : {value: null}\n    });\n\n    \"28\";\n    async function vec_is_nan(v) {\n        \"29\";\n        return (await scalar_is_nan(v.x)) || (await scalar_is_nan(v.y)) || (await scalar_is_nan(v.z));\n    };\n    if (!vec_is_nan.__argnames__) Object.defineProperties(vec_is_nan, {\n        __argnames__ : {value: [\"v\"]},\n        __module__ : {value: null}\n    });\n\n    \"31\";\n    async function dump_labels() {\n        var \u03c1\u03c3_ls, s, L, i;\n        \"33\";\n        s = \"LABEL DUMP:\\n\";\n        \"34\";\n        var \u03c1\u03c3_Iter1 = range(len(all_labels));\n        \u03c1\u03c3_Iter1 = ((typeof \u03c1\u03c3_Iter1[Symbol.iterator] === \"function\") ? (\u03c1\u03c3_Iter1 instanceof Map ? \u03c1\u03c3_Iter1.keys() : \u03c1\u03c3_Iter1) : Object.keys(\u03c1\u03c3_Iter1));\n        for (var \u03c1\u03c3_Index1 of \u03c1\u03c3_Iter1) {\n            i = \u03c1\u03c3_Index1;\n            \"35\";\n            L = \u03c1\u03c3_getitem(all_labels, i);\n            \"37\";\n            s=s[\"+\"](\"index=\"[\"+\"](str(i)));\n            \"38\";\n            s=s[\"+\"](\" text=\"[\"+\"](str(L.text)));\n            \"39\";\n            s=s[\"+\"](\" pos=\"[\"+\"](str(L.pos)));\n            \"40\";\n            s=s[\"+\"](\"\\n\");\n        }\n        \"41\";\n        return s;\n    };\n    if (!dump_labels.__module__) Object.defineProperties(dump_labels, {\n        __module__ : {value: null}\n    });\n\n    \"43\";\n    async function save_log_simple(text) {\n        var \u03c1\u03c3_ls, js;\n        \"44\";\n        js = \"var blob = new Blob([`\"[\"+\"](text)[\"+\"](\"`], {type:'text\/plain'});\");\n        \"45\";\n        js=js[\"+\"](\"var url = URL.createObjectURL(blob); window.open(url);\");\n        \"46\";\n        window.eval(js);\n    };\n    if (!save_log_simple.__argnames__) Object.defineProperties(save_log_simple, {\n        __argnames__ : {value: [\"text\"]},\n        __module__ : {value: null}\n    });\n\n    \"50\";\n    alat = 27;\n    \"51\";\n    alon = 1[\"-u\"]()[\"*\"](77.53);\n    \"52\";\n    olat = 27.491;\n    \"53\";\n    olon = 1[\"-u\"]()[\"*\"](77.413667);\n    \"54\";\n    hsdeg = 33.621667;\n    \"55\";\n    hadeg = 33.585;\n    \"56\";\n    hodeg = 33.831667;\n    \"57\";\n    gp_dec = 1[\"-u\"]()[\"*\"](21.3183);\n    \"58\";\n    gp_gha = 48.53;\n    \"59\";\n    ll_vector = (await latlon_to_vector(alat, alon));\n    \"60\";\n    ob_vector = (await latlon_to_vector(olat, olon));\n    \"62\";\n    alat2 = 27;\n    \"63\";\n    alon2 = 1[\"-u\"]()[\"*\"](77.168333);\n    \"71\";\n    gp2_dec = 1[\"-u\"]()[\"*\"](21.338333);\n    \"72\";\n    gp2_gha = 90.021667;\n    \"73\";\n    ll2_vector = (await latlon_to_vector(alat2, alon2));\n    \"76\";\n    base_line_radius = 5e-4;\n    \"77\";\n    line_radius = base_line_radius;\n    \"78\";\n    base_marker_radius = .0013;\n    \"79\";\n    marker_radius = base_marker_radius;\n    \"80\";\n    line_radius_change_rate = 1[\"-u\"]()[\"*\"](.7);\n    \"81\";\n    marker_radius_change_rate = 1[\"-u\"]()[\"*\"](.5);\n    \"84\";\n    paused = false;\n    \"85\";\n    data_off = true;\n    \"89\";\n    async function normalize(angle) {\n        \"90\";\n        return angle[\"%\"](360)[\"+\"](360)[\"%\"](360);\n    };\n    if (!normalize.__argnames__) Object.defineProperties(normalize, {\n        __argnames__ : {value: [\"angle\"]},\n        __module__ : {value: null}\n    });\n\n    \"92\";\n    scene_brightness = .3;\n    \"93\";\n    bg_color = color.black;\n    \"94\";\n    globe_opacity = 1;\n    \"95\";\n    R = 1;\n    \"96\";\n    globe_shininess = 0;\n    \"97\";\n    globe_texture = textures.earth;\n    \"98\";\n    globe_color = vector(.401, .772, .991);\n    \"102\";\n    ua = window.navigator.userAgent.lower();\n    \"103\";\n    isMobile = \u03c1\u03c3_in(\"mobile\", ua) || \u03c1\u03c3_in(\"android\", ua) || \u03c1\u03c3_in(\"iphone\", ua);\n    \"105\";\n    isPortrait = window.innerHeight[\">=\"](window.innerWidth);\n    \"106\";\n    isLandscape = window.innerWidth[\">\"](window.innerHeight);\n    \"109\";\n    scene.lights = \u03c1\u03c3_list_decorate([]);\n    \"112\";\n    if (isMobile) {\n        \"113\";\n        if (isPortrait) {\n            \"114\";\n            scene = \u03c1\u03c3_interpolate_kwargs.call(this, canvas, [\u03c1\u03c3_desugar_kwargs({width: window.innerWidth[\"-\"](1[\"*\"](56)), height: 300, align: \"none\", pixel_ratio: 2, background: bg_color})]);\n            \"115\";\n        } else {\n            \"116\";\n            scene = \u03c1\u03c3_interpolate_kwargs.call(this, canvas, [\u03c1\u03c3_desugar_kwargs({width: window.innerWidth[\"-\"](1[\"*\"](56)), height: window.innerHeight, align: \"none\", pixel_ratio: 2, background: bg_color})]);\n            \"117\";\n        }\n    } else {\n        \"118\";\n        if (isPortrait) {\n            \"119\";\n            offset = 100;\n            \"120\";\n            scene = \u03c1\u03c3_interpolate_kwargs.call(this, canvas, [\u03c1\u03c3_desugar_kwargs({width: window.innerWidth[\"-\"](1[\"*\"](100)), height: window.innerHeight, align: \"none\", pixel_ratio: 2, background: bg_color})]);\n            \"121\";\n        } else {\n            \"122\";\n            scene = \u03c1\u03c3_interpolate_kwargs.call(this, canvas, [\u03c1\u03c3_desugar_kwargs({width: window.innerWidth[\"-\"](1[\"*\"](300)), height: window.innerHeight, align: \"none\", pixel_ratio: 2, background: bg_color})]);\n        }\n    }\n    \"125\";\n    scene.userzoom = false;\n    \"126\";\n    scene.userspin = false;\n    \"127\";\n    scene.userpan = false;\n    (await sleep(.1));\n    \"128\";\n    scene.autoscale = false;\n    \"129\";\n    scene.ambient = color.white[\"*\"](scene_brightness);\n    \"131\";\n    if (isMobile) {\n        \"132\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, print_options, [\u03c1\u03c3_desugar_kwargs({width: window.innerWidth, height: 125})]);\n        \"133\";\n    } else {\n        \"134\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, print_options, [\u03c1\u03c3_desugar_kwargs({width: window.innerWidth[\"-\"](1[\"*\"](17)), height: 125})]);\n    }\n    \"137\";\n    initial_camera_rad = mag(scene.camera.pos);\n    \"140\";\n    txt = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({text: \"https:\/\/steely.org\", pixel_pos: true, pos: vector(scene.width[\"-\"](1[\"*\"](65)), 20, 0), height: 12, box: false, opacity: 0, pixel_scale: true, color: color.gray(.5)})]);\n    \"150\";\n    if (isMobile) {\n        \"151\";\n        dev_lbl_height = 11;\n        \"152\";\n    } else {\n        \"153\";\n        dev_lbl_height = 14;\n        \"156\";\n    }\n    if (isMobile) {\n        \"157\";\n        dev_txt_height = .05;\n        \"158\";\n    } else {\n        \"159\";\n        dev_txt_height = .04;\n    }\n    \"161\";\n    all_labels = \u03c1\u03c3_list_decorate([]);\n    \"162\";\n    label_scale = 1;\n    \"164\";\n    \u03c1\u03c3_interpolate_kwargs.call(this, distant_light, [\u03c1\u03c3_desugar_kwargs({direction: vector(1[\"-u\"]()[\"*\"](1), 0, 0)})]);\n    \"165\";\n    \u03c1\u03c3_interpolate_kwargs.call(this, distant_light, [\u03c1\u03c3_desugar_kwargs({direction: vector(1, 2, 3)})]);\n    \"166\";\n    \u03c1\u03c3_interpolate_kwargs.call(this, distant_light, [\u03c1\u03c3_desugar_kwargs({direction: vector(1[\"-u\"]()[\"*\"](1), 1[\"-u\"]()[\"*\"](2), 1[\"-u\"]()[\"*\"](1))})]);\n    \"168\";\n    async function rotate_camera(x_angle_deg, y_angle_deg) {\n        var \u03c1\u03c3_ls, x_angle, y_angle;\n        \"175\";\n        try {\n            \"177\";\n            x_angle = (await radians(x_angle_deg));\n            \"178\";\n            y_angle = (await radians(y_angle_deg));\n            \"181\";\n            \u03c1\u03c3_interpolate_kwargs.call(scene.camera, scene.camera.rotate, [\u03c1\u03c3_desugar_kwargs({angle: x_angle, axis: vector(1, 0, 0), origin: vector(0, 0, 0)})]);\n            \"184\";\n            \u03c1\u03c3_interpolate_kwargs.call(scene.camera, scene.camera.rotate, [\u03c1\u03c3_desugar_kwargs({angle: y_angle, axis: vector(0, 1, 0), origin: vector(0, 0, 0)})]);\n            \"186\";\n        } catch (\u03c1\u03c3_Exception) {\n            \u03c1\u03c3_last_exception = \u03c1\u03c3_Exception;\n            if (\u03c1\u03c3_Exception instanceof Error) {\n                var e = \u03c1\u03c3_Exception;\n                \"187\";\n                print(\"Error rotating camera: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", e))[\"+\"](\"\"));\n            } else {\n                throw \u03c1\u03c3_Exception;\n            }\n        }\n    };\n    if (!rotate_camera.__argnames__) Object.defineProperties(rotate_camera, {\n        __argnames__ : {value: [\"x_angle_deg\", \"y_angle_deg\"]},\n        __module__ : {value: null}\n    });\n\n    \"190\";\n    earth = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), radius: R, texture: globe_texture, shininess: globe_shininess, opacity: globe_opacity, color: globe_color, res: 128})]);\n    \"194\";\n    async function rotate_around_x(v, angle_rad) {\n        \"195\";\n        return \u03c1\u03c3_interpolate_kwargs.call(v, v.rotate, [\u03c1\u03c3_desugar_kwargs({angle: angle_rad, axis: vector(1, 0, 0)})]);\n    };\n    if (!rotate_around_x.__argnames__) Object.defineProperties(rotate_around_x, {\n        __argnames__ : {value: [\"v\", \"angle_rad\"]},\n        __module__ : {value: null}\n    });\n\n    \"196\";\n    async function rotate_around_y(v, angle_rad) {\n        \"197\";\n        return \u03c1\u03c3_interpolate_kwargs.call(v, v.rotate, [\u03c1\u03c3_desugar_kwargs({angle: angle_rad, axis: vector(0, 1, 0)})]);\n    };\n    if (!rotate_around_y.__argnames__) Object.defineProperties(rotate_around_y, {\n        __argnames__ : {value: [\"v\", \"angle_rad\"]},\n        __module__ : {value: null}\n    });\n\n    \"198\";\n    async function rotate_around_z(v, angle_rad) {\n        \"199\";\n        return \u03c1\u03c3_interpolate_kwargs.call(v, v.rotate, [\u03c1\u03c3_desugar_kwargs({angle: angle_rad, axis: vector(0, 0, 1)})]);\n    };\n    if (!rotate_around_z.__argnames__) Object.defineProperties(rotate_around_z, {\n        __argnames__ : {value: [\"v\", \"angle_rad\"]},\n        __module__ : {value: null}\n    });\n\n    \"201\";\n    async function rotate_like_earth(v) {\n        var \u03c1\u03c3_ls, v1, v2;\n        \"203\";\n        v1 = (await rotate_around_x(v, (await radians(1[\"-u\"]()[\"*\"](90)))));\n        \"204\";\n        v2 = (await rotate_around_y(v1, pi));\n        \"205\";\n        return v2;\n    };\n    if (!rotate_like_earth.__argnames__) Object.defineProperties(rotate_like_earth, {\n        __argnames__ : {value: [\"v\"]},\n        __module__ : {value: null}\n    });\n\n    \"207\";\n    async function latlon_to_vector(lat_deg, lon_deg) {\n        var \u03c1\u03c3_ls, lat_rads, lon_rads, x, y, z, ll_vec, vec_rot_x, vec_rot_y;\n        \"213\";\n        lat_rads = (await radians(lat_deg));\n        \"214\";\n        lon_rads = (await radians(lon_deg));\n        \"216\";\n        x = cos(lat_rads)[\"*\"](cos(lon_rads));\n        \"217\";\n        y = cos(lat_rads)[\"*\"](sin(lon_rads));\n        \"218\";\n        z = sin(lat_rads);\n        \"219\";\n        ll_vec = vector(x, y, z);\n        \"222\";\n        vec_rot_x = (await rotate_around_x(ll_vec, (await radians(1[\"-u\"]()[\"*\"](90)))));\n        \"223\";\n        vec_rot_y = (await rotate_around_y(vec_rot_x, (await radians(1[\"-u\"]()[\"*\"](90)))));\n        \"225\";\n        return vec_rot_y;\n    };\n    if (!latlon_to_vector.__argnames__) Object.defineProperties(latlon_to_vector, {\n        __argnames__ : {value: [\"lat_deg\", \"lon_deg\"]},\n        __module__ : {value: null}\n    });\n\n    \"227\";\n    async function vector_to_latlon(v) {\n        var \u03c1\u03c3_ls, unrot_y, unrot_x, x, y, z, lat_deg, lon_deg;\n        \"235\";\n        unrot_y = (await rotate_around_y(v, (await radians(90))));\n        \"236\";\n        unrot_x = (await rotate_around_x(unrot_y, (await radians(90))));\n        \"238\";\n        x = unrot_x.x;\n        \"239\";\n        y = unrot_x.y;\n        \"240\";\n        z = unrot_x.z;\n        \"243\";\n        lat_deg = (await degrees(asin(z)));\n        \"244\";\n        lon_deg = (await degrees(atan2(y, x)));\n        \"246\";\n        return [lat_deg, lon_deg];\n    };\n    if (!vector_to_latlon.__argnames__) Object.defineProperties(vector_to_latlon, {\n        __argnames__ : {value: [\"v\"]},\n        __module__ : {value: null}\n    });\n\n    \"249\";\n    async function deg_to_dms(dec_deg) {\n        var \u03c1\u03c3_ls, sign, x, total_seconds, deg, rem, minutes, seconds, dec_minutes, dms_string;\n        \"258\";\n        sign = 1;\n        \"259\";\n        if (dec_deg[\"<\"](0)) {\n            \"260\";\n            sign = 1[\"-u\"]()[\"*\"](1);\n        }\n        \"261\";\n        x = abs(dec_deg);\n        \"264\";\n        total_seconds = int(round(x[\"*\"](3600)));\n        \"267\";\n        deg = Math.floor(total_seconds[\"\/\"](3600));\n        \"268\";\n        rem = total_seconds[\"%\"](3600);\n        \"269\";\n        minutes = Math.floor(rem[\"\/\"](60));\n        \"270\";\n        seconds = rem[\"%\"](60);\n        \"273\";\n        dec_minutes = minutes[\"+\"](seconds[\"\/\"](60));\n        \"276\";\n        deg=deg[\"*\"](sign);\n        \"279\";\n        dms_string = \"\"[\"+\"](\u03c1\u03c3_str.format(\"{}\", deg))[\"+\"](\"\u00b0 \")[\"+\"](\u03c1\u03c3_str.format(\"{}\", minutes))[\"+\"](\"' \")[\"+\"](\u03c1\u03c3_str.format(\"{}\", seconds))[\"+\"](\"\\\"\");\n        \"281\";\n        return [deg, minutes, seconds, dec_minutes, sign, dms_string];\n    };\n    if (!deg_to_dms.__argnames__) Object.defineProperties(deg_to_dms, {\n        __argnames__ : {value: [\"dec_deg\"]},\n        __module__ : {value: null}\n    });\n\n    \"284\";\n    async function get_scene_north_pole() {\n        var \u03c1\u03c3_ls, NP, NP_rot;\n        \"285\";\n        NP = vector(0, 0, 1);\n        \"286\";\n        NP_rot = (await rotate_like_earth(NP));\n        \"288\";\n        return NP_rot.norm();\n    };\n    if (!get_scene_north_pole.__module__) Object.defineProperties(get_scene_north_pole, {\n        __module__ : {value: null}\n    });\n\n    \"290\";\n    np_vec = (await get_scene_north_pole());\n    \"294\";\n    async function dec_az_to_cartesian() {\n        var dec_deg = ( 0 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true) ? undefined : arguments[0];\n        var az_deg = ( 1 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true) ? undefined : arguments[1];\n        var globe_radius = (arguments[2] === undefined || ( 2 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true)) ? dec_az_to_cartesian.__defaults__.globe_radius : arguments[2];\n        var \u03c1\u03c3_kwargs_obj = arguments[arguments.length[\"-\"](1)];\n        if (\u03c1\u03c3_kwargs_obj === null || typeof \u03c1\u03c3_kwargs_obj !== \"object\" || \u03c1\u03c3_kwargs_obj [\u03c1\u03c3_kwargs_symbol] !== true) \u03c1\u03c3_kwargs_obj = {};\n        if (Object.prototype.hasOwnProperty.call(\u03c1\u03c3_kwargs_obj, \"globe_radius\")){\n            globe_radius = \u03c1\u03c3_kwargs_obj.globe_radius;\n        }\n        var \u03c1\u03c3_ls, dec_rads, az_rads, x, y, z, vec_rot_x, vec_rot_y;\n        \"305\";\n        if (!((1[\"-u\"]()[\"*\"](90)[\"<=\"](dec_deg) && dec_deg[\"<=\"](90)))) {\n            \"306\";\n            throw new (await ValueError(\"Declination must be between -90 and 90 degrees.\"));\n            \"307\";\n        }\n        if (!((0[\"<=\"](az_deg) && az_deg[\"<=\"](360)))) {\n            \"308\";\n            throw new (await ValueError(\"Azimuth must be between 0 and 360 degrees.\"));\n            \"309\";\n        }\n        if (globe_radius[\"<\"](0)) {\n            \"310\";\n            throw new (await ValueError(\"Globe radius must be non-negative.\"));\n        }\n        \"313\";\n        dec_rads = (await radians(dec_deg));\n        \"314\";\n        az_rads = (await radians(az_deg));\n        \"317\";\n        x = globe_radius[\"*\"](cos(dec_rads))[\"*\"](sin(az_rads));\n        \"318\";\n        y = globe_radius[\"*\"](cos(dec_rads))[\"*\"](cos(az_rads));\n        \"319\";\n        z = globe_radius[\"*\"](sin(dec_rads));\n        \"322\";\n        vec_rot_x = (await rotate_around_x(vector(x, y, z), (await radians(1[\"-u\"]()[\"*\"](90)))));\n        \"323\";\n        vec_rot_y = (await rotate_around_y(vec_rot_x, pi));\n        \"325\";\n        return vec_rot_y;\n    };\n    if (!dec_az_to_cartesian.__annotations__) Object.defineProperties(dec_az_to_cartesian, {\n        __annotations__ : {value: {dec_deg: float, az_deg: float, globe_radius: float}},\n        __defaults__ : {value: {globe_radius:1}},\n        __handles_kwarg_interpolation__ : {value: true},\n        __argnames__ : {value: [\"dec_deg\", \"az_deg\", \"globe_radius\"]},\n        __module__ : {value: null}\n    });\n\n    \"328\";\n    gp_vec = (await dec_az_to_cartesian(gp_dec, gp_gha, R));\n    \"329\";\n    gp_vec_original = gp_vec;\n    \"331\";\n    gp2_vec = (await dec_az_to_cartesian(gp2_dec, gp2_gha, R));\n    \"335\";\n    async function slerp_GP(gp_vec, ob_vector, slide_factor) {\n        var \u03c1\u03c3_ls, u, v, theta, gp_new;\n        \"336\";\n        u = norm(gp_vec);\n        \"337\";\n        v = norm(ob_vector);\n        \"338\";\n        theta = acos(dot(u, v));\n        \"340\";\n        if ((theta === 0 || typeof theta === \"object\" && \u03c1\u03c3_equals(theta, 0))) {\n            \"341\";\n            return R[\"*\"](u);\n        }\n        \"343\";\n        gp_new = sin(1[\"-\"](1[\"*\"](slide_factor))[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](u)[\"+\"](sin(slide_factor[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](v));\n        \"345\";\n        return R[\"*\"](gp_new);\n        \"347\";\n    };\n    if (!slerp_GP.__argnames__) Object.defineProperties(slerp_GP, {\n        __argnames__ : {value: [\"gp_vec\", \"ob_vector\", \"slide_factor\"]},\n        __module__ : {value: null}\n    });\n\n    if (isLandscape) {\n        \"349\";\n        upbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='7,2 2,11 12,11' fill='orange'\/><\\\/svg>\", bind: rotate_up, color: color.orange, background: color.black})]);\n        \"350\";\n        scene.append_to_caption(\" \");\n        \"351\";\n        dnbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='2,3 12,3 7,12' fill='orange'\/><\/svg>\", bind: rotate_down, color: color.orange, background: color.black})]);\n        \"352\";\n        scene.append_to_caption(\" \");\n        \"353\";\n        lfbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='11,2 3,7 11,12' fill='orange'\/><\/svg>\", bind: rotate_left, color: color.orange, background: color.black})]);\n        \"354\";\n        scene.append_to_caption(\" \");\n        \"355\";\n        rtbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='3,2 11,7 3,12' fill='orange'\/><\/svg>\", bind: rotate_right, color: color.orange, background: color.black})]);\n        \"356\";\n        scene.append_to_caption(\" \");\n        \"357\";\n        zinbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">\uff0b<\/span>\", bind: zoom_in, color: color.orange, background: color.black})]);\n        \"358\";\n        scene.append_to_caption(\" \");\n        \"359\";\n        zoutbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">\uff0d<\/span>\", bind: zoom_out, color: color.orange, background: color.black})]);\n        \"360\";\n        scene.append_to_caption(\" \");\n        \"361\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">A +<\/span>\", bind: bigger, color: color.orange, background: color.black})]);\n        \"362\";\n        scene.append_to_caption(\" \");\n        \"363\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">A -<\/span>\", bind: smaller, color: color.orange, background: color.black})]);\n        \"364\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"365\";\n        scene.append_to_caption(\"Scenarios\");\n        \"366\";\n        scene.append_to_caption(\"\\n\");\n        \"367\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"1\", bind: p1_bn_handler, color: color.orange, background: color.black})]);\n        \"368\";\n        scene.append_to_caption(\" \");\n        \"369\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"2\", bind: p2_bn_handler, color: color.orange, background: color.black})]);\n        \"370\";\n        scene.append_to_caption(\" \");\n        \"371\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"3\", bind: p3_bn_handler, color: color.orange, background: color.black})]);\n        \"372\";\n        scene.append_to_caption(\" \");\n        \"373\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"4\", bind: p4_bn_handler, color: color.orange, background: color.black})]);\n        \"374\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"376\";\n        gp_slider = \u03c1\u03c3_interpolate_kwargs.call(this, slider, [\u03c1\u03c3_desugar_kwargs({min: 0, max: .995, value: 0, step: .005, bind: set_gp_factor, left: 0})]);\n        \"377\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, wtext, [\u03c1\u03c3_desugar_kwargs({text: \" GP-1 Radius form Observer\"})]);\n        \"378\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"380\";\n        ap_slider = \u03c1\u03c3_interpolate_kwargs.call(this, slider, [\u03c1\u03c3_desugar_kwargs({min: 0, max: 4, value: 1, step: .01, bind: set_ap_degrees, left: 0})]);\n        \"381\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, wtext, [\u03c1\u03c3_desugar_kwargs({text: \" AP-1 Radius from Observer\"})]);\n        \"382\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"384\";\n        speed_slider = \u03c1\u03c3_interpolate_kwargs.call(this, slider, [\u03c1\u03c3_desugar_kwargs({min: 1, max: 30, value: 10, step: 1, bind: set_speed, left: 0})]);\n        \"385\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, wtext, [\u03c1\u03c3_desugar_kwargs({text: \" Speed\"})]);\n        \"386\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"388\";\n        rsbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"Reset\", bind: reset_page, color: color.orange, background: color.black})]);\n        \"389\";\n        scene.append_to_caption(\" \");\n        \"391\";\n        pause_btn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"Pause\", bind: toggle_pause, color: color.orange, background: color.black})]);\n        \"392\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"394\";\n    } else {\n        \"395\";\n        upbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='7,2 2,11 12,11' fill='orange'\/><\/svg>\", bind: rotate_up, color: color.orange, background: color.black})]);\n        \"396\";\n        scene.append_to_caption(\" \");\n        \"397\";\n        dnbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='2,3 12,3 7,12' fill='orange'\/><\/svg>\", bind: rotate_down, color: color.orange, background: color.black})]);\n        \"398\";\n        scene.append_to_caption(\" \");\n        \"399\";\n        lfbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='11,2 3,7 11,12' fill='orange'\/><\/svg>\", bind: rotate_left, color: color.orange, background: color.black})]);\n        \"400\";\n        scene.append_to_caption(\" \");\n        \"401\";\n        rtbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<svg width='14' height='14'><polygon points='3,2 11,7 3,12' fill='orange'\/><\/svg>\", bind: rotate_right, color: color.orange, background: color.black})]);\n        \"402\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"403\";\n        zinbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">\uff0b<\/span>\", bind: zoom_in, color: color.orange, background: color.black})]);\n        \"404\";\n        scene.append_to_caption(\" \");\n        \"405\";\n        zoutbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">\uff0d<\/span>\", bind: zoom_out, color: color.orange, background: color.black})]);\n        \"406\";\n        scene.append_to_caption(\" \");\n        \"407\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">A +<\/span>\", bind: bigger, color: color.orange, background: color.black})]);\n        \"408\";\n        scene.append_to_caption(\" \");\n        \"409\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"<span class=\\\"notranslate\\\">A -<\/span>\", bind: smaller, color: color.orange, background: color.black})]);\n        \"410\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"411\";\n        scene.append_to_caption(\"Scenarios\");\n        \"412\";\n        scene.append_to_caption(\"\\n\");\n        \"413\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"1\", bind: p1_bn_handler, color: color.orange, background: color.black})]);\n        \"414\";\n        scene.append_to_caption(\" \");\n        \"415\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"2\", bind: p2_bn_handler, color: color.orange, background: color.black})]);\n        \"416\";\n        scene.append_to_caption(\" \");\n        \"417\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"3\", bind: p3_bn_handler, color: color.orange, background: color.black})]);\n        \"418\";\n        scene.append_to_caption(\" \");\n        \"419\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"4\", bind: p4_bn_handler, color: color.orange, background: color.black})]);\n        \"420\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"422\";\n        gp_slider = \u03c1\u03c3_interpolate_kwargs.call(this, slider, [\u03c1\u03c3_desugar_kwargs({min: 0, max: .995, value: 0, step: .005, bind: set_gp_factor, left: 0, length: 200})]);\n        \"423\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, wtext, [\u03c1\u03c3_desugar_kwargs({text: \" GP-1 from OB\"})]);\n        \"424\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"426\";\n        ap_slider = \u03c1\u03c3_interpolate_kwargs.call(this, slider, [\u03c1\u03c3_desugar_kwargs({min: 0, max: 4, value: 1, step: .01, bind: set_ap_degrees, left: 0, length: 200})]);\n        \"427\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, wtext, [\u03c1\u03c3_desugar_kwargs({text: \" AP-1 from OB\"})]);\n        \"428\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"430\";\n        speed_slider = \u03c1\u03c3_interpolate_kwargs.call(this, slider, [\u03c1\u03c3_desugar_kwargs({min: 1, max: 30, value: 10, step: 1, bind: set_speed, left: 0, length: 200})]);\n        \"431\";\n        \u03c1\u03c3_interpolate_kwargs.call(this, wtext, [\u03c1\u03c3_desugar_kwargs({text: \" Speed\"})]);\n        \"432\";\n        scene.append_to_caption(\"\\n\\n\");\n        \"434\";\n        rsbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"Reset\", bind: reset_page, color: color.orange, background: color.black})]);\n        \"435\";\n        scene.append_to_caption(\" \");\n        \"437\";\n        pause_btn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({text: \"Pause\", bind: toggle_pause, color: color.orange, background: color.black})]);\n        \"438\";\n        scene.append_to_caption(\"\\n\\n\");\n    }\n    \"440\";\n    ssbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({bind: ss_bn_handler, text: \"Snapshot \", color: color.orange, background: color.black})]);\n    \"441\";\n    scene.append_to_caption(\" \");\n    \"443\";\n    data_bn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({bind: toggle_data, text: \"Data\", color: color.orange, background: color.black})]);\n    \"444\";\n    scene.append_to_caption(\"\\n\\n\");\n    \"446\";\n    mpbn = \u03c1\u03c3_interpolate_kwargs.call(this, button, [\u03c1\u03c3_desugar_kwargs({bind: mp_bn_handler, text: \"Main Page\", color: color.orange, background: color.black})]);\n    \"447\";\n    scene.append_to_caption(\"\\n\\n\");\n    \"451\";\n    camera_rad = mag(scene.camera.pos);\n    \"453\";\n    async function rotate_left(evt) {\n        \"454\";\n        scene.camera.pos = \u03c1\u03c3_interpolate_kwargs.call(this, rotate, [scene.camera.pos].concat([\u03c1\u03c3_desugar_kwargs({angle: (await radians(1)), axis: vector(0, 1, 0)})]));\n    };\n    if (!rotate_left.__argnames__) Object.defineProperties(rotate_left, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"459\";\n    async function rotate_right(evt) {\n        \"460\";\n        scene.camera.pos = \u03c1\u03c3_interpolate_kwargs.call(this, rotate, [scene.camera.pos].concat([\u03c1\u03c3_desugar_kwargs({angle: 1[\"-u\"]()[\"*\"]((await radians(1))), axis: vector(0, 1, 0)})]));\n    };\n    if (!rotate_right.__argnames__) Object.defineProperties(rotate_right, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"464\";\n    async function rotate_down(evt) {\n        var \u03c1\u03c3_ls, right;\n        \"465\";\n        right = cross(scene.camera.pos, vector(0, 1, 0));\n        \"466\";\n        scene.camera.pos = \u03c1\u03c3_interpolate_kwargs.call(this, rotate, [scene.camera.pos].concat([\u03c1\u03c3_desugar_kwargs({angle: (await radians(1)), axis: right})]));\n    };\n    if (!rotate_down.__argnames__) Object.defineProperties(rotate_down, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"470\";\n    async function rotate_up(evt) {\n        var \u03c1\u03c3_ls, right;\n        \"471\";\n        right = cross(scene.camera.pos, vector(0, 1, 0));\n        \"472\";\n        scene.camera.pos = \u03c1\u03c3_interpolate_kwargs.call(this, rotate, [scene.camera.pos].concat([\u03c1\u03c3_desugar_kwargs({angle: 1[\"-u\"]()[\"*\"]((await radians(1))), axis: right})]));\n    };\n    if (!rotate_up.__argnames__) Object.defineProperties(rotate_up, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"479\";\n    preset_clicked = false;\n    \"481\";\n    async function zoom_in(evt) {\n        var \u03c1\u03c3_ls, first_zoom_after_preset, zoom_factor, line_scale, marker_scale, step;\n        \"482\";\n        \"485\";\n        first_zoom_after_preset = preset_clicked;\n        \"487\";\n        zoom_factor = initial_camera_rad[\"\/\"](camera_rad);\n        \"488\";\n        damping = 1[\"\/\"](1[\"+\"](zoom_factor));\n        \"491\";\n        if (first_zoom_after_preset) {\n            \"493\";\n            line_radius=line_radius[\"*\"](1.15);\n            \"494\";\n            marker_radius=marker_radius[\"*\"](1.05);\n            \"495\";\n        } else {\n            \"497\";\n            line_scale = base_line_radius[\"*\"](Math.pow(zoom_factor, line_radius_change_rate));\n            \"498\";\n            line_radius = max(2e-4, min(9e-4, line_scale));\n            \"500\";\n            marker_scale = base_marker_radius[\"*\"](Math.pow(zoom_factor, marker_radius_change_rate));\n            \"501\";\n            marker_radius = max(5e-4, min(.002, marker_scale));\n        }\n        \"504\";\n        (await update_all_line_radii(line_radius, marker_radius));\n        \"507\";\n        if (first_zoom_after_preset) {\n            \"508\";\n            step = 1[\"-\"](1[\"*\"](.02)[\"*\"](damping));\n            \"509\";\n        } else {\n            \"510\";\n            step = 1[\"-\"](1[\"*\"](.1)[\"*\"](damping));\n        }\n        \"513\";\n        scene.camera.pos = scene.camera.pos[\"*\"](step);\n        \"514\";\n        camera_rad = mag(scene.camera.pos);\n        \"517\";\n        preset_clicked = false;\n    };\n    if (!zoom_in.__argnames__) Object.defineProperties(zoom_in, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"519\";\n    async function zoom_out(evt) {\n        var \u03c1\u03c3_ls, zoom_factor, damping, step, line_scale, marker_scale;\n        \"520\";\n        \"521\";\n        zoom_factor = initial_camera_rad[\"\/\"](camera_rad);\n        \"522\";\n        damping = 1[\"\/\"](1[\"+\"](zoom_factor));\n        \"523\";\n        step = 1[\"+\"](.1[\"*\"](damping));\n        \"524\";\n        scene.camera.pos = scene.camera.pos[\"*\"](step);\n        \"525\";\n        camera_rad = mag(scene.camera.pos);\n        \"526\";\n        line_scale = base_line_radius[\"*\"](Math.pow(zoom_factor, line_radius_change_rate));\n        \"527\";\n        line_radius = max(2e-4, min(9e-4, line_scale));\n        \"528\";\n        marker_scale = base_line_radius[\"*\"](Math.pow(zoom_factor, marker_radius_change_rate));\n        \"529\";\n        marker_radius = max(6e-4, min(8e-4, marker_scale));\n        \"531\";\n        (await update_all_line_radii(line_radius, marker_radius));\n    };\n    if (!zoom_out.__argnames__) Object.defineProperties(zoom_out, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"534\";\n    async function p1_bn_handler(evt) {\n        \"535\";\n        \"536\";\n        preset_clicked = true;\n        \"537\";\n        scene.camera.pos = vector(1[\"-u\"]()[\"*\"](.923145), .487845, .208398);\n        \"538\";\n        scene.camera.axis = vector(.923145, 1[\"-u\"]()[\"*\"](.487845), 1[\"-u\"]()[\"*\"](.208398));\n        \"542\";\n        if (!isMobile && isPortrait) {\n            \"543\";\n            scene.range = .44;\n        }\n        \"545\";\n        line_radius = 2e-4;\n        \"546\";\n        marker_radius = 5e-4;\n        \"547\";\n        (await update_all_line_radii(line_radius, marker_radius));\n        \"548\";\n        gp_slider.value = 0;\n        \"549\";\n        ap_slider.value = 1;\n        \"550\";\n        speed_slider.value = 20;\n    };\n    if (!p1_bn_handler.__argnames__) Object.defineProperties(p1_bn_handler, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"553\";\n    async function p2_bn_handler(evt) {\n        \"554\";\n        \"555\";\n        \"556\";\n        preset_clicked = true;\n        \"557\";\n        scene.camera.pos = vector(1[\"-u\"]()[\"*\"](.923145), .487845, .208398);\n        \"558\";\n        scene.camera.axis = vector(.923145, 1[\"-u\"]()[\"*\"](.487845), 1[\"-u\"]()[\"*\"](.208398));\n        \"562\";\n        if (!isMobile && isPortrait) {\n            \"563\";\n            scene.range = .44;\n        }\n        \"565\";\n        line_radius = 2e-4;\n        \"566\";\n        marker_radius = 5e-4;\n        \"567\";\n        (await update_all_line_radii(line_radius, marker_radius));\n        \"568\";\n        gp_slider.value = .95;\n        \"569\";\n        ap_slider.value = 1;\n        \"570\";\n        speed_slider.value = 20;\n    };\n    if (!p2_bn_handler.__argnames__) Object.defineProperties(p2_bn_handler, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"573\";\n    async function p3_bn_handler(evt) {\n        \"574\";\n        \"575\";\n        preset_clicked = true;\n        \"576\";\n        scene.camera.pos = vector(1[\"-u\"]()[\"*\"](.897114), .474089, .202522);\n        \"577\";\n        scene.camera.axis = vector(.923145, 1[\"-u\"]()[\"*\"](.487845), 1[\"-u\"]()[\"*\"](.208398));\n        \"581\";\n        if (!isMobile && isPortrait) {\n            \"582\";\n            scene.range = .44;\n        }\n        \"584\";\n        line_radius = 2e-4;\n        \"585\";\n        marker_radius = 5e-4;\n        \"586\";\n        (await update_all_line_radii(line_radius, marker_radius));\n        \"587\";\n        gp_slider.value = 0;\n        \"588\";\n        ap_slider.value = .1;\n        \"589\";\n        speed_slider.value = 20;\n    };\n    if (!p3_bn_handler.__argnames__) Object.defineProperties(p3_bn_handler, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"592\";\n    async function p4_bn_handler(evt) {\n        \"593\";\n        \"594\";\n        preset_clicked = true;\n        \"595\";\n        scene.camera.pos = vector(1[\"-u\"]()[\"*\"](.897114), .474089, .202522);\n        \"596\";\n        scene.camera.axis = vector(.923145, 1[\"-u\"]()[\"*\"](.487845), 1[\"-u\"]()[\"*\"](.208398));\n        \"600\";\n        if (!isMobile && isPortrait) {\n            \"601\";\n            scene.range = .44;\n        }\n        \"603\";\n        line_radius = 2e-4;\n        \"604\";\n        marker_radius = 5e-4;\n        \"605\";\n        (await update_all_line_radii(line_radius, marker_radius));\n        \"606\";\n        gp_slider.value = .95;\n        \"607\";\n        ap_slider.value = .1;\n        \"608\";\n        speed_slider.value = 20;\n    };\n    if (!p4_bn_handler.__argnames__) Object.defineProperties(p4_bn_handler, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"611\";\n    async function ss_bn_handler(evt) {\n        \"612\";\n        (await scene.capture(\"CNMM_Snapshot\"));\n        \"614\";\n        ssbn.background = color.white;\n        \"615\";\n        (await sleep(.1));\n        \"616\";\n        ssbn.background = color.black;\n    };\n    if (!ss_bn_handler.__argnames__) Object.defineProperties(ss_bn_handler, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"620\";\n    async function set_gp_factor(evt) {\n        \"621\";\n        \"622\";\n        gp_slide_factor = gp_slider.value;\n    };\n    if (!set_gp_factor.__argnames__) Object.defineProperties(set_gp_factor, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"626\";\n    async function set_ap_degrees(evt) {\n        \"627\";\n        \"628\";\n        ap_slide_degrees = ap_slider.value;\n    };\n    if (!set_ap_degrees.__argnames__) Object.defineProperties(set_ap_degrees, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"632\";\n    async function set_speed(evt) {\n        \"633\";\n        \"634\";\n        anim_rate = speed_slider.value;\n    };\n    if (!set_speed.__argnames__) Object.defineProperties(set_speed, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"637\";\n    async function mp_bn_handler(evt) {\n        \"639\";\n        mpbn.background = color.gray(.5);\n        \"640\";\n        (await sleep(.1));\n        \"641\";\n        mpbn.background = color.black;\n        \"642\";\n        window.open(\"https:\/\/steely.org\/celnav\", \"_blank\");\n    };\n    if (!mp_bn_handler.__argnames__) Object.defineProperties(mp_bn_handler, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"645\";\n    async function reset_page(evt) {\n        \"647\";\n        rsbn.background = color.gray(.5);\n        \"648\";\n        (await sleep(.1));\n        \"649\";\n        rsbn.background = color.black;\n        \"650\";\n        window.location.reload();\n    };\n    if (!reset_page.__argnames__) Object.defineProperties(reset_page, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"652\";\n    async function toggle_pause() {\n        \"653\";\n        \"655\";\n        pause_btn.background = color.gray(.5);\n        \"656\";\n        (await sleep(.1));\n        \"657\";\n        pause_btn.background = color.black;\n        \"658\";\n        paused = !paused;\n        \"659\";\n        pause_btn.text = (paused) ? \"Resume\" : \"Pause\";\n    };\n    if (!toggle_pause.__module__) Object.defineProperties(toggle_pause, {\n        __module__ : {value: null}\n    });\n\n    \"661\";\n    async function toggle_data() {\n        \"662\";\n        \"663\";\n        data_off = !data_off;\n        \"665\";\n        if (data_off) {\n            \"666\";\n            \u03c1\u03c3_interpolate_kwargs.call(this, print_options, [\u03c1\u03c3_desugar_kwargs({clear: true})]);\n            \"667\";\n            data_bn.color = color.orange;\n            \"668\";\n            data_bn.background = color.black;\n            \"669\";\n        } else {\n            \"670\";\n            data_bn.color = color.white;\n            \"671\";\n            data_bn.background = color.green;\n        }\n    };\n    if (!toggle_data.__module__) Object.defineProperties(toggle_data, {\n        __module__ : {value: null}\n    });\n\n    \"674\";\n    async function bigger(evt) {\n        \"675\";\n        \"676\";\n        label_scale=label_scale[\"*\"](1.1);\n    };\n    if (!bigger.__argnames__) Object.defineProperties(bigger, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"678\";\n    async function smaller(evt) {\n        \"679\";\n        \"680\";\n        label_scale=label_scale[\"\/\"](1.1);\n    };\n    if (!smaller.__argnames__) Object.defineProperties(smaller, {\n        __argnames__ : {value: [\"evt\"]},\n        __module__ : {value: null}\n    });\n\n    \"683\";\n    async function update_all_line_radii(line_radius, marker_radius) {\n        \"684\";\n        ob_Zn_curve.radius = line_radius;\n        \"685\";\n        ob_lop_curve.radius = line_radius;\n        \"686\";\n        fixed_zn2_curve.radius = line_radius;\n        \"687\";\n        fixed_ap2_to_int_curve.radius = line_radius[\"+\"](1e-4);\n        \"688\";\n        fixed_lop2_curve.radius = line_radius;\n        \"689\";\n        obea1_curve.radius = line_radius;\n        \"690\";\n        obea2_curve.radius = line_radius;\n        \"691\";\n        ap_Zn_curve.radius = line_radius;\n        \"692\";\n        ap_to_int_curve.radius = line_radius[\"+\"](1e-4);\n        \"693\";\n        lop_short.radius = line_radius;\n        \"694\";\n        gp_marker.radius = marker_radius;\n        \"695\";\n        gp2_marker.radius = marker_radius;\n        \"696\";\n        ap_marker.radius = marker_radius;\n        \"697\";\n        ap2_marker.radius = marker_radius;\n        \"698\";\n        fixed_P2int_marker.radius = marker_radius;\n        \"699\";\n        observer_marker.radius = marker_radius;\n        \"700\";\n        Pint_marker.radius = marker_radius;\n        \"701\";\n        fix_marker_point.radius = marker_radius;\n    };\n    if (!update_all_line_radii.__argnames__) Object.defineProperties(update_all_line_radii, {\n        __argnames__ : {value: [\"line_radius\", \"marker_radius\"]},\n        __module__ : {value: null}\n    });\n\n    \"706\";\n    async function label_Zn_on_curve() {\n        var zn_curve_obj = ( 0 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true) ? undefined : arguments[0];\n        var P_int = ( 1 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true) ? undefined : arguments[1];\n        var gp_vec = ( 2 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true) ? undefined : arguments[2];\n        var zn_lbl_text = (arguments[3] === undefined || ( 3 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true)) ? label_Zn_on_curve.__defaults__.zn_lbl_text : arguments[3];\n        var curve_shift = (arguments[4] === undefined || ( 4 === arguments.length[\"-\"](1) && arguments[arguments.length[\"-\"](1)] !== null && typeof arguments[arguments.length[\"-\"](1)] === \"object\" && arguments[arguments.length[\"-\"](1)] [\u03c1\u03c3_kwargs_symbol] === true)) ? label_Zn_on_curve.__defaults__.curve_shift : arguments[4];\n        var \u03c1\u03c3_kwargs_obj = arguments[arguments.length[\"-\"](1)];\n        if (\u03c1\u03c3_kwargs_obj === null || typeof \u03c1\u03c3_kwargs_obj !== \"object\" || \u03c1\u03c3_kwargs_obj [\u03c1\u03c3_kwargs_symbol] !== true) \u03c1\u03c3_kwargs_obj = {};\n        if (Object.prototype.hasOwnProperty.call(\u03c1\u03c3_kwargs_obj, \"zn_lbl_text\")){\n            zn_lbl_text = \u03c1\u03c3_kwargs_obj.zn_lbl_text;\n        }\n        if (Object.prototype.hasOwnProperty.call(\u03c1\u03c3_kwargs_obj, \"curve_shift\")){\n            curve_shift = \u03c1\u03c3_kwargs_obj.curve_shift;\n        }\n        var \u03c1\u03c3_ls, A, B, dotAB, theta, t, sin_theta, P, final_pos;\n        \"707\";\n        if (zn_curve_obj === null) {\n            \"708\";\n            return;\n        }\n        \"711\";\n        A = norm(P_int);\n        \"712\";\n        B = norm(gp_vec);\n        \"715\";\n        dotAB = dot(A, B);\n        \"716\";\n        if (dotAB[\">\"](1)) {\n            dotAB = 1;\n        }\n        \"717\";\n        if (dotAB[\"<\"](1[\"-u\"]()[\"*\"](1))) {\n            dotAB = 1[\"-u\"]()[\"*\"](1);\n        }\n        \"718\";\n        theta = acos(dotAB);\n        \"720\";\n        if (theta[\"<\"](1e-6)) {\n            \"721\";\n            return;\n        }\n        \"724\";\n        t = .5[\"+\"](curve_shift);\n        \"725\";\n        if (t[\"<\"](0)) {\n            t = 0;\n        }\n        \"726\";\n        if (t[\">\"](1)) {\n            t = 1;\n        }\n        \"729\";\n        sin_theta = sin(theta);\n        \"730\";\n        P = sin(1[\"-\"](1[\"*\"](t))[\"*\"](theta))[\"\/\"](sin_theta)[\"*\"](A)[\"+\"](sin(t[\"*\"](theta))[\"\/\"](sin_theta)[\"*\"](B));\n        \"733\";\n        final_pos = P[\"+\"](norm(P)[\"*\"](0));\n        \"736\";\n        if ((await hasattr(zn_curve_obj, \"zn_label\"))) {\n            \"737\";\n            zn_curve_obj.zn_label.pos = final_pos;\n            \"738\";\n        } else {\n            \"739\";\n            zn_curve_obj.zn_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: final_pos, text: zn_lbl_text, height: dev_lbl_height, box: false, opacity: 0, color: color.cyan})]);\n            \"748\";\n            all_labels.append(zn_curve_obj.zn_label);\n        }\n        \"750\";\n        return zn_curve_obj.zn_label;\n    };\n    if (!label_Zn_on_curve.__defaults__) Object.defineProperties(label_Zn_on_curve, {\n        __defaults__ : {value: {zn_lbl_text:\"Zn\", curve_shift:0}},\n        __handles_kwarg_interpolation__ : {value: true},\n        __argnames__ : {value: [\"zn_curve_obj\", \"P_int\", \"gp_vec\", \"zn_lbl_text\", \"curve_shift\"]},\n        __module__ : {value: null}\n    });\n\n    \"753\";\n    ob_vector = (await latlon_to_vector(olat, olon));\n    \"755\";\n    uO = norm(ob_vector);\n    \"756\";\n    uGP = norm(gp_vec);\n    \"759\";\n    async function draw_observer_Zn(uO, uGP) {\n        var \u03c1\u03c3_ls, ob_Zn_dir, theta, ob_Zn_curve, steps, s, P, k;\n        \"761\";\n        ob_Zn_dir = norm(uGP[\"-\"](1[\"*\"](dot(uGP, uO))[\"*\"](uO)));\n        \"763\";\n        theta = acos(dot(uO, uGP));\n        \"765\";\n        ob_Zn_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.cyan, radius: line_radius})]);\n        \"767\";\n        steps = 100;\n        \"768\";\n        for (var \u03c1\u03c3_Index2 = 0; \u03c1\u03c3_Index2[\"<\"](steps); \u03c1\u03c3_Index2++) {\n            k = \u03c1\u03c3_Index2;\n            \"769\";\n            s = k[\"\/\"](steps[\"-\"](1[\"*\"](1)))[\"*\"](theta);\n            \"770\";\n            P = R[\"*\"](uO[\"*\"](cos(s))[\"+\"](ob_Zn_dir[\"*\"](sin(s))));\n            \"771\";\n            \u03c1\u03c3_interpolate_kwargs.call(ob_Zn_curve, ob_Zn_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: P})]);\n        }\n        \"773\";\n        await \u03c1\u03c3_list_decorate(\u03c1\u03c3_interpolate_kwargs.call(this, label_Zn_on_curve, [ob_Zn_curve, ob_vector, gp_vec, \"OB Zn\"].concat([\u03c1\u03c3_desugar_kwargs({curve_shift: 1[\"-u\"]()[\"*\"](.3)})])));\n        \"775\";\n        return [ob_Zn_dir, ob_Zn_curve];\n    };\n    if (!draw_observer_Zn.__argnames__) Object.defineProperties(draw_observer_Zn, {\n        __argnames__ : {value: [\"uO\", \"uGP\"]},\n        __module__ : {value: null}\n    });\n\n    \"777\";\n    async function update_observer_Zn(ob_Zn_curve, gp_vec, UO) {\n        var \u03c1\u03c3_ls, ob_Zn_dir, theta, steps, s, P, k;\n        \"780\";\n        ob_Zn_dir = norm(uGP[\"-\"](1[\"*\"](dot(gp_vec, UO))[\"*\"](UO)));\n        \"782\";\n        theta = acos(dot(UO, gp_vec));\n        \"784\";\n        steps = 100;\n        \"785\";\n        for (var \u03c1\u03c3_Index3 = 0; \u03c1\u03c3_Index3[\"<\"](steps); \u03c1\u03c3_Index3++) {\n            k = \u03c1\u03c3_Index3;\n            \"786\";\n            s = k[\"\/\"](steps[\"-\"](1[\"*\"](1)))[\"*\"](theta);\n            \"787\";\n            P = R[\"*\"](uO[\"*\"](cos(s))[\"+\"](ob_Zn_dir[\"*\"](sin(s))));\n            \"789\";\n            \u03c1\u03c3_interpolate_kwargs.call(ob_Zn_curve, ob_Zn_curve.modify, [k].concat([\u03c1\u03c3_desugar_kwargs({pos: P})]));\n        }\n        \"791\";\n        await \u03c1\u03c3_list_decorate(\u03c1\u03c3_interpolate_kwargs.call(this, label_Zn_on_curve, [ob_Zn_curve, ob_vector, gp_vec, \"OB Zn\"].concat([\u03c1\u03c3_desugar_kwargs({curve_shift: 1[\"-u\"]()[\"*\"](.4)})])));\n        \"793\";\n        return ob_Zn_curve;\n    };\n    if (!update_observer_Zn.__argnames__) Object.defineProperties(update_observer_Zn, {\n        __argnames__ : {value: [\"ob_Zn_curve\", \"gp_vec\", \"UO\"]},\n        __module__ : {value: null}\n    });\n\n    \"795\";\n    async function draw_observer_LOP(uO, Zn_dir) {\n        var \u03c1\u03c3_ls, ob_lop_dir, d, k, center, r, v, v_hat, t_hat, theta_max, steps, ob_lop_curve, theta, p, i, ob_label_pos, ob_lop_label;\n        \"798\";\n        ob_lop_dir = cross(uO, Zn_dir);\n        \"799\";\n        if (mag(ob_lop_dir)[\"<\"](1e-12)) {\n            \"800\";\n            ob_lop_dir = cross(uO, vector(1, 0, 0));\n            \"801\";\n            if (mag(ob_lop_dir)[\"<\"](1e-12)) {\n                \"802\";\n                ob_lop_dir = cross(uO, vector(0, 1, 0));\n            }\n        }\n        \"803\";\n        ob_lop_dir = norm(ob_lop_dir);\n        \"806\";\n        d = norm(Zn_dir);\n        \"809\";\n        k = dot(d, R[\"*\"](uO));\n        \"812\";\n        center = d[\"*\"](k);\n        \"815\";\n        r = sqrt(R[\"*\"](R)[\"-\"](1[\"*\"](k)[\"*\"](k)));\n        \"818\";\n        v = R[\"*\"](uO)[\"-\"](1[\"*\"](center));\n        \"819\";\n        if (mag(v)[\"<\"](1e-12)) {\n            \"820\";\n            v = cross(d, uO);\n        }\n        \"821\";\n        v_hat = norm(v)[\"*\"](r);\n        \"824\";\n        t_hat = cross(d, v_hat);\n        \"825\";\n        if (mag(t_hat)[\"<\"](1e-12)) {\n            \"826\";\n            t_hat = cross(d, vector(0, 0, 1));\n        }\n        \"827\";\n        t_hat = norm(t_hat);\n        \"830\";\n        theta_max = .25;\n        \"831\";\n        steps = 60;\n        \"833\";\n        ob_lop_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.green, radius: line_radius})]);\n        \"835\";\n        for (var \u03c1\u03c3_Index4 = 0; \u03c1\u03c3_Index4[\"<\"](steps[\"+\"](1)); \u03c1\u03c3_Index4++) {\n            i = \u03c1\u03c3_Index4;\n            \"836\";\n            theta = 1[\"-u\"]()[\"*\"](theta_max)[\"+\"](2[\"*\"](theta_max)[\"*\"](i)[\"\/\"](steps));\n            \"837\";\n            p = center[\"+\"](v_hat[\"*\"](cos(theta)))[\"+\"](t_hat[\"*\"](sin(theta)));\n            \"838\";\n            \u03c1\u03c3_interpolate_kwargs.call(ob_lop_curve, ob_lop_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: p})]);\n        }\n        \"851\";\n        ob_label_pos = ob_lop_curve.point(40).pos;\n        \"852\";\n        ob_lop_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: ob_label_pos, text: \"OB LOP\", color: color.green, box: false, opacity: 0, height: dev_lbl_height, pixel_pos: false})]);\n        \"863\";\n        all_labels.append(ob_lop_label);\n        \"866\";\n        return [ob_lop_label, ob_lop_dir, ob_lop_curve];\n    };\n    if (!draw_observer_LOP.__argnames__) Object.defineProperties(draw_observer_LOP, {\n        __argnames__ : {value: [\"uO\", \"Zn_dir\"]},\n        __module__ : {value: null}\n    });\n\n    \"868\";\n    \u03c1\u03c3_unpack = (await draw_observer_Zn(uO, uGP));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n    Zn_dir = \u03c1\u03c3_unpack[0];\n    ob_Zn_curve = \u03c1\u03c3_unpack[1];\n    \"870\";\n    \u03c1\u03c3_unpack = (await draw_observer_LOP(uO, Zn_dir));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(3, \u03c1\u03c3_unpack);\n    ob_lop_label = \u03c1\u03c3_unpack[0];\n    ob_lop_dir = \u03c1\u03c3_unpack[1];\n    ob_lop_curve = \u03c1\u03c3_unpack[2];\n    \"876\";\n    gp_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: gp_vec, radius: marker_radius, color: color.yellow, make_trail: false})]);\n    \"877\";\n    gp_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: gp_vec, text: \"GP-1\", color: color.yellow, line: false, xoffset: 5, height: dev_lbl_height, box: false, opacity: 0})]);\n    \"887\";\n    all_labels.append(gp_label);\n    \"889\";\n    gp2_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: gp2_vec, radius: marker_radius, color: color.yellow, make_trail: false})]);\n    \"890\";\n    gp2_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: gp2_vec, text: \"GP-2\", color: color.yellow, line: false, xoffset: 5, height: dev_lbl_height, box: false, opacity: 0})]);\n    \"900\";\n    all_labels.append(gp2_label);\n    \"903\";\n    ap2_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: ll2_vector, radius: marker_radius, color: color.red})]);\n    \"905\";\n    ap2_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: ap2_marker.pos, xoffset: 20, yoffset: 1[\"-u\"]()[\"*\"](20), text: \"AP-2\", color: color.red, height: dev_lbl_height, line: true, linecolor: color.red, box: false, opacity: 0})]);\n    \"918\";\n    all_labels.append(ap2_label);\n    \"920\";\n    fixed_zn2_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.cyan, radius: line_radius})]);\n    \"922\";\n    fixed_ap2_to_int_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.magenta, radius: line_radius[\"+\"](1e-4)})]);\n    \"923\";\n    fixed_lop2_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.red, radius: line_radius})]);\n    \"924\";\n    fixed_P2int_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({color: color.black, radius: marker_radius})]);\n    \"926\";\n    async function label_fixed_zn_curve() {\n        var \u03c1\u03c3_ls, mid, idx, P, offset, fixed_zn_label;\n        \"928\";\n        if (fixed_zn2_curve === null) {\n            \"929\";\n            return;\n            \"930\";\n        }\n        if (fixed_zn2_curve.npoints[\"<\"](2)) {\n            \"931\";\n            return;\n        }\n        \"934\";\n        mid = floor(fixed_zn2_curve.npoints[\"\/\"](2));\n        \"937\";\n        idx = floor(.15[\"*\"](fixed_zn2_curve.npoints[\"-\"](1[\"*\"](1))));\n        \"940\";\n        P = fixed_zn2_curve.point(idx).pos;\n        \"943\";\n        offset = norm(P)[\"*\"](.07);\n        \"945\";\n        fixed_zn_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: P[\"+\"](offset), text: \"AP\u20112 Zn\", color: color.cyan, height: dev_lbl_height, box: false, opacity: 0})]);\n        \"954\";\n        all_labels.append(fixed_zn_label);\n    };\n    if (!label_fixed_zn_curve.__module__) Object.defineProperties(label_fixed_zn_curve, {\n        __module__ : {value: null}\n    });\n\n    \"956\";\n    lop2_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), text: \"AP-2 LOP\", color: color.red, box: false, opacity: 0, height: dev_lbl_height, pixel_pos: false})]);\n    \"966\";\n    all_labels.append(lop2_label);\n    \"968\";\n    async function draw_fixed_ap2_lop(AP2, GP2) {\n        var \u03c1\u03c3_ls, Ho2, Hc2, z2_calc, z2_obs, a2, dotp, theta, t, P2_int, steps_arc, u, p, i, axis_zn2, dotp2, theta_zn2, steps_zn2, t2, lop2_dir, n2, v2_hat, t2_hat, theta2_max, steps2, phi, p_end, beyond, offset;\n        \"970\";\n        fixed_ap2_to_int_curve.clear();\n        \"971\";\n        fixed_lop2_curve.clear();\n        \"972\";\n        fixed_zn2_curve.clear();\n        \"975\";\n        Ho2 = (await calc_altitude(ob_vector, GP2));\n        \"976\";\n        if (Ho2[\"<=\"](0)) {\n            \"977\";\n            return null;\n        }\n        \"980\";\n        Hc2 = (await calc_altitude(AP2, GP2));\n        \"983\";\n        z2_calc = (await radians(90[\"-\"](1[\"*\"](Hc2))));\n        \"984\";\n        z2_obs = (await radians(90[\"-\"](1[\"*\"](Ho2))));\n        \"985\";\n        a2 = z2_calc[\"-\"](1[\"*\"](z2_obs));\n        \"988\";\n        dotp = max(1[\"-u\"]()[\"*\"](1), min(1, dot(AP2, GP2)));\n        \"989\";\n        theta = acos(dotp);\n        \"990\";\n        if (theta[\"<\"](1e-12)) {\n            \"991\";\n            return null;\n        }\n        \"993\";\n        t = a2[\"\/\"](theta);\n        \"994\";\n        if (abs(t)[\"<\"](1e-12)) {\n            \"995\";\n            P2_int = AP2;\n            \"996\";\n        } else {\n            \"998\";\n            P2_int = sin(1[\"-\"](1[\"*\"](t))[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](AP2)[\"+\"](sin(t[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](GP2));\n        }\n        \"1000\";\n        P2_int = norm(P2_int);\n        \"1001\";\n        fixed_P2int_marker.pos = P2_int;\n        \"1004\";\n        steps_arc = 40;\n        \"1005\";\n        for (var \u03c1\u03c3_Index5 = 0; \u03c1\u03c3_Index5[\"<\"](steps_arc[\"+\"](1)); \u03c1\u03c3_Index5++) {\n            i = \u03c1\u03c3_Index5;\n            \"1006\";\n            u = i[\"\/\"](steps_arc);\n            \"1008\";\n            p = sin(1[\"-\"](1[\"*\"](u))[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](AP2)[\"+\"](sin(u[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](P2_int));\n            \"1009\";\n            \u03c1\u03c3_interpolate_kwargs.call(fixed_ap2_to_int_curve, fixed_ap2_to_int_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: norm(p)})]);\n        }\n        \"1015\";\n        axis_zn2 = cross(AP2, GP2);\n        \"1016\";\n        if (mag(axis_zn2)[\"<\"](1e-12)) {\n            \"1017\";\n            axis_zn2 = cross(AP2, vector(1, 0, 0));\n        }\n        \"1018\";\n        axis_zn2 = norm(axis_zn2);\n        \"1021\";\n        fixed_zn2_curve.clear();\n        \"1022\";\n        dotp2 = max(1[\"-u\"]()[\"*\"](1), min(1, dot(AP2, GP2)));\n        \"1023\";\n        theta_zn2 = acos(dotp2);\n        \"1025\";\n        steps_zn2 = 60;\n        \"1026\";\n        for (var \u03c1\u03c3_Index6 = 0; \u03c1\u03c3_Index6[\"<\"](steps_zn2[\"+\"](1)); \u03c1\u03c3_Index6++) {\n            i = \u03c1\u03c3_Index6;\n            \"1027\";\n            u = i[\"\/\"](steps_zn2);\n            \"1029\";\n            p = sin(1[\"-\"](1[\"*\"](u))[\"*\"](theta_zn2))[\"\/\"](sin(theta_zn2))[\"*\"](AP2)[\"+\"](sin(u[\"*\"](theta_zn2))[\"\/\"](sin(theta_zn2))[\"*\"](GP2));\n            \"1030\";\n            \u03c1\u03c3_interpolate_kwargs.call(fixed_zn2_curve, fixed_zn2_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: norm(p)})]);\n        }\n        \"1032\";\n        (await label_fixed_zn_curve());\n        \"1039\";\n        t2 = cross(axis_zn2, P2_int);\n        \"1040\";\n        t2 = norm(t2);\n        \"1043\";\n        lop2_dir = norm(cross(P2_int, t2));\n        \"1046\";\n        n2 = cross(P2_int, lop2_dir);\n        \"1047\";\n        if (mag(n2)[\"<\"](1e-12)) {\n            \"1048\";\n            return null;\n        }\n        \"1049\";\n        n2 = norm(n2);\n        \"1052\";\n        v2_hat = norm(P2_int)[\"*\"](R);\n        \"1053\";\n        t2_hat = cross(n2, v2_hat);\n        \"1054\";\n        if (mag(t2_hat)[\"<\"](1e-12)) {\n            \"1055\";\n            t2_hat = cross(n2, vector(0, 0, 1));\n        }\n        \"1056\";\n        t2_hat = norm(t2_hat);\n        \"1059\";\n        theta2_max = .25;\n        \"1060\";\n        steps2 = 60;\n        \"1062\";\n        fixed_lop2_curve.clear();\n        \"1063\";\n        for (var \u03c1\u03c3_Index7 = 0; \u03c1\u03c3_Index7[\"<\"](steps2[\"+\"](1)); \u03c1\u03c3_Index7++) {\n            i = \u03c1\u03c3_Index7;\n            \"1064\";\n            phi = 1[\"-u\"]()[\"*\"](theta2_max)[\"+\"](2[\"*\"](theta2_max)[\"*\"](i)[\"\/\"](steps2));\n            \"1065\";\n            p = v2_hat[\"*\"](cos(phi))[\"+\"](t2_hat[\"*\"](sin(phi)));\n            \"1066\";\n            \u03c1\u03c3_interpolate_kwargs.call(fixed_lop2_curve, fixed_lop2_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: p})]);\n        }\n        \"1069\";\n        p_end = fixed_lop2_curve.point(fixed_lop2_curve.npoints[\"-\"](1[\"*\"](1))).pos;\n        \"1070\";\n        beyond = p_end[\"+\"](.025[\"*\"](lop2_dir));\n        \"1071\";\n        offset = 0[\"*\"](norm(scene.camera.pos[\"-\"](1[\"*\"](beyond))));\n        \"1072\";\n        lop2_label.pos = beyond[\"+\"](offset);\n        \"1075\";\n        return [fixed_ap2_to_int_curve, fixed_lop2_curve, Hc2, P2_int, t2, n2];\n    };\n    if (!draw_fixed_ap2_lop.__argnames__) Object.defineProperties(draw_fixed_ap2_lop, {\n        __argnames__ : {value: [\"AP2\", \"GP2\"]},\n        __module__ : {value: null}\n    });\n\n    \"1077\";\n    \u03c1\u03c3_unpack = (await draw_fixed_ap2_lop(ll2_vector, gp2_vec));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(6, \u03c1\u03c3_unpack);\n    fixed_ap2_to_int_curve = \u03c1\u03c3_unpack[0];\n    fixed_lop2_curve = \u03c1\u03c3_unpack[1];\n    Hc2 = \u03c1\u03c3_unpack[2];\n    P2_int = \u03c1\u03c3_unpack[3];\n    t2_lop = \u03c1\u03c3_unpack[4];\n    lop2_plane_normal = \u03c1\u03c3_unpack[5];\n    \"1083\";\n    U_obs = norm(ob_vector);\n    \"1084\";\n    NP = norm(np_vec);\n    \"1087\";\n    N_obs = NP[\"-\"](1[\"*\"](dot(NP, U_obs))[\"*\"](U_obs));\n    \"1088\";\n    N_obs = norm(N_obs);\n    \"1091\";\n    E_obs = norm(cross(N_obs, U_obs));\n    \"1100\";\n    observer_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: ob_vector, radius: marker_radius, color: color.green, opacity: .8, linecolor: color.green, line: false})]);\n    \"1110\";\n    observer_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: ob_vector, xoffset: 1[\"-u\"]()[\"*\"](50), yoffset: 1[\"-u\"]()[\"*\"](10), text: \"OB\", height: dev_lbl_height, color: color.green, line: true, linecolor: color.green, box: false, opacity: 0})]);\n    \"1123\";\n    all_labels.append(observer_label);\n    \"1126\";\n    Pint_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({radius: marker_radius, color: color.black, make_trail: false})]);\n    \"1134\";\n    if (isMobile) {\n        \"1135\";\n        aval_label_y_offset = 63;\n        \"1136\";\n    } else {\n        \"1137\";\n        aval_label_y_offset = 65;\n    }\n    \"1139\";\n    aval_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), text: \"\", xoffset: 0, yoffset: aval_label_y_offset, height: dev_lbl_height, box: false, color: color.magenta, linecolor: color.magenta, opacity: 0, line: false})]);\n    \"1152\";\n    all_labels.append(aval_label);\n    \"1158\";\n    async function draw_observer_ea_circle(ob_vector, gp_vec, ea_label_shift, obea_lbl_text) {\n        var \u03c1\u03c3_ls, Ho, r, temp, u, v, obea_curve, steps, phi, p, i, obea_label_pos, obea_label_offset, obea_label;\n        \"1160\";\n        Ho = (await calc_altitude(ob_vector, gp_vec));\n        \"1161\";\n        if (Ho[\"<=\"](0)) {\n            \"1162\";\n            return null;\n        }\n        \"1164\";\n        r = (await radians(90[\"-\"](1[\"*\"](Ho))));\n        \"1166\";\n        if (abs(gp_vec.x)[\">\"](abs(gp_vec.y))) {\n            \"1167\";\n            temp = vector(gp_vec.z, 0, 1[\"-u\"]()[\"*\"](gp_vec.x));\n            \"1168\";\n        } else {\n            \"1169\";\n            temp = vector(0, 1[\"-u\"]()[\"*\"](gp_vec.z), gp_vec.y);\n        }\n        \"1171\";\n        u = norm(cross(gp_vec, temp));\n        \"1172\";\n        v = cross(gp_vec, u);\n        \"1174\";\n        obea_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.yellow, radius: line_radius})]);\n        \"1175\";\n        steps = 361;\n        \"1176\";\n        for (var \u03c1\u03c3_Index8 = 0; \u03c1\u03c3_Index8[\"<\"](steps[\"+\"](1)); \u03c1\u03c3_Index8++) {\n            i = \u03c1\u03c3_Index8;\n            \"1177\";\n            phi = 2[\"*\"](pi)[\"*\"](i)[\"\/\"](steps);\n            \"1178\";\n            p = gp_vec[\"*\"](cos(r))[\"+\"](u[\"*\"](cos(phi))[\"+\"](v[\"*\"](sin(phi)))[\"*\"](sin(r)));\n            \"1179\";\n            \u03c1\u03c3_interpolate_kwargs.call(obea_curve, obea_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: norm(p)})]);\n        }\n        \"1183\";\n        obea_label_pos = \u03c1\u03c3_getitem(obea_curve.point(ea_label_shift), \"pos\");\n        \"1184\";\n        obea_label_offset = 1.01;\n        \"1185\";\n        obea_label_pos = norm(obea_label_pos)[\"*\"](R)[\"*\"](obea_label_offset);\n        \"1187\";\n        obea_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: obea_label_pos, text: obea_lbl_text, height: dev_lbl_height, color: color.yellow, align: \"center\", box: false, opacity: 0})]);\n        \"1196\";\n        all_labels.append(obea_label);\n        \"1198\";\n        return [obea_label, obea_curve];\n    };\n    if (!draw_observer_ea_circle.__argnames__) Object.defineProperties(draw_observer_ea_circle, {\n        __argnames__ : {value: [\"ob_vector\", \"gp_vec\", \"ea_label_shift\", \"obea_lbl_text\"]},\n        __module__ : {value: null}\n    });\n\n    \"1200\";\n    \u03c1\u03c3_unpack = await \u03c1\u03c3_list_decorate(\u03c1\u03c3_interpolate_kwargs.call(this, draw_observer_ea_circle, [ob_vector, gp_vec, 40].concat([\u03c1\u03c3_desugar_kwargs({obea_lbl_text: \"OB Equal\\nAltitudes-1\"})])));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n    obea1_label = \u03c1\u03c3_unpack[0];\n    obea1_curve = \u03c1\u03c3_unpack[1];\n    \"1201\";\n    \u03c1\u03c3_unpack = await \u03c1\u03c3_list_decorate(\u03c1\u03c3_interpolate_kwargs.call(this, draw_observer_ea_circle, [ob_vector, gp2_vec, 330].concat([\u03c1\u03c3_desugar_kwargs({obea_lbl_text: \"OB Equal\\nAltitudes-2\"})])));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n    obea2_label = \u03c1\u03c3_unpack[0];\n    obea2_curve = \u03c1\u03c3_unpack[1];\n    \"1203\";\n    async function update_obea1_curve(ob_vector, gp_vec) {\n        var \u03c1\u03c3_ls, Ho, r, temp, u, v, N, phi, p, i, obea1_lbl_shift, obea1_label_pos, obea1_label_offset;\n        \"1205\";\n        Ho = (await calc_altitude(ob_vector, gp_vec));\n        \"1212\";\n        r = (await radians(90[\"-\"](1[\"*\"](Ho))));\n        \"1215\";\n        if (abs(gp_vec.x)[\">\"](abs(gp_vec.y))) {\n            \"1216\";\n            temp = vector(gp_vec.z, 0, 1[\"-u\"]()[\"*\"](gp_vec.x));\n            \"1217\";\n        } else {\n            \"1218\";\n            temp = vector(0, 1[\"-u\"]()[\"*\"](gp_vec.z), gp_vec.y);\n        }\n        \"1220\";\n        u = norm(cross(gp_vec, temp));\n        \"1221\";\n        v = cross(gp_vec, u);\n        \"1223\";\n        N = 361;\n        \"1226\";\n        for (var \u03c1\u03c3_Index9 = 0; \u03c1\u03c3_Index9[\"<\"](N[\"+\"](1)); \u03c1\u03c3_Index9++) {\n            i = \u03c1\u03c3_Index9;\n            \"1227\";\n            phi = 2[\"*\"](pi)[\"*\"](i)[\"\/\"](N);\n            \"1228\";\n            p = gp_vec[\"*\"](cos(r))[\"+\"](u[\"*\"](cos(phi))[\"+\"](v[\"*\"](sin(phi)))[\"*\"](sin(r)));\n            \"1230\";\n            \u03c1\u03c3_interpolate_kwargs.call(obea1_curve, obea1_curve.modify, [i].concat([\u03c1\u03c3_desugar_kwargs({pos: norm(p)})]));\n        }\n        \"1233\";\n        obea1_lbl_shift = 40;\n        \"1234\";\n        obea1_label_pos = \u03c1\u03c3_getitem(obea1_curve.point(obea1_lbl_shift), \"pos\");\n        \"1235\";\n        obea1_label_offset = 1.01;\n        \"1236\";\n        obea1_label.pos = norm(obea1_label_pos)[\"*\"](R)[\"*\"](obea1_label_offset);\n        \"1238\";\n        return obea1_curve;\n    };\n    if (!update_obea1_curve.__argnames__) Object.defineProperties(update_obea1_curve, {\n        __argnames__ : {value: [\"ob_vector\", \"gp_vec\"]},\n        __module__ : {value: null}\n    });\n\n    \"1244\";\n    async function AP_from_OBS(OBS, N_obs, E_obs, r, theta) {\n        var \u03c1\u03c3_ls, tangential;\n        \"1247\";\n        tangential = cos(theta)[\"*\"](N_obs)[\"+\"](sin(theta)[\"*\"](E_obs));\n        \"1248\";\n        return norm(cos(r)[\"*\"](OBS)[\"+\"](sin(r)[\"*\"](tangential)));\n    };\n    if (!AP_from_OBS.__argnames__) Object.defineProperties(AP_from_OBS, {\n        __argnames__ : {value: [\"OBS\", \"N_obs\", \"E_obs\", \"r\", \"theta\"]},\n        __module__ : {value: null}\n    });\n\n    \"1254\";\n    async function calc_altitude(P_vec, GP_vec) {\n        var \u03c1\u03c3_ls, z;\n        \"1255\";\n        z = acos(dot(P_vec, GP_vec));\n        \"1256\";\n        return 90[\"-\"](1[\"*\"]((await degrees(z))));\n    };\n    if (!calc_altitude.__argnames__) Object.defineProperties(calc_altitude, {\n        __argnames__ : {value: [\"P_vec\", \"GP_vec\"]},\n        __module__ : {value: null}\n    });\n\n    \"1262\";\n    ap_Zn_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.cyan, radius: line_radius})]);\n    \"1263\";\n    for (var \u03c1\u03c3_Index10 = 0; \u03c1\u03c3_Index10[\"<\"](41); \u03c1\u03c3_Index10++) {\n        i = \u03c1\u03c3_Index10;\n        \"1264\";\n        \u03c1\u03c3_interpolate_kwargs.call(ap_Zn_curve, ap_Zn_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0)})]);\n    }\n    \"1267\";\n    ap_to_int_curve = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({color: color.magenta, radius: line_radius[\"+\"](1e-4)})]);\n    \"1268\";\n    for (var \u03c1\u03c3_Index11 = 0; \u03c1\u03c3_Index11[\"<\"](41); \u03c1\u03c3_Index11++) {\n        i = \u03c1\u03c3_Index11;\n        \"1269\";\n        \u03c1\u03c3_interpolate_kwargs.call(ap_to_int_curve, ap_to_int_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0)})]);\n    }\n    \"1272\";\n    ap_marker = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: ll_vector, radius: marker_radius, color: color.red, make_trail: false, retain: 5, interval: 10, trail_type: \"points\"})]);\n    \"1274\";\n    ap_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), xoffset: 10, yoffset: 10, text: \"AP-1\", color: color.red, height: dev_lbl_height, line: true, linecolor: color.red, box: false, opacity: 0})]);\n    \"1286\";\n    all_labels.append(ap_label);\n    \"1288\";\n    async function calc_azimuth(AP, GP) {\n        var \u03c1\u03c3_ls, up, global_north, north, east, dir_vec, x, y, az;\n        \"1295\";\n        up = norm(AP);\n        \"1298\";\n        global_north = vector(0, 1, 0);\n        \"1299\";\n        north = global_north[\"-\"](1[\"*\"](dot(global_north, up))[\"*\"](up));\n        \"1300\";\n        north = norm(north);\n        \"1303\";\n        east = cross(north, up);\n        \"1306\";\n        dir_vec = GP[\"-\"](1[\"*\"](dot(GP, up))[\"*\"](up));\n        \"1307\";\n        dir_vec = norm(dir_vec);\n        \"1310\";\n        x = dot(dir_vec, east);\n        \"1311\";\n        y = dot(dir_vec, north);\n        \"1314\";\n        az = atan2(x, y);\n        \"1315\";\n        if (az[\"<\"](0)) {\n            \"1316\";\n            az=az[\"+\"](2[\"*\"](pi));\n        }\n        \"1318\";\n        return az;\n    };\n    if (!calc_azimuth.__argnames__) Object.defineProperties(calc_azimuth, {\n        __argnames__ : {value: [\"AP\", \"GP\"]},\n        __module__ : {value: null}\n    });\n\n    \"1320\";\n    async function compute_lop_directions(AP_vec, GP_vec, P_int) {\n        var \u03c1\u03c3_ls, A_hat, G_hat, plane_n, tmp, t_lop, lop_dir;\n        \"1321\";\n        A_hat = norm(AP_vec);\n        \"1322\";\n        G_hat = norm(GP_vec);\n        \"1325\";\n        plane_n = cross(A_hat, G_hat);\n        \"1326\";\n        if (mag(plane_n)[\"<\"](1e-8)) {\n            \"1327\";\n            tmp = vector(0, 1, 0);\n            \"1328\";\n            if (abs(dot(tmp, A_hat))[\">\"](.9)) {\n                \"1329\";\n                tmp = vector(1, 0, 0);\n            }\n            \"1330\";\n            plane_n = cross(A_hat, tmp);\n        }\n        \"1331\";\n        plane_n = norm(plane_n);\n        \"1334\";\n        t_lop = cross(plane_n, P_int);\n        \"1335\";\n        t_lop = norm(t_lop);\n        \"1338\";\n        lop_dir = norm(cross(P_int, t_lop));\n        \"1340\";\n        return [t_lop, lop_dir];\n    };\n    if (!compute_lop_directions.__argnames__) Object.defineProperties(compute_lop_directions, {\n        __argnames__ : {value: [\"AP_vec\", \"GP_vec\", \"P_int\"]},\n        __module__ : {value: null}\n    });\n\n    \"1342\";\n    async function draw_short_lop(AP, GP, P_int, lop_short) {\n        var \u03c1\u03c3_ls, axis_zn, t, lop_dir, n_lop, v_hat, t_hat, theta_max, steps, theta, p, i, p_end, beyond, offset;\n        \"1347\";\n        axis_zn = cross(AP, GP);\n        \"1348\";\n        if (mag(axis_zn)[\"<\"](1e-12)) {\n            \"1349\";\n            axis_zn = cross(AP, vector(1, 0, 0));\n        }\n        \"1350\";\n        axis_zn = norm(axis_zn);\n        \"1353\";\n        t = cross(axis_zn, P_int);\n        \"1354\";\n        t = norm(t);\n        \"1357\";\n        lop_dir = norm(cross(P_int, t));\n        \"1364\";\n        n_lop = cross(P_int, lop_dir);\n        \"1365\";\n        if (mag(n_lop)[\"<\"](1e-12)) {\n            \"1366\";\n            return null;\n        }\n        \"1367\";\n        n_lop = norm(n_lop);\n        \"1370\";\n        v_hat = norm(P_int)[\"*\"](R);\n        \"1373\";\n        t_hat = cross(n_lop, v_hat);\n        \"1374\";\n        if (mag(t_hat)[\"<\"](1e-12)) {\n            \"1375\";\n            t_hat = cross(n_lop, vector(0, 0, 1));\n        }\n        \"1376\";\n        t_hat = norm(t_hat);\n        \"1379\";\n        theta_max = .25;\n        \"1380\";\n        steps = 60;\n        \"1382\";\n        for (var \u03c1\u03c3_Index12 = 0; \u03c1\u03c3_Index12[\"<\"](steps[\"+\"](1)); \u03c1\u03c3_Index12++) {\n            i = \u03c1\u03c3_Index12;\n            \"1383\";\n            theta = 1[\"-u\"]()[\"*\"](theta_max)[\"+\"](2[\"*\"](theta_max)[\"*\"](i)[\"\/\"](steps));\n            \"1384\";\n            p = v_hat[\"*\"](cos(theta))[\"+\"](t_hat[\"*\"](sin(theta)));\n            \"1386\";\n            \u03c1\u03c3_interpolate_kwargs.call(lop_short, lop_short.modify, [i].concat([\u03c1\u03c3_desugar_kwargs({pos: p})]));\n        }\n        \"1390\";\n        p_end = lop_short.point(lop_short.npoints[\"-\"](1[\"*\"](1))).pos;\n        \"1393\";\n        beyond = p_end[\"+\"](.01[\"*\"](lop_dir));\n        \"1396\";\n        offset = .03[\"*\"](norm(scene.camera.pos[\"-\"](1[\"*\"](beyond))));\n        \"1398\";\n        lop_label.pos = beyond[\"+\"](offset);\n        \"1399\";\n        lop_label.axis = scene.camera.pos[\"-\"](1[\"*\"](lop_label.pos));\n        \"1402\";\n        return n_lop;\n    };\n    if (!draw_short_lop.__argnames__) Object.defineProperties(draw_short_lop, {\n        __argnames__ : {value: [\"AP\", \"GP\", \"P_int\", \"lop_short\"]},\n        __module__ : {value: null}\n    });\n\n    \"1407\";\n    async function update_lop(AP, GP) {\n        var \u03c1\u03c3_ls, Ho, Hc, z_calc, z_obs, a, tora, a_deg, \u03c1\u03c3_unpack, deg, minutes, seconds, dec_minutes, sign, dms_string, central_angle, nm_distance, ob_gp_cent_angle, ob_gp_nm_dist, dotp, theta, t, P_int, steps_arc, u, p, i, lop_dir;\n        \"1412\";\n        Ho = (await calc_altitude(ob_vector, GP));\n        \"1413\";\n        if (Ho[\"<=\"](0)) {\n            \"1414\";\n            return null;\n        }\n        \"1417\";\n        Hc = (await calc_altitude(AP, GP));\n        \"1420\";\n        z_calc = (await radians(90[\"-\"](1[\"*\"](Hc))));\n        \"1421\";\n        z_obs = (await radians(90[\"-\"](1[\"*\"](Ho))));\n        \"1422\";\n        a = z_calc[\"-\"](1[\"*\"](z_obs));\n        \"1425\";\n        if (Hc[\">\"](Ho)) {\n            \"1426\";\n            tora = \"Away\";\n            \"1427\";\n        } else {\n            \"1428\";\n            tora = \"Toward\";\n        }\n        \"1430\";\n        a_deg = (await degrees(a));\n        \"1431\";\n        \u03c1\u03c3_unpack = (await deg_to_dms(a_deg));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(6, \u03c1\u03c3_unpack);\n        deg = \u03c1\u03c3_unpack[0];\n        minutes = \u03c1\u03c3_unpack[1];\n        seconds = \u03c1\u03c3_unpack[2];\n        dec_minutes = \u03c1\u03c3_unpack[3];\n        sign = \u03c1\u03c3_unpack[4];\n        dms_string = \u03c1\u03c3_unpack[5];\n        \"1432\";\n        aval_label.text = \"a-value: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", deg))[\"+\"](\"\u00b0 \")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", dec_minutes))[\"+\"](\"' \")[\"+\"](\u03c1\u03c3_str.format(\"{}\", tora))[\"+\"](\"\");\n        \"1435\";\n        central_angle = ob_vector.diff_angle(AP);\n        \"1438\";\n        nm_distance = (await degrees(central_angle))[\"*\"](60);\n        \"1440\";\n        ob_gp_cent_angle = ob_vector.diff_angle(gp_vec);\n        \"1441\";\n        ob_gp_nm_dist = (await degrees(ob_gp_cent_angle))[\"*\"](60);\n        \"1443\";\n        dist_label.text = \"Ho: \"[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", Ho))[\"+\"](\"\u00b0   AP-1 Hc: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", Hc))[\"+\"](\"\u00b0  AP-2 Hc: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", Hc2))[\"+\"](\"\u00b0\\nAP-1 to OB dist.: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.1f}\", nm_distance))[\"+\"](\" NM   GP-1 to OB dist.: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.1f}\", ob_gp_nm_dist))[\"+\"](\" NM\\nFix distance from observer: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", fix_distance_nm))[\"+\"](\" NM\");\n        \"1446\";\n        dotp = max(1[\"-u\"]()[\"*\"](1), min(1, dot(AP, GP)));\n        \"1447\";\n        theta = acos(dotp);\n        \"1449\";\n        if (theta[\"<\"](1e-12)) {\n            \"1450\";\n            return null;\n        }\n        \"1453\";\n        t = a[\"\/\"](theta);\n        \"1455\";\n        if (abs(t)[\"<\"](1e-12)) {\n            \"1456\";\n            P_int = AP;\n            \"1457\";\n        } else {\n            \"1459\";\n            P_int = sin(1[\"-\"](1[\"*\"](t))[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](AP)[\"+\"](sin(t[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](GP));\n        }\n        \"1461\";\n        P_int = norm(P_int);\n        \"1464\";\n        steps_arc = 40;\n        \"1465\";\n        for (var \u03c1\u03c3_Index13 = 0; \u03c1\u03c3_Index13[\"<\"](steps_arc[\"+\"](1)); \u03c1\u03c3_Index13++) {\n            i = \u03c1\u03c3_Index13;\n            \"1466\";\n            u = i[\"\/\"](steps_arc);\n            \"1467\";\n            if ((theta === 0 || typeof theta === \"object\" && \u03c1\u03c3_equals(theta, 0))) {\n                \"1468\";\n                p = AP;\n                \"1469\";\n            } else {\n                \"1471\";\n                p = sin(1[\"-\"](1[\"*\"](u))[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](AP)[\"+\"](sin(u[\"*\"](theta))[\"\/\"](sin(theta))[\"*\"](P_int));\n            }\n            \"1473\";\n            \u03c1\u03c3_interpolate_kwargs.call(ap_to_int_curve, ap_to_int_curve.modify, [i].concat([\u03c1\u03c3_desugar_kwargs({pos: norm(p)})]));\n        }\n        \"1476\";\n        Pint_marker.pos = P_int;\n        \"1478\";\n        intercept_label.pos = P_int;\n        \"1479\";\n        aval_label.pos = P_int;\n        \"1481\";\n        lop_dir = (await draw_short_lop(AP, GP, P_int, lop_short));\n        \"1483\";\n        return [P_int, Hc, Ho, lop_dir, nm_distance];\n    };\n    if (!update_lop.__argnames__) Object.defineProperties(update_lop, {\n        __argnames__ : {value: [\"AP\", \"GP\"]},\n        __module__ : {value: null}\n    });\n\n    \"1485\";\n    lop_short = \u03c1\u03c3_interpolate_kwargs.call(this, curve, [\u03c1\u03c3_desugar_kwargs({radius: line_radius, color: color.red})]);\n    \"1486\";\n    for (var \u03c1\u03c3_Index14 = 0; \u03c1\u03c3_Index14[\"<\"](61); \u03c1\u03c3_Index14++) {\n        i = \u03c1\u03c3_Index14;\n        \"1487\";\n        \u03c1\u03c3_interpolate_kwargs.call(lop_short, lop_short.append, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0)})]);\n    }\n    \"1489\";\n    dist_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pixel_pos: true, pixel_scale: true, pos: vector(scene.width[\"\/\"](2), 70, 0), text: \"\", line: false, color: color.white, height: dev_lbl_height, box: true, opacity: 0})]);\n    \"1500\";\n    all_labels.append(dist_label);\n    \"1502\";\n    intercept_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), text: \"Intercept\", color: color.black, xoffset: 0, yoffset: 50, height: dev_lbl_height, box: false, opacity: 0})]);\n    \"1512\";\n    all_labels.append(intercept_label);\n    \"1514\";\n    lop_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({text: \"AP-1 LOP\", color: color.red, box: false, opacity: 0, height: dev_lbl_height, pixel_pos: false, pos: vector(0, 0, 0)})]);\n    \"1523\";\n    all_labels.append(lop_label);\n    \"1529\";\n    async function update_AP_Zn(AP, P_int, GP) {\n        var \u03c1\u03c3_ls, steps, ap_gp_theta, f, v, i, ap1_zn_label;\n        \"1532\";\n        steps = 40;\n        \"1533\";\n        ap_gp_theta = acos(dot(AP, GP));\n        \"1535\";\n        if ((ap_gp_theta === 0 || typeof ap_gp_theta === \"object\" && \u03c1\u03c3_equals(ap_gp_theta, 0))) {\n            \"1536\";\n            \u03c1\u03c3_interpolate_kwargs.call(ap_Zn_curve, ap_Zn_curve.append, [\u03c1\u03c3_desugar_kwargs({pos: AP})]);\n            \"1537\";\n            return;\n        }\n        \"1539\";\n        for (var \u03c1\u03c3_Index15 = 0; \u03c1\u03c3_Index15[\"<\"](steps[\"+\"](1)); \u03c1\u03c3_Index15++) {\n            i = \u03c1\u03c3_Index15;\n            \"1540\";\n            f = i[\"\/\"](steps);\n            \"1541\";\n            v = sin(1[\"-\"](1[\"*\"](f))[\"*\"](ap_gp_theta))[\"\/\"](sin(ap_gp_theta))[\"*\"](AP)[\"+\"](sin(f)[\"*\"](ap_gp_theta)[\"\/\"](sin(ap_gp_theta))[\"*\"](GP));\n            \"1543\";\n            \u03c1\u03c3_interpolate_kwargs.call(ap_Zn_curve, ap_Zn_curve.modify, [i].concat([\u03c1\u03c3_desugar_kwargs({pos: norm(v)})]));\n        }\n        \"1545\";\n        ap1_zn_label = await \u03c1\u03c3_list_decorate(\u03c1\u03c3_interpolate_kwargs.call(this, label_Zn_on_curve, [ap_Zn_curve, P_int, GP].concat([\u03c1\u03c3_desugar_kwargs({zn_lbl_text: \"AP-1 Zn\", curve_shift: 1[\"-u\"]()[\"*\"](.3)})])));\n        \"1547\";\n        return [ap_Zn_curve, ap1_zn_label];\n    };\n    if (!update_AP_Zn.__argnames__) Object.defineProperties(update_AP_Zn, {\n        __argnames__ : {value: [\"AP\", \"P_int\", \"GP\"]},\n        __module__ : {value: null}\n    });\n\n    \"1549\";\n    async function bearing_from_Zn_vector(Obs_vec, NP_vec, Zn_vec) {\n        var \u03c1\u03c3_ls, north_raw, north_hat, east_hat, x, y, Zn_rad, Zn_deg;\n        \"1553\";\n        north_raw = NP_vec[\"-\"](1[\"*\"](dot(NP_vec, Obs_vec))[\"*\"](Obs_vec));\n        \"1554\";\n        north_hat = norm(north_raw);\n        \"1557\";\n        east_hat = norm(cross(north_hat, Obs_vec));\n        \"1561\";\n        x = dot(Zn_vec, north_hat);\n        \"1562\";\n        y = dot(Zn_vec, east_hat);\n        \"1565\";\n        Zn_rad = atan2(y, x);\n        \"1566\";\n        Zn_deg = (await normalize(Zn_rad[\"*\"](180)[\"\/\"](pi)));\n        \"1568\";\n        return Zn_deg;\n    };\n    if (!bearing_from_Zn_vector.__argnames__) Object.defineProperties(bearing_from_Zn_vector, {\n        __argnames__ : {value: [\"Obs_vec\", \"NP_vec\", \"Zn_vec\"]},\n        __module__ : {value: null}\n    });\n\n    \"1570\";\n    ob_Zn_vec = norm(\u03c1\u03c3_getitem(ob_Zn_curve.point(2), \"pos\")[\"-\"](1[\"*\"](\u03c1\u03c3_getitem(ob_Zn_curve.point(0), \"pos\"))));\n    \"1571\";\n    ob_zn_bearing = (await bearing_from_Zn_vector(ob_vector, np_vec, ob_Zn_vec));\n    \"1573\";\n    fix_marker_ring = \u03c1\u03c3_interpolate_kwargs.call(this, ring, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), color: color.white, axis: vector(0, 0, 0), radius: .004, thickness: 3e-4})]);\n    \"1581\";\n    fix_marker_point = \u03c1\u03c3_interpolate_kwargs.call(this, sphere, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), color: color.white, radius: .0015})]);\n    \"1587\";\n    fix_marker_point_label = \u03c1\u03c3_interpolate_kwargs.call(this, label, [\u03c1\u03c3_desugar_kwargs({pos: vector(0, 0, 0), xoffset: 0, yoffset: 30, text: \"Fix\", height: dev_lbl_height, color: color.white, line: true, linecolor: color.white, box: false, opacity: 0})]);\n    \"1600\";\n    all_labels.append(fix_marker_point_label);\n    \"1602\";\n    async function lop_normal_from_curve(curve_obj) {\n        var \u03c1\u03c3_ls, p1, p2;\n        \"1604\";\n        p1 = norm(curve_obj.point(0).pos);\n        \"1605\";\n        p2 = norm(curve_obj.point(Math.floor(curve_obj.npoints[\"\/\"](2))).pos);\n        \"1607\";\n        return norm(cross(p1, p2));\n    };\n    if (!lop_normal_from_curve.__argnames__) Object.defineProperties(lop_normal_from_curve, {\n        __argnames__ : {value: [\"curve_obj\"]},\n        __module__ : {value: null}\n    });\n\n    \"1609\";\n    async function dist_to_fix_nm(P1_int, lop1_dir, P2_int, lop2_dir, AP1_hat, earth_radius_nm) {\n        var \u03c1\u03c3_ls, n1, n2, k1, k2, L, A, B, C, det, a, b, r0, A2, B2, C2, disc, sqrt_disc, t1, t2, cand1, cand2, fix1, fix2, fix_hat, \u03c1\u03c3_unpack, fix_lat, fix_lon, ang;\n        \"1614\";\n        n1 = norm(lop1_dir);\n        \"1615\";\n        n2 = norm(lop2_dir);\n        \"1617\";\n        k1 = dot(n1, P1_int);\n        \"1618\";\n        k2 = dot(n2, P2_int);\n        \"1621\";\n        L = cross(n1, n2);\n        \"1622\";\n        if (mag(L)[\"<\"](1e-12)) {\n            \"1623\";\n            return null;\n        }\n        \"1624\";\n        L = norm(L);\n        \"1627\";\n        A = dot(n1, n1);\n        \"1628\";\n        B = dot(n1, n2);\n        \"1629\";\n        C = dot(n2, n2);\n        \"1631\";\n        det = A[\"*\"](C)[\"-\"](1[\"*\"](B)[\"*\"](B));\n        \"1632\";\n        if (abs(det)[\"<\"](1e-12)) {\n            \"1633\";\n            return null;\n        }\n        \"1635\";\n        a = k1[\"*\"](C)[\"-\"](1[\"*\"](k2)[\"*\"](B))[\"\/\"](det);\n        \"1636\";\n        b = k2[\"*\"](A)[\"-\"](1[\"*\"](k1)[\"*\"](B))[\"\/\"](det);\n        \"1638\";\n        r0 = a[\"*\"](n1)[\"+\"](b[\"*\"](n2));\n        \"1641\";\n        A2 = dot(L, L);\n        \"1642\";\n        B2 = 2[\"*\"](dot(r0, L));\n        \"1643\";\n        C2 = dot(r0, r0)[\"-\"](1[\"*\"](1));\n        \"1645\";\n        disc = B2[\"*\"](B2)[\"-\"](1[\"*\"](4)[\"*\"](A2)[\"*\"](C2));\n        \"1646\";\n        if (disc[\"<\"](0)) {\n            \"1647\";\n            return null;\n        }\n        \"1649\";\n        sqrt_disc = sqrt(disc);\n        \"1650\";\n        t1 = 1[\"-u\"]()[\"*\"](B2)[\"+\"](sqrt_disc)[\"\/\"](2[\"*\"](A2));\n        \"1651\";\n        t2 = 1[\"-u\"]()[\"*\"](B2)[\"-\"](1[\"*\"](sqrt_disc))[\"\/\"](2[\"*\"](A2));\n        \"1653\";\n        cand1 = r0[\"+\"](t1[\"*\"](L));\n        \"1654\";\n        cand2 = r0[\"+\"](t2[\"*\"](L));\n        \"1656\";\n        fix1 = norm(cand1);\n        \"1657\";\n        fix2 = norm(cand2);\n        \"1660\";\n        fix_hat = (dot(fix1, AP1_hat)[\">\"](0)) ? fix1 : fix2;\n        \"1662\";\n        \u03c1\u03c3_unpack = (await vector_to_latlon(fix_hat));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n        fix_lat = \u03c1\u03c3_unpack[0];\n        fix_lon = \u03c1\u03c3_unpack[1];\n        \"1664\";\n        if (!data_off) {\n            \"1665\";\n            print(\"Fix: Lat=\"[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", fix_lat))[\"+\"](\" Lon=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", fix_lon))[\"+\"](\"\"));\n        }\n        \"1668\";\n        fix_marker_ring.pos = fix_hat;\n        \"1669\";\n        fix_marker_ring.axis = fix_hat;\n        \"1670\";\n        fix_marker_point.pos = fix_hat;\n        \"1671\";\n        fix_marker_point_label.pos = fix_hat;\n        \"1674\";\n        ang = acos(dot(ob_vector, fix_hat));\n        \"1676\";\n        return [earth_radius_nm[\"*\"](ang), fix_marker_point.pos];\n    };\n    if (!dist_to_fix_nm.__argnames__) Object.defineProperties(dist_to_fix_nm, {\n        __argnames__ : {value: [\"P1_int\", \"lop1_dir\", \"P2_int\", \"lop2_dir\", \"AP1_hat\", \"earth_radius_nm\"]},\n        __module__ : {value: null}\n    });\n\n    \"1679\";\n    scene.camera.pos = vector(1[\"-u\"]()[\"*\"](1.26078), .605223, .255051);\n    \"1680\";\n    scene.camera.axis = vector(1.59998, 1[\"-u\"]()[\"*\"](.783473), 1[\"-u\"]()[\"*\"](.31085));\n    \"1686\";\n    t = 0;\n    \"1688\";\n    theta = 0;\n    \"1689\";\n    prev_gp_slider_val = null;\n    \"1690\";\n    prev_label_scale = null;\n    \"1691\";\n    not_zoomed = true;\n    \"1693\";\n    while (true) {\n        \"1695\";\n        (await rate(speed_slider.value));\n        \"1698\";\n        if (paused) {\n            \"1699\";\n            continue;\n            \"1702\";\n        }\n        if ((gp_slider.value !== prev_gp_slider_val && (typeof gp_slider.value !== \"object\" || \u03c1\u03c3_not_equals(gp_slider.value, prev_gp_slider_val)))) {\n            \"1703\";\n            gp_vec = (await slerp_GP(gp_vec_original, ob_vector, gp_slider.value));\n            \"1704\";\n            prev_gp_slider_val = gp_slider.value;\n            \"1705\";\n            gp_marker.pos = gp_vec;\n            \"1706\";\n            gp_label.pos = gp_vec;\n            \"1708\";\n            uO = norm(ob_vector);\n            \"1709\";\n            uGP = norm(gp_vec);\n            \"1710\";\n            ob_Zn_curve = (await update_observer_Zn(ob_Zn_curve, uGP, uO));\n            \"1711\";\n            obea1_curve = (await update_obea1_curve(ob_vector, gp_vec));\n        }\n        \"1715\";\n        AP_distance_deg = ap_slider.value;\n        \"1716\";\n        r_AP = (await radians(AP_distance_deg));\n        \"1718\";\n        theta = t;\n        \"1719\";\n        AP = (await AP_from_OBS(ob_vector, N_obs, E_obs, r_AP, theta));\n        \"1721\";\n        ap_marker.pos = AP;\n        \"1722\";\n        ap_label.pos = ap_marker.pos;\n        \"1724\";\n        \u03c1\u03c3_unpack = (await update_lop(AP, gp_vec));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(5, \u03c1\u03c3_unpack);\n        P_int = \u03c1\u03c3_unpack[0];\n        Hc = \u03c1\u03c3_unpack[1];\n        Ho = \u03c1\u03c3_unpack[2];\n        lop_plane_normal = \u03c1\u03c3_unpack[3];\n        nm_distance = \u03c1\u03c3_unpack[4];\n        \"1726\";\n        if (P_int === null) {\n            \"1727\";\n            continue;\n        }\n        \"1729\";\n        \u03c1\u03c3_unpack = (await update_AP_Zn(AP, P_int, gp_vec));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n        ap_Zn_curve = \u03c1\u03c3_unpack[0];\n        ap_zn_label = \u03c1\u03c3_unpack[1];\n        \"1732\";\n        \u03c1\u03c3_unpack = (await compute_lop_directions(AP, gp_vec, P_int));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n        t_lop = \u03c1\u03c3_unpack[0];\n        lop_tangent = \u03c1\u03c3_unpack[1];\n        \"1734\";\n        short_len = .1;\n        \"1735\";\n        p1 = P_int[\"+\"](short_len[\"*\"](lop_tangent));\n        \"1736\";\n        p2 = P_int[\"-\"](1[\"*\"](short_len)[\"*\"](lop_tangent));\n        \"1738\";\n        lop_short.point(0).pos = p1;\n        \"1739\";\n        lop_short.point(1).pos = p2;\n        \"1741\";\n        if (nm_distance[\"<\"](10)) {\n            \"1742\";\n            dt = .04;\n            \"1743\";\n        } else {\n            \"1744\";\n            dt = .02;\n        }\n        \"1746\";\n        t=t[\"+\"](dt);\n        \"1748\";\n        ap_Zn_vec = norm(\u03c1\u03c3_getitem(ap_Zn_curve.point(2), \"pos\")[\"-\"](1[\"*\"](\u03c1\u03c3_getitem(ap_Zn_curve.point(0), \"pos\"))));\n        \"1749\";\n        ap_zn_bearing = (await bearing_from_Zn_vector(ll_vector, np_vec, ap_Zn_vec));\n        \"1751\";\n        ap2_Zn_vec = norm(\u03c1\u03c3_getitem(fixed_ap2_to_int_curve.point(0), \"pos\")[\"-\"](1[\"*\"](\u03c1\u03c3_getitem(fixed_ap2_to_int_curve.point(2), \"pos\"))));\n        \"1752\";\n        ap2_zn_bearing = (await bearing_from_Zn_vector(ll2_vector, np_vec, ap2_Zn_vec));\n        \"1754\";\n        \u03c1\u03c3_unpack = (await vector_to_latlon(AP));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n        ap_lat = \u03c1\u03c3_unpack[0];\n        ap_lon = \u03c1\u03c3_unpack[1];\n        \"1756\";\n        if (!data_off) {\n            \"1757\";\n            print(\"Observer Zn bearing: \"[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", ob_zn_bearing))[\"+\"](\"  AP-1 Zn bearing: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", ap_zn_bearing))[\"+\"](\"  Ap-2 Zn bearing: \")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", ap2_zn_bearing))[\"+\"](\"\"));\n            \"1758\";\n            print(\"Observer: Lat=\"[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", olat))[\"+\"](\" Lon=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", olon))[\"+\"](\"\"));\n            \"1759\";\n            print(\"AP-2: Lat=\"[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", alat2))[\"+\"](\" Lon=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", alon2))[\"+\"](\" AP-1: Lat=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", ap_lat))[\"+\"](\" Lon=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", ap_lon))[\"+\"](\"\"));\n            \"1760\";\n            print(\"GP-1: Dec=\"[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", gp_dec))[\"+\"](\" GHA=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", gp_gha))[\"+\"](\" GP-2: Dec=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", gp2_dec))[\"+\"](\" GHA=\")[\"+\"](\u03c1\u03c3_str.format(\"{:.2f}\", gp2_gha))[\"+\"](\"\"));\n        }\n        \"1762\";\n        \u03c1\u03c3_unpack = (await dist_to_fix_nm(P_int, lop_plane_normal, P2_int, lop2_plane_normal, ll_vector, 3440.065));\n\u03c1\u03c3_unpack = \u03c1\u03c3_unpack_asarray(2, \u03c1\u03c3_unpack);\n        fix_distance_nm = \u03c1\u03c3_unpack[0];\n        fix_marker_pos = \u03c1\u03c3_unpack[1];\n        \"1766\";\n        if (not_zoomed) {\n            \"1768\";\n            for (var \u03c1\u03c3_Index16 = 0; \u03c1\u03c3_Index16[\"<\"](29); \u03c1\u03c3_Index16++) {\n                i = \u03c1\u03c3_Index16;\n                \"1769\";\n                (await rate(7));\n                \"1770\";\n                (await zoom_in());\n            }\n            \"1771\";\n            not_zoomed = false;\n            \"1772\";\n            ap_marker.make_trail = true;\n            \"1774\";\n        }\n        if ((label_scale !== prev_label_scale && (typeof label_scale !== \"object\" || \u03c1\u03c3_not_equals(label_scale, prev_label_scale)))) {\n            \"1775\";\n            var \u03c1\u03c3_Iter17 = all_labels;\n            \u03c1\u03c3_Iter17 = ((typeof \u03c1\u03c3_Iter17[Symbol.iterator] === \"function\") ? (\u03c1\u03c3_Iter17 instanceof Map ? \u03c1\u03c3_Iter17.keys() : \u03c1\u03c3_Iter17) : Object.keys(\u03c1\u03c3_Iter17));\n            for (var \u03c1\u03c3_Index17 of \u03c1\u03c3_Iter17) {\n                L = \u03c1\u03c3_Index17;\n                \"1776\";\n                L.height = dev_lbl_height[\"*\"](label_scale);\n            }\n            \"1777\";\n            prev_label_scale = label_scale;\n            \"1780\";\n        }\n        if (debug) {\n            \"1782\";\n            if ((await vec_is_nan(AP))) {\n                \"1783\";\n                log(\"AP is NaN\");\n                \"1784\";\n                (await save_log());\n                \"1785\";\n                break;\n                \"1787\";\n            }\n            if ((await vec_is_nan(P_int))) {\n                \"1788\";\n                log(\"P_int is NaN\");\n                \"1789\";\n                (await save_log());\n                \"1790\";\n                break;\n                \"1792\";\n            }\n            if ((await vec_is_nan(lop_tangent))) {\n                \"1793\";\n                log(\"LOP tangent is NaN\");\n                \"1794\";\n                (await save_log());\n                \"1795\";\n                break;\n                \"1797\";\n            }\n            if (len(all_labels)[\">\"](17)) {\n                \"1798\";\n                log(\"Label leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(all_labels)))[\"+\"](\"\"));\n                \"1799\";\n                leak_report = \"LABEL LEAK DETECTED\\n\";\n                \"1800\";\n                leak_report=leak_report[\"+\"]((await dump_labels()));\n                \"1801\";\n                (await save_log_simple(leak_report));\n                \"1802\";\n                (await save_log());\n                \"1803\";\n                break;\n                \"1805\";\n            }\n            if (len(ob_Zn_curve.npoints)[\">\"](100)) {\n                \"1806\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(ob_Zn_curve.npoints)))[\"+\"](\"\"));\n                \"1807\";\n                (await save_log());\n                \"1808\";\n                break;\n                \"1810\";\n            }\n            if (len(ob_lop_curve.npoints)[\">\"](61)) {\n                \"1811\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(ob_lop_curve.npoints)))[\"+\"](\"\"));\n                \"1812\";\n                (await save_log());\n                \"1813\";\n                break;\n                \"1815\";\n            }\n            if (len(fixed_zn2_curve.npoints)[\">\"](61)) {\n                \"1816\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(fixed_zn2_curve.npoints)))[\"+\"](\"\"));\n                \"1817\";\n                (await save_log());\n                \"1818\";\n                break;\n                \"1820\";\n            }\n            if (len(fixed_ap2_to_int_curve.npoints)[\">\"](41)) {\n                \"1821\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(fixed_ap2_to_int_curve.npoints)))[\"+\"](\"\"));\n                \"1822\";\n                (await save_log());\n                \"1823\";\n                break;\n                \"1825\";\n            }\n            if (len(fixed_lop2_curve.npoints)[\">\"](61)) {\n                \"1826\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(fixed_lop2_curve.npoints)))[\"+\"](\"\"));\n                \"1827\";\n                (await save_log());\n                \"1828\";\n                break;\n                \"1830\";\n            }\n            if (len(obea1_curve.npoints)[\">\"](362)) {\n                \"1831\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(obea1_curve.npoints)))[\"+\"](\"\"));\n                \"1832\";\n                (await save_log());\n                \"1833\";\n                break;\n                \"1835\";\n            }\n            if (len(obea2_curve.npoints)[\">\"](362)) {\n                \"1836\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(obea2_curve.npoints)))[\"+\"](\"\"));\n                \"1837\";\n                (await save_log());\n                \"1838\";\n                break;\n                \"1840\";\n            }\n            if (len(ap_Zn_curve.npoints)[\">\"](41)) {\n                \"1841\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(ap_Zn_curve.npoints)))[\"+\"](\"\"));\n                \"1842\";\n                (await save_log());\n                \"1843\";\n                break;\n                \"1845\";\n            }\n            if (len(ap_to_int_curve.npoints)[\">\"](41)) {\n                \"1846\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(ap_to_int_curve.npoints)))[\"+\"](\"\"));\n                \"1847\";\n                (await save_log());\n                \"1848\";\n                break;\n                \"1850\";\n            }\n            if (len(lop_short.npoints)[\">\"](61)) {\n                \"1851\";\n                log(\"Curve leak detected: \"[\"+\"](\u03c1\u03c3_str.format(\"{}\", len(lop_short.npoints)))[\"+\"](\"\"));\n                \"1852\";\n                (await save_log());\n                \"1853\";\n                break;\n            }\n            \"1855\";\n            print(\"ob_Zn_curve.npoints: \", ob_Zn_curve.npoints);\n            \"1856\";\n            print(\"ob_lop_curve.npoints: \", ob_lop_curve.npoints);\n            \"1857\";\n            print(\"fixed_zn2_curve.npoints: \", fixed_zn2_curve.npoints);\n            \"1858\";\n            print(\"fixed_ap2_to_int_curve.npoints: \", fixed_ap2_to_int_curve.npoints);\n            \"1859\";\n            print(\"fixed_lop2_curve.npoints: \", fixed_lop2_curve.npoints);\n            \"1860\";\n            print(\"obea1_curve.npoints: \", obea1_curve.npoints);\n            \"1861\";\n            print(\"obea2_curve.npoints: \", obea2_curve.npoints);\n            \"1862\";\n            print(\"ap_Zn_curve.npoints: \", ap_Zn_curve.npoints);\n            \"1863\";\n            print(\"ap_to_int_curve.npoints: \", ap_to_int_curve.npoints);\n            \"1864\";\n            print(\"lop_short.npoints: \", lop_short.npoints);\n            \"1865\";\n            print(\"len all_labels: \", len(all_labels));\n            \"1867\";\n            count = 0;\n            \"1868\";\n            var \u03c1\u03c3_Iter18 = scene.objects;\n            \u03c1\u03c3_Iter18 = ((typeof \u03c1\u03c3_Iter18[Symbol.iterator] === \"function\") ? (\u03c1\u03c3_Iter18 instanceof Map ? \u03c1\u03c3_Iter18.keys() : \u03c1\u03c3_Iter18) : Object.keys(\u03c1\u03c3_Iter18));\n            for (var \u03c1\u03c3_Index18 of \u03c1\u03c3_Iter18) {\n                obj = \u03c1\u03c3_Index18;\n                \"1869\";\n                if ((obj.constructor.name === \"point\" || typeof obj.constructor.name === \"object\" && \u03c1\u03c3_equals(obj.constructor.name, \"point\"))) {\n                    \"1870\";\n                    continue;\n                }\n                \"1871\";\n                print(\"type: \", obj.constructor.name, \" color: \", obj.color);\n                \"1872\";\n                count=count[\"+\"](1);\n                \"1873\";\n                if (count[\">=\"](50)) {\n                    \"1874\";\n                    break;\n                }\n            }\n            \"1875\";\n            var \u03c1\u03c3_Iter19 = scene.objects;\n            \u03c1\u03c3_Iter19 = ((typeof \u03c1\u03c3_Iter19[Symbol.iterator] === \"function\") ? (\u03c1\u03c3_Iter19 instanceof Map ? \u03c1\u03c3_Iter19.keys() : \u03c1\u03c3_Iter19) : Object.keys(\u03c1\u03c3_Iter19));\n            for (var \u03c1\u03c3_Index19 of \u03c1\u03c3_Iter19) {\n                obj = \u03c1\u03c3_Index19;\n                \"1876\";\n                if ((obj.constructor.name === \"point\" || typeof obj.constructor.name === \"object\" && \u03c1\u03c3_equals(obj.constructor.name, \"point\"))) {\n                    \"1877\";\n                    count=count[\"+\"](1);\n                }\n            }\n            \"1878\";\n            print(\"num points: \", count);\n        }\n    }\n    \"1882\";\n    async function print_camera_position() {\n        \"1883\";\n        print(\"camera_rad: \", camera_rad, \"Camera pos: \", scene.camera.pos, \"Camera axis: \", scene.camera.axis, \"Zoom level (distance):\", mag(scene.camera.pos));\n        \"1884\";\n        print(\"Scene range: \", scene.range, \" Scene fov: \", scene.fov, \" scene.pixel_to_world: \", scene.pixel_to_world);\n    };\n    if (!print_camera_position.__module__) Object.defineProperties(print_camera_position, {\n        __module__ : {value: null}\n    });\n\n};\nif (!__main__.__module__) Object.defineProperties(__main__, {\n    __module__ : {value: null}\n});\n\n;$(function(){ window.__context = { glowscript_container: $(\"#glowscript\").removeAttr(\"id\") }; __main__() })})()\n\/\/ END JAVASCRIPT\n\n\/\/--><!]]><\/script>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">The assumed position (labeled AP) is an estimated position (latitude and longitude) of a vessel derived from dead reckoning (DR). Dead reckoning is the periodic updating of a vessel&#8217;s position based on it&#8217;s course and speed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What is in the Rendering<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The animated rendering aims to show how the fix is influenced by the assumed position. The animation revolves an imaginary assumed position from a celestial sight, AP-1 (red dot), 360 degrees around a stationary observer labelled OB (green dot). A second assumed position from a second celestial sight, AP-2 (red dot), is stationary and serves to define two LOPs (red lines) where the fix is designated by the white &#8220;target&#8221; at the LOP&#8217;s intersection. AP-1 and the observer share GP-1 (yellow dot) while GP-2 is from the AP-2 sight. The two circles of equal altitude around GP-1 and GP-2 (yellow circles) intersect at the observer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The observer&#8217;s LOP (green line) is tangent to the observer&#8217;s circle of equal altitude around GP-1 at the observer&#8217;s position. The Zn bearings of the observer and both APs are cyan. As AP-1 revolves, its Zn bearing, LOP, a-value (magenta line) and intercept (black dot) all move accordingly. The current a-value can be read in the moving label. The remaining objects are stationary.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>AP Accuracy<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, how accurate does the estimated dead reckoned position, and therefore the AP, need to be to derive an accurate celestial fix? <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Using the sliders, change the AP-1 and GP-1 distances from the observer to see what effect the distances have on the fix shown as the white target. The nautical mile distance from the observer to the fix is shown in the text box and other data is updated in the print area at the bottom of the page. Observe how the fix distance changes with the AP-1 to observer bearing and distances. The animation speed can be changed with the Speed slider, and the animation can be paused and resumed with the Pause button. The Reset button redraws the initial view.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The view angle and zoom level can be changed with the arrow buttons. Alternately, use the preset buttons 1-4 to make the following predefined changes:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Scenario 1:<\/strong> The AP-1 distance is 60 nm away from the observer with GP-1 far from the observer. The fix drifts nominally.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><strong>Scenario<\/strong> 2:<\/strong> The AP-1 distance is 60 nm away from the observer with GP-1 very close to the observer. The Ho and AP-1 Hc altitudes are very high. The AP-1 LOP rocks and the fix drifts wildly away.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><strong>Scenario<\/strong> 3:<\/strong> The AP-1 distance is only 6 nm away from the observer with GP-1 far from the observer. The fix does not drift.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><strong>Scenario<\/strong> 4:<\/strong> The AP-1 distance is only 6 nm away from the observer with GP-1 very close to the observer. The Ho and AP-1 Hc altitudes are very high, but the fix drifts nominally.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Conclusion<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is generally observed that AP does not have to be very accurate as the a-value that determines where to plot the LOP will change to maintain the LOP tangent to the observer&#8217;s circle of equal altitudes. This behavior can be seen in the animation as the magenta-colored a-value line shrinks and grows. There are limits however to how well the a-value can maintain the LOP. The animation illustrates how the fix drifts away from the observer&#8217;s position under the following conditions, and is magnified if these conditions coexist:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p class=\"wp-block-paragraph\">As the assumed position Zn bearing diverges from the observer&#8217;s Zn bearing<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\" style=\"line-height:0.3\">      As the assumed position altitude Hc gets extremely high<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\" style=\"line-height:0.3\">      As the assumed position gets farther from the observer<\/p>\n<\/div><\/div>\n<\/div><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">In the animation, the AP&#8217;s distance to the observer is exaggerated for clarity. In practice, we can usually get the DR close enough so that the AP does not have to be very accurate. In order for the AP and the observer&#8217;s position to both fall on the plotting sheet, the AP should be within 30 nautical miles or so from the observer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:20px\"><strong>The Basics<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The AP&#8217;s Function<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The AP serves two main functions in celestial navigation. First, it serves as a base position from which to calculate the radius of the vessel&#8217;s circle of equal altitudes on a plotting sheet. The circle of equal altitudes is a circle centered on the geographical position (GP) of the sighted celestial body with a circumference that passes through the vessel&#8217;s position (here the vessel is labeled OB for &#8216;observer&#8217;). The circle&#8217;s radius is determined by the altitude or height of the celestial body in relation to the observer&#8217;s horizon as measured with the sextant. The same altitude could have been measured anywhere around the circle hence the name &#8216;circle of equal altitudes&#8217;. Accordingly, the observer could be anywhere around the circle&#8217;s circumference.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While we can determine the circle&#8217;s radius directly from the altitude, we cannot plot the entire circle on the plotting sheet. The circle may have a radius of thousands of nautical miles, but the plotting sheet often has a radius of about 120 nautical miles. Furthermore, the geographic position will likely be off the plot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A way around the problem is to use the Intercept Method.  The Intercept Method enables us to plot a short segment of the circle&#8217;s diameter that falls within the plotting area. The procedure begins by defining a position (latitude and longitude) that is near the observer known as the assumed position or AP. The AP is a derivation of the vessel&#8217;s dead reckoning (DR) position as the DR should be near the observer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The AP, being a position on the surface of Earth, also has an altitude to the same celestial body that was sighted by the observer and thus also has a circle of equal altitudes. The AP&#8217;s altitude wasn&#8217;t sighted with a sextant on a sea horizon, but it can be computed for the AP in the sight reduction tables based on the body&#8217;s altitude in relation to the AP&#8217;s &#8216;apparent horizon&#8217;. The AP&#8217;s apparent horizon is a plane passing through the center of the Earth at 90 degrees to the AP&#8217;s &#8216;zenith&#8217; which is a point directly above the AP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Comparing the altitudes of the observer and the AP, the difference in radii of the two circles can be determined &#8211; this is called the &#8216;a-value&#8217;. Along with the a-value, we also need to know the direction to the GP from the AP. But since the geographic position of the celestial body can&#8217;t be plotted on the small plotting sheet, we obtain it&#8217;s direction from the sight reduction tables. Now we have two datapoints to locate the observer&#8217;s circle from the AP reference position.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Plotting<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On the plot, the AP position is marked, and a line is plotted from the AP in the direction of the GP denoted &#8216;Zn&#8217; which is the bearing of the GP relative to North (the angular distance from the AP to the GP is called the &#8216;zenith distance&#8217; or &#8216;z&#8217; &#8211; Zn is the north-relative bearing to this line). The a-value distance is marked-off along the Zn line from the AP either toward or away from the GP. If the AP&#8217;s altitude is greater than the observer&#8217;s altitude (the observer is farther from the GP than AP is), it is plotted &#8216;Away&#8217; from the GP because the observer&#8217;s circle is larger; otherwise (the observer is closer to the GP than the AP is), it is plotted &#8216;Toward&#8217; the GP because the observer&#8217;s circle is smaller.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The end point of the a-value distance is called the &#8216;intercept&#8217;. The intercept marks a point on the observer&#8217;s circle of equal altitudes. At the intercept, a straight line of position (LOP) is drawn perpendicular to the Zn line which causes it to be tangent to the observer&#8217;s circle of equal altitudes. Because the circle&#8217;s diameter is so great in relation to the &#8216;zoomed-in&#8217; plotting area, the straight LOP in effect describes a segment of the observer&#8217;s circle that falls within the plotting area.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Where is the Fix?<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To determine the vessel&#8217;s position or &#8216;fix&#8217; (technically an &#8216;observed position&#8217;), two or more LOPs from two or more sights of different celestial bodies, or the same body sighted at a later time, must be plotted. If the vessel was underway between sights, the earlier LOPs must be &#8216;advanced&#8217; along the vessel&#8217;s DR course. The vessel&#8217;s position will be close to where the LOPs intersect.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>A Secondary Function<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The AP is also used to provide whole-degree lookup values that are needed for using the sight reduction tables. To keep the sight reduction tables to a manageable size, they cannot provide infinite solutions to every possible position on Earth. To limit the resolution of the solutions, the input values required to enter the tables are in whole degrees. These values are the AP latitude, the local hour angle (LHA) and the declination of the celestial body. The DR latitude is rounded to the nearest whole degree to specify the AP latitude, and the AP longitude is specified in a manner that causes the local hour angle (LHA) computation to result in whole degrees.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The browser must support WebGL, and Javascript must be enabled. These are usually enabled by default. To improve performance, keep the data area turned off (default) using the &#8220;Data&#8221; button. The data area is a text pane at the bottom of the page that appears when data is turned on. Mobile users: finger drags are &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/steely.org\/celnav\/assumed-position\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Assumed Position&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3351","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/pages\/3351","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/comments?post=3351"}],"version-history":[{"count":155,"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/pages\/3351\/revisions"}],"predecessor-version":[{"id":3646,"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/pages\/3351\/revisions\/3646"}],"wp:attachment":[{"href":"https:\/\/steely.org\/celnav\/wp-json\/wp\/v2\/media?parent=3351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}