(() => {

    if (globalThis.IOCDevLoader?.version === 3) return;

    const IOCDevLoader = (() => {

        const injectLibraries = () => {
            Object.values(angular.element("#sc_cat_item").scope().$$childTail.item._fields)
                .filter(field => {
                    const v3LoaderWidgetId = 'c5368b9c875f629c131bca640cbb35fc';
                    return field.type === 'widget' && field.widget.sys_id === v3LoaderWidgetId;
                })
                .reduce((data, spvar) => spvar.widget.data.libraries, [])
                .filter(library => !Object.hasOwn(libraries, library.version))
                .forEach(library => {
                    const script = document.createElement('script');
                    script.setAttribute('type', 'text/javascript');
                    script.setAttribute('id', 'iocdev_library_'.concat(library.version));
                    script.textContent = library.script;
                    angular.element("#sc_cat_item").get(0).insertAdjacentElement('afterend', script);
                });
        };

        const libraries = {};

        const self = (...args) => {

            const [version, as = 'cdev'] = args.map((arg, i) => (i === 0 && [1, 2].includes(arg) && 'v'.concat(arg)) || arg);

            if (!Object.hasOwn(libraries, version)) injectLibraries();

            const klass = libraries[version];

            if (klass.loader) return klass.loader(klass, args);

            globalThis[as] = new klass.lib();
        };

        self.version = 3;
        self.name = 'IOCDevLoader v3';
        self.register = (version, lib, loader) => (libraries[version] = { version, lib, loader });

        return self;
    })();

    Object.defineProperty(globalThis, 'IOCDevLoader', {
        value: IOCDevLoader,
        writable: false,
    });
})();
