UNPKG

@humandialog/auth.svelte

Version:

Svelte package to deal with ObjectReef OAuth 2 Identity Provider

3,391 lines 120 kB
(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.auth = global.auth || {}, global.auth.svelte = {})));
})(this, (function (exports) { 'use strict';

    function noop() { }
    function assign(tar, src) {
        // @ts-ignore
        for (const k in src)
            tar[k] = src[k];
        return tar;
    }
    function run(fn) {
        return fn();
    }
    function blank_object() {
        return Object.create(null);
    }
    function run_all(fns) {
        fns.forEach(run);
    }
    function is_function(thing) {
        return typeof thing === 'function';
    }
    function safe_not_equal(a, b) {
        return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
    }
    function is_empty(obj) {
        return Object.keys(obj).length === 0;
    }
    function subscribe(store, ...callbacks) {
        if (store == null) {
            return noop;
        }
        const unsub = store.subscribe(...callbacks);
        return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
    }
    function get_store_value(store) {
        let value;
        subscribe(store, _ => value = _)();
        return value;
    }
    function component_subscribe(component, store, callback) {
        component.$$.on_destroy.push(subscribe(store, callback));
    }
    function create_slot(definition, ctx, $$scope, fn) {
        if (definition) {
            const slot_ctx = get_slot_context(definition, ctx, $$scope, fn);
            return definition[0](slot_ctx);
        }
    }
    function get_slot_context(definition, ctx, $$scope, fn) {
        return definition[1] && fn
            ? assign($$scope.ctx.slice(), definition[1](fn(ctx)))
            : $$scope.ctx;
    }
    function get_slot_changes(definition, $$scope, dirty, fn) {
        if (definition[2] && fn) {
            const lets = definition[2](fn(dirty));
            if ($$scope.dirty === undefined) {
                return lets;
            }
            if (typeof lets === 'object') {
                const merged = [];
                const len = Math.max($$scope.dirty.length, lets.length);
                for (let i = 0; i < len; i += 1) {
                    merged[i] = $$scope.dirty[i] | lets[i];
                }
                return merged;
            }
            return $$scope.dirty | lets;
        }
        return $$scope.dirty;
    }
    function update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) {
        if (slot_changes) {
            const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn);
            slot.p(slot_context, slot_changes);
        }
    }
    function get_all_dirty_from_scope($$scope) {
        if ($$scope.ctx.length > 32) {
            const dirty = [];
            const length = $$scope.ctx.length / 32;
            for (let i = 0; i < length; i++) {
                dirty[i] = -1;
            }
            return dirty;
        }
        return -1;
    }
    function set_store_value(store, ret, value) {
        store.set(value);
        return ret;
    }
    function append(target, node) {
        target.appendChild(node);
    }
    function insert(target, node, anchor) {
        target.insertBefore(node, anchor || null);
    }
    function detach(node) {
        if (node.parentNode) {
            node.parentNode.removeChild(node);
        }
    }
    function destroy_each(iterations, detaching) {
        for (let i = 0; i < iterations.length; i += 1) {
            if (iterations[i])
                iterations[i].d(detaching);
        }
    }
    function element(name) {
        return document.createElement(name);
    }
    function text(data) {
        return document.createTextNode(data);
    }
    function space() {
        return text(' ');
    }
    function empty() {
        return text('');
    }
    function listen(node, event, handler, options) {
        node.addEventListener(event, handler, options);
        return () => node.removeEventListener(event, handler, options);
    }
    function attr(node, attribute, value) {
        if (value == null)
            node.removeAttribute(attribute);
        else if (node.getAttribute(attribute) !== value)
            node.setAttribute(attribute, value);
    }
    function children(element) {
        return Array.from(element.childNodes);
    }
    function set_data(text, data) {
        data = '' + data;
        if (text.wholeText !== data)
            text.data = data;
    }

    let current_component;
    function set_current_component(component) {
        current_component = component;
    }
    function get_current_component() {
        if (!current_component)
            throw new Error('Function called outside component initialization');
        return current_component;
    }
    /**
     * Associates an arbitrary `context` object with the current component and the specified `key`
     * and returns that object. The context is then available to children of the component
     * (including slotted content) with `getContext`.
     *
     * Like lifecycle functions, this must be called during component initialisation.
     *
     * https://svelte.dev/docs#run-time-svelte-setcontext
     */
    function setContext(key, context) {
        get_current_component().$$.context.set(key, context);
        return context;
    }
    /**
     * Retrieves the context that belongs to the closest parent component with the specified `key`.
     * Must be called during component initialisation.
     *
     * https://svelte.dev/docs#run-time-svelte-getcontext
     */
    function getContext(key) {
        return get_current_component().$$.context.get(key);
    }
    /**
     * Checks whether a given `key` has been set in the context of a parent component.
     * Must be called during component initialisation.
     *
     * https://svelte.dev/docs#run-time-svelte-hascontext
     */
    function hasContext(key) {
        return get_current_component().$$.context.has(key);
    }

    const dirty_components = [];
    const binding_callbacks = [];
    const render_callbacks = [];
    const flush_callbacks = [];
    const resolved_promise = Promise.resolve();
    let update_scheduled = false;
    function schedule_update() {
        if (!update_scheduled) {
            update_scheduled = true;
            resolved_promise.then(flush);
        }
    }
    function tick() {
        schedule_update();
        return resolved_promise;
    }
    function add_render_callback(fn) {
        render_callbacks.push(fn);
    }
    // flush() calls callbacks in this order:
    // 1. All beforeUpdate callbacks, in order: parents before children
    // 2. All bind:this callbacks, in reverse order: children before parents.
    // 3. All afterUpdate callbacks, in order: parents before children. EXCEPT
    //    for afterUpdates called during the initial onMount, which are called in
    //    reverse order: children before parents.
    // Since callbacks might update component values, which could trigger another
    // call to flush(), the following steps guard against this:
    // 1. During beforeUpdate, any updated components will be added to the
    //    dirty_components array and will cause a reentrant call to flush(). Because
    //    the flush index is kept outside the function, the reentrant call will pick
    //    up where the earlier call left off and go through all dirty components. The
    //    current_component value is saved and restored so that the reentrant call will
    //    not interfere with the "parent" flush() call.
    // 2. bind:this callbacks cannot trigger new flush() calls.
    // 3. During afterUpdate, any updated components will NOT have their afterUpdate
    //    callback called a second time; the seen_callbacks set, outside the flush()
    //    function, guarantees this behavior.
    const seen_callbacks = new Set();
    let flushidx = 0; // Do *not* move this inside the flush() function
    function flush() {
        // Do not reenter flush while dirty components are updated, as this can
        // result in an infinite loop. Instead, let the inner flush handle it.
        // Reentrancy is ok afterwards for bindings etc.
        if (flushidx !== 0) {
            return;
        }
        const saved_component = current_component;
        do {
            // first, call beforeUpdate functions
            // and update components
            try {
                while (flushidx < dirty_components.length) {
                    const component = dirty_components[flushidx];
                    flushidx++;
                    set_current_component(component);
                    update(component.$$);
                }
            }
            catch (e) {
                // reset dirty state to not end up in a deadlocked state and then rethrow
                dirty_components.length = 0;
                flushidx = 0;
                throw e;
            }
            set_current_component(null);
            dirty_components.length = 0;
            flushidx = 0;
            while (binding_callbacks.length)
                binding_callbacks.pop()();
            // then, once components are updated, call
            // afterUpdate functions. This may cause
            // subsequent updates...
            for (let i = 0; i < render_callbacks.length; i += 1) {
                const callback = render_callbacks[i];
                if (!seen_callbacks.has(callback)) {
                    // ...so guard against infinite loops
                    seen_callbacks.add(callback);
                    callback();
                }
            }
            render_callbacks.length = 0;
        } while (dirty_components.length);
        while (flush_callbacks.length) {
            flush_callbacks.pop()();
        }
        update_scheduled = false;
        seen_callbacks.clear();
        set_current_component(saved_component);
    }
    function update($$) {
        if ($$.fragment !== null) {
            $$.update();
            run_all($$.before_update);
            const dirty = $$.dirty;
            $$.dirty = [-1];
            $$.fragment && $$.fragment.p($$.ctx, dirty);
            $$.after_update.forEach(add_render_callback);
        }
    }
    const outroing = new Set();
    let outros;
    function group_outros() {
        outros = {
            r: 0,
            c: [],
            p: outros // parent group
        };
    }
    function check_outros() {
        if (!outros.r) {
            run_all(outros.c);
        }
        outros = outros.p;
    }
    function transition_in(block, local) {
        if (block && block.i) {
            outroing.delete(block);
            block.i(local);
        }
    }
    function transition_out(block, local, detach, callback) {
        if (block && block.o) {
            if (outroing.has(block))
                return;
            outroing.add(block);
            outros.c.push(() => {
                outroing.delete(block);
                if (callback) {
                    if (detach)
                        block.d(1);
                    callback();
                }
            });
            block.o(local);
        }
        else if (callback) {
            callback();
        }
    }
    function create_component(block) {
        block && block.c();
    }
    function mount_component(component, target, anchor, customElement) {
        const { fragment, after_update } = component.$$;
        fragment && fragment.m(target, anchor);
        if (!customElement) {
            // onMount happens before the initial afterUpdate
            add_render_callback(() => {
                const new_on_destroy = component.$$.on_mount.map(run).filter(is_function);
                // if the component was destroyed immediately
                // it will update the `$$.on_destroy` reference to `null`.
                // the destructured on_destroy may still reference to the old array
                if (component.$$.on_destroy) {
                    component.$$.on_destroy.push(...new_on_destroy);
                }
                else {
                    // Edge case - component was destroyed immediately,
                    // most likely as a result of a binding initialising
                    run_all(new_on_destroy);
                }
                component.$$.on_mount = [];
            });
        }
        after_update.forEach(add_render_callback);
    }
    function destroy_component(component, detaching) {
        const $$ = component.$$;
        if ($$.fragment !== null) {
            run_all($$.on_destroy);
            $$.fragment && $$.fragment.d(detaching);
            // TODO null out other refs, including component.$$ (but need to
            // preserve final state?)
            $$.on_destroy = $$.fragment = null;
            $$.ctx = [];
        }
    }
    function make_dirty(component, i) {
        if (component.$$.dirty[0] === -1) {
            dirty_components.push(component);
            schedule_update();
            component.$$.dirty.fill(0);
        }
        component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
    }
    function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) {
        const parent_component = current_component;
        set_current_component(component);
        const $$ = component.$$ = {
            fragment: null,
            ctx: [],
            // state
            props,
            update: noop,
            not_equal,
            bound: blank_object(),
            // lifecycle
            on_mount: [],
            on_destroy: [],
            on_disconnect: [],
            before_update: [],
            after_update: [],
            context: new Map(options.context || (parent_component ? parent_component.$$.context : [])),
            // everything else
            callbacks: blank_object(),
            dirty,
            skip_bound: false,
            root: options.target || parent_component.$$.root
        };
        append_styles && append_styles($$.root);
        let ready = false;
        $$.ctx = instance
            ? instance(component, options.props || {}, (i, ret, ...rest) => {
                const value = rest.length ? rest[0] : ret;
                if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
                    if (!$$.skip_bound && $$.bound[i])
                        $$.bound[i](value);
                    if (ready)
                        make_dirty(component, i);
                }
                return ret;
            })
            : [];
        $$.update();
        ready = true;
        run_all($$.before_update);
        // `false` as a special case of no DOM component
        $$.fragment = create_fragment ? create_fragment($$.ctx) : false;
        if (options.target) {
            if (options.hydrate) {
                const nodes = children(options.target);
                // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                $$.fragment && $$.fragment.l(nodes);
                nodes.forEach(detach);
            }
            else {
                // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                $$.fragment && $$.fragment.c();
            }
            if (options.intro)
                transition_in(component.$$.fragment);
            mount_component(component, options.target, options.anchor, options.customElement);
            flush();
        }
        set_current_component(parent_component);
    }
    /**
     * Base class for Svelte components. Used when dev=false.
     */
    class SvelteComponent {
        $destroy() {
            destroy_component(this, 1);
            this.$destroy = noop;
        }
        $on(type, callback) {
            if (!is_function(callback)) {
                return noop;
            }
            const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
            callbacks.push(callback);
            return () => {
                const index = callbacks.indexOf(callback);
                if (index !== -1)
                    callbacks.splice(index, 1);
            };
        }
        $set($$props) {
            if (this.$$set && !is_empty($$props)) {
                this.$$.skip_bound = true;
                this.$$set($$props);
                this.$$.skip_bound = false;
            }
        }
    }

    //import base64url from "base64url";
    class Token {
        _raw;
        header;
        payload;
        constructor(token, parse_as_jwt = true) {
            this._raw = token;
            if (!parse_as_jwt)
                return;
            let parts;
            parts = token.split('.');
            let sheader = parts[0];
            let spayload = parts[1];
            sheader = this.decode_base64url(sheader);
            spayload = this.decode_base64url(spayload);
            this.header = JSON.parse(sheader);
            this.payload = JSON.parse(spayload);
        }
        get raw() {
            return this._raw;
        }
        get is_jwt() {
            if (this.header == undefined)
                return false;
            if (this.header == null)
                return false;
            if (this.header["typ"] === "JWT")
                return true;
            else
                return false;
        }
        get not_expired() {
            let exp;
            exp = this.get_claim("exp");
            if (exp === undefined)
                return false;
            let margin_s = 2 * 60; // 2 min default
            let iat;
            iat = this.get_claim("iat");
            if (iat) {
                const tokenDuration_min = (exp - iat) / 60;
                if (tokenDuration_min > 59) {
                    margin_s = 5 * 60; // 5 min
                }
                else if (tokenDuration_min > 29) {
                    margin_s = 3 * 60; // 3 min
                }
                else if (tokenDuration_min > 14) {
                    margin_s = 2 * 60; // 2 min
                }
                else if (tokenDuration_min > 9) {
                    margin_s = 1.5 * 60; // 1.5 min
                }
                else if (tokenDuration_min > 4) {
                    margin_s = 60; // 1 min
                }
                else {
                    margin_s = 15; // 15 sec
                }
            }
            const now = Math.floor(Date.now() / 1000);
            if (exp > now + margin_s)
                return true;
            return false;
        }
        get_claim(key) {
            if (this.payload == undefined)
                return undefined;
            if (this.payload == null)
                return undefined;
            let v;
            v = this.payload[key];
            if (v === undefined)
                return undefined;
            return v;
        }
        decode_base64url(input) {
            let output = input;
            output = output.replace('-', '+');
            output = output.replace('_', '/');
            switch (output.length % 4) {
                case 0:
                    break;
                case 2:
                    output += "==";
                    break;
                case 3:
                    output += "=";
                    break;
                default:
                    return "";
            }
            return atob(output);
        }
    }

    class Browser_storage {
        set(key, value, permanent = false) {
            if (permanent)
                localStorage.setItem(key, value);
            else
                sessionStorage.setItem(key, value);
        }
        set_num(key, value, permanent = false) {
            if (permanent)
                localStorage.setItem(key, value.toString());
            else
                sessionStorage.setItem(key, value.toString());
        }
        has(key) {
            let v = sessionStorage.getItem(key);
            if ((v != undefined) && (v != ""))
                return true;
            else {
                v = localStorage.getItem(key);
                if ((v != undefined) && (v != ""))
                    return true;
                else
                    return false;
            }
        }
        get(key, out) {
            let v = sessionStorage.getItem(key);
            if ((v != undefined) && (v != "")) {
                out(v);
                return true;
            }
            else {
                v = localStorage.getItem(key);
                if ((v != undefined) && (v != "")) {
                    out(v);
                    return true;
                }
                else
                    return false;
            }
        }
        get_num(key, out) {
            let vs;
            const ret = this.get(key, (v) => { vs = v; });
            if (ret)
                out(parseInt(vs));
            return ret;
        }
    }
    const gv = new Browser_storage;

    var Mode;
    (function (Mode) {
        Mode[Mode["Remote"] = 0] = "Remote";
        Mode[Mode["Local"] = 1] = "Local";
        Mode[Mode["Disabled"] = 2] = "Disabled";
    })(Mode || (Mode = {}));
    class Local_user {
        username;
        role = "";
        groupId = 0;
        uid = 0;
    }
    class Configuration {
        mode = Mode.Disabled;
        iss = "";
        client_id = "";
        client_secret = "";
        scope = "";
        local_api = "";
        local_users = [];
        api_version = "v001";
        tenant = "";
        groups_only = false;
        ask_organization_name = true;
        let_choose_group_first = false;
        refresh_token_persistent = true;
        terms_and_conditions_href = "";
        privacy_policy_href = "";
    }

    const subscriber_queue = [];
    /**
     * Creates a `Readable` store that allows reading by subscription.
     * @param value initial value
     * @param {StartStopNotifier}start start and stop notifications for subscriptions
     */
    function readable(value, start) {
        return {
            subscribe: writable(value, start).subscribe
        };
    }
    /**
     * Create a `Writable` store that allows both updating and reading by subscription.
     * @param {*=}value initial value
     * @param {StartStopNotifier=}start start and stop notifications for subscriptions
     */
    function writable(value, start = noop) {
        let stop;
        const subscribers = new Set();
        function set(new_value) {
            if (safe_not_equal(value, new_value)) {
                value = new_value;
                if (stop) { // store is ready
                    const run_queue = !subscriber_queue.length;
                    for (const subscriber of subscribers) {
                        subscriber[1]();
                        subscriber_queue.push(subscriber, value);
                    }
                    if (run_queue) {
                        for (let i = 0; i < subscriber_queue.length; i += 2) {
                            subscriber_queue[i][0](subscriber_queue[i + 1]);
                        }
                        subscriber_queue.length = 0;
                    }
                }
            }
        }
        function update(fn) {
            set(fn(value));
        }
        function subscribe(run, invalidate = noop) {
            const subscriber = [run, invalidate];
            subscribers.add(subscriber);
            if (subscribers.size === 1) {
                stop = start(set) || noop;
            }
            run(value);
            return () => {
                subscribers.delete(subscriber);
                if (subscribers.size === 0) {
                    stop();
                    stop = null;
                }
            };
        }
        return { set, update, subscribe };
    }
    function derived(stores, fn, initial_value) {
        const single = !Array.isArray(stores);
        const stores_array = single
            ? [stores]
            : stores;
        const auto = fn.length < 2;
        return readable(initial_value, (set) => {
            let inited = false;
            const values = [];
            let pending = 0;
            let cleanup = noop;
            const sync = () => {
                if (pending) {
                    return;
                }
                cleanup();
                const result = fn(single ? values[0] : values, set);
                if (auto) {
                    set(result);
                }
                else {
                    cleanup = is_function(result) ? result : noop;
                }
            };
            const unsubscribers = stores_array.map((store, i) => subscribe(store, (value) => {
                values[i] = value;
                pending &= ~(1 << i);
                if (inited) {
                    sync();
                }
            }, () => {
                pending |= (1 << i);
            }));
            inited = true;
            sync();
            return function stop() {
                run_all(unsubscribers);
                cleanup();
            };
        });
    }

    class User {
        given_name = "";
        family_name = "";
        picture = "";
        email = "";
        email_verified = false;
    }
    class Session {
        my_validation_ticket = 0;
        _is_active = false;
        _user;
        _id_token;
        _access_token;
        _refresh_token;
        storage;
        appInstanceInfo = null;
        configuration;
        sessionId;
        constructor(storage) {
            this.storage = storage;
            if (typeof globalThis !== "undefined" &&
                globalThis.crypto &&
                typeof globalThis.crypto.getRandomValues === "function") {
                let arr = new Uint8Array((16) / 2);
                globalThis.crypto.getRandomValues(arr);
                const dec2hex = (dec) => dec.toString(16).padStart(2, "0");
                this.sessionId = Array.from(arr, dec2hex).join('');
            }
        }
        configure(cfg, internal = false) {
            console.log('configure', 'internal', internal, cfg);
            this.configuration = new Configuration;
            if (cfg) {
                switch (cfg.mode) {
                    case 'remote':
                        this.configuration.mode = Mode.Remote;
                        this.configuration.iss = cfg.remote.iss;
                        this.configuration.client_id = cfg.remote.client_id ?? cfg.remote.clientID;
                        this.configuration.client_secret = cfg.remote.client_secret ?? cfg.remote.clientSecret;
                        this.configuration.scope = cfg.remote.scope;
                        this.configuration.api_version = cfg.remote.api_version ?? cfg.remote.apiVersion ?? "v001";
                        this.configuration.tenant = cfg.remote.tenant ?? "";
                        this.configuration.groups_only = cfg.remote.groupsOnly ?? cfg.remote.groups_only ?? false;
                        this.configuration.ask_organization_name = cfg.remote.ask_organization_name ?? cfg.remote.askOrganizationName ?? true;
                        this.configuration.refresh_token_persistent = cfg.remote.refresh_token_persistent ?? cfg.remote.refreshTokenPersistent ?? true;
                        this.configuration.terms_and_conditions_href = cfg.remote.terms_and_conditions_href ?? cfg.remote.termsAndConditionsHRef;
                        this.configuration.privacy_policy_href = cfg.remote.privacy_policy_href ?? cfg.remote.privacyPolicyHRef;
                        this.configuration.let_choose_group_first = cfg.remote.let_choose_group_first ?? cfg.remote.letChooseGroupFirst ?? false;
                        break;
                    case 'local':
                        this.configuration.mode = Mode.Local;
                        this.configuration.local_api = cfg.local.api;
                        this.configuration.api_version = cfg.local.api_version ?? cfg.local.apiVersion ?? "v001";
                        this.configuration.local_users = [];
                        if (cfg.local.users && Array.isArray(cfg.local.users)) {
                            cfg.local.users.forEach(u => {
                                switch (typeof u) {
                                    case 'string':
                                        {
                                            const user = new Local_user();
                                            user.username = u;
                                            this.configuration.local_users.push(user);
                                        }
                                        break;
                                    case 'object':
                                        {
                                            const user = new Local_user();
                                            user.username = u.username ?? "";
                                            user.role = u.role ?? "";
                                            user.groupId = u.groupId ?? 0;
                                            user.uid = u.uid ?? 0;
                                            this.configuration.local_users.push(user);
                                        }
                                        break;
                                }
                            });
                        }
                        break;
                    case 'disabled':
                        this.configuration.mode = Mode.Disabled;
                        this.configuration.local_api = cfg.local.api;
                        this.configuration.api_version = cfg.local.api_version ?? cfg.local.apiVersion ?? "v001";
                        break;
                }
            }
            else {
                this.configuration.mode = Mode.Disabled;
            }
            this.setup_mode(this.configuration.mode);
            if (!internal) {
                this.storage.set('_hd_auth_cfg', JSON.stringify(cfg));
                if (this.isValid)
                    this.boost_validation_ticket();
                let new_session = new Session(this.storage);
                new_session.clone_from(this);
                session.set(new_session); // forces store subscribers
            }
        }
        clone_from(src) {
            this.my_validation_ticket = src.my_validation_ticket;
            this._is_active = src._is_active;
            this._user = src._user;
            this._id_token = src._id_token;
            this._access_token = src._access_token;
            this._refresh_token = src._refresh_token;
            this.configuration = src.configuration;
        }
        get isActive() {
            if (!this.isValid)
                this.validate();
            return this._is_active;
        }
        get user() {
            if (!this.isValid)
                this.validate();
            return this._user;
        }
        get idToken() {
            if (!this.isValid)
                this.validate();
            return this._id_token;
        }
        get accessToken() {
            if (!this.isValid)
                this.validate();
            return this._access_token;
        }
        get refreshToken() {
            if (!this.isValid)
                this.validate();
            return this._refresh_token;
        }
        get isValid() {
            let ticket;
            if (!this.storage.get_num("_hd_auth_session_validation_ticket", (v) => { ticket = v; }))
                return false;
            return (ticket == this.my_validation_ticket);
        }
        get apiAddress() {
            let res;
            if (this.storage.get("_hd_auth_api_address", (v) => { res = v; }))
                return res;
            else
                return "";
        }
        get tid() {
            let res;
            if (this.storage.get("_hd_auth_tenant", (v) => { res = v; }))
                return res;
            else
                return "";
        }
        get appId() {
            let scopes = this.configuration.scope.split(' ');
            if (!scopes.length)
                return '';
            //remove predefined scopes
            scopes = scopes.filter(s => (s != 'openid') && (s != 'profile') && (s != 'email') && (s != 'address') && (s != 'phone'));
            if (!scopes.length)
                return '';
            let app_id = scopes[0];
            return app_id;
        }
        get tenants() {
            let res;
            if (!this.storage.get("_hd_signedin_tenants", (v) => { res = v; }))
                return [];
            if (!res)
                return [];
            const tenants = JSON.parse(res);
            return tenants;
        }
        set tenants(infos) {
            const tInfos = JSON.stringify(infos);
            this.storage.set("_hd_signedin_tenants", tInfos, false);
        }
        get isUnauthorizedGuest() {
            let result = false;
            let res;
            if (!this.storage.get("_hd_auth_unauthorized_guest", (v) => { res = v; }))
                result = false;
            else if (res == "1")
                result = true;
            else
                result = false;
            return result;
        }
        set isUnauthorizedGuest(val) {
            this.storage.set("_hd_auth_unauthorized_guest", val ? "1" : "", true);
        }
        validate() {
            console.log('auth: session validate');
            if (!this.storage.get_num("_hd_auth_session_validation_ticket", (v) => { this.my_validation_ticket = v; })) {
                this.my_validation_ticket = 1;
                this.storage.set_num("_hd_auth_session_validation_ticket", this.my_validation_ticket);
            }
            if (!this.configuration) {
                let cfg_json;
                if (this.storage.get('_hd_auth_cfg', (v) => cfg_json = v)) {
                    try {
                        let cfg = JSON.parse(cfg_json);
                        this.configure(cfg, true);
                    }
                    catch (err) {
                        console.error(err);
                    }
                }
            }
            if (this.disabled) {
                this.setCurrentTenantAPI(this.configuration.local_api, '');
                this._is_active = true;
                return;
            }
            else if (this.local) {
                if (this.localDevCurrentUser) {
                    this._is_active = true;
                }
                else {
                    this._is_active = false;
                }
                this.setCurrentTenantAPI(this.configuration.local_api, '');
                return;
            }
            this._is_active = false;
            let token;
            if (this.storage.get("_hd_auth_id_token", (v) => { token = v; })) {
                this._id_token = new Token(token);
                this._user = new User();
                this._user.given_name = this._id_token.get_claim("given_name");
                this._user.family_name = this._id_token.get_claim("family_name");
                this._user.picture = this._id_token.get_claim("picture");
                this._user.email = this._id_token.get_claim("email");
                this._user.email_verified = this._id_token.get_claim("email_verified");
            }
            else
                this._id_token = null;
            if (this.storage.get("_hd_auth_access_token", (v) => { token = v; }))
                this._access_token = new Token(token);
            else
                this._access_token = null;
            if (this.storage.get("_hd_auth_refresh_token", (v) => { token = v; }))
                this._refresh_token = new Token(token, false);
            else
                this._refresh_token = null;
            if ((this._access_token != null) || (this._id_token != null))
                this._is_active = true;
        }
        checkStorageConsistency() {
            let error = false;
            error = this.checkStoredKey('_hd_auth_cfg') || error;
            error = this.checkStoredKey('_hd_signedin_tenants') || error;
            error = this.checkStoredKey('_hd_auth_id_token') || error;
            error = this.checkStoredKey('_hd_auth_access_token') || error;
            error = this.checkStoredKey('_hd_auth_refresh_token') || error;
            error = this.checkStoredKey('_hd_auth_api_address') || error;
            error = this.checkStoredKey('_hd_auth_tenant') || error;
            error = this.checkStoredKey('_hd_auth_last_chosen_tenant_id') || error;
            error = this.checkStoredKey('_hd_auth_session_validation_ticket') || error;
            return !error;
        }
        checkStoredKey(key) {
            let val;
            this.storage.get(key, (v) => val = v);
            if (!val) {
                console.log('checkStorageConsistency ', key, ' empty');
                return true;
            }
            return false;
        }
        refreshTokens(tokens_info, chosen_tenant_id = undefined) {
            if (!tokens_info.access_token)
                return false;
            if (!tokens_info.id_token)
                return false;
            if (!tokens_info.refresh_token)
                return false;
            this.storage.set("_hd_auth_id_token", tokens_info.id_token);
            this.storage.set("_hd_auth_access_token", tokens_info.access_token);
            this.storage.set("_hd_auth_refresh_token", tokens_info.refresh_token, this.configuration.refresh_token_persistent);
            this._id_token = new Token(tokens_info.id_token);
            this._user = new User();
            this._user.given_name = this._id_token.get_claim("given_name");
            this._user.family_name = this._id_token.get_claim("family_name");
            this._user.picture = this._id_token.get_claim("picture");
            this._user.email = this._id_token.get_claim("email");
            this._user.email_verified = this._id_token.get_claim("email_verified");
            this._access_token = new Token(tokens_info.access_token);
            this._refresh_token = new Token(tokens_info.refresh_token, false);
            this._is_active = true;
            if (tokens_info.tenant != undefined) {
                this.setCurrentTenantAPI(tokens_info.tenant.url, tokens_info.tenant.id);
                this.tenants = [tokens_info.tenant];
            }
            else if ((tokens_info.tenants != undefined) && (tokens_info.tenants.length > 0)) {
                if (tokens_info.tenants.length == 1)
                    this.setCurrentTenantAPI(tokens_info.tenants[0].url, tokens_info.tenants[0].id);
                else {
                    if (chosen_tenant_id) {
                        const chosen_tenant = tokens_info.tenants.find(el => el.id == chosen_tenant_id);
                        if (chosen_tenant)
                            this.setCurrentTenantAPI(chosen_tenant.url, chosen_tenant.id);
                        else
                            this.setCurrentTenantAPI(tokens_info.tenants[0].url, tokens_info.tenants[0].id);
                    }
                    else
                        this.setCurrentTenantAPI(tokens_info.tenants[0].url, tokens_info.tenants[0].id);
                }
                this.tenants = tokens_info.tenants;
            }
            else
                return false;
            return true;
        }
        signin(tokens_info, chosen_tenant_id = undefined) {
            if ((tokens_info.access_token == undefined) || (tokens_info.access_token == "")) {
                this.signout();
                return true;
            }
            if ((tokens_info.id_token == undefined) || (tokens_info.id_token == "")) {
                this.signout();
                return true;
            }
            if ((tokens_info.refresh_token == undefined) || (tokens_info.refresh_token == "")) {
                this.signout();
                return true;
            }
            this.storage.set("_hd_auth_access_token", tokens_info.access_token);
            this.storage.set("_hd_auth_id_token", tokens_info.id_token);
            this.storage.set("_hd_auth_refresh_token", tokens_info.refresh_token, this.configuration.refresh_token_persistent);
            if (tokens_info.tenant != undefined) {
                this.setCurrentTenantAPI(tokens_info.tenant.url, tokens_info.tenant.id);
                this.tenants = [tokens_info.tenant];
            }
            else if ((tokens_info.tenants != undefined) && (tokens_info.tenants.length > 0)) {
                if (tokens_info.tenants.length == 1)
                    this.setCurrentTenantAPI(tokens_info.tenants[0].url, tokens_info.tenants[0].id);
                else {
                    if (chosen_tenant_id) {
                        const chosen_tenant = tokens_info.tenants.find(el => el.id == chosen_tenant_id);
                        if (chosen_tenant)
                            this.setCurrentTenantAPI(chosen_tenant.url, chosen_tenant.id);
                        else
                            this.setCurrentTenantAPI(tokens_info.tenants[0].url, tokens_info.tenants[0].id);
                    }
                    else
                        this.setCurrentTenantAPI(tokens_info.tenants[0].url, tokens_info.tenants[0].id);
                }
                this.tenants = tokens_info.tenants;
            }
            else if ((tokens_info.apps != undefined) && (tokens_info.apps.length > 0)) {
                // todo: multi app not supported yet?
                this.signout();
                return false;
            }
            else {
                this.signout();
                return false;
            }
            this.boost_validation_ticket();
            this.validate();
            this.checkServerAndClientTimeMismatch();
            let new_session = new Session(this.storage);
            new_session.clone_from(this);
            session.set(new_session); // forces store subscribers
            return true;
        }
        checkServerAndClientTimeMismatch() {
            if (!this._access_token)
                return;
            const serverTime = this._access_token.get_claim("iat");
            if (!serverTime)
                return;
            const clientTime = Math.floor(Date.now() / 1000);
            const timeShift = clientTime - serverTime;
            // now just logging. In the near future we need to store this value and use on Token::not_expired property
            console.log('Server/Client time mismatch: ', timeShift);
        }
        boost_validation_ticket() {
            let validation_ticket = 0;
            this.storage.get_num("_hd_auth_session_validation_ticket", (v) => { validation_ticket = v; });
            validation_ticket++;
            this.storage.set_num("_hd_auth_session_validation_ticket", validation_ticket);
            this.my_validation_ticket = validation_ticket;
        }
        setCurrentTenantAPI(url, tid) {
            this.storage.set("_hd_auth_api_address", url);
            this.storage.set("_hd_auth_tenant", tid);
            this.storage.set('_hd_auth_last_chosen_tenant_id', tid, true);
        }
        get lastChosenTenantId() {
            let res;
            if (!this.storage.get('_hd_auth_last_chosen_tenant_id', (v) => res = v))
                return '';
            return res;
        }
        signout() {
            this.storage.set("_hd_auth_id_token", "");
            this.storage.set("_hd_auth_access_token", "");
            this.storage.set("_hd_auth_refresh_token", "", this.configuration.refresh_token_persistent);
            this.storage.set("_hd_auth_api_address", "");
            this.storage.set("_hd_auth_tenant", "");
            this.storage.set("_hd_auth_local_dev_user", "");
            this.storage.set('_hd_auth_unauthorized_guest', "", true);
            this.storage.set("_hd_signedin_tenants", "");
            this._id_token = null;
            this._access_token = null;
            this._refresh_token = null;
            this._is_active = false;
            this.boost_validation_ticket();
            let new_session = new Session(this.storage);
            new_session.clone_from(this);
            session.set(new_session); // forces store subscribers
        }
        appAccessRole() {
            if (!this.configuration)
                return '';
            const scopes = this.configuration.scope.split(' ');
            if ((!scopes) || scopes.length == 0)
                return '';
            const appId = scopes[scopes.length - 1];
            if (!this.isActive)
                return '';
            const token = this.accessToken;
            if (token == undefined)
                return '';
            if (token == null)
                return '';
            if (!token.raw)
                return '';
            if (!token.is_jwt)
                return '';
            const access = token.payload['access'];
            if (!!access &&
                access.length > 0) {
                const scopeIdx = access.findIndex(e => e['app'] == appId);
                if (scopeIdx < 0)
                    return '';
                const accessScope = access[scopeIdx];
                const scopeTenants = accessScope['tenants'];
                if (!scopeTenants || scopeTenants.length == 0)
                    return '';
                for (let i = 0; i < scopeTenants.length; i++) {
                    const tenantInfo = scopeTenants[i];
                    if (typeof tenantInfo === 'object' && tenantInfo !== null) {
                        if (tenantInfo['tid'] == this.tid) {
                            if (!tenantInfo.details)
                                return '';
                            const accessDetails = JSON.parse(tenantInfo.details);
                            return accessDetails.role ?? '';
                        }
                    }
                }
                return '';
            }
            else
                return '';
        }
        authAccessGroup() {
            return this.accessGroup("auth");
        }
        filesAccessGroup() {
            return this.accessGroup("files");
        }
        accessGroup(scope) {
            if (!this.isActive)
                return 0;
            const token = this.accessToken;
            if (token == undefined)
                return 0;
            if (token == null)
                return 0;
            if (!token.raw)
                return 0;
            if (!token.is_jwt)
                return 0;
            const access = token.payload['access'];
            if (!!access &&
                access.length > 0) {
                const scopeIdx = access.findIndex(e => e['app'] == scope);
                if (scopeIdx < 0)
                    return 0;
                const accessScope = access[scopeIdx];
                const scopeTenants = accessScope['tenants'];
                if (!scopeTenants || scopeTenants.length == 0)
                    return 0;
                for (let i = 0; i < scopeTenants.length; i++) {
                    const tenantInfo = scopeTenants[i];
                    if (typeof tenantInfo === 'object' && tenantInfo !== null) {
                        if (tenantInfo['tid'] == this.tid)
                            return tenantInfo['gid'] ?? 0;
                    }
                }
                return 0;
            }
            else
                return 0;
        }
        async __is_admin() {
            if (!this.isValid)
                this.validate();
            if (!this.isActive)
                return false;
            if (this.tid == "")
                return false;
            let path;
            path = this.configuration.iss + "/auth/am_i_admin";
            path += "?tenant=" + this.tid;
            const res = await fetch(path, {
                method: 'get',
                headers: new Headers({
                    'Authorization': 'Bearer ' + this._access_token.raw,
                    'Accept': 'application/json'
                })
            });
            if (!res.ok)
                return false;
            const result = await res.json();
            return result.response === true;
        }
        get mode() {
            let num_mode = 0;
            if (!this.storage.get_num('_hd_auth_session_mode', (v) => { num_mode = v; }))
                return Mode.Remote;
            else
                switch (num_mode) {
                    case 0:
                        return Mode.Remote;
                    case 1:
                        return Mode.Local;
                    case 2:
                        return Mode.Disabled;
                    default:
                        return Mode.Remote;
                }
        }
        set mode(m) {
            switch (m) {
                case Mode.Remote:
                    this.storage.set_num("_hd_auth_session_mode", 0);
                    break;
                case Mode.Local:
                    this.storage.set_num("_hd_auth_session_mode", 1);
                    break;
                case Mode.Disabled:
                    this.storage.set_num("_hd_auth_session_mode", 2);
                    break;
            }
        }
        get remote() {
            return (this.mode == Mode.Remote);
        }
        get local() {
            return (this.mode == Mode.Local);
        }
        get disabled() {
            return (this.mode == Mode.Disabled);
        }
        setup_mode(m) {
            this.mode == Mode.Remote;
            //this.signout();
            this.mode = m;
            if (m == Mode.Remote) ;
            else {
                if (this.configuration && this.configuration.local_api) ;
            }
        }
        setLocalDevCurrentUser(email) {
            this.storage.set('_hd_auth_local_dev_user', email);
            this.boost_validation_ticket();
            this.validate();
            let new_session = new Session(this.storage);
            new_session.clone_from(this);
            session.set(new_session); // forces store subscribers
        }
        get localDevCurrentUser() {
            let email;
            this.storage.get('_hd_auth_local_dev_user', (v) => { email = v; });
            if (!email)
                return null;
            const foundUser = this.configuration.local_users.find(u => u.username == email);
            return foundUser;
        }
    }
    const session = writable(new Session(gv));

    let refreshingSemaphore = false;
    class reef {
        static configure(cfg) {
            let _session = get_store_value(session);
            _session.configure(cfg);
        }
        static async fetch(...args) {
            let [resource, options] = args;
            let given_url = '';
            given_url = resource;
            let _session = get_store_value(session);
            // check if resource is absolute url, if not we add session.apiAddress obtained with auth tokens
            let absolute_pattern = /^https?:\/\//i;
            if (!absolute_pattern.test(given_url)) {
                let full_path = _session.apiAddress;
                if (full_path.endsWith('/')) {
                    if (given_url.startsWith('/'))
                        full_path = full_path + given_url.substr(1);
                    else
                        full_path = full_path + given_url;
                }
                else {
                    if (given_url.startsWith('/'))
                        full_path = full_path + given_url;
                    else
                        full_path = full_path + '/' + given_url;
                }
                resource = full_path;
            }
            if ((options == undefined) || (options == null))
                options = {};
            if ((options.headers == undefined) || (options.headers == null))
                options.headers = new Headers();
            const hasConfiguration = _session && _session.configuration;
            const isRemoteSession = _session && _session.configuration && (_session.configuration.mode == Mode.Remote);
            if ((!hasConfiguration) || isRemoteSession) {
                if (!_session.checkStorageConsistency()) {
                    console.log('sessionStorage problem, full_path: ', resource);
                }
                if (!_session.isActive) {
                    console.log('session not active on fetch: ', resource);
                }
            }
            if (!options.headers.has("Authorization")) {
                if (_session.accessToken != null) {
                    if (!_session.accessToken.not_expired) {
                        console.log('sessionId:', _session.sessionId);
                        const iat = _session.accessToken.get_claim("iat");
                        const exp = _session.accessToken.get_claim("exp");
                        console.log('iat:', iat, new Date(iat * 1000));
                        console.log('exp:', exp, new Date(exp * 1000));
                        if (refreshingSemaphore) {
                            console.log('auth: request need to wait for tokens refreshing... ', resource);
                            const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
                            let triesNo = 10;
                            while (refreshingSemaphore && triesNo > 0) {
                                await sleep(1000);
                                triesNo--;
                            }
                            if (refreshingSemaphore) {
                                console.log('auth: too long refresh waiting. drop the request');
                                return null;
                            }
                        }
                        else {
                            console.log('auth: first req with expired token, refreshing...', resource);
                            //refreshingSemaphore = true;
                            const refreshingSuccess = await this.refreshTokens(_session);
                            //refreshingSemaphore = false;
                            if (!refreshingSuccess)
                                this.redirectToSignIn();
                        }
                    }
                    options.headers.append("Authorization", "Bearer " + _session.accessToken.raw);
                }
                else {
                    console.log('auth: setting up x-reef- headers for local developement');
                    const user = _session.localDevCurrentUser;
                    if (user) {
                        if (user.uid > 0) {
                            if (!options.headers.has("X-Reef-User-Id"))
                                options.headers.append('X-Reef-User-Id', user.uid);
                        }
                        else {
                            if (!options.headers.has("X-Reef-As-User"))
                                options.headers.append('X-Reef-As-User', user.username);
                        }
                        if (user.role) {
                            if (!options.headers.has("X-Reef-Access-Role"))
                                options.headers.append('X-Reef-Access-Role', user.role);
                        }
                        if (user.groupId) {
                            if (!options.headers.has("X-Reef-Group-Id"))
                                options.headers.append('X-Reef-Group-Id', user.groupId);
                        }
                    }
                }
            }
            if (_session.tenants.length > 0) {
                const tenantInfo = _session.tenants.find(t => t.id == _session.tid);
                if (tenantInfo && tenantInfo.headers && tenantInfo.headers.length > 0) {
                    tenantInfo.headers.forEach(h => options.headers.append(h.key, h.value));
                }
            }
            return fetch(resource, options);
        }
        static correct_path_with_api_version_if_needed(path) {
            if (path.startsWith('/json/'))
                return path;
            let apiver = 'v001'; // default
            let _session = get_store_value(session);
            if (_session && _session.configuration && _session.configuration.api_version)
                apiver = _session.configuration.api_version;
            if (path.startsWith('/'))
                return `/json/${apiver}${path}`;
            else
                return `/json/${apiver}/${path}`;
        }
        static get_general_cloud_address() {
            let result = '';
            const _session = get_store_value(session);
            const conf = _session.configuration;
            if (conf.mode == Mode.Remote)
                result = conf.iss;
            else
                result = conf.local_api;
            if (result.endsWith('/'))
                return result.substring(0, result.length - 1);
            else
                return result;
        }
        static async get(_path, onError) {
            let path = reef.correct_path_with_api_version_if_needed(_path);
            try {
                let res = await reef.fetch(path, {});
                if (res.ok) {
                    const response_string = await res.text();
                    if (!response_string)
                        return {};
                    else
                        return JSON.parse(response_string);
                }
                else {
                    const err = await res.text();
                    console.error(err);
                    if (onError)
                        onError(err);
                    return null;
                }
            }
            catch (err) {
                console.error(err);
                if (onError)
                    onError(err);
                return null;
            }
        }
        static async post(_path, request_object, onError) {
            let path = reef.correct_path_with_api_version_if_needed(_path);
            try {
                let res = await reef.fetch(path, {
                    method: 'POST',
                    body: JSON.stringify(request_object)
                });
                if (res.ok) {
                    const response_string = await res.text();
                    if (!response_string)
                        return {};
                    else
                        return JSON.parse(response_string);
                }
                else {
                    const err = await res.text();
                    console.error(err);
                    if (onError)
                        onError(err);
                    return null;
                }
            }
            catch (err) {
                console.error(err);
                if (onError)
                    onError(err);
                return null;
            }
        }
        static async delete(_path, onError) {
            let path = reef.correct_path_with_api_version_if_needed(_path);
            try {
                let res = await reef.fetch(path, { method: 'DELETE' });
                if (res.ok) {
                    const response_string = await res.text();
                    if (!response_string)
                        return {};
                    else
                        return JSON.parse(response_string);
                }
                else {
                    const err = await res.text();
                    console.error(err);
                    if (onError)
                        onError(err);
                    return null;
                }
            }
            catch (err) {
                console.error(err);
                if (onError)
                    onError(err);
                return null;
            }
        }
        static result_with(res) {
            refreshingSemaphore = false;
            return res;
        }
        static async refreshTokens(_session = null) {
            if (refreshingSemaphore) {
                console.log('pararell token refreshing');
                console.trace();
            }
            refreshingSemaphore = true;
            if (!_session)
                _session = get_store_value(session);
            console.log('refreshTokens');
            if (_session.refreshToken == null) {
                console.log('refreshToken is null');
                return reef.result_with(false);
            }
            let refresh_token = _session.refreshToken.raw;
            if (refresh_token == "") {
                console.log('refreshToken is empty');
                return reef.result_with(false);
            }
            let conf = _session.configuration;
            let data = new URLSearchParams();
            data.append("grant_type", "refresh_token");
            data.append("refresh_token", refresh_token);
            data.append("client_id", conf.client_id);
            data.append("scope", conf.scope);
            if (conf.tenant)
                data.append("tenant", conf.tenant);
            if (conf.groups_only)
                data.append("groups_only", "true");
            try {
                const res = await fetch(conf.iss + "/auth/token", {
                    method: 'post',
                    headers: new Headers({
                        'Authorization': 'Basic ' + btoa('' + conf.client_id + ':' + conf.client_secret),
                        'Content-Type': 'application/x-www-form-urlencoded',
                        'Accept': 'application/json'
                    }),
                    body: data,
                    credentials: "include"
                });
                if (res.ok) {
                    console.log('/auth/token 200 OK');
                    let tokens = await res.json();
                    if (tokens.tenants && Array.isArray(tokens.tenants) && tokens.tenants.length > 1) {
                        if (conf.tenant) // do we have global tenant specified?
                         {
                            let filteredTenants = [];
                            if (conf.groups_only)
                                filteredTenants = tokens.tenants.filter(t => t.id.startsWith(conf.tenant + '/'));
                            else
                                filteredTenants = tokens.tenants.filter(t => t.id.startsWith(conf.tenant));
                            tokens.tenants = [...filteredTenants];
                            if (tokens.tenants.length == 1) {
                                if (_session.refreshTokens(tokens)) {
                                    return reef.result_with(true);
                                }
                                else {
                                    console.log("Can't signin (1)", tokens);
                                    return reef.result_with(false);
                                }
                            }
                        }
                        const lastChosenTenantId = _session.lastChosenTenantId;
                        if (lastChosenTenantId) {
                            if (tokens.tenants.some(t => t.id == lastChosenTenantId)) // is last used included 
                             {
                                if (_session.refreshTokens(tokens, lastChosenTenantId)) {
                                    return reef.result_with(true);
                                }
                                else {
                                    console.log("Can't signin (2)", tokens);
                                    return reef.result_with(false);
                                }
                            }
                            else {
                                console.log("Can't signin (3)", lastChosenTenantId);
                                return reef.result_with(false);
                            }
                        }
                        else {
                            console.log("Can't signin (4)");
                            return reef.result_with(false);
                        }
                    }
                    if (_session.refreshTokens(tokens))
                        return reef.result_with(true);
                    else {
                        console.log("Can't signin (5)", tokens);
                        return reef.result_with(false);
                    }
                }
                else {
                    _session.signout(); // clean up session data
                    res.json().then((err) => console.log('refreshing tokens not succees: ', err.error, err.error_description));
                    return reef.result_with(false);
                }
            }
            catch (error) {
                _session.signout(); // clean up session data
                console.error(error);
                return reef.result_with(false);
            }
        }
        static async amIAdmin() {
            let _session = get_store_value(session);
            let tenant_id = _session.tid;
            let path = `/auth/am_i_admin?tenant=${tenant_id}`;
            try {
                let res = await reef.fetch(path, {});
                if (res.ok) {
                    const response_string = await res.text();
                    if (!response_string)
                        return false;
                    else {
                        let res = JSON.parse(response_string);
                        return res.response ?? false;
                    }
                }
                else
                    return false;
            }
            catch (err) {
                console.error(err);
                return false;
            }
        }
        static redirectToSignIn() {
            console.log('redirectToSignIn');
            let current_path;
            current_path = window.location.href;
            let navto = window.location.pathname;
            if (!navto)
                navto = '/';
            if (!navto.endsWith('/'))
                navto += '/';
            navto += "#/auth/signin?redirect=" + encodeURIComponent(current_path);
            //await tick();
            window.location.href = navto;
        }
        static async getAppInstanceInfo(onError) {
            let _session = get_store_value(session);
            if (_session.appInstanceInfo)
                return _session.appInstanceInfo;
            if (!_session.configuration.tenant)
                return null;
            let app_id = _session.appId;
            if (!app_id)
                return null;
            try {
                const res = await reef.fetch(`/dev/get-tenant-info?app_id=${app_id}&tenant_id=${_session.configuration.tenant}`, {});
                if (res.ok) {
                    let response = await res.json();
                    _session.appInstanceInfo = response;
                    return response;
                }
                else {
                    const err = await res.text();
                    console.error(err);
                    if (onError)
                        onError(err);
                    return null;
                }
            }
            catch (err) {
                console.error(err);
                if (onError)
                    onError(err);
                return null;
            }
        }
        static locationChanged(...args) {
            if (get_store_value(loc).href != window.location.href) {
                let event = new PopStateEvent('popstate', { state: {} });
                dispatchEvent(event);
            }
        }
    }
    function isBrowser() {
        return typeof window !== "undefined" && typeof window.location !== "undefined";
    }
    function get_location() {
        if (!isBrowser()) {
            return {
                href: '',
                location: '',
                querystring: '',
                base_address: '',
                orgin: ''
            };
        }
        const href = window.location.href;
        const hashPosition = href.indexOf('#/');
        let base_address = window.location.pathname;
        let location = (hashPosition > -1) ? href.substr(hashPosition + 1) : '/';
        const orgin = window.location.origin;
        // Check if there's a querystring
        const qsPosition = location.indexOf('?');
        let querystring = '';
        if (qsPosition > -1) {
            querystring = location.substr(qsPosition + 1);
            location = location.substr(0, qsPosition);
        }
        return { href, location, querystring, base_address, orgin };
    }
    const loc = readable(null, function start(set) {
        set(get_location());
        if (!isBrowser())
            return () => { };
        const update = () => { set(get_location()); };
        window.addEventListener('hashchange', update, false); // hash based routers
        window.addEventListener('popstate', (event) => { update(); }); // history based routers
        return function stop() {
            window.removeEventListener('hashchange', update, false);
            window.removeEventListener('popstate', (event) => { update(); });
        };
    });
    const _hd_auth_location = derived(loc, ($loc) => $loc.location);
    const _hd_auth_querystring = derived(loc, ($loc) => $loc.querystring);
    derived(loc, ($loc) => $loc.base_address);
    const signInHRef = derived(loc, ($loc) => '#/auth/signin?redirect=' + encodeURIComponent($loc.href));
    const signOutHRef = derived(loc, ($loc) => '#/auth/signout?redirect=' + encodeURIComponent($loc.orgin));
    const signUpHRef = derived(loc, ($loc) => '#/auth/signup?redirect=' + encodeURIComponent($loc.href));

    /* src\Authorize.svelte generated by Svelte v3.55.1 */

    function create_else_block$2(ctx) {
    	let p;
    	let t;

    	return {
    		c() {
    			p = element("p");
    			t = text("Redirecting..");
    			attr(p, "class", /*normalTextClass*/ ctx[1]);
    		},
    		m(target, anchor) {
    			insert(target, p, anchor);
    			append(p, t);
    		},
    		p(ctx, dirty) {
    			if (dirty & /*normalTextClass*/ 2) {
    				attr(p, "class", /*normalTextClass*/ ctx[1]);
    			}
    		},
    		d(detaching) {
    			if (detaching) detach(p);
    		}
    	};
    }

    // (343:0) {#if err_msg.length > 0}
    function create_if_block$4(ctx) {
    	let p;
    	let t0;
    	let t1;
    	let t2;
    	let br;
    	let t3;
    	let a;

    	return {
    		c() {
    			p = element("p");
    			t0 = text("Error: ");
    			t1 = text(/*err_msg*/ ctx[0]);
    			t2 = space();
    			br = element("br");
    			t3 = space();
    			a = element("a");
    			a.textContent = "Reload page";
    			attr(a, "href", "/");
    			attr(a, "class", "underline text-sm font-semibold cursor-pointer text-stone-900 dark:text-white");
    			attr(p, "class", /*errorTextClass*/ ctx[2]);
    		},
    		m(target, anchor) {
    			insert(target, p, anchor);
    			append(p, t0);
    			append(p, t1);
    			append(p, t2);
    			append(p, br);
    			append(p, t3);
    			append(p, a);
    		},
    		p(ctx, dirty) {
    			if (dirty & /*err_msg*/ 1) set_data(t1, /*err_msg*/ ctx[0]);

    			if (dirty & /*errorTextClass*/ 4) {
    				attr(p, "class", /*errorTextClass*/ ctx[2]);
    			}
    		},
    		d(detaching) {
    			if (detaching) detach(p);
    		}
    	};
    }

    function create_fragment$5(ctx) {
    	let if_block_anchor;

    	function select_block_type(ctx, dirty) {
    		if (/*err_msg*/ ctx[0].length > 0) return create_if_block$4;
    		return create_else_block$2;
    	}

    	let current_block_type = select_block_type(ctx);
    	let if_block = current_block_type(ctx);

    	return {
    		c() {
    			if_block.c();
    			if_block_anchor = empty();
    		},
    		m(target, anchor) {
    			if_block.m(target, anchor);
    			insert(target, if_block_anchor, anchor);
    		},
    		p(ctx, [dirty]) {
    			if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) {
    				if_block.p(ctx, dirty);
    			} else {
    				if_block.d(1);
    				if_block = current_block_type(ctx);

    				if (if_block) {
    					if_block.c();
    					if_block.m(if_block_anchor.parentNode, if_block_anchor);
    				}
    			}
    		},
    		i: noop,
    		o: noop,
    		d(detaching) {
    			if_block.d(detaching);
    			if (detaching) detach(if_block_anchor);
    		}
    	};
    }

    async function get_code_challenge(verifier) {
    	const encoder = new TextEncoder();
    	const data = encoder.encode(verifier);
    	let hashed = await window.crypto.subtle.digest('SHA-256', data);
    	let challenge = "";
    	let bytes = new Uint8Array(hashed);
    	let len = bytes.byteLength;

    	for (var i = 0; i < len; i++) {
    		challenge += String.fromCharCode(bytes[i]);
    	}

    	return btoa(challenge).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
    }

    function instance$5($$self, $$props, $$invalidate) {
    	let $session;
    	let $_hd_auth_querystring;
    	let $_hd_auth_location;
    	component_subscribe($$self, _hd_auth_querystring, $$value => $$invalidate(4, $_hd_auth_querystring = $$value));
    	component_subscribe($$self, _hd_auth_location, $$value => $$invalidate(5, $_hd_auth_location = $$value));
    	let redirect = "";
    	let code = "";
    	let state = "";
    	let desc = "";
    	let asGuest = false;
    	let err_msg = "";
    	let normalTextClass = '';
    	if (hasContext('__hd_auth_normal_text_class')) normalTextClass = getContext('__hd_auth_normal_text_class');
    	let errorTextClass = 'text-red-800';
    	if (hasContext('__hd_auth_error_text_class')) errorTextClass = getContext('__hd_auth_error_text_class');
    	const storage = gv;
    	const session$1 = session;
    	component_subscribe($$self, session$1, value => $$invalidate(11, $session = value));

    	async function initialize(location, querystring) {
    		let segments = location.split('/');
    		if (segments.length <= 1) return;
    		const last_segment = segments[segments.length - 1];
    		let cmd = last_segment;
    		let args = new URLSearchParams(querystring);
    		redirect = args.has("redirect") ? args.get("redirect") : "";
    		code = args.has("code") ? args.get("code") : "";
    		state = args.has("state") ? args.get("state") : "";
    		desc = args.has("desc") ? args.get("desc") : "";
    		asGuest = args.has("guest") ? true : false;
    		if (redirect.startsWith('#')) redirect = redirect.slice(1);
    		$$invalidate(0, err_msg = "");
    		let redirect_to = "/";

    		switch (cmd) {
    			case "signin":
    				{
    					if (redirect == "") redirect = "/";

    					if ($session.disabled) {
    						await tick();
    						window.location.replace(redirect);
    					} else if ($session.local) {
    						let navto = window.location.pathname;
    						if (!navto) navto = '/';
    						if (!navto.endsWith('/')) navto += '/';
    						navto += "#/auth-local?redirect=" + encodeURIComponent(redirect);
    						await tick();
    						window.location.replace(navto);
    					} else {
    						let session_refreshed_successfully = false;
    						if ($session?.refreshToken?.raw) session_refreshed_successfully = await reef.refreshTokens();

    						if (session_refreshed_successfully) {
    							await tick();
    							window.location.replace(redirect);
    						} else {
    							redirect_to = await generate_signin_redirection(redirect);
    							await tick();
    							window.location.replace(redirect_to);
    						}
    					}
    				}
    				break;
    			case "signout":
    				$session.signout();
    				await tick();
    				window.location.replace(redirect);
    				break;
    			case "signup":
    				{
    					if (redirect == "") redirect = "/";

    					if ($session.disabled) {
    						await tick();
    						window.location.replace(redirect);
    					} else if ($session.local) {
    						let navto = window.location.pathname;
    						if (!navto) navto = '/';
    						if (!navto.endsWith('/')) navto += '/';
    						navto += "#/auth/err?desc=Signup+is+not+supported+in+local+environment";
    						await tick();
    						window.location.replace(navto);
    					} else {
    						$session.signout();
    						redirect_to = await generate_signup_redirection(redirect);
    						await tick();
    						window.location.replace(redirect_to);
    					}
    				}
    				break;
    			case "cb":
    				redirect_to = await handle_authorization_callback();
    				await tick();
    				window.location.replace(redirect_to);
    				break;
    			case "err":
    				$$invalidate(0, err_msg = desc);
    				break;
    			default:
    				{
    					let navto = window.location.pathname;
    					if (!navto) navto = '/';
    					if (!navto.endsWith('/')) navto += '/';
    					navto += "#/auth/err?desc=Bad+request:+" + encodeURIComponent(window.location.href) + '+cmd:+' + encodeURIComponent(cmd) + '+location:+' + encodeURIComponent(location);
    					await tick();
    					window.location.replace(navto);
    				}
    				break;
    		}
    	}

    	async function generate_signin_redirection(redirection_after_signin) {
    		let conf = $session.configuration;
    		let result;
    		result = conf.iss + "/auth/authorize";
    		result += "?redirect_uri=" + encodeURIComponent(window.location.origin + "/#/auth/cb");
    		result += "&scope=" + encodeURIComponent(conf.scope);
    		result += "&grant_type=code";
    		result += "&client_id=" + conf.client_id;
    		if (conf.tenant) result += "&tenant=" + conf.tenant;
    		if (conf.ask_organization_name) result += "&org_name=true";
    		if (conf.groups_only) result += "&groups_only=true";
    		let code_verfier = push_code_verifier();
    		let code_challenge = await get_code_challenge(code_verfier);
    		result += "&code_challenge=" + code_challenge;
    		result += "&code_challenge_method=S256";
    		result += "&state=" + encodeURIComponent(redirection_after_signin);
    		if (conf.terms_and_conditions_href) result += "&terms=" + encodeURIComponent(conf.terms_and_conditions_href);
    		if (conf.privacy_policy_href) result += "&privacy=" + encodeURIComponent(conf.privacy_policy_href);
    		return result;
    	}

    	async function generate_signup_redirection(redirection_after_signin) {
    		let conf = $session.configuration;
    		let result;
    		result = conf.iss + "/auth/authorize";
    		result += "?redirect_uri=" + encodeURIComponent(window.location.origin + "/#/auth/cb");
    		result += "&scope=" + encodeURIComponent(conf.scope);
    		result += "&grant_type=code";
    		result += "&client_id=" + conf.client_id;
    		if (conf.tenant) result += "&tenant=" + conf.tenant;
    		if (conf.ask_organization_name) result += "&org_name=true";
    		if (conf.groups_only) result += "&groups_only=true";
    		let code_verfier = push_code_verifier();
    		let code_challenge = await get_code_challenge(code_verfier);
    		result += "&code_challenge=" + code_challenge;
    		result += "&code_challenge_method=S256";
    		result += "&state=" + encodeURIComponent(redirection_after_signin);
    		result += "&is_signup=true";
    		if (conf.terms_and_conditions_href) result += "&terms=" + encodeURIComponent(conf.terms_and_conditions_href);
    		if (conf.privacy_policy_href) result += "&privacy=" + encodeURIComponent(conf.privacy_policy_href);
    		return result;
    	}

    	function push_code_verifier() {
    		let array = new Uint32Array(56 / 2);
    		window.crypto.getRandomValues(array);
    		let verifier;

    		verifier = Array.from(array, dec => {
    			return ('0' + dec.toString(16)).substr(-2);
    		}).join('');

    		storage.set("_hd_auth_code_verifier", verifier);
    		return verifier;
    	}

    	function pop_code_verifier() {
    		let verifier = "";

    		storage.get("_hd_auth_code_verifier", v => {
    			verifier = v;
    		});

    		storage.set("_hd_auth_code_verifier", "");
    		return verifier;
    	}

    	async function handle_authorization_callback() {
    		if (asGuest) {
    			set_store_value(session$1, $session.isUnauthorizedGuest = true, $session);
    			return state;
    		}

    		if (code == "") return state;
    		let conf = $session.configuration;
    		let data = new URLSearchParams();
    		data.append("client_id", conf.client_id);
    		data.append("redirect_uri", window.location.origin + "/#/auth/cb");
    		data.append("code", code);
    		data.append("code_verifier", pop_code_verifier());
    		data.append("grant_type", "authorization_code");
    		if (conf.tenant) data.append("tenant", conf.tenant);
    		if (conf.groups_only) data.append("groups_only", "true");

    		try {
    			const res = await fetch(conf.iss + "/auth/token", {
    				method: 'post',
    				headers: new Headers({
    						'Content-Type': 'application/x-www-form-urlencoded',
    						'Accept': 'application/json'
    					}),
    				body: data,
    				credentials: "include"
    			});

    			if (res.ok) {
    				let tokens = await res.json();

    				// user needs to choose the tenant
    				if (tokens.tenants && Array.isArray(tokens.tenants) && tokens.tenants.length > 1) {
    					let lastChosenTenantId = $session.lastChosenTenantId;

    					if (conf.tenant) {
    						let filteredTenants = []; // do we have global tenant specified?
    						if (conf.groups_only) filteredTenants = tokens.tenants.filter(t => t.id.startsWith(conf.tenant + '/')); else filteredTenants = tokens.tenants.filter(t => t.id.startsWith(conf.tenant));
    						tokens.tenants = [...filteredTenants];

    						if (tokens.tenants.length == 1) {
    							if ($session.signin(tokens)) return state; else return "/#/auth/err?desc=Something+wrong+with+tokens.";
    						}
    					}

    					if (lastChosenTenantId) {
    						if (tokens.tenants.some(t => t.id == lastChosenTenantId)) {
    							if ($session.signin(tokens, lastChosenTenantId)) {
    								return state; // is last used included 
    							} else return "/#/auth/err?desc=Something+wrong+with+tokens.";
    						} else {
    							if (conf.let_choose_group_first) {
    								// let user choose. user is removed from last used tenant
    								storage.set("_hd_auth_obtained_tokens_info", JSON.stringify(tokens));

    								return '/#/auth/choose-tenant?redirect=' + encodeURIComponent(state);
    							} else {
    								const firstTenantId = tokens.tenants[0].id;

    								if ($session.signin(tokens, firstTenantId)) {
    									return state;
    								} else return "/#/auth/err?desc=Something+wrong+with+tokens.";
    							}
    						}
    					} else {
    						// let user choose. It's first time
    						if (conf.let_choose_group_first) {
    							storage.set("_hd_auth_obtained_tokens_info", JSON.stringify(tokens));
    							return '/#/auth/choose-tenant?redirect=' + encodeURIComponent(state);
    						} else {
    							const firstTenantId = tokens.tenants[0].id;

    							if ($session.signin(tokens, firstTenantId)) {
    								return state;
    							} else return "/#/auth/err?desc=Something+wrong+with+tokens.";
    						}
    					}
    				} /*
    if(conf.tenant)
    {
        


        if(lastChoosenTenantId && !isTenantIncluded(tokens.tenants, lastChoosenTenantId))
        {
            storage.set("_hd_auth_obtained_tokens_info", JSON.stringify(tokens))
            return '/#/auth/choose-tenant?redirect=' + encodeURIComponent(state);
        }
        
        if($session.signin(tokens, conf.tenant))
        {
            storage.set('_hd_auth_last_chosen_tenant_id', conf.tenant, true); //$session.configuration.refresh_token_persistent)
            return state;
        }
        else
            return "/#/auth/err?desc=Something+wrong+with+tokens.";
    }
    else
    {
        storage.set("_hd_auth_obtained_tokens_info", JSON.stringify(tokens))
        return '/#/auth/choose-tenant?redirect=' + encodeURIComponent(state);
    }
    */

    				if ($session.signin(tokens)) return state; else return "/#/auth/err?desc=Something+wrong+with+tokens.";
    			} else {
    				const result = await res.json();

    				let msg = !!result.error_description
    				? result.error_description
    				: "";

    				if (msg == "") msg = !!result.error ? result.error : "";
    				return "/#/auth/err?desc=" + encodeURIComponent(msg);
    			}
    		} catch(error) {
    			console.error(error);
    			return "/#/auth/err?desc=" + encodeURIComponent(error.toString());
    		}
    	}

    	$$self.$$.update = () => {
    		if ($$self.$$.dirty & /*$_hd_auth_location, $_hd_auth_querystring*/ 48) {
    			initialize($_hd_auth_location, $_hd_auth_querystring);
    		}
    	};

    	return [
    		err_msg,
    		normalTextClass,
    		errorTextClass,
    		session$1,
    		$_hd_auth_querystring,
    		$_hd_auth_location
    	];
    }

    class Authorize extends SvelteComponent {
    	constructor(options) {
    		super();
    		init(this, options, instance$5, create_fragment$5, safe_not_equal, {});
    	}
    }

    /* src\LocalAuthorize.svelte generated by Svelte v3.55.1 */

    function get_each_context$1(ctx, list, i) {
    	const child_ctx = ctx.slice();
    	child_ctx[7] = list[i];
    	const constants_0 = /*user*/ child_ctx[7].username;
    	child_ctx[8] = constants_0;
    	return child_ctx;
    }

    // (29:12) {#each $session.configuration.local_users as user}
    function create_each_block$1(ctx) {
    	let button;
    	let t0_value = /*username*/ ctx[8] + "";
    	let t0;
    	let t1;
    	let mounted;
    	let dispose;

    	function click_handler() {
    		return /*click_handler*/ ctx[5](/*username*/ ctx[8]);
    	}

    	return {
    		c() {
    			button = element("button");
    			t0 = text(t0_value);
    			t1 = space();
    			attr(button, "type", "button");
    			attr(button, "class", /*buttonClass*/ ctx[0]);
    		},
    		m(target, anchor) {
    			insert(target, button, anchor);
    			append(button, t0);
    			append(button, t1);

    			if (!mounted) {
    				dispose = listen(button, "click", click_handler);
    				mounted = true;
    			}
    		},
    		p(new_ctx, dirty) {
    			ctx = new_ctx;
    			if (dirty & /*$session*/ 2 && t0_value !== (t0_value = /*username*/ ctx[8] + "")) set_data(t0, t0_value);

    			if (dirty & /*buttonClass*/ 1) {
    				attr(button, "class", /*buttonClass*/ ctx[0]);
    			}
    		},
    		d(detaching) {
    			if (detaching) detach(button);
    			mounted = false;
    			dispose();
    		}
    	};
    }

    function create_fragment$4(ctx) {
    	let div2;
    	let div1;
    	let div0;
    	let h1;
    	let t1;
    	let hr;
    	let t2;
    	let each_value = /*$session*/ ctx[1].configuration.local_users;
    	let each_blocks = [];

    	for (let i = 0; i < each_value.length; i += 1) {
    		each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i));
    	}

    	return {
    		c() {
    			div2 = element("div");
    			div1 = element("div");
    			div0 = element("div");
    			h1 = element("h1");
    			h1.textContent = "Local sign in";
    			t1 = space();
    			hr = element("hr");
    			t2 = space();

    			for (let i = 0; i < each_blocks.length; i += 1) {
    				each_blocks[i].c();
    			}

    			attr(h1, "class", "mb-1 text-xl leading-tight tracking-tight text-stone-900 md:text-2xl dark:text-white font-normal");
    			attr(hr, "class", "min-w-full border-1 border-stone-400 opacity-75");
    			attr(div0, "class", "flex flex-col items-center");
    			attr(div1, "class", "w-full pt-2 pb-6 bg-stone-100 rounded-lg shadow dark:border md:mt-0 sm:max-w-md dark:bg-stone-700 bg-opacity-75");
    			attr(div2, "class", "flex flex-col items-center mt-0 sm:mt-10 ");
    		},
    		m(target, anchor) {
    			insert(target, div2, anchor);
    			append(div2, div1);
    			append(div1, div0);
    			append(div0, h1);
    			append(div0, t1);
    			append(div0, hr);
    			append(div0, t2);

    			for (let i = 0; i < each_blocks.length; i += 1) {
    				each_blocks[i].m(div0, null);
    			}
    		},
    		p(ctx, [dirty]) {
    			if (dirty & /*buttonClass, signin_local_user, $session*/ 11) {
    				each_value = /*$session*/ ctx[1].configuration.local_users;
    				let i;

    				for (i = 0; i < each_value.length; i += 1) {
    					const child_ctx = get_each_context$1(ctx, each_value, i);

    					if (each_blocks[i]) {
    						each_blocks[i].p(child_ctx, dirty);
    					} else {
    						each_blocks[i] = create_each_block$1(child_ctx);
    						each_blocks[i].c();
    						each_blocks[i].m(div0, null);
    					}
    				}

    				for (; i < each_blocks.length; i += 1) {
    					each_blocks[i].d(1);
    				}

    				each_blocks.length = each_value.length;
    			}
    		},
    		i: noop,
    		o: noop,
    		d(detaching) {
    			if (detaching) detach(div2);
    			destroy_each(each_blocks, detaching);
    		}
    	};
    }

    function instance$4($$self, $$props, $$invalidate) {
    	let $session;
    	let $_hd_auth_querystring;
    	component_subscribe($$self, _hd_auth_querystring, $$value => $$invalidate(4, $_hd_auth_querystring = $$value));
    	let buttonClass = 'mt-2 focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800';
    	if (hasContext('__hd_auth_button_class')) buttonClass = getContext('__hd_auth_button_class');
    	let redirect = "";
    	const session$1 = session;
    	component_subscribe($$self, session$1, value => $$invalidate(1, $session = value));

    	async function signin_local_user(user) {
    		$session.setLocalDevCurrentUser(user);

    		if (redirect) {
    			await tick();
    			window.location.replace(redirect);
    		}
    	}

    	const click_handler = username => {
    		signin_local_user(username);
    	};

    	$$self.$$.update = () => {
    		if ($$self.$$.dirty & /*$_hd_auth_querystring*/ 16) {
    			{
    				let args = new URLSearchParams($_hd_auth_querystring);
    				redirect = args.has("redirect") ? args.get("redirect") : "";
    			}
    		}
    	};

    	return [
    		buttonClass,
    		$session,
    		session$1,
    		signin_local_user,
    		$_hd_auth_querystring,
    		click_handler
    	];
    }

    class LocalAuthorize extends SvelteComponent {
    	constructor(options) {
    		super();
    		init(this, options, instance$4, create_fragment$4, safe_not_equal, {});
    	}
    }

    /* src\ChooseTenant.svelte generated by Svelte v3.55.1 */

    function get_each_context(ctx, list, i) {
    	const child_ctx = ctx.slice();
    	child_ctx[12] = list[i];
    	return child_ctx;
    }

    // (79:20) {:else}
    function create_else_block$1(ctx) {
    	let t_value = /*tenant*/ ctx[12].id + "";
    	let t;

    	return {
    		c() {
    			t = text(t_value);
    		},
    		m(target, anchor) {
    			insert(target, t, anchor);
    		},
    		p(ctx, dirty) {
    			if (dirty & /*tenants*/ 1 && t_value !== (t_value = /*tenant*/ ctx[12].id + "")) set_data(t, t_value);
    		},
    		d(detaching) {
    			if (detaching) detach(t);
    		}
    	};
    }

    // (77:20) {#if tenant.name}
    function create_if_block$3(ctx) {
    	let t_value = /*tenant*/ ctx[12].name + "";
    	let t;

    	return {
    		c() {
    			t = text(t_value);
    		},
    		m(target, anchor) {
    			insert(target, t, anchor);
    		},
    		p(ctx, dirty) {
    			if (dirty & /*tenants*/ 1 && t_value !== (t_value = /*tenant*/ ctx[12].name + "")) set_data(t, t_value);
    		},
    		d(detaching) {
    			if (detaching) detach(t);
    		}
    	};
    }

    // (67:12) {#each tenants as tenant}
    function create_each_block(ctx) {
    	let button;
    	let t;
    	let mounted;
    	let dispose;

    	function select_block_type(ctx, dirty) {
    		if (/*tenant*/ ctx[12].name) return create_if_block$3;
    		return create_else_block$1;
    	}

    	let current_block_type = select_block_type(ctx);
    	let if_block = current_block_type(ctx);

    	function click_handler() {
    		return /*click_handler*/ ctx[5](/*tenant*/ ctx[12]);
    	}

    	return {
    		c() {
    			button = element("button");
    			if_block.c();
    			t = space();
    			attr(button, "type", "button");
    			attr(button, "class", "mt-2 px-5 py-2.5 mr-2 mb-2 text-white bg-green-700 hover:bg-green-800 dark:bg-green-600 dark:hover:bg-green-700 focus:outline-none focus:ring-4 focus:ring-green-300 dark:focus:ring-green-800 font-medium text-sm rounded-lg");
    		},
    		m(target, anchor) {
    			insert(target, button, anchor);
    			if_block.m(button, null);
    			append(button, t);

    			if (!mounted) {
    				dispose = listen(button, "click", click_handler);
    				mounted = true;
    			}
    		},
    		p(new_ctx, dirty) {
    			ctx = new_ctx;

    			if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) {
    				if_block.p(ctx, dirty);
    			} else {
    				if_block.d(1);
    				if_block = current_block_type(ctx);

    				if (if_block) {
    					if_block.c();
    					if_block.m(button, t);
    				}
    			}
    		},
    		d(detaching) {
    			if (detaching) detach(button);
    			if_block.d();
    			mounted = false;
    			dispose();
    		}
    	};
    }

    function create_fragment$3(ctx) {
    	let div2;
    	let div1;
    	let div0;
    	let h1;
    	let t1;
    	let hr;
    	let t2;
    	let each_value = /*tenants*/ ctx[0];
    	let each_blocks = [];

    	for (let i = 0; i < each_value.length; i += 1) {
    		each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
    	}

    	return {
    		c() {
    			div2 = element("div");
    			div1 = element("div");
    			div0 = element("div");
    			h1 = element("h1");
    			h1.textContent = "Choose a group";
    			t1 = space();
    			hr = element("hr");
    			t2 = space();

    			for (let i = 0; i < each_blocks.length; i += 1) {
    				each_blocks[i].c();
    			}

    			attr(h1, "class", "mb-1 text-xl leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white font-normal");
    			attr(hr, "class", "min-w-full border-1 border-zinc-400 opacity-75");
    			attr(div0, "class", "flex flex-col items-center");
    			attr(div1, "class", "w-full pt-2 pb-6 bg-zinc-100 rounded-lg shadow dark:border md:mt-0 sm:max-w-md dark:bg-zinc-700 bg-opacity-75");
    			attr(div2, "class", "flex flex-col items-center mt-0 sm:mt-10 ");
    		},
    		m(target, anchor) {
    			insert(target, div2, anchor);
    			append(div2, div1);
    			append(div1, div0);
    			append(div0, h1);
    			append(div0, t1);
    			append(div0, hr);
    			append(div0, t2);

    			for (let i = 0; i < each_blocks.length; i += 1) {
    				each_blocks[i].m(div0, null);
    			}
    		},
    		p(ctx, [dirty]) {
    			if (dirty & /*select_tenant, tenants*/ 5) {
    				each_value = /*tenants*/ ctx[0];
    				let i;

    				for (i = 0; i < each_value.length; i += 1) {
    					const child_ctx = get_each_context(ctx, each_value, i);

    					if (each_blocks[i]) {
    						each_blocks[i].p(child_ctx, dirty);
    					} else {
    						each_blocks[i] = create_each_block(child_ctx);
    						each_blocks[i].c();
    						each_blocks[i].m(div0, null);
    					}
    				}

    				for (; i < each_blocks.length; i += 1) {
    					each_blocks[i].d(1);
    				}

    				each_blocks.length = each_value.length;
    			}
    		},
    		i: noop,
    		o: noop,
    		d(detaching) {
    			if (detaching) detach(div2);
    			destroy_each(each_blocks, detaching);
    		}
    	};
    }

    function instance$3($$self, $$props, $$invalidate) {
    	let $session;
    	let $_hd_auth_querystring;
    	let $_hd_auth_location;
    	component_subscribe($$self, _hd_auth_querystring, $$value => $$invalidate(3, $_hd_auth_querystring = $$value));
    	component_subscribe($$self, _hd_auth_location, $$value => $$invalidate(4, $_hd_auth_location = $$value));
    	let redirect;
    	let tenants = [];
    	let tokens_info;
    	const storage = gv;
    	const session$1 = session;
    	component_subscribe($$self, session$1, value => $$invalidate(8, $session = value));

    	async function initialize(location, querystring) {
    		let args = new URLSearchParams(querystring);
    		redirect = args.has("redirect") ? args.get("redirect") : "";
    		if (!redirect) return await error("Parameter 'redirect' not specified");
    		let tis;

    		if (!storage.get("_hd_auth_obtained_tokens_info", v => {
    			tis = v;
    		})) return await error("Unknown tokens info");

    		storage.set("_hd_auth_obtained_tokens_info", '');
    		if (!tis) return await error("Unknown tokens info");
    		tokens_info = JSON.parse(tis);
    		if (!tokens_info) return await error("Unknown tokens info");
    		let tenants_info = tokens_info.tenants;
    		if (tenants_info && Array.isArray(tenants_info) && tenants_info.length > 0) $$invalidate(0, tenants = tenants_info); else return await error("Tenants list not specified in resulted tokens info");
    	}

    	async function select_tenant(tenant) {
    		if ($session.signin(tokens_info, tenant.id)) {
    			await tick();
    			window.location.replace(redirect);
    		} else await error("Something wrong with tokens");
    	}

    	async function error(msg) {
    		await tick();
    		window.location.replace("/#/auth/err?desc=" + encodeURIComponent(msg));
    		return msg;
    	}

    	const click_handler = tenant => {
    		select_tenant(tenant);
    	};

    	$$self.$$.update = () => {
    		if ($$self.$$.dirty & /*$_hd_auth_location, $_hd_auth_querystring*/ 24) {
    			initialize($_hd_auth_location, $_hd_auth_querystring);
    		}
    	};

    	return [
    		tenants,
    		session$1,
    		select_tenant,
    		$_hd_auth_querystring,
    		$_hd_auth_location,
    		click_handler
    	];
    }

    class ChooseTenant extends SvelteComponent {
    	constructor(options) {
    		super();
    		init(this, options, instance$3, create_fragment$3, safe_not_equal, {});
    	}
    }

    /* src\AuthorizedView.svelte generated by Svelte v3.55.1 */

    function create_else_block(ctx) {
    	let div1;
    	let div0;
    	let current_block_type_index;
    	let if_block;
    	let current;
    	const if_block_creators = [create_if_block_1, create_if_block_2, create_if_block_3, create_else_block_1];
    	const if_blocks = [];

    	function select_block_type_1(ctx, dirty) {
    		if (/*show*/ ctx[3] == AUTHORIZE) return 0;
    		if (/*show*/ ctx[3] == CHOOSE_LOCAL_USER) return 1;
    		if (/*show*/ ctx[3] == CHOOSE_TENANT) return 2;
    		return 3;
    	}

    	current_block_type_index = select_block_type_1(ctx);
    	if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);

    	return {
    		c() {
    			div1 = element("div");
    			div0 = element("div");
    			if_block.c();
    			attr(div0, "class", /*layoutClass*/ ctx[1]);
    			attr(div1, "class", /*layoutTheme*/ ctx[0]);
    		},
    		m(target, anchor) {
    			insert(target, div1, anchor);
    			append(div1, div0);
    			if_blocks[current_block_type_index].m(div0, null);
    			current = true;
    		},
    		p(ctx, dirty) {
    			let previous_block_index = current_block_type_index;
    			current_block_type_index = select_block_type_1(ctx);

    			if (current_block_type_index === previous_block_index) {
    				if_blocks[current_block_type_index].p(ctx, dirty);
    			} else {
    				group_outros();

    				transition_out(if_blocks[previous_block_index], 1, 1, () => {
    					if_blocks[previous_block_index] = null;
    				});

    				check_outros();
    				if_block = if_blocks[current_block_type_index];

    				if (!if_block) {
    					if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
    					if_block.c();
    				} else {
    					if_block.p(ctx, dirty);
    				}

    				transition_in(if_block, 1);
    				if_block.m(div0, null);
    			}

    			if (!current || dirty & /*layoutClass*/ 2) {
    				attr(div0, "class", /*layoutClass*/ ctx[1]);
    			}

    			if (!current || dirty & /*layoutTheme*/ 1) {
    				attr(div1, "class", /*layoutTheme*/ ctx[0]);
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(if_block);
    			current = true;
    		},
    		o(local) {
    			transition_out(if_block);
    			current = false;
    		},
    		d(detaching) {
    			if (detaching) detach(div1);
    			if_blocks[current_block_type_index].d();
    		}
    	};
    }

    // (106:0) {#if show == CONTENT}
    function create_if_block$2(ctx) {
    	let current;
    	const default_slot_template = /*#slots*/ ctx[14].default;
    	const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[13], null);

    	return {
    		c() {
    			if (default_slot) default_slot.c();
    		},
    		m(target, anchor) {
    			if (default_slot) {
    				default_slot.m(target, anchor);
    			}

    			current = true;
    		},
    		p(ctx, dirty) {
    			if (default_slot) {
    				if (default_slot.p && (!current || dirty & /*$$scope*/ 8192)) {
    					update_slot_base(
    						default_slot,
    						default_slot_template,
    						ctx,
    						/*$$scope*/ ctx[13],
    						!current
    						? get_all_dirty_from_scope(/*$$scope*/ ctx[13])
    						: get_slot_changes(default_slot_template, /*$$scope*/ ctx[13], dirty, null),
    						null
    					);
    				}
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(default_slot, local);
    			current = true;
    		},
    		o(local) {
    			transition_out(default_slot, local);
    			current = false;
    		},
    		d(detaching) {
    			if (default_slot) default_slot.d(detaching);
    		}
    	};
    }

    // (118:8) {:else}
    function create_else_block_1(ctx) {
    	let p;
    	let t;

    	return {
    		c() {
    			p = element("p");
    			t = text("Validating session..");
    			attr(p, "class", /*normalTextClass*/ ctx[2]);
    		},
    		m(target, anchor) {
    			insert(target, p, anchor);
    			append(p, t);
    		},
    		p(ctx, dirty) {
    			if (dirty & /*normalTextClass*/ 4) {
    				attr(p, "class", /*normalTextClass*/ ctx[2]);
    			}
    		},
    		i: noop,
    		o: noop,
    		d(detaching) {
    			if (detaching) detach(p);
    		}
    	};
    }

    // (116:40) 
    function create_if_block_3(ctx) {
    	let choosetenant;
    	let current;
    	choosetenant = new ChooseTenant({});

    	return {
    		c() {
    			create_component(choosetenant.$$.fragment);
    		},
    		m(target, anchor) {
    			mount_component(choosetenant, target, anchor);
    			current = true;
    		},
    		p: noop,
    		i(local) {
    			if (current) return;
    			transition_in(choosetenant.$$.fragment, local);
    			current = true;
    		},
    		o(local) {
    			transition_out(choosetenant.$$.fragment, local);
    			current = false;
    		},
    		d(detaching) {
    			destroy_component(choosetenant, detaching);
    		}
    	};
    }

    // (114:44) 
    function create_if_block_2(ctx) {
    	let localauthorize;
    	let current;
    	localauthorize = new LocalAuthorize({});

    	return {
    		c() {
    			create_component(localauthorize.$$.fragment);
    		},
    		m(target, anchor) {
    			mount_component(localauthorize, target, anchor);
    			current = true;
    		},
    		p: noop,
    		i(local) {
    			if (current) return;
    			transition_in(localauthorize.$$.fragment, local);
    			current = true;
    		},
    		o(local) {
    			transition_out(localauthorize.$$.fragment, local);
    			current = false;
    		},
    		d(detaching) {
    			destroy_component(localauthorize, detaching);
    		}
    	};
    }

    // (112:8) {#if show == AUTHORIZE}
    function create_if_block_1(ctx) {
    	let authorize;
    	let current;
    	authorize = new Authorize({});

    	return {
    		c() {
    			create_component(authorize.$$.fragment);
    		},
    		m(target, anchor) {
    			mount_component(authorize, target, anchor);
    			current = true;
    		},
    		p: noop,
    		i(local) {
    			if (current) return;
    			transition_in(authorize.$$.fragment, local);
    			current = true;
    		},
    		o(local) {
    			transition_out(authorize.$$.fragment, local);
    			current = false;
    		},
    		d(detaching) {
    			destroy_component(authorize, detaching);
    		}
    	};
    }

    function create_fragment$2(ctx) {
    	let current_block_type_index;
    	let if_block;
    	let if_block_anchor;
    	let current;
    	const if_block_creators = [create_if_block$2, create_else_block];
    	const if_blocks = [];

    	function select_block_type(ctx, dirty) {
    		if (/*show*/ ctx[3] == CONTENT) return 0;
    		return 1;
    	}

    	current_block_type_index = select_block_type(ctx);
    	if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);

    	return {
    		c() {
    			if_block.c();
    			if_block_anchor = empty();
    		},
    		m(target, anchor) {
    			if_blocks[current_block_type_index].m(target, anchor);
    			insert(target, if_block_anchor, anchor);
    			current = true;
    		},
    		p(ctx, [dirty]) {
    			let previous_block_index = current_block_type_index;
    			current_block_type_index = select_block_type(ctx);

    			if (current_block_type_index === previous_block_index) {
    				if_blocks[current_block_type_index].p(ctx, dirty);
    			} else {
    				group_outros();

    				transition_out(if_blocks[previous_block_index], 1, 1, () => {
    					if_blocks[previous_block_index] = null;
    				});

    				check_outros();
    				if_block = if_blocks[current_block_type_index];

    				if (!if_block) {
    					if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
    					if_block.c();
    				} else {
    					if_block.p(ctx, dirty);
    				}

    				transition_in(if_block, 1);
    				if_block.m(if_block_anchor.parentNode, if_block_anchor);
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(if_block);
    			current = true;
    		},
    		o(local) {
    			transition_out(if_block);
    			current = false;
    		},
    		d(detaching) {
    			if_blocks[current_block_type_index].d(detaching);
    			if (detaching) detach(if_block_anchor);
    		}
    	};
    }

    const WAITING = 0;
    const CHOOSE_LOCAL_USER = 1;
    const AUTHORIZE = 2;
    const CHOOSE_TENANT = 3;
    const CONTENT = 4;

    function instance$2($$self, $$props, $$invalidate) {
    	let show;
    	let $session;
    	let $_hd_auth_querystring;
    	let $_hd_auth_location;
    	component_subscribe($$self, _hd_auth_querystring, $$value => $$invalidate(15, $_hd_auth_querystring = $$value));
    	component_subscribe($$self, _hd_auth_location, $$value => $$invalidate(12, $_hd_auth_location = $$value));
    	let { $$slots: slots = {}, $$scope } = $$props;
    	let { isDisabled = false } = $$props;
    	let { automaticallyRefreshTokens = false } = $$props;
    	let { autoRedirectToSignIn = true } = $$props;
    	let { optionalGuestMode = false } = $$props;
    	let { layoutTheme = '' } = $$props;
    	let { layoutClass = '' } = $$props;
    	let { buttonClass = '' } = $$props;
    	let { normalTextClass = '' } = $$props;
    	let { errorTextClass = '' } = $$props;
    	const session$1 = session;
    	component_subscribe($$self, session$1, value => $$invalidate(11, $session = value));
    	if (layoutClass) setContext('__hd_auth_layout_class', layoutClass);
    	if (buttonClass) setContext('__hd_auth_button_class', buttonClass);
    	if (normalTextClass) setContext('__hd_auth_normal_text_class', normalTextClass);
    	if (errorTextClass) setContext('__hd_auth_error_text_class', errorTextClass);

    	function what_to_show(...args) {
    		let location = $_hd_auth_location;
    		let params = new URLSearchParams($_hd_auth_querystring);
    		params.has('gid') ? params.get('gid') : '';

    		if (optionalGuestMode) {
    			if ($session.isUnauthorizedGuest) return CONTENT;
    		}

    		if (isDisabled) {
    			return CONTENT;
    		} else if (location.startsWith('/auth-local')) {
    			return CHOOSE_LOCAL_USER;
    		} else if (location.startsWith('/auth/choose-tenant')) {
    			return CHOOSE_TENANT;
    		} else if (location.startsWith('/auth')) {
    			return AUTHORIZE;
    		} else if ($session.isActive) {

    			return CONTENT;
    		} else if (automaticallyRefreshTokens) {
    			if ($session?.refreshToken?.raw) {
    				console.log('sessionId 2:', $session.sessionId);

    				reef.refreshTokens().then(res => {
    					if (!res) {
    						if (autoRedirectToSignIn) setTimeout(() => reef.redirectToSignIn(), 100); else {
    							$session.signout();

    							setTimeout(
    								() => {
    									window.location.href = '/';
    								},
    								100
    							);
    						}
    					} else {
    						$$invalidate(3, show = CONTENT);
    					}
    				});

    				return WAITING;
    			} else {
    				return CONTENT;
    			}
    		} else if (autoRedirectToSignIn) {

    			setTimeout(() => reef.redirectToSignIn(), 100);
    			return WAITING;
    		} else /*else if(landingForUnauthorized)
    {
        return CONTENT
    }
    */ {
    			return CONTENT;
    		}
    	}

    	$$self.$$set = $$props => {
    		if ('isDisabled' in $$props) $$invalidate(5, isDisabled = $$props.isDisabled);
    		if ('automaticallyRefreshTokens' in $$props) $$invalidate(6, automaticallyRefreshTokens = $$props.automaticallyRefreshTokens);
    		if ('autoRedirectToSignIn' in $$props) $$invalidate(7, autoRedirectToSignIn = $$props.autoRedirectToSignIn);
    		if ('optionalGuestMode' in $$props) $$invalidate(8, optionalGuestMode = $$props.optionalGuestMode);
    		if ('layoutTheme' in $$props) $$invalidate(0, layoutTheme = $$props.layoutTheme);
    		if ('layoutClass' in $$props) $$invalidate(1, layoutClass = $$props.layoutClass);
    		if ('buttonClass' in $$props) $$invalidate(9, buttonClass = $$props.buttonClass);
    		if ('normalTextClass' in $$props) $$invalidate(2, normalTextClass = $$props.normalTextClass);
    		if ('errorTextClass' in $$props) $$invalidate(10, errorTextClass = $$props.errorTextClass);
    		if ('$$scope' in $$props) $$invalidate(13, $$scope = $$props.$$scope);
    	};

    	$$self.$$.update = () => {
    		if ($$self.$$.dirty & /*$session, $_hd_auth_location*/ 6144) {
    			$$invalidate(3, show = what_to_show($session, $_hd_auth_location));
    		}
    	};

    	return [
    		layoutTheme,
    		layoutClass,
    		normalTextClass,
    		show,
    		session$1,
    		isDisabled,
    		automaticallyRefreshTokens,
    		autoRedirectToSignIn,
    		optionalGuestMode,
    		buttonClass,
    		errorTextClass,
    		$session,
    		$_hd_auth_location,
    		$$scope,
    		slots
    	];
    }

    class AuthorizedView extends SvelteComponent {
    	constructor(options) {
    		super();

    		init(this, options, instance$2, create_fragment$2, safe_not_equal, {
    			isDisabled: 5,
    			automaticallyRefreshTokens: 6,
    			autoRedirectToSignIn: 7,
    			optionalGuestMode: 8,
    			layoutTheme: 0,
    			layoutClass: 1,
    			buttonClass: 9,
    			normalTextClass: 2,
    			errorTextClass: 10
    		});
    	}
    }

    /* src\Authorized.svelte generated by Svelte v3.55.1 */

    function create_if_block$1(ctx) {
    	let current;
    	const default_slot_template = /*#slots*/ ctx[3].default;
    	const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null);

    	return {
    		c() {
    			if (default_slot) default_slot.c();
    		},
    		m(target, anchor) {
    			if (default_slot) {
    				default_slot.m(target, anchor);
    			}

    			current = true;
    		},
    		p(ctx, dirty) {
    			if (default_slot) {
    				if (default_slot.p && (!current || dirty & /*$$scope*/ 4)) {
    					update_slot_base(
    						default_slot,
    						default_slot_template,
    						ctx,
    						/*$$scope*/ ctx[2],
    						!current
    						? get_all_dirty_from_scope(/*$$scope*/ ctx[2])
    						: get_slot_changes(default_slot_template, /*$$scope*/ ctx[2], dirty, null),
    						null
    					);
    				}
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(default_slot, local);
    			current = true;
    		},
    		o(local) {
    			transition_out(default_slot, local);
    			current = false;
    		},
    		d(detaching) {
    			if (default_slot) default_slot.d(detaching);
    		}
    	};
    }

    function create_fragment$1(ctx) {
    	let if_block_anchor;
    	let current;
    	let if_block = (/*$session*/ ctx[0].isActive || /*$session*/ ctx[0].isUnauthorizedGuest) && create_if_block$1(ctx);

    	return {
    		c() {
    			if (if_block) if_block.c();
    			if_block_anchor = empty();
    		},
    		m(target, anchor) {
    			if (if_block) if_block.m(target, anchor);
    			insert(target, if_block_anchor, anchor);
    			current = true;
    		},
    		p(ctx, [dirty]) {
    			if (/*$session*/ ctx[0].isActive || /*$session*/ ctx[0].isUnauthorizedGuest) {
    				if (if_block) {
    					if_block.p(ctx, dirty);

    					if (dirty & /*$session*/ 1) {
    						transition_in(if_block, 1);
    					}
    				} else {
    					if_block = create_if_block$1(ctx);
    					if_block.c();
    					transition_in(if_block, 1);
    					if_block.m(if_block_anchor.parentNode, if_block_anchor);
    				}
    			} else if (if_block) {
    				group_outros();

    				transition_out(if_block, 1, 1, () => {
    					if_block = null;
    				});

    				check_outros();
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(if_block);
    			current = true;
    		},
    		o(local) {
    			transition_out(if_block);
    			current = false;
    		},
    		d(detaching) {
    			if (if_block) if_block.d(detaching);
    			if (detaching) detach(if_block_anchor);
    		}
    	};
    }

    function instance$1($$self, $$props, $$invalidate) {
    	let $session;
    	let { $$slots: slots = {}, $$scope } = $$props;
    	const session$1 = session;
    	component_subscribe($$self, session$1, value => $$invalidate(0, $session = value));

    	$$self.$$set = $$props => {
    		if ('$$scope' in $$props) $$invalidate(2, $$scope = $$props.$$scope);
    	};

    	return [$session, session$1, $$scope, slots];
    }

    class Authorized extends SvelteComponent {
    	constructor(options) {
    		super();
    		init(this, options, instance$1, create_fragment$1, safe_not_equal, {});
    	}
    }

    /* src\NotAuthorized.svelte generated by Svelte v3.55.1 */

    function create_if_block(ctx) {
    	let current;
    	const default_slot_template = /*#slots*/ ctx[3].default;
    	const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[2], null);

    	return {
    		c() {
    			if (default_slot) default_slot.c();
    		},
    		m(target, anchor) {
    			if (default_slot) {
    				default_slot.m(target, anchor);
    			}

    			current = true;
    		},
    		p(ctx, dirty) {
    			if (default_slot) {
    				if (default_slot.p && (!current || dirty & /*$$scope*/ 4)) {
    					update_slot_base(
    						default_slot,
    						default_slot_template,
    						ctx,
    						/*$$scope*/ ctx[2],
    						!current
    						? get_all_dirty_from_scope(/*$$scope*/ ctx[2])
    						: get_slot_changes(default_slot_template, /*$$scope*/ ctx[2], dirty, null),
    						null
    					);
    				}
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(default_slot, local);
    			current = true;
    		},
    		o(local) {
    			transition_out(default_slot, local);
    			current = false;
    		},
    		d(detaching) {
    			if (default_slot) default_slot.d(detaching);
    		}
    	};
    }

    function create_fragment(ctx) {
    	let if_block_anchor;
    	let current;
    	let if_block = !/*$session*/ ctx[0].isActive && !/*$session*/ ctx[0].isUnauthorizedGuest && create_if_block(ctx);

    	return {
    		c() {
    			if (if_block) if_block.c();
    			if_block_anchor = empty();
    		},
    		m(target, anchor) {
    			if (if_block) if_block.m(target, anchor);
    			insert(target, if_block_anchor, anchor);
    			current = true;
    		},
    		p(ctx, [dirty]) {
    			if (!/*$session*/ ctx[0].isActive && !/*$session*/ ctx[0].isUnauthorizedGuest) {
    				if (if_block) {
    					if_block.p(ctx, dirty);

    					if (dirty & /*$session*/ 1) {
    						transition_in(if_block, 1);
    					}
    				} else {
    					if_block = create_if_block(ctx);
    					if_block.c();
    					transition_in(if_block, 1);
    					if_block.m(if_block_anchor.parentNode, if_block_anchor);
    				}
    			} else if (if_block) {
    				group_outros();

    				transition_out(if_block, 1, 1, () => {
    					if_block = null;
    				});

    				check_outros();
    			}
    		},
    		i(local) {
    			if (current) return;
    			transition_in(if_block);
    			current = true;
    		},
    		o(local) {
    			transition_out(if_block);
    			current = false;
    		},
    		d(detaching) {
    			if (if_block) if_block.d(detaching);
    			if (detaching) detach(if_block_anchor);
    		}
    	};
    }

    function instance($$self, $$props, $$invalidate) {
    	let $session;
    	let { $$slots: slots = {}, $$scope } = $$props;
    	const session$1 = session;
    	component_subscribe($$self, session$1, value => $$invalidate(0, $session = value));

    	$$self.$$set = $$props => {
    		if ('$$scope' in $$props) $$invalidate(2, $$scope = $$props.$$scope);
    	};

    	return [$session, session$1, $$scope, slots];
    }

    class NotAuthorized extends SvelteComponent {
    	constructor(options) {
    		super();
    		init(this, options, instance, create_fragment, safe_not_equal, {});
    	}
    }

    exports.Authorized = Authorized;
    exports.AuthorizedView = AuthorizedView;
    exports.NotAuthorized = NotAuthorized;
    exports.reef = reef;
    exports.session = session;
    exports.signInHRef = signInHRef;
    exports.signOutHRef = signOutHRef;
    exports.signUpHRef = signUpHRef;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
//# sourceMappingURL=index.umd.js.map