// File Protocol Templating Engine
class FPTemplatingEngine {
	version = '1.0.0.0';
	defaultConfig = {
		pages: {},
		components: {},
		openingTag: '{{',
		closingTag: '}}',
		replacingRegex: (e, t, n) => new RegExp(`${e}${n}${t}`, 'gm'),
		autoInit: !0,
		awaitSources: !0,
		mainOutlet: 'main-content',
	};
	types = { page: 'pages', component: 'components' };
	injectMethods = { replace: 'replace', append: 'append' };
	functionTypes = {
		noParams: 'function',
		bound: 'function-bound',
		template: 'function-template',
	};
	attributes = {
		injectPage: 'inject-page',
		injectComponent: 'inject-component',
		replace: 'replace',
		ignore: 'ignore',
		injectOutlet: 'inject-outlet',
		ignoreTitle: 'ignore-title',
		params: 'params',
		defaultPage: 'default-page',
	};
	constructor(e) {
		const t = e.openingTag,
			n = e.closingTag;
		e.replacingRegex ||
			(e.replacingRegex = this.defaultConfig.replacingRegex.bind(
				this,
				t ? n : this.defaultConfig.openingTag,
				n ? t : this.defaultConfig.closingTag
			)),
			(this.config = Object.assign(this.defaultConfig, e)),
			(this.pages = this.generateReplacerMapFor('pages')),
			(this.components = this.generateReplacerMapFor('components')),
			this.config.sources &&
				this.config.sources.forEach(e => {
					this.bindFiles(e);
				}),
			this.config.autoInit &&
				(this.config.awaitSources
					? window.addEventListener('load', () => {
							this.init();
					  })
					: this.init());
	}
	init() {
		(document.body.innerHTML = this.replaceAllInElement(
			document.body.innerHTML
		)),
			this.injectAllPages(document),
			this.injectAllComponents(document),
			this.loadOutletDefaultPages(document);
	}
	loadOutletDefaultPages(e) {
		const t = this.attributes.injectOutlet,
			n = e.querySelectorAll(`[${t}]`),
			i = this.getUrlParameter('page'),
			s = this.getUrlParameter('params');
		n.forEach(e => {
			const n = e.getAttribute(`${t}`);
			if (n === this.config.mainOutlet && i) return void this.loadPage(i, n, s);
			const a = e.getAttribute(this.attributes.defaultPage);
			a && this.loadToOutlet(a, n);
		});
	}
	loadPage(e, t, n = null) {
		const i = document.querySelector(`[inject-outlet=${t}]`);
		if (!i) return;
		let s = !1;
		const a = i.getAttribute(this.attributes.ignoreTitle);
		a && (s = a),
			// First only inject the pages template
			this.injectPageByKey(i, e, n, s),
			// Then replace all placeholders
			(i.innerHTML = this.replaceAllInElement(i)),
			// Then check for any other injection needs for pages
			this.injectAllPages(i),
			// Then check for any injection needs for components
			this.injectAllComponents(i);
		t === this.config.mainOutlet && this.updateUrl(e, n),
			this.loadOutletDefaultPages(i);
	}
	loadComponent(e, t, n = null) {
		const i = document.querySelector(`[inject-outlet=${t}]`);
		if (!i) return;
		let s = !1;
		const a = i.getAttribute(this.attributes.ignoreTitle);
		a && (s = a),
			// First only inject the pages template
			this.injectComponentByKey(i, e, n, s),
			// Then replace all placeholders
			(i.innerHTML = this.replaceAllInElement(i)),
			// Then check for any other injection needs for pages
			this.injectAllPages(i),
			// Then check for any injection needs for components
			this.injectAllComponents(i);
		t === this.config.mainOutlet && this.updateUrl(e, n),
			this.loadOutletDefaultPages(i);
	}
	injectAllPages(e) {
		const t = this.attributes.injectPage;
		e.querySelectorAll(`[${t}]`).forEach(e => {
			const n = e.getAttribute(t);
			let i = !1;
			const s = e.getAttribute(this.attributes.ignoreTitle);
			s && (i = s);
			let a = e.getAttribute(this.attributes.params);
			this.injectPageByKey(e, n, a, i),
				(e.innerHTML = this.replaceAllInElement(e)),
				this.injectAllComponents(e);
			e.querySelectorAll(`[${t}]`).forEach(e => {
				this.injectAllPages(e);
			});
		});
	}
	injectAllComponents(e) {
		const t = this.attributes.injectComponent;
		e.querySelectorAll(`[${t}]`).forEach(e => {
			const n = e.getAttribute(t);
			this.injectComponentByKey(e, n),
				(e.innerHTML = this.replaceAllInElement(e));
			e.querySelectorAll(`[${t}]`).forEach(e => {
				this.injectAllPages(e);
			});
		});
	}
	injectPageByKey(e, t, n, i) {
		const s = this.getPageData(t);
		if (!s) return;
		const a = this.getTemplate(s, n),
			o = this.getInjectionMethod(s);
		this.injectIntoElement(o, e, t, a),
			s.title && !i && (document.title = s.title);
	}
	injectComponentByKey(e, t, n = null) {
		const i = this.getComponentData(t),
			s = this.getTemplate(i, n),
			a = this.getInjectionMethod(i);
		this.injectIntoElement(a, e, t, s);
	}
	injectIntoElement(e, t, n, i) {
		switch (e) {
			case this.injectMethods.replace:
				t.innerHTML = i;
				break;
			case this.injectMethods.append:
				t.innerHTML = `${t.innerHTML}${i}`;
				break;
			default:
				t.innerHTML = this.findAndReplace(t.innerHTML, n, i);
		}
	}
	loadToOutlet(e, t = this.config.mainOutlet, n = 'page', i = null) {
		let s;
		switch (n) {
			case 'page':
			case 'pages':
				s = this.types.page;
				break;
			case 'component':
			case 'components':
				s = this.types.component;
		}
		s !== this.types.page
			? this.loadComponent(e, t, i)
			: this.loadPage(e, t, i);
	}
	replaceAllInElement(e, t = []) {
		let n = e.innerHTML,
			i = e;
		'string' == typeof e && ((n = e), (i = this.generateTempElement(n)));
		// Generate ignore List
		i.querySelectorAll(`[${this.attributes.ignore}]`).forEach(e => {
			const n = e.getAttribute(this.attributes.ignore),
				i = n ? n.split(' ') : [];
			t = t.concat(...i);
		});
		return (
			this.findAllReplacers(n).forEach(e => {
				let [i, s] = e[0]
					.replaceAll(this.config.openingTag, '')
					.replaceAll(this.config.closingTag, '')
					.split('=');
				if (t.includes(i)) return;
				const a = this.getDataFromSources(i);
				s || (s = null);
				let o = this.getTemplate(a, s);
				if (!o) return n;
				(o = this.replaceAllInElement(o, t)), (n = n.replaceAll(e, o));
			}),
			n
		);
	}
	replaceAllInString(e, t) {
		let n = e;
		return (
			this.components.forEach((e, i) => {
				t.includes(i) || (n = this.findAndReplace(n, i, e.template));
			}),
			n
		);
	}
	findAllReplacers(e) {
		const t = this.config.replacingRegex('.*?');
		return [...e.matchAll(t)];
	}
	findAndReplace(e, t, n) {
		const i = this.config.replacingRegex(t);
		return e.replaceAll(i, n);
	}
	// Getters
	getPageData(e) {
		return this.pages.get(e);
	}
	getComponentData(e) {
		return this.components.get(e);
	}
	getTemplate(e, t = null) {
		if (!e) return;
		let n = e.template;
		if (!n) return '';
		const i = new RegExp(/\[.*\]/gm);
		// Check if the template is a function
		if (
			('string' == typeof t &&
				t.trim().length > 0 &&
				i.test(t) &&
				(t = JSON.parse(t)),
			'function' == typeof n || 'function' === e.templateType)
		)
			switch (e.functionType) {
				case this.functionTypes.template:
					n = n(t);
					break;
				case this.functionTypes.bound:
				default:
					n = n();
			}
		return n;
	}
	getDataFromSources(e) {
		const t = this.getPageData(e);
		if (t) return t;
		const n = this.getComponentData(e);
		return n || void 0;
	}
	getInjectionMethod(e, t = this.injectMethods.replace) {
		if (!e) return;
		const n = e.injectMethod;
		return n || t;
	}
	getRegex() {
		return this.config.replacingRegex instanceof RegExp
			? this.config.replacingRegex
			: 'string' == typeof this.config.replacingRegex
			? new RegExp(this.config.replacingRegex, 'gm')
			: this.defaultConfig.replacingRegex(
					this.config.openingTag,
					this.config.closingTag
			  );
	}
	// Generators
	generateReplacerMapFor(e) {
		const t = new Map();
		return (
			Object.entries(this.config[e]).forEach(([e, n]) => {
				t.set(e, n);
			}),
			t
		);
	}
	// Helper Functions
	bindFiles(e) {
		const t = document.createElement('script');
		t.setAttribute('src', e), document.head.appendChild(t);
	}
	registerTemplate(e, t, n) {
		let i;
		switch (n) {
			case 'page':
			case 'pages':
				i = this.types.page;
				break;
			case 'component':
			case 'components':
				i = this.types.component;
				break;
			default:
				i = this.types.component;
		}
		const s = { ...this[i].get(t) };
		(s.template = e), this[i].set(t, s);
	}
	register(e, t, n) {
		let i;
		switch (n.toLowerCase()) {
			case 'page':
			case 'pages':
				i = this.types.page;
				break;
			case 'component':
			case 'components':
				i = this.types.component;
				break;
			default:
				i = this.types.component;
		}
		this[i].set(e, t);
	}
	updateUrl(e, t) {
		const n = `&params=${t}`;
		window.history.replaceState(null, null, `?page=${e}${t ? n : ''}`);
	}
	getUrlParameter(e) {
		const t = window.location.search;
		return new URLSearchParams(t).get(e);
	}
	generateTempElement(e) {
		const t = document.createElement('template');
		return (t.innerHTML = e), t.content;
	}
}
//# sourceMappingURL=fpte.min.js.map
