/*! elementor - v3.16.0 - 14-09-2023 */ "use strict"; (self["webpackChunkelementor"] = self["webpackChunkelementor"] || []).push([["accordion"],{ /***/ "../assets/dev/js/frontend/handlers/accordion.js": /*!*******************************************************!*\ !*** ../assets/dev/js/frontend/handlers/accordion.js ***! \*******************************************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); Object.defineProperty(exports, "__esModule", ({ value: true })); exports["default"] = void 0; var _baseTabs = _interopRequireDefault(__webpack_require__(/*! ./base-tabs */ "../assets/dev/js/frontend/handlers/base-tabs.js")); class Accordion extends _baseTabs.default { getDefaultSettings() { const defaultSettings = super.getDefaultSettings(); return { ...defaultSettings, showTabFn: 'slideDown', hideTabFn: 'slideUp' }; } } exports["default"] = Accordion; /***/ }), /***/ "../assets/dev/js/frontend/handlers/base-tabs.js": /*!*******************************************************!*\ !*** ../assets/dev/js/frontend/handlers/base-tabs.js ***! \*******************************************************/ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); exports["default"] = void 0; class baseTabs extends elementorModules.frontend.handlers.Base { getDefaultSettings() { return { selectors: { tablist: '[role="tablist"]', tabTitle: '.elementor-tab-title', tabContent: '.elementor-tab-content' }, classes: { active: 'elementor-active' }, showTabFn: 'show', hideTabFn: 'hide', toggleSelf: true, hidePrevious: true, autoExpand: true, keyDirection: { ArrowLeft: elementorFrontendConfig.is_rtl ? 1 : -1, ArrowUp: -1, ArrowRight: elementorFrontendConfig.is_rtl ? -1 : 1, ArrowDown: 1 } }; } getDefaultElements() { const selectors = this.getSettings('selectors'); return { $tabTitles: this.findElement(selectors.tabTitle), $tabContents: this.findElement(selectors.tabContent) }; } activateDefaultTab() { const settings = this.getSettings(); if (!settings.autoExpand || 'editor' === settings.autoExpand && !this.isEdit) { return; } const defaultActiveTab = this.getEditSettings('activeItemIndex') || 1, originalToggleMethods = { showTabFn: settings.showTabFn, hideTabFn: settings.hideTabFn }; // Toggle tabs without animation to avoid jumping this.setSettings({ showTabFn: 'show', hideTabFn: 'hide' }); this.changeActiveTab(defaultActiveTab); // Return back original toggle effects this.setSettings(originalToggleMethods); } handleKeyboardNavigation(event) { const tab = event.currentTarget, $tabList = jQuery(tab.closest(this.getSettings('selectors').tablist)), // eslint-disable-next-line @wordpress/no-unused-vars-before-return $tabs = $tabList.find(this.getSettings('selectors').tabTitle), isVertical = 'vertical' === $tabList.attr('aria-orientation'); switch (event.key) { case 'ArrowLeft': case 'ArrowRight': if (isVertical) { return; } break; case 'ArrowUp': case 'ArrowDown': if (!isVertical) { return; } event.preventDefault(); break; case 'Home': event.preventDefault(); $tabs.first().trigger('focus'); return; case 'End': event.preventDefault(); $tabs.last().trigger('focus'); return; default: return; } const tabIndex = tab.getAttribute('data-tab') - 1, direction = this.getSettings('keyDirection')[event.key], nextTab = $tabs[tabIndex + direction]; if (nextTab) { nextTab.focus(); } else if (-1 === tabIndex + direction) { $tabs.last().trigger('focus'); } else { $tabs.first().trigger('focus'); } } deactivateActiveTab(tabIndex) { const settings = this.getSettings(), activeClass = settings.classes.active, activeFilter = tabIndex ? '[data-tab="' + tabIndex + '"]' : '.' + activeClass, $activeTitle = this.elements.$tabTitles.filter(activeFilter), $activeContent = this.elements.$tabContents.filter(activeFilter); $activeTitle.add($activeContent).removeClass(activeClass); $activeTitle.attr({ tabindex: '-1', 'aria-selected': 'false', 'aria-expanded': 'false' }); $activeContent[settings.hideTabFn](); $activeContent.attr('hidden', 'hidden'); } activateTab(tabIndex) { const settings = this.getSettings(), activeClass = settings.classes.active, $requestedTitle = this.elements.$tabTitles.filter('[data-tab="' + tabIndex + '"]'), $requestedContent = this.elements.$tabContents.filter('[data-tab="' + tabIndex + '"]'), animationDuration = 'show' === settings.showTabFn ? 0 : 400; $requestedTitle.add($requestedContent).addClass(activeClass); $requestedTitle.attr({ tabindex: '0', 'aria-selected': 'true', 'aria-expanded': 'true' }); $requestedContent[settings.showTabFn](animationDuration, () => elementorFrontend.elements.$window.trigger('elementor-pro/motion-fx/recalc')); $requestedContent.removeAttr('hidden'); } isActiveTab(tabIndex) { return this.elements.$tabTitles.filter('[data-tab="' + tabIndex + '"]').hasClass(this.getSettings('classes.active')); } bindEvents() { this.elements.$tabTitles.on({ keydown: event => { // Support for old markup that includes an `` tag in the tab if (jQuery(event.target).is('a') && `Enter` === event.key) { event.preventDefault(); } // We listen to keydowon event for these keys in order to prevent undesired page scrolling if (['End', 'Home', 'ArrowUp', 'ArrowDown'].includes(event.key)) { this.handleKeyboardNavigation(event); } }, keyup: event => { switch (event.code) { case 'ArrowLeft': case 'ArrowRight': this.handleKeyboardNavigation(event); break; case 'Enter': case 'Space': event.preventDefault(); this.changeActiveTab(event.currentTarget.getAttribute('data-tab')); break; } }, click: event => { event.preventDefault(); this.changeActiveTab(event.currentTarget.getAttribute('data-tab')); } }); } onInit() { super.onInit(...arguments); this.activateDefaultTab(); } onEditSettingsChange(propertyName) { if ('activeItemIndex' === propertyName) { this.activateDefaultTab(); } } changeActiveTab(tabIndex) { const isActiveTab = this.isActiveTab(tabIndex), settings = this.getSettings(); if ((settings.toggleSelf || !isActiveTab) && settings.hidePrevious) { this.deactivateActiveTab(); } if (!settings.hidePrevious && isActiveTab) { this.deactivateActiveTab(tabIndex); } if (!isActiveTab) { this.activateTab(tabIndex); } } } exports["default"] = baseTabs; /***/ }) }]); //# sourceMappingURL=accordion.c16b88b2e8a0c50189bc.bundle.js.map(function(e,t){"use strict";var n=e.History=e.History||{},r=e.jQuery;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={bind:function(e,t,n){r(e).bind(t,n)},trigger:function(e,t,n){r(e).trigger(t,n)},extractEventData:function(e,n,r){var i=n&&n.originalEvent&&n.originalEvent[e]||r&&r[e]||t;return i},onDomLoad:function(e){r(e)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s=e.sessionStorage,s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window){"id":2044,"date":"2021-09-16T11:21:47","date_gmt":"2021-09-16T04:21:47","guid":{"rendered":"https:\/\/uetacad.com\/?p=2044"},"modified":"2021-09-16T11:21:50","modified_gmt":"2021-09-16T04:21:50","slug":"gioi-thieu-ve-cloud-formation-va-cach-su-dung-co-ban","status":"publish","type":"post","link":"https:\/\/uetacad.com\/gioi-thieu-ve-cloud-formation-va-cach-su-dung-co-ban\/","title":{"rendered":"Gi\u1edbi thi\u1ec7u v\u1ec1 cloud formation v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng c\u01a1 b\u1ea3n"},"content":{"rendered":"\n

Cloud formation l\u00e0 g\u00ec?<\/h2>\n\n\n\n

C\u00e1ch d\u1ec5 nh\u1ea5t \u0111\u1ec3 m\u00f4 t\u1ea3 CloudFormation l\u00e0 n\u00f3 l\u00e0 m\u1ed9t c\u00f4ng c\u1ee5 t\u1eeb AWS cho ph\u00e9p b\u1ea1n kh\u1edfi t\u1ea1o t\u00e0i nguy\u00ean m\u1ed9t c\u00e1ch d\u1ec5 d\u00e0ng. B\u1ea1n x\u00e1c \u0111\u1ecbnh t\u1ea5t c\u1ea3 c\u00e1c t\u00e0i nguy\u00ean m\u00e0 b\u1ea1n mu\u1ed1n AWS b\u1eadt l\u00ean trong m\u1ed9t b\u1ea3n thi\u1ebft k\u1ebf chi ti\u1ebft, b\u1ea5m v\u00e0o m\u1ed9t n\u00fat, v\u00e0 sau \u0111\u00f3 AWS s\u1ebd th\u1ef1c hi\u1ec7n gi\u00fap b\u1ea1n ph\u1ea7n vi\u1ec7c c\u00f2n l\u1ea1i. B\u1ea3n thi\u1ebft k\u1ebf n\u00e0y \u0111\u01b0\u1ee3c g\u1ecdi l\u00e0 m\u1ed9t template trong CloudFormation. CloudFormation \u0111\u1ea3m b\u1ea3o r\u1eb1ng c\u00e1c t\u00e0i nguy\u00ean ph\u1ee5 thu\u1ed9c trong template c\u1ee7a b\u1ea1n \u0111\u1ec1u \u0111\u01b0\u1ee3c t\u1ea1o theo \u0111\u00fang th\u1ee9 t\u1ef1. V\u00ed d\u1ee5, gi\u1ea3 s\u1eed ch\u00fang ta mu\u1ed1n t\u1ea1o record DNS Route53 v\u00e0 m\u1ed9t instance EC2 c\u00f3 record DNS tr\u1ecf t\u1edbi instance EC2. CloudFormation s\u1ebd \u0111\u1ec3 cung c\u1ea5p instance EC2 tr\u01b0\u1edbc, ch\u1edd cho n\u00f3 s\u1eb5n s\u00e0ng \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng, v\u00e0 sau \u0111\u00f3 t\u1ea1o b\u1ea3n ghi DNS. AWS CloudFormation \u0111i\u1ec1u ph\u1ed1i vi\u1ec7c cung c\u1ea5p c\u00e1c t\u00e0i nguy\u00ean mong mu\u1ed1n. V\u00ec v\u1eady, thay v\u00ec ph\u1ea3i vi\u1ebft script v\u1edbi m\u1ed9t lo\u1ea1t c\u00e1c l\u1eddi g\u1ecdi API AWS, ch\u1edd v\u00f2ng l\u1eb7p v\u00e0 th\u1eed l\u1ea1i logic, b\u1ea1n ch\u1ec9 c\u1ea7n m\u00f4 t\u1ea3 nh\u1eefng g\u00ec b\u1ea1n mu\u1ed1n v\u00e0 y\u00eau c\u1ea7u CloudFormation th\u1ef1c hi\u1ec7n \u0111i\u1ec1u \u0111\u00f3 cho b\u1ea1n. Th\u1eadt tuy\u1ec7t ph\u1ea3i kh\u00f4ng?<\/p>\n\n\n\n

V\u00ed d\u1ee5 c\u01a1 b\u1ea3n v\u1ec1 Cloud formation<\/h2>\n\n\n\n

Ch\u00fang ta h\u00e3y xem qua m\u1ed9t v\u00ed d\u1ee5 \u0111\u01a1n gi\u1ea3n v\u1ec1 vi\u1ec7c b\u1eadt m\u1ed9t stack CloudFormation l\u00ean. Ch\u00fang ta s\u1ebd kh\u1edfi t\u1ea1o m\u1ed9t instance EC2 v\u00e0 m\u1ed9t security group. Sau \u0111\u00f3, ta s\u1ebd ssh v\u00e0o server \u0111\u1ec3 x\u00e1c nh\u1eadn. \u0110\u1ec3 th\u1ef1c hi\u1ec7n tutorial n\u00e0y b\u1ea1n s\u1ebd c\u1ea7n m\u1ed9t t\u00e0i kho\u1ea3n AWS c\u1ee7a ri\u00eang b\u1ea1n v\u00e0 t\u1ed1n m\u1ed9t s\u1ed1 ti\u1ec1n nh\u1ecf. Thay v\u00ec b\u1eaft \u0111\u1ea7u v\u1edbi m\u1ed9t template CloudFormation tr\u1ed1ng, h\u00e3y l\u1ea5y m\u1ed9t template m\u1eabu t\u1eeb document c\u1ee7a AWS. \u0110i\u1ec1u \u0111\u01a1n gi\u1ea3n m\u00e0 ch\u00fang ta mu\u1ed1n l\u00e0 instance Amazon EC2 trong m\u1ed9t security group. Theo v\u0103n b\u1ea3n n\u00e0y, template v\u00ed d\u1ee5 \u0111\u01b0\u1ee3c cung c\u1ea5p \u1edf d\u1ea1ng json nh\u01b0ng t\u00f4i th\u00edch s\u1eed d\u1ee5ng yaml. V\u00ec v\u1eady, t\u00f4i \u0111\u00e3 l\u1ea5y template m\u1eabu v\u00e0 \u0111\u00e3 chuy\u1ec3n \u0111\u1ed5i n\u00f3 th\u00e0nh \u0111\u1ecbnh d\u1ea1ng yaml. N\u00f3 c\u00f3 s\u1eb5n tr\u00ean GitHub: tongueroo\/cloudformation-examples\/ templates single_instance.yml. H\u00e3y d\u00f9ng c\u00e1c l\u1ec7nh sau \u0111\u1ec3 t\u1ea3i xu\u1ed1ng v\u00e0 chuy\u1ec3n \u0111\u1ed5i m\u1eabu json th\u00e0nh yaml:<\/p>\n\n\n\n

$ mkdir templates\n$ cd templates\n$ curl -o single_instance.json \"https:\/\/s3-us-west-2.amazonaws.com\/cloudformation-templates-us-west-2\/EC2InstanceWithSecurityGroupSample.template\"\n$ ruby -ryaml -rjson -e 'puts YAML.dump(JSON.load(ARGF))' < single_instance.json > single_instance.yml\n<\/code><\/pre>\n\n\n\n

Ch\u00fang ta h\u00e3y c\u00f9ng t\u00ecm hi\u1ec3u v\u1ec1 template. \u1ede top level c\u1ee7a template, c\u00f3 6 properties. \u0110\u1ec3 \u0111i\u1ec1u tra v\u1ec1 template, t\u00f4i s\u1ebd d\u00f9ng version json c\u1ee7a file n\u00e0y v\u00ec jq<\/a> tool gi\u00fap cho vi\u1ec7c t\u00ecm hi\u1ec3u c\u00e1c top level keys d\u1ec5 d\u00e0ng h\u01a1n:<\/p>\n\n\n\n

$ cat single_instance.json | jq -r 'keys[]'\n<\/code><\/pre>\n\n\n\n

\u0110\u00e2y l\u00e0 m\u1ed9t gi\u1ea3i th\u00edch ng\u1eafn g\u1ecdn v\u1ec1 \u00fd ngh\u0129a c\u1ee7a nh\u1eefng m\u1ee5c tr\u00ean:<\/p>\n\n\n\n

  • AWSTemplateFormatVersion: Cho bi\u1ebft version c\u1ee7a file template AWS CloudFormation<\/li>
  • Description: \u0110o\u1ea1n v\u0103n b\u1ea3n gi\u1ea3i th\u00edch v\u1ec1 template<\/li>
  • Mappings: \u00c1nh x\u1ea1 c\u00e1c key v\u00e0 c\u00e1c gi\u00e1 tr\u1ecb li\u00ean quan m\u00e0 b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng \u0111\u1ec3 ch\u1ec9 \u0111\u1ecbnh c\u00e1c gi\u00e1 tr\u1ecb tham s\u1ed1 c\u00f3 \u0111i\u1ec1u ki\u1ec7n. \u0110\u00e2y l\u00e0 version CloudFormation c\u1ee7a c\u00fa ph\u00e1p “case”.<\/li>
  • Outputs:M\u00f4 t\u1ea3 c\u00e1c gi\u00e1 tr\u1ecb \u0111\u01b0\u1ee3c tr\u1ea3 v\u1ec1 b\u1ea5t c\u1ee9 khi n\u00e0o b\u1ea1n xem c\u00e1c properties c\u1ee7a stack c\u1ee7a m\u00ecnh. Ph\u1ea7n n\u00e0y \u0111\u01b0\u1ee3c hi\u1ec3n th\u1ecb trong Console c\u1ee7a CloudFormation AWS.<\/li>
  • Parameters: Ch\u1ec9 \u0111\u1ecbnh c\u00e1c gi\u00e1 tr\u1ecb m\u00e0 b\u1ea1n c\u00f3 th\u1ec3 thi\u1ebft l\u1eadp cho c\u00e1c m\u1ee5c trong template c\u1ee7a m\u00ecnh khi kh\u1edfi t\u1ea1o stack<\/li>
  • Resources: Ch\u1ec9 \u0111\u1ecbnh c\u00e1c resource v\u00e0 properties c\u1ee7a stack, v\u00ed d\u1ee5 nh\u01b0 ch\u1ec9 \u0111\u1ecbnh instance EC2. \u0110\u00e2y l\u00e0 property duy nh\u1ea5t b\u1eaft bu\u1ed9c ph\u1ea3i c\u00f3.<\/li><\/ul>\n\n\n\n

    C\u00e1c thu\u1ed9c t\u00ednh level cao nh\u1ea5t quan tr\u1ecdng nh\u1ea5t c\u1ee7a m\u1ed9t template CloudFormation l\u00e0 c\u00e1c Parameter v\u00e0 Resources. Resources l\u00e0 n\u01a1i m\u00e0 instance EC2 c\u1ee7a ch\u00fang ta \u0111\u01b0\u1ee3c \u0111\u1ecbnh ngh\u0129a. H\u00e3y xem x\u00e9t t\u00e0i nguy\u00ean EC2 Instance m\u1ed9t c\u00e1ch c\u1ee5 th\u1ec3 h\u01a1n: templates\/single_instance.yml#L361-L378 N\u00f3 \u0111\u01b0\u1ee3c vi\u1ebft l\u1ea1i \u1edf \u0111\u00e2y \u0111\u1ec3 thu\u1eadn ti\u1ec7n cho vi\u1ec7c theo d\u00f5i:<\/p>\n\n\n\n

    EC2Instance:\n    Type: AWS::EC2::Instance\n    Properties:\n      InstanceType:\n        Ref: InstanceType\n      SecurityGroups:\n      - Ref: InstanceSecurityGroup\n      KeyName:\n        Ref: KeyName\n      ImageId:\n        Fn::FindInMap:\n        - AWSRegionArch2AMI\n        - Ref: AWS::Region\n        - Fn::FindInMap:\n          - AWSInstanceType2Arch\n          - Ref: InstanceType\n          - Arch\n<\/code><\/pre>\n\n\n\n

    V\u00ed d\u1ee5 n\u00e0y r\u1ea5t ph\u00f9 h\u1ee3p v\u1edbi t\u00e0i li\u1ec7u tham kh\u1ea3o template AWS CloudFormation v\u00e0 AWS Resource Types documentation v\u1ec1 AWS :: EC2 :: Instance. T\u00e0i li\u1ec7u tham kh\u1ea3o s\u1ebd tr\u1edf th\u00e0nh ng\u01b0\u1eddi b\u1ea1n t\u1ed1t nh\u1ea5t c\u1ee7a b\u1ea1n khi b\u1ea1n l\u00e0m vi\u1ec7c v\u1edbi CloudFormation.<\/p>\n\n\n\n

    T\u00e0i nguy\u00ean EC2 Instance n\u00e0y tr\u00ecnh b\u00e0y m\u1ed9t v\u00e0i c\u00e1ch s\u1eed d\u1ee5ng Ref. Ref l\u00e0 m\u1ed9t c\u00e1ch \u0111\u1ec3 g\u1ecdi \u0111\u1ebfn c\u00e1c gi\u00e1 tr\u1ecb t\u1eeb c\u00e1c ph\u1ea7n kh\u00e1c c\u1ee7a m\u1eabu. V\u00ed d\u1ee5, Ref: InstanceSecurityGroup g\u1ecdi \u0111\u1ebfn \u0111\u1ebfn t\u00e0i nguy\u00ean duy nh\u1ea5t kh\u00e1c trong m\u1eabu n\u00e0y, nh\u00f3m SecurityGroup s\u1ebd \u0111\u01b0\u1ee3c t\u1ea1o. D\u01b0\u1edbi \u0111\u00e2y l\u00e0 \u0111\u1ecbnh ngh\u0129a c\u1ee7a t\u00e0i nguy\u00ean \u0111\u00f3:<\/p>\n\n\n\n

    InstanceSecurityGroup:\n    Type: AWS::EC2::SecurityGroup\n    Properties:\n      GroupDescription: Enable SSH access via port 22\n      SecurityGroupIngress:\n      - IpProtocol: tcp\n        FromPort: '22'\n        ToPort: '22'\n        CidrIp:\n          Ref: SSHLocation\n\n<\/code><\/pre>\n\n\n\n

    Ref: InstanceType<\/code> c\u0169ng \u0111\u1ec1 c\u1eadp \u0111\u1ebfn nh\u1eefng tham s\u1ed1 InstanceType c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c truy\u1ec1n v\u00e0o. Ph\u1ea7n Tham s\u1ed1 level cao nh\u1ea5t l\u00e0 n\u01a1i tham s\u1ed1 InstanceType \u0111\u1ebfn t\u1eeb \u0111\u00f3. H\u00e3y xem ph\u1ea7n \u0111\u00f3 c\u1ee7a m\u1ee5c Parameter:<\/p>\n\n\n\n

    Parameters:\n  KeyName:\n    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance\n    Type: AWS::EC2::KeyPair::KeyName\n    ConstraintDescription: must be the name of an existing EC2 KeyPair.\n  InstanceType:\n    Description: WebServer EC2 instance type\n    Type: String\n    Default: t2.small\n    AllowedValues:\n    - t1.micro\n    - t2.nano\n    - t2.micro\n    - t2.small\n    - t2.medium\n<\/code><\/pre>\n\n\n\n

    B\u1ea1n c\u00f3 th\u1ec3 th\u1ea5y r\u1eb1ng tham s\u1ed1 m\u1eb7c \u0111\u1ecbnh cho ki\u1ec3u Instance EC2 \u0111\u1ec3 kh\u1edfi t\u1ea1o l\u00e0 t2.small. B\u1ea1n c\u00f3 th\u1ec3 ghi \u0111\u00e8 gi\u00e1 tr\u1ecb n\u00e0y khi b\u1ea1n kh\u1edfi \u0111\u1ed9ng instance n\u1ebfu b\u1ea1n mu\u1ed1n. \u0110\u1ed1i v\u1edbi c\u00e1c tham s\u1ed1 c\u00f3 gi\u00e1 tr\u1ecb m\u1eb7c \u0111\u1ecbnh, b\u1ea1n kh\u00f4ng c\u1ea7n ph\u1ea3i cung c\u1ea5p tham s\u1ed1. \u0110\u1ed1i v\u1edbi c\u00e1c tham s\u1ed1 kh\u00f4ng c\u00f3 gi\u00e1 tr\u1ecb m\u1eb7c \u0111\u1ecbnh, b\u1ea1n s\u1ebd c\u1ea7n ph\u1ea3i cung c\u1ea5p gi\u00e1 tr\u1ecb. Trong template c\u1ee5 th\u1ec3 n\u00e0y, tham s\u1ed1 b\u1eaft bu\u1ed9c duy nh\u1ea5t l\u00e0 KeyName<\/code>. KeyName<\/code> l\u00e0 s\u1eed d\u1ee5ng ssh key \u0111\u1ec3 truy c\u1eadp v\u00e0o instance. B\u1ea1n c\u00f3 th\u1ec3 t\u1ea1o kh\u00f3a ssh b\u1eb1ng menu EC2 Console trong \u201cKey Pairs\u201d. V\u1edbi h\u01b0\u1edbng d\u1eabn n\u00e0y, t\u00f4i \u0111\u00e3 t\u1ea1o ra m\u1ed9t tutorial keypair v\u00e0 s\u1ebd s\u1eed d\u1ee5ng n\u00f3.<\/p>\n\n\n\n

    B\u1eadt Stack<\/h2>\n\n\n\n

    Cu\u1ed1i c\u00f9ng, ta h\u00e3y c\u00f9ng nhau b\u1eadt stack l\u00ean th\u1eed xem sao!<\/p>\n\n\n\n

    $ aws cloudformation create-stack --template-body file:\/\/templates\/single_instance.yml --stack-name single-instance --parameters ParameterKey=KeyName,ParameterValue=tutorial ParameterKey=InstanceType,ParameterValue=t2.micro\n<\/code><\/pre>\n\n\n\n

    Sau khi b\u1eadt th\u00e0nh c\u00f4ng Stack CloudFormation, b\u1eadn s\u1ebd th\u1ea5y output gi\u1ed1ng nh\u01b0 sau:<\/p>\n\n\n\n

    {\n    \"StackId\": \"arn:aws:cloudformation:us-west-2:1606191131234:stack\/single-instance\/3401e900-3d83-11e7-bb7e-503f2a2cee4a\"\n}\n<\/code><\/pre>\n\n\n\n

    \u0110\u1ec3 ki\u1ec3m tra tr\u1ea1ng th\u00e1i c\u1ee7a stack m\u1edbi b\u1eadt, b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng console c\u1ee7a AWS CloudFormation v\u00e0 \u1ea5n v\u00e0o Tab Events sau khi ch\u1ecdn t\u00ean Stack. N\u00f3 s\u1ebd gi\u1ed1ng nh\u01b0 sau:\"\"<\/p>\n\n\n\n

    B\u1ea1n c\u00f3 th\u1ec3 th\u1ea5y r\u1eb1ng EC2 Instance v\u00e0 nh\u00f3m EC2 Security \u0111\u00e3 \u0111\u01b0\u1ee3c t\u1ea1o ch\u1ec9 trong v\u00f2ng kho\u1ea3ng m\u1ed9t ph\u00fat. Ti\u1ebfp theo, h\u00e3y t\u00ecm instance \u0111ang ch\u1ea1y \u0111\u1ec3 ta c\u00f3 th\u1ec3 l\u1ea5y public DNS \u0111\u1ec3 \u0111\u0103ng nh\u1eadp. Ta c\u00f3 th\u1ec3 t\u00ecm th\u1ea5y tr\u00ean Console EC2.\"\"<\/p>\n\n\n\n

    H\u00e3y ssh v\u00e0o instance s\u1eed d\u1ee5ng th\u00f4ng tin DNS \u1edf tr\u00ean<\/p>\n\n\n\n

    $ ssh -i ~\/.ssh\/tutorial.pem ec2-user@ec2\u201354\u201371\u2013197\u2013155.us-west-2.compute.amazonaws.com\n$ uptime\n<\/code><\/pre>\n\n\n\n

    Ch\u00fac m\u1eebng b\u1ea1n \u0111\u00e3 b\u1eadt th\u00e0nh c\u00f4ng instance EC2 CloudFormation v\u00e0 ssh \u0111\u01b0\u1ee3c v\u00e0o n\u00f3!<\/p>\n\n\n\n

    Clean up<\/h2>\n\n\n\n

    Ta h\u00e3y c\u00f9ng xo\u00e1 resource v\u1eeba t\u1ea1o, \u0111\u1ec3 b\u1ea1n kh\u00f4ng ph\u1ea3i m\u1ea5t th\u00eam kho\u1ea3n ti\u1ec1n n\u00e0o ch\u1ea1y n\u00f3 n\u1eefa. Vi\u1ec7c n\u00e0y r\u1ea5t \u0111\u01a1n gi\u1ea3n:<\/p>\n\n\n\n

    aws cloudformation delete-stack --stack-name single-instance\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"

    Cloud formation l\u00e0 g\u00ec? C\u00e1ch d\u1ec5 nh\u1ea5t \u0111\u1ec3 m\u00f4 t\u1ea3 CloudFormation l\u00e0 n\u00f3 l\u00e0 m\u1ed9t c\u00f4ng c\u1ee5 t\u1eeb AWS cho ph\u00e9p b\u1ea1n kh\u1edfi t\u1ea1o t\u00e0i nguy\u00ean m\u1ed9t c\u00e1ch d\u1ec5 d\u00e0ng. B\u1ea1n x\u00e1c \u0111\u1ecbnh t\u1ea5t c\u1ea3 c\u00e1c t\u00e0i nguy\u00ean m\u00e0 b\u1ea1n mu\u1ed1n AWS b\u1eadt l\u00ean trong m\u1ed9t b\u1ea3n thi\u1ebft k\u1ebf chi ti\u1ebft, b\u1ea5m v\u00e0o m\u1ed9t n\u00fat, […]<\/p>\n","protected":false},"author":9,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[122,128,126],"tags":[172,152,131,171,130],"class_list":["post-2044","post","type-post","status-publish","format-standard","hentry","category-blog","category-tech","category-tutor","tag-automation","tag-aws","tag-cloud-computing","tag-cloudformation","tag-dien-toan-dam-may"],"_links":{"self":[{"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/posts\/2044"}],"collection":[{"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/users\/9"}],"replies":[{"embeddable":true,"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/comments?post=2044"}],"version-history":[{"count":1,"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/posts\/2044\/revisions"}],"predecessor-version":[{"id":2045,"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/posts\/2044\/revisions\/2045"}],"wp:attachment":[{"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/media?parent=2044"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/categories?post=2044"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/uetacad.com\/wp-json\/wp\/v2\/tags?post=2044"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}