{"version":3,"sources":["jsdelivr-header.js","/npm/fontsampler-js@0.1.4/src/fontsampler.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;ACGA,IAAI,OAAS,QAAQ,0BAEjB,WAAa,QAAQ,gBACrB,UAAY,QAAQ,QACpB,UAAY,QAAQ,eAEpB,OAAS,QAAQ,sBACjB,OAAS,QAAQ,sBACjB,UAAY,QAAQ,wBAEpB,QAAU,QAAQ,qBAClB,MAAQ,QAAQ,mBAChB,IAAM,QAAQ,iBACd,SAAW,QAAQ,sBAQvB,SAAS,YAAY,EAAO,EAAQ,GAChC,QAAQ,MAAM,gBAAiB,EAAO,EAAQ,GAE9C,IAAI,EAAI,EAAS,EACb,EAAY,IAAI,UAChB,GAAkB,EAElB,EAAY,KAAK,MAAM,KAAK,UAAU,YACtC,EAAO,KAKX,GAAI,OAAS,OACT,MAAM,IAAI,MAAM,OAAO,SAI3B,IAAK,EACD,MAAM,IAAI,MAAM,OAAO,YAAc,GAGzC,IAAK,MAAM,QAAQ,IAAW,EAAO,OAAS,EAC1C,MAAM,IAAI,MAAM,OAAO,cA0J3B,SAAS,IAGL,KAAK,KAAK,iBAAiB,OAAO,iBAAiB,WAC/C,IAAI,EAAM,EAAG,cACb,EAAG,iBAAiB,EACxB,IAGA,IAAI,EAAO,KACX,KAAK,KAAK,iBAAiB,OAAO,aAAa,SAAS,GAChD,EAAE,OAAO,WACwB,IAAtB,KAAgB,aACvB,EAAK,SAAS,EAAE,OAAO,KAGnC,GACJ,CASA,SAAS,EAAS,GAEd,IAAI,EAAW,EAAK,SA8BpB,GA5BA,EAAG,eAAe,EAAQ,QAAQ,cAAc,GAG5C,QAAS,EAAK,aAAe,EAAK,YAAY,KAC9C,QAAQ,MAAM,kCAAmC,EAAK,YAAY,KAClE,EAAG,YAAY,YAAa,EAAK,OAAS,UAC1C,EAAG,YAAY,aAAc,EAAK,QAAU,UAC5C,EAAG,YAAY,aAAc,IAC7B,EAAG,aAAa,EAAK,YAAY,KACxB,EAAK,YAAY,iBAG1B,QAAQ,MAAM,qCAAsC,EAAK,YAAa,GACtE,EAAK,YAAY,SAAW,EAC5B,EAAG,YAAY,aAAc,EAAS,QACtC,EAAG,YAAY,YAAa,EAAS,OAAS,UAC9C,EAAG,YAAY,aAAc,EAAS,QAAU,UAChD,EAAG,aAAa,IACP,EAAS,QAIlB,aAAc,EAAK,aACT,IAAM,EAAK,YAAY,SAIrC,EAAG,cAAc,EAAK,YAAY,MAC9B,aAAc,EAAK,cAAgB,EACnC,IAAK,IAAI,KAAO,EAAK,YAAY,SAC7B,EAAG,SAAS,EAAK,EAAK,YAAY,SAAS,IAKnD,EAAG,kBAAkB,EAAK,YAAY,UAGI,iBAA/B,EAAK,YAAoB,UAChC,EAAG,kBAAkB,EAAK,YAAY,UAG1C,EAAG,cAAc,EAAK,YAAY,MAElC,EAAU,SAGV,IAAI,gBAAgB,EAAK,KAAM,eAC/B,IAAI,gBAAgB,EAAK,KAAM,aAC/B,IAAI,aAAa,EAAK,KAAQ,EAAK,YAAY,SAAW,cAAe,aACzE,EAAM,cAAc,IAAI,YAAY,OAAO,aAAc,CACrD,OAAQ,CACJ,YAAa,KAIzB,CAmJA,OAjYA,KAAK,KAAO,EACZ,KAAK,aAAc,EACnB,KAAK,aAAc,EACnB,KAAK,YAAc,GAInB,EAyDA,SAAsB,GAClB,IAGI,EACA,EAJA,GAAmB,EACnB,EAAa,KAAK,KAAK,iBAAiB,eACxC,EAAc,GAGd,EAAS,GAIb,GAAI,YAAa,KAAK,KAAK,QACvB,IACI,EAAmB,KAAK,MAAM,KAAK,KAAK,QAAQ,QACpD,CAAE,MAAO,GACL,QAAQ,MAAM,EAClB,CAIgB,iBAAV,GAAmD,iBAAvB,EAClC,EAAkB,QAAO,EAAM,EAAK,GACb,iBAAV,EACb,EAAkB,EACkB,iBAAvB,IACb,EAAkB,GAgBlB,EAb4B,iBAAtB,EAaI,QAAO,EAAM,EAAU,GAEvB,EASd,GAAI,EAAW,OAAS,EACpB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAW,OAAQ,IACnC,EAAY,GAAK,EAAW,GAAG,QAAQ,KAG/C,EAAgC,iBAAV,GAAsB,UAAW,EAAM,MAAM,YAAY,EAAI,OAAS,GAC5F,EAA6B,iBAAV,GAAsB,OAAQ,EAAM,OAAO,KAAK,EAAI,IAAM,GAC7E,EAAS,EAAY,OAAO,EAAe,IAIT,KAHlC,EAAS,MAAM,YAAY,IAGhB,QAAQ,WACf,EAAO,KAAK,UAIG,iBAAR,GAAoB,UAAW,GAAO,MAAM,QAAQ,EAAI,QAAU,EAAI,MAAM,OACnF,EAAQ,MAAQ,EAAI,MAEQ,iBAArB,GAAiC,UAAW,GACnD,MAAM,QAAQ,EAAiB,QAAU,EAAiB,MAAM,SAChE,EAAQ,MAAQ,EAAiB,OAMrC,IADA,IAAI,EAAmB,MAAM,YAAY,EAAQ,OACxC,EAAI,EAAG,EAAI,EAAO,OAAQ,KACc,IAAzC,EAAiB,QAAQ,EAAO,KAChC,EAAQ,MAAM,KAAK,EAAO,IAIlC,OAAO,CACX,EA9IuB,KAAK,KAAM,GAClC,EAIA,SAAoB,GAGhB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAiB,OAAQ,IAAK,CAC9C,IAAI,EAAO,EAAiB,GAsB5B,GApBI,aAAc,GACd,EAAK,SAAW,QAAQ,eAAe,EAAK,UAC5C,EAAK,KAAO,OAAO,KAAK,EAAK,WAE7B,EAAK,KAAO,GAGV,UAAW,IACb,EAAK,MAAQ,UAGX,WAAY,IACd,EAAK,OAAS,IAGV,aAAc,GAAQ,SAAU,EAAK,WACrC,EAAK,OAAS,EAAK,SAAe,SAIpC,WAAY,IAAS,EAAK,MAC5B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,MAAM,OAAQ,IAAK,CACxC,IAAI,EAAI,EAAK,MAAM,GACf,EAAS,EAAE,UAAU,EAAE,YAAY,KAAO,GAG9C,GAFA,EAAS,EAAO,UAAU,EAAG,EAAO,YAAY,MAE5C,EAAQ,CACR,EAAK,OAAS,EAAO,QAAQ,OAAQ,IACrC,KACJ,CACJ,CAER,CAEA,OAAO,CACX,EA7CmB,KAAK,KAAM,GAC9B,EAAK,UAAU,KAAM,EAAO,GA2O5B,KAAK,KAAO,WACR,QAAQ,MAAM,qBAAsB,KAAM,KAAK,MAE/C,IAAI,EAAO,KACP,EAAc,EAElB,GAAI,eAAgB,EAAQ,QACxB,SAAU,EAAQ,OAAO,aAAe,GACG,iBAApC,EAAQ,OAAO,WAAe,MACF,KAAnC,EAAQ,OAAO,WAAW,KAE1B,EAAc,EAAQ,OAAO,WAAW,SACrC,CAIH,IAAI,EAAY,CAAC,EACjB,IAAK,IAAI,KAAO,EAAQ,OAChB,EAAG,UAAU,IAAQ,SAAU,EAAQ,OAAO,KAC9C,EAAU,GAAO,EAAQ,OAAO,GAAK,MAG7C,GAAsC,IAAlC,OAAO,KAAK,GAAW,OAAc,CAOrC,EAAK,KAAK,iBAAiB,OAAO,cANlC,SAAS,IACL,IAAK,IAAI,KAAQ,EACb,EAAG,SAAS,EAAM,EAAU,IAEhC,EAAK,KAAK,oBAAoB,OAAO,aAAc,EACvD,GAEJ,CACJ,CAwBA,OAtBA,EAAG,OACH,EAAc,KAAK,MACnB,KAAK,SAAS,KAAK,KAAM,GAErB,EAAQ,WACR,EAAG,eAAe,EAAQ,QAAQ,iBAAiB,GACnD,EAAU,KAAK,GAAO,WAClB,EAAG,eAAe,EAAQ,QAAQ,iBAAiB,GACnD,EAAM,cAAc,IAAI,YAAY,OAAO,gBAC/C,KAGJ,IAAI,aAAa,KAAK,KAAM,EAAQ,QAAQ,WAC5C,IAAI,aAAa,KAAK,KAAM,SAAS,MAAQ,aAAe,aAC5D,IAAI,aAAa,KAAK,KAAM,SAAS,cAAgB,sBAAwB,0BAE7E,KAAK,KAAK,cAAc,IAAI,YAAY,OAAO,OAC/C,KAAK,aAAc,EAKZ,IACX,EAKA,KAAK,SAAW,SAAS,GAErB,IAAI,EADJ,QAAQ,MAAM,uBAAwB,GAGtC,EAAU,QACV,EAAG,eAAe,EAAQ,QAAQ,cAAc,GAChD,EAAG,eAAe,EAAQ,QAAQ,cAAc,GAErB,iBAAjB,GACN,EAAO,EAAM,QAAO,SAAS,EAAO,GAChC,OAAO,EAAM,GAAO,OAAS,CACjC,IAAG,SAIC,QAAQ,KAAK,wBAA0B,EAAa,wCAAyC,GAC7F,EAAO,EAAM,IAEa,iBAAjB,GAA6B,GAAc,GAAK,GAAc,EAAM,SACjF,EAAO,EAAM,IAGb,KAAK,aAAe,KAAK,YAAY,OAAS,KAAK,UAAU,KAAK,YAAY,SAAW,KAAK,UAAU,EAAK,QAI7G,EAAK,SAAW,KAAK,YAAY,SACjC,KAAK,YAAc,EACnB,EAAS,KAAK,eAId,KAAK,YAAc,EAGnB,WAAW,UAAU,GAAM,SAAS,GAEhC,EAAK,SAAW,EAGhB,IAAI,EAAQ,CAAC,EACb,IAAK,IAAI,KAAK,EACV,EAAM,GAAK,EAAS,GAExB,EAAQ,KAAK,UAAU,IAEkB,IAArC,EAAK,YAAY,QAAQ,KACzB,EAAK,YAAY,KAAK,GACtB,EAAM,cAAc,IAAI,YAAY,OAAO,WAAY,CAAE,OAAQ,MAGrE,EAAS,EACb,IAAG,WACC,EAAG,eAAe,EAAQ,QAAQ,cAAc,GAChD,EAAG,eAAe,EAAQ,QAAQ,cAAc,GAChD,EAAK,aAAc,CACvB,GAAG,EAAQ,SAEnB,EAEA,KAAK,QAAU,SAAS,GACpB,EAAG,aAAa,EACpB,EAEA,KAAK,SAAW,SAAS,GACrB,OAAO,EAAG,SAAS,EACvB,EAEA,KAAK,SAAW,SAAS,EAAK,GAC1B,OAAO,EAAG,SAAS,EAAK,EAC5B,EAEA,KAAK,SAAW,SAAS,EAAK,GAC1B,OAAO,EAAG,cAAc,EAAK,EACjC,EAEA,KAAK,iBAAmB,SAAS,EAAO,GACpC,KAAK,KAAK,iBAAiB,EAAO,EACtC,EAEO,IACX,CAEA,OAAO,QAAU","file":"/npm/fontsampler-js@0.1.4/src/fontsampler.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.19.2.\n * Original file: /npm/fontsampler-js@0.1.4/src/fontsampler.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n * Fontsampler.js\n * \n * A configurable standalone webfont type tester for displaying and manipulating sample text.\n * \n * @author Johannes Neumeier <hello@underscoretype.com>\n * @copyright 2019-2024 Johannes Neumeier\n * @license GNU GPLv3\n */\nvar extend = require(\"../node_modules/extend\")\n\nvar Fontloader = require(\"./fontloader\")\nvar Interface = require(\"./ui\")\nvar Preloader = require(\"./preloader\")\n\nvar errors = require(\"./constants/errors\")\nvar events = require(\"./constants/events\")\nvar _defaults = require(\"./constants/defaults\")\n\nvar helpers = require(\"./helpers/helpers\")\nvar utils = require(\"./helpers/utils\")\nvar dom = require(\"./helpers/dom\")\nvar supports = require(\"./helpers/supports\")\n\n/**\n * The main constructor for setting up a new Fontsampler instance\n * @param Node root \n * @param Object | null fonts\n * @param Object | null opt\n */\nfunction Fontsampler(_root, _fonts, _options) {\n    console.debug(\"Fontsampler()\", _root, _fonts, _options)\n\n    var ui, options, fonts,\n        preloader = new Preloader(),\n        passedInOptions = false,\n        // deep clone the _defaults\n        defaults = (JSON.parse(JSON.stringify(_defaults))),\n        that = this\n\n    // Make sure new instances are create with new Fontsampler\n    // this will === window if Fontsampler() is used without\n    // the new keyword\n    if (this === window) {\n        throw new Error(errors.newInit)\n    }\n\n    // At the very least confirm a valid root element to render to\n    if (!_root) {\n        throw new Error(errors.missingRoot + _root)\n    }\n    \n    if (!Array.isArray(_fonts) || _fonts.length < 1) {\n        throw new Error(errors.missingFonts)\n    }\n    this.root = _root\n    this.initialized = false\n    this.currentFont = false\n    this.loadedFonts = []\n\n    // Parse fonts and options from the passed in objects or possibly\n    // from the root node data attributes\n    options = parseOptions.call(this, _options)\n    fonts = parseFonts.call(this, _fonts)\n    ui = Interface(this, fonts, options)\n\n\n    function parseFonts(font_definitions) {\n        \n        // Store each font, axes and parse instance definitions into obj form\n        for (var i = 0; i < font_definitions.length; i++) {\n            var font = font_definitions[i];\n\n            if (\"instance\" in font) {\n                font.instance = helpers.parseVariation(font.instance)\n                font.axes = Object.keys(font.instance)\n            } else {\n                font.axes = []\n            }\n\n            if (!(\"style\" in font)) {\n                font.style = \"normal\"\n            }\n\n            if (!(\"weight\" in font)) {\n                font.weight = 400\n                \n                // Set font weight implicitly from instance\n                if (\"instance\" in font && \"wght\" in font.instance) {\n                    font.weight = font.instance[\"wght\"]\n                }\n            }\n\n            if (!(\"family\" in font) && font.files) {                \n                for (let i = 0; i < font.files.length; i++) {\n                    let f = font.files[i];\n                    let family = f.substring(f.lastIndexOf(\"/\") + 1);\n                    family = family.substring(0, family.lastIndexOf(\".\"))\n\n                    if (family) {\n                        font.family = family.replace(/\\W/gm, \"\")\n                        break\n                    }\n                }\n            }\n        }\n\n        return font_definitions\n    }\n\n    /**\n     * \n     * @param {*} opt \n     * By default:\n     * - dont generate any DOM\n     * - if an element is set either in ui.xxx or order is set, generate those\n     * - if anything is present in the dom, validate and use those\n     * ALWAYS append tester if it is not present\n     */\n    function parseOptions(opt) {\n        var extractedOptions = false,\n            nodesInDom = this.root.querySelectorAll(\"[data-fsjs]\"),\n            blocksInDom = [],\n            blocksInOrder = [],\n            blocksInUI = [],\n            blocks = []\n\n        // Extend or use the default options in order of:\n        // defaults < options < data-options\n        if (\"options\" in this.root.dataset) {\n            try {\n                extractedOptions = JSON.parse(this.root.dataset.options)\n            } catch (e) {\n                console.error(e)\n            }\n        }\n\n        // Determine if we got any passed in options at all\n        if (typeof(opt) === \"object\" && typeof(extractedOptions) === \"object\") {\n            passedInOptions = extend(true, opt, extractedOptions)\n        } else if (typeof(opt) === \"object\") {\n            passedInOptions = opt\n        } else if (typeof(extractedOptions) === \"object\") {\n            passedInOptions = extractedOptions\n        }\n\n        if (typeof(passedInOptions) === \"object\") {\n            // If any of the passed in options.config.xxx are simply \"true\" instead of\n            // an boolean let’s copy the default values for this ui element\n            // if (\"ui\" in passedInOptions === true) {\n            //     for (var u in passedInOptions.config) {\n            //         if (passedInOptions.config.hasOwnProperty(u)) {\n            //             if (typeof(passedInOptions.config[u]) !== \"object\") {\n            //                 passedInOptions.config[u] = defaults.ui[u]\n            //             }\n            //         }\n            //     }\n            // }\n            // Extend the defaults\n            options = extend(true, defaults, passedInOptions)\n        } else {\n            options = defaults\n        }\n\n        // Go through all DOM UI nodes, passed in ui ´order´ options and ´ui´ options\n        // to determine what blocks are in the Fontsampler, and make sure all defined\n        // blocks get rendered. \"Defined\" can be a combination of:\n        // · block in the DOM\n        // · block in options.order\n        // · block in options.config\n        if (nodesInDom.length > 0) {\n            for (var b = 0; b < nodesInDom.length; b++) {\n                blocksInDom[b] = nodesInDom[b].dataset.fsjs\n            }\n        }\n        blocksInOrder = typeof(opt) === \"object\" && \"order\" in opt ? utils.flattenDeep(opt.order) : []\n        blocksInUI = typeof(opt) === \"object\" && \"ui\" in opt ? Object.keys(opt.ui) : []\n        blocks = blocksInDom.concat(blocksInOrder, blocksInUI)\n        blocks = utils.arrayUnique(blocks)\n\n        // Always make sure we are rendering at least a tester, no matter the configuration\n        if (blocks.indexOf(\"tester\") === -1) {\n            blocks.push(\"tester\")\n        }\n\n        // A passed in UI order superseeds, not extends!, the default\n        if (typeof opt === \"object\" && \"order\" in opt && Array.isArray(opt.order) && opt.order.length) {\n            options.order = opt.order\n        } else if (\n            typeof extractedOptions === \"object\" && \"order\" in extractedOptions &&\n            Array.isArray(extractedOptions.order) && extractedOptions.order.length) {\n            options.order = extractedOptions.order\n        }\n\n        // Then: check DOM and UI for any other present blocks and append them\n        // in case they are missing\n        var blocksInOrderNow = utils.flattenDeep(options.order)\n        for (var i = 0; i < blocks.length; i++) {\n            if (blocksInOrderNow.indexOf(blocks[i]) === -1) {\n                options.order.push(blocks[i])\n            }\n        }\n\n        return options\n    }\n\n    // Setup the interface listeners and delegate events back to the interface\n    function setupUIEvents() {\n\n        // checkbox\n        this.root.addEventListener(events.opentypeChanged, function() {\n            var val = ui.getOpentype()\n            ui.setInputOpentype(val)\n        })\n\n        // dropdowns\n        var that = this\n        this.root.addEventListener(events.fontChanged, function(e) {\n            if (e.detail.font) {\n                if (typeof(this.currentFont) === \"undefined\") {\n                    that.showFont(e.detail.font)\n                }\n            }\n        })\n    }\n\n    /**\n     * Encapuslation for what should happen on a font switch, either\n     * after the font has loaded or after the already current font\n     * has received this update (e.g. dropdown select of a variable\n     * font instance)\n     */\n    // function initFont(fontface) {\n    function initFont(font) {\n        var family = \"\"\n        let fontface = font.fontface;\n\n        ui.setStatusClass(options.classes.loadingClass, false)\n\n        // Try show a font by using a predefined 'cls'\n        if (\"cls\" in that.currentFont && that.currentFont.cls) {\n            console.debug(\"Fontsampler.initFont with class\", that.currentFont.cls)\n            ui.setInputCss(\"fontStyle\", font.style || \"normal\")\n            ui.setInputCss(\"fontWeight\", font.weight || \"normal\")\n            ui.setInputCss(\"fontFamily\", \"\")\n            ui.setFontClass(that.currentFont.cls)\n            family = that.currentFont[\"font-family\"]\n            \n        } else {\n            console.debug(\"Fontsampler.initFont without class\", that.currentFont, fontface)\n            that.currentFont.fontface = fontface\n            ui.setInputCss(\"fontFamily\", fontface.family)\n            ui.setInputCss(\"fontStyle\", fontface.style || \"normal\")\n            ui.setInputCss(\"fontWeight\", fontface.weight || \"normal\")\n            ui.setFontClass(\"\")\n            family = fontface.family\n        }\n\n        // Update the css font family\n        if (\"fallback\" in that.currentFont) {\n            family += \",\" + that.currentFont.fallback\n        }\n\n        // Update active axes and set variation of this instance\n        ui.setActiveAxes(that.currentFont.axes)\n        if (\"instance\" in that.currentFont === true) {\n            for (var tag in that.currentFont.instance) {\n                ui.setValue(tag, that.currentFont.instance[tag])\n            }\n        }\n\n        // Update available OT features for this font\n        ui.setActiveOpentype(that.currentFont.features)\n\n        // Update the currently select language if the font defines one\n        if (typeof(that.currentFont.language) === \"string\") {\n            ui.setActiveLanguage(that.currentFont.language)\n        }\n\n        ui.setActiveFont(that.currentFont.name)\n\n        preloader.resume()\n\n        // Set the is-instance or is-static class on the root\n        dom.nodeRemoveClass(that.root, \"is-instance\")\n        dom.nodeRemoveClass(that.root, \"is-static\")\n        dom.nodeAddClass(that.root, !!that.currentFont.instance ? \"is-instance\": \"is-static\")\n        _root.dispatchEvent(new CustomEvent(events.fontRendered, {\n            detail: {\n                fontsampler: that\n            }\n        }))\n\n    }\n\n    /**\n     * PUBLIC API\n     */\n\n    this.init = function() {\n        console.debug(\"Fontsampler.init()\", this, this.root)\n\n        var that = this,\n            initialFont = 0;\n\n        if (\"fontfamily\" in options.config &&\n            \"init\" in options.config.fontfamily === true &&\n            typeof(options.config.fontfamily.init) === \"string\" &&\n            options.config.fontfamily.init !== \"\") {\n\n            initialFont = options.config.fontfamily.init\n        } else {\n            // If the initial font was not set explicity and we have variable\n            // axes, then their init values should be set once the font has\n            // loaded\n            var axesInits = {}\n            for (var key in options.config) {\n                if (ui.isAxisKey(key) && \"init\" in options.config[key]) {\n                    axesInits[key] = options.config[key].init\n                }\n            }\n            if (Object.keys(axesInits).length === 0) {\n                function setAxesInits() {\n                    for (var axis in axesInits) {\n                        ui.setValue(axis, axesInits[axis])\n                    }\n                    that.root.removeEventListener(events.fontRendered, setAxesInits)\n                }\n                that.root.addEventListener(events.fontRendered, setAxesInits)\n            }\n        }\n\n        ui.init()\n        setupUIEvents.call(this)\n        this.showFont.call(this, initialFont)\n\n        if (options.lazyload) {\n            ui.setStatusClass(options.classes.preloadingClass, true)\n            preloader.load(fonts, function() {\n                ui.setStatusClass(options.classes.preloadingClass, false)\n                _root.dispatchEvent(new CustomEvent(events.fontsPreloaded))\n            })\n        }\n\n        dom.nodeAddClass(this.root, options.classes.initClass)\n        dom.nodeAddClass(this.root, supports.woff2 ? \"fsjs-woff2\" : \"fsjs-woff\")\n        dom.nodeAddClass(this.root, supports.variableFonts ? \"fsjs-variable-fonts\" : \"fsjs-no-variable-fonts\")\n\n        this.root.dispatchEvent(new CustomEvent(events.init))\n        this.initialized = true\n\n        // For convenience also have the init method return the instance\n        // This way you can create the object and init it, e.g.\n        // var fs = new Fontsampler().init()\n        return this\n    }\n\n    /**\n     * The public interface for showing (and possibly loading) a font\n     */\n    this.showFont = function(indexOrKey) {\n        console.debug(\"Fontsampler.showFont\", indexOrKey)\n        var font;\n\n        preloader.pause()\n        ui.setStatusClass(options.classes.loadingClass, true)\n        ui.setStatusClass(options.classes.timeoutClass, false)\n\n        if (typeof(indexOrKey) === \"string\") {\n            font = fonts.filter(function(value, index) {\n                return fonts[index].name === indexOrKey\n            }).pop()\n\n            // If no font or instance of that name is found in fonts default to first\n            if (!font) {\n                console.warn(\"Fontsampler.showFont(\" + indexOrKey + \") - font not found, using first font.\", fonts)\n                font = fonts[0]\n            }\n        } else if (typeof(indexOrKey) === \"number\" && indexOrKey >= 0 && indexOrKey <= fonts.length) {\n            font = fonts[indexOrKey]\n        }\n\n        if (this.currentFont && this.currentFont.files && JSON.stringify(this.currentFont.files) === JSON.stringify(font.files)) {\n            // Same font file (Variation might be different)\n            // Skip straight to \"fontLoaded\" procedure, but retain the fontface\n            // of the currentFont\n            font.fontface = this.currentFont.fontface\n            this.currentFont = font\n            initFont(this.currentFont)\n\n        } else {\n            // Load a new font file\n            this.currentFont = font\n\n            // The actual font load\n            Fontloader.fromFiles(font, function(fontface) {\n\n                font.fontface = fontface\n\n                // Generate a unique string for this fontface, cache as loaded\n                var fjson = {};\n                for (let k in fontface) {\n                    fjson[k] = fontface[k]\n                }\n                fjson = JSON.stringify(fjson)\n                \n                if (that.loadedFonts.indexOf(fjson) === -1) {\n                    that.loadedFonts.push(fjson)\n                    _root.dispatchEvent(new CustomEvent(events.fontLoaded, { detail: fontface }))\n                }\n\n                initFont(font)\n            }, function( /* fontface */ ) {\n                ui.setStatusClass(options.classes.loadingClass, false)\n                ui.setStatusClass(options.classes.timeoutClass, true)\n                that.currentFont = false\n            }, options.timeout)\n        }\n    }\n\n    this.setText = function(text) {\n        ui.setInputText(text)\n    }\n\n    this.getValue = function(key) {\n        return ui.getValue(key)\n    }\n\n    this.setValue = function(key, value) {\n        return ui.setValue(key, value)\n    }\n\n    this.setLabel = function(key, value) {\n        return ui.setLabelValue(key, value)\n    }\n\n    this.addEventListener = function(event, listener) {\n        this.root.addEventListener(event, listener)\n    }\n\n    return this\n}\n\nmodule.exports = Fontsampler"]}