{"version":3,"sources":["plugins/src/PluginManager.js"],"names":["$","Craft","PluginManager","Garnish","Base","extend","this","getPluginLicenseInfo","handle","response","hasOwnProperty","isComposerInstalled","Plugin","addUninstalledPluginRow","sendApiRequest","resolve","reject","params","include","pluginLicenses","license","textStatus","contentType","$table","info","length","id","class","replaceWith","html","$row","children","appendTo","append","name","description","src","iconUrl","documentationUrl","text","normalizeUserKey","href","target","t","size","maxlength","value","licenseKey","readonly","disabled","licensedEdition","data-title","latestVersion","getCsrfInput","method","accept-charset","type","packageName","substr","$keyContainer","replace","updateTimeout","data-icon","data-align","initUiElements","$oldIcon","$newIcon","key","toUpperCase","hasMultipleEditions","manager","$newEdition","$details","$keyInput","$spinner","$buyBtn","edition","find","isTrial","removeAttr","data","addListener","getKey","insertBefore","val","$oldEdition","remove","select","onKeyChange","showLicenseKey","userKey","setTimeout","updateLicenseStatus","bind","addClass","postActionRequest","then","update","message","licenseKeyStatus","licenseIssues","charAt","buyUrl","getCpUrl","upgradeAvailable","getUrl","version","removeClass","match","$form","$issues","$p","add","i","substring","accountLink","$newExpired","$oldExpired","expired","renewalUrl","jQuery"],"mappings":"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","file":"PluginManager.min.js","sourcesContent":["(function($) {\n    /** global: Craft */\n    /** global: Garnish */\n    Craft.PluginManager = Garnish.Base.extend({\n        init: function() {\n            this.getPluginLicenseInfo()\n                .then(response => {\n                    for (var handle in response) {\n                        if (response.hasOwnProperty(handle)) {\n                            if (!response[handle].isComposerInstalled) {\n                                this.addUninstalledPluginRow(handle, response[handle]);\n                            } else {\n                                (new Plugin(this, $('#plugin-' + handle))).update(response[handle]);\n                            }\n                        }\n                    }\n                });\n        },\n\n        getPluginLicenseInfo: function() {\n            return new Promise(function(resolve, reject) {\n                Craft.sendApiRequest('GET', 'cms-licenses', {\n                        params: {\n                            include: 'plugins',\n                        },\n                    })\n                    .then(function(response) {\n                        Craft.postActionRequest('app/get-plugin-license-info', {\n                            pluginLicenses: response.license.pluginLicenses || [],\n                        }, function(response, textStatus) {\n                            if (textStatus === 'success') {\n                                resolve(response);\n                            } else {\n                                reject();\n                            }\n                        }, {\n                            contentType: 'json'\n                        });\n                    })\n                    .catch(reject);\n            });\n        },\n\n        addUninstalledPluginRow: function(handle, info) {\n            var $table = $('#plugins');\n            if (!$table.length) {\n                $table = $('<table/>', {\n                    id: 'plugins',\n                    'class': 'data fullwidth collapsible',\n                    html: '<tbody></tbody>'\n                });\n                $('#no-plugins').replaceWith($table);\n            }\n\n            var $row = $('<tr/>', {\n                    data: {\n                        handle: handle,\n                    }\n                })\n                .appendTo($table.children('tbody'))\n                .append(\n                    $('<th/>')\n                        .append(\n                            $('<div/>', {'class': 'plugin-infos'})\n                                .append(\n                                    $('<div/>', {'class': 'icon'})\n                                        .append(\n                                            $('<img/>', {src: info.iconUrl})\n                                        )\n                                )\n                                .append(\n                                    $('<div/>', {'class': 'details'})\n                                        .append(\n                                            $('<h2/>', {text: info.name})\n                                        )\n                                        .append(\n                                            info.description\n                                                ? $('<p/>', {text: info.description})\n                                                : $()\n                                        )\n                                        .append(\n                                            info.documentationUrl\n                                                ? $('<p/>', {'class': 'links'})\n                                                .append(\n                                                    $('<a/>', {\n                                                        href: info.documentationUrl,\n                                                        target: '_blank',\n                                                        text: Craft.t('app', 'Documentation')\n                                                    })\n                                                )\n                                                : $()\n                                        )\n                                        .append(\n                                            $('<div/>', {'class': 'flex license-key'})\n                                                .append(\n                                                    $('<div />', {'class': 'pane'})\n                                                        .append(\n                                                            $('<input/>', {\n                                                                'class': 'text code',\n                                                                size: 29,\n                                                                maxlength: 29,\n                                                                value: Craft.PluginManager.normalizeUserKey(info.licenseKey),\n                                                                readonly: true,\n                                                                disabled: true\n                                                            })\n                                                        )\n                                                )\n                                        )\n                                )\n                        )\n                )\n                .append(\n                    $('<td/>', {\n                        'class': 'nowrap',\n                        'data-title': Craft.t('app', 'Status')\n                    })\n                        .append(\n                            $('<span/>', {'class': 'status'})\n                        )\n                        .append(\n                            $('<span/>', {'class': 'light', text: Craft.t('app', 'Missing')})\n                        )\n                )\n                .append(\n                    info.latestVersion\n                        ? $('<td/>', {\n                            'class': 'nowrap thin',\n                            'data-title': Craft.t('app', 'Action')\n                        })\n                        .append(\n                            $('<form/>', {\n                                method: 'post',\n                                'accept-charset': 'UTF-8',\n                            })\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'action',\n                                        value: 'pluginstore/install'\n                                    })\n                                )\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'packageName',\n                                        value: info.packageName\n                                    })\n                                )\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'handle',\n                                        value: handle\n                                    })\n                                )\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'edition',\n                                        value: info.licensedEdition\n                                    })\n                                )\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'version',\n                                        value: info.latestVersion\n                                    })\n                                )\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'licenseKey',\n                                        value: info.licenseKey\n                                    })\n                                )\n                                .append(\n                                    $('<input/>', {\n                                        type: 'hidden',\n                                        name: 'return',\n                                        value: 'settings/plugins'\n                                    })\n                                )\n                                .append(Craft.getCsrfInput())\n                                .append(\n                                    $('<div/>', {'class': 'btngroup'})\n                                        .append(\n                                            $('<button/>', {\n                                                type: 'button',\n                                                'class': 'btn menubtn',\n                                                'data-icon': 'settings'\n                                            })\n                                        )\n                                        .append(\n                                            $('<div/>', {\n                                                'class': 'menu',\n                                                'data-align': 'right',\n                                            })\n                                                .append(\n                                                    $('<ul/>')\n                                                        .append(\n                                                            $('<li/>')\n                                                                .append(\n                                                                    $('<a/>', {\n                                                                        'class': 'formsubmit',\n                                                                        text: Craft.t('app', 'Install')\n                                                                    })\n                                                                )\n                                                        )\n                                                )\n                                        )\n                                )\n                        )\n                        : $()\n                )\n            ;\n\n            Craft.initUiElements($row);\n        }\n    }, {\n        normalizeUserKey: function(key) {\n            if (typeof key !== 'string' || key === '') {\n                return '';\n            }\n            if (key[0] === '$') {\n                return key;\n            }\n            return key.replace(/.{4}/g, '$&-').substr(0, 29).toUpperCase();\n        }\n    });\n\n    var Plugin = Garnish.Base.extend({\n        manager: null,\n        $row: null,\n        $details: null,\n        $keyContainer: null,\n        $keyInput: null,\n        $spinner: null,\n        $buyBtn: null,\n        handle: null,\n        updateTimeout: null,\n\n        init: function(manager, $row) {\n            this.manager = manager;\n            this.$row = $row;\n            this.$details = this.$row.find('.details');\n            this.$keyContainer = $row.find('.license-key')\n            this.$keyInput = this.$keyContainer.find('input.text').removeAttr('readonly');\n            this.$buyBtn = this.$keyContainer.find('.btn');\n            this.$spinner = $row.find('.spinner');\n            this.handle = this.$row.data('handle');\n            this.addListener(this.$keyInput, 'focus', 'onKeyFocus')\n            this.addListener(this.$keyInput, 'input', 'onKeyChange');\n        },\n\n        getKey: function() {\n            return this.$keyInput.val().replace(/\\-/g, '').toUpperCase();\n        },\n\n        onKeyFocus: function() {\n            this.$keyInput.select();\n        },\n\n        onKeyChange: function() {\n            if (this.updateTimeout) {\n                clearTimeout(this.updateTimeout);\n            }\n            var key = this.getKey();\n            if (key.length === 0 || key.length === 24 || (key.length > 1 && key[0] === '$')) {\n                // normalize\n                var userKey = Craft.PluginManager.normalizeUserKey(key);\n                this.$keyInput.val(userKey);\n                this.updateTimeout = setTimeout(this.updateLicenseStatus.bind(this), 100);\n            }\n        },\n\n        updateLicenseStatus: function() {\n            this.$spinner.removeClass('hidden');\n            Craft.postActionRequest('app/update-plugin-license', {handle: this.handle, key: this.getKey()}, (response, textStatus) => {\n                if (textStatus === 'success') {\n                    this.manager.getPluginLicenseInfo()\n                        .then(response => {\n                            this.$spinner.addClass('hidden');\n                            this.update(response[this.handle]);\n                        });\n                }\n            });\n        },\n\n        update: function(info) {\n            // update the status icon\n            var $oldIcon = this.$row.find('.license-key-status');\n            if (info.licenseKeyStatus == 'valid' || info.licenseIssues.length) {\n                var $newIcon = $('<span/>', {'class': 'license-key-status ' + (info.licenseIssues.length === 0 ? 'valid' : '')});\n                if ($oldIcon.length) {\n                    $oldIcon.replaceWith($newIcon);\n                } else {\n                    $newIcon.appendTo(this.$row.find('.icon'));\n                }\n            } else if ($oldIcon.length) {\n                $oldIcon.remove();\n            }\n\n            // add the edition/trial badge\n            var $oldEdition = this.$row.find('.edition');\n            if (info.hasMultipleEditions || info.isTrial) {\n                var $newEdition = info.upgradeAvailable\n                    ? $('<a/>', {href: Craft.getUrl('plugin-store/' + this.handle), 'class': 'edition'})\n                    : $('<div/>', {'class': 'edition'});\n                if (info.hasMultipleEditions) {\n                    $('<div/>', {'class': 'edition-name', text: info.edition}).appendTo($newEdition);\n                }\n                if (info.isTrial) {\n                    $('<div/>', {'class': 'edition-trial', text: Craft.t('app', 'Trial')}).appendTo($newEdition);\n                }\n                if ($oldEdition.length) {\n                    $oldEdition.replaceWith($newEdition);\n                } else {\n                    $newEdition.insertBefore(this.$row.find('.version'));\n                }\n            } else if ($oldEdition.length) {\n                $oldEdition.remove();\n            }\n\n            // show the license key?\n            var showLicenseKey = info.licenseKey || info.licenseKeyStatus !== 'unknown';\n            if (showLicenseKey) {\n                this.$keyContainer.removeClass('hidden');\n                if (info.licenseKey && !this.$keyInput.val().match(/^\\$/)) {\n                    this.$keyInput.val(Craft.PluginManager.normalizeUserKey(info.licenseKey));\n                }\n            } else {\n                this.$keyContainer.addClass('hidden');\n            }\n\n            // update the license key input class\n            if (showLicenseKey && info.licenseIssues.length) {\n                this.$keyInput.addClass('error');\n            } else {\n                this.$keyInput.removeClass('error');\n            }\n\n            // add the error message\n            this.$row.find('p.error').remove();\n            if (info.licenseIssues.length) {\n                var $issues = $();\n                var $p, $form, message;\n                for (var i = 0; i < info.licenseIssues.length; i++) {\n                    switch (info.licenseIssues[i]) {\n                        case 'no_trials':\n                            message = Craft.t('app', 'Plugin trials are not allowed on this domain.');\n                            break;\n                        case 'wrong_edition':\n                            message = Craft.t('app', 'This license is for the {name} edition.', {\n                                name: info.licensedEdition.charAt(0).toUpperCase() + info.licensedEdition.substring(1)\n                            }) + ' <button type=\"button\" class=\"btn submit small formsubmit\">' + Craft.t('app', 'Switch') + '</button>';\n                            break;\n                        case 'mismatched':\n                            message = Craft.t('app', 'This license is tied to another Craft install. Visit {accountLink} to detach it, or <a href=\"{buyUrl}\">buy a new license</a>', {\n                                accountLink: '<a href=\"https://id.craftcms.com\" rel=\"noopener\" target=\"_blank\">id.craftcms.com</a>',\n                                buyUrl: Craft.getCpUrl(`plugin-store/buy/${this.handle}/${info.edition}`),\n                            });\n                            break;\n                        case 'astray':\n                            message = Craft.t('app', 'This license isn’t allowed to run version {version}.', {\n                                version: info.version\n                            });\n                            break;\n                        case 'required':\n                            message = Craft.t('app', 'A license key is required.');\n                            break;\n                        default:\n                            message = Craft.t('app', 'Your license key is invalid.');\n                    }\n\n                    $p = $('<p/>', {'class': 'error', html: message});\n                    if (info.licenseIssues[i] === 'wrong_edition') {\n                        $form = $('<form/>', {\n                            method: 'post',\n                            'accept-charset': 'UTF-8',\n                        })\n                            .append(Craft.getCsrfInput())\n                            .append(\n                                $('<input/>', {\n                                    type: 'hidden',\n                                    name: 'action',\n                                    value: 'plugins/switch-edition'\n                                })\n                            )\n                            .append(\n                                $('<input/>', {\n                                    type: 'hidden',\n                                    name: 'pluginHandle',\n                                    value: this.handle\n                                })\n                            )\n                            .append(\n                                $('<input/>', {\n                                    type: 'hidden',\n                                    name: 'edition',\n                                    value: info.licensedEdition\n                                })\n                            )\n                            .append($p);\n\n                        Craft.initUiElements($form);\n                        $issues = $issues.add($form);\n                    } else {\n                        $issues = $issues.add($p);\n                    }\n                }\n                $issues.appendTo(this.$details);\n                Craft.initUiElements()\n            }\n\n            // add the expired badge\n            var $oldExpired = this.$row.find('.expired');\n            if (info.expired) {\n                var $newExpired = $('<p/>', {\n                    'class': 'warning with-icon expired',\n                    html: Craft.t('app', 'This license has expired.') +\n                        ' ' +\n                        Craft.t('app', '<a>Renew now</a> for another year of updates.').replace('<a>', '<a href=\"' + info.renewalUrl + '\" target=\"_blank\">')\n                });\n                if ($oldExpired.length) {\n                    $oldExpired.replaceWith($newExpired);\n                } else {\n                    $newExpired.appendTo(this.$details);\n                }\n            }\n\n            // show/hide the Buy button\n            if (info.licenseKeyStatus === 'trial') {\n                this.$buyBtn.removeClass('hidden');\n                if (info.licenseIssues.length) {\n                    this.$buyBtn.addClass('submit');\n                } else {\n                    this.$buyBtn.removeClass('submit');\n                }\n            } else {\n                this.$buyBtn.addClass('hidden');\n            }\n        }\n    })\n})(jQuery);\n"]}