diff options
author | Henry.Sun <henry.a.sun@est.tech> | 2020-03-24 15:16:46 +0800 |
---|---|---|
committer | Henry.Sun <henry.a.sun@est.tech> | 2020-03-25 12:48:02 +0800 |
commit | fd5306f16f1e1f1bd07c706f073d57a700eff603 (patch) | |
tree | 81cc348197a2014422bc9fc54d2477e3368ddf84 /gui-pdp-monitoring | |
parent | f9e85b70f97c139911466336f29fb365de53306c (diff) |
add coverage test for JS
Issue-ID: POLICY-2311
Change-Id: I12a041f59bf07ed4e8688545522e64a338cdb326
Signed-off-by: Henry.Sun <henry.a.sun@est.tech>
Diffstat (limited to 'gui-pdp-monitoring')
12 files changed, 444 insertions, 48 deletions
diff --git a/gui-pdp-monitoring/src/webapp/js/MonitoringChart.js b/gui-pdp-monitoring/src/webapp/js/MonitoringChart.js index 514446b..a9b5f33 100644 --- a/gui-pdp-monitoring/src/webapp/js/MonitoringChart.js +++ b/gui-pdp-monitoring/src/webapp/js/MonitoringChart.js @@ -257,4 +257,4 @@ function formatDate(date) { return date.toLocaleString().replace(',', ''); } -export { initTooltip, createChart, updateChart };
\ No newline at end of file +export { initTooltip, createChart, updateChart, generateRandomData };
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/MonitoringMain.js b/gui-pdp-monitoring/src/webapp/js/MonitoringMain.js index 456f3a9..9198d63 100644 --- a/gui-pdp-monitoring/src/webapp/js/MonitoringMain.js +++ b/gui-pdp-monitoring/src/webapp/js/MonitoringMain.js @@ -64,46 +64,48 @@ function servicesCallback(data){ /* * Called after the DOM is ready */ -$(document).ready( - function() { - window.restRootURL = location.protocol +function readyCallback() { + window.restRootURL = location.protocol + "//" + window.location.hostname + ':' + config.restPort + (location.pathname.endsWith("/monitoring/") ? location.pathname.substring(0, location.pathname.indexOf("monitoring/")) : location.pathname) + "papservices/monitoring/"; - // Initialize tooltip for the charts - initTooltip(); + // Initialize tooltip for the charts + initTooltip(); - // Set up the structure of the page - setUpPage(true); + // Set up the structure of the page + setUpPage(true); - // Check cookies for engine URL - getEngineURL(); + // Check cookies for engine URL + getEngineURL(); - // Add click event to config icon for clearing engine URL - $(".ebSystemBar-config").click( - function() { + // Add click event to config icon for clearing engine URL + $(".ebSystemBar-config").click( + function() { // Clear the engine URL clearEngineURL(true); // Request the engine URL getEngineURL(); - } - ); + } + ); - ['hashchange', 'load'].forEach(event => window.addEventListener(event, function() { - // Get ID from url - window.id = window.location.hash.replace('#', ''); - if (window.id !== ''){ - var arr = window.id.split("/"); - window.groupName = arr[0]; - window.subGroupName = arr[1]; - highlightSelected(window.id); - ajax_get_statistics(restRootURL + "statistics/", servicesCallback, - window.services.useHttps, window.services.hostname, window.services.port, - window.services.username, window.services.password, window.id); - } - })); - } -);
\ No newline at end of file + ['hashchange', 'load'].forEach(event => window.addEventListener(event, function () { + // Get ID from url + window.id = window.location.hash.replace('#', ''); + if (window.id !== '') { + var arr = window.id.split("/"); + window.groupName = arr[0]; + window.subGroupName = arr[1]; + highlightSelected(window.id); + ajax_get_statistics(restRootURL + "statistics/", servicesCallback, + window.services.useHttps, window.services.hostname, window.services.port, + window.services.username, window.services.password, window.id); + } + })); +} + +$(document).ready(readyCallback); +// Export for unit testing +export { readyCallback, servicesCallback };
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/PdpEngineWorkerStatus.js b/gui-pdp-monitoring/src/webapp/js/PdpEngineWorkerStatus.js index 4ba8703..f130617 100644 --- a/gui-pdp-monitoring/src/webapp/js/PdpEngineWorkerStatus.js +++ b/gui-pdp-monitoring/src/webapp/js/PdpEngineWorkerStatus.js @@ -121,7 +121,8 @@ function setEngineStatusData(engineStatusData, changed) { var lastPolicyDurationDiv = document.createElement("div"); lastPolicyDurationDiv.setAttribute("id", chartConfig.parent); lastPolicyDurationDiv.setAttribute("class", "papChart"); - createChart(JSON.parse(engineStatusData[esd].lastPolicyDuration), lastPolicyDurationDiv, + + createChart(engineStatusData[esd].lastPolicyDuration, lastPolicyDurationDiv, chartConfig.title, chartConfig.unit, chartConfig.lineStroke, chartConfig.nodeColour); $(chartWrapper).append(lastPolicyDurationDiv); } @@ -136,7 +137,7 @@ function setEngineStatusData(engineStatusData, changed) { var averagePolicyDurationDiv = document.createElement("div"); averagePolicyDurationDiv.setAttribute("id", chartConfig.parent); averagePolicyDurationDiv.setAttribute("class", "papChart"); - createChart(JSON.parse(engineStatusData[esd].averagePolicyDuration), averagePolicyDurationDiv, + createChart(engineStatusData[esd].averagePolicyDuration, averagePolicyDurationDiv, chartConfig.title, chartConfig.unit, chartConfig.lineStroke, chartConfig.nodeColour); $(chartWrapper).append(averagePolicyDurationDiv); } diff --git a/gui-pdp-monitoring/src/webapp/js/PdpStatisticsSummary.js b/gui-pdp-monitoring/src/webapp/js/PdpStatisticsSummary.js index 4060c05..b8065bb 100644 --- a/gui-pdp-monitoring/src/webapp/js/PdpStatisticsSummary.js +++ b/gui-pdp-monitoring/src/webapp/js/PdpStatisticsSummary.js @@ -118,7 +118,7 @@ function getAvgPolicyDuration(data) { var chartData = []; var avgPolicyDurations = []; for ( var d in data) { - var avgPolicyDuration = JSON.parse(data[d].averagePolicyDuration); + var avgPolicyDuration = data[d].averagePolicyDuration; avgPolicyDurations.push(avgPolicyDuration); } diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringChart.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringChart.test.js new file mode 100644 index 0000000..6fa0e05 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringChart.test.js @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import * as MonitoringChart from "../MonitoringChart"; + +const data = MonitoringChart.generateRandomData(); +const container = null; +const title = null; +const unit = null; +const lineStroke = ""; +const nodeColour = ""; + +test("test create chart is available", () => { + MonitoringChart.createChart(data, container, title, unit, lineStroke, nodeColour); + expect(data.length).toBe(30); +}); + +test("update Chart", () => { + MonitoringChart.initTooltip; + expect(data.length).toBe(30); +}); + + diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringMain.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringMain.test.js new file mode 100644 index 0000000..cfbfaf6 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringMain.test.js @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import * as sut from "../MonitoringMain"; + +import * as MonitoringChart from "../MonitoringChart"; +import * as MonitoringUtils from "../MonitoringUtils"; +import * as PdpInformation from "../PdpInformation"; +import * as PdpStatisticsSummary from "../PdpStatisticsSummary"; +import * as PdpEngineWorkerStatus from "../PdpEngineWorkerStatus"; + +test("test ready", () => { + MonitoringChart.initTooltip = jest.fn(); + MonitoringUtils.setUpPage = jest.fn(); + MonitoringUtils.getEngineURL = jest.fn(); + sut.readyCallback(); + expect(MonitoringChart.initTooltip).toHaveBeenCalled(); + expect(MonitoringUtils.setUpPage).toHaveBeenCalled(); + expect(MonitoringUtils.getEngineURL).toHaveBeenCalled(); +}); + +test("test service callback", () => { + const storedData = { + useHttps: "http", + hostname: "localhost", + port: 7979, + username: "username", + password: "password", + }; + + const data = { + server: "localhost", + port: 7979, + } + window.localStorage.setItem("pap-monitor-services", JSON.stringify(storedData)); + PdpInformation.setEngineServiceData = jest.fn(); + PdpStatisticsSummary.setEngineSummaryData = jest.fn(); + PdpEngineWorkerStatus.setEngineStatusData = jest.fn(); + sut.servicesCallback(data); + expect(PdpInformation.setEngineServiceData).toHaveBeenCalled(); + expect(PdpStatisticsSummary.setEngineSummaryData).toHaveBeenCalled(); + expect(PdpEngineWorkerStatus.setEngineStatusData).toHaveBeenCalled(); +});
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringTable.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringTable.test.js new file mode 100644 index 0000000..2f67925 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringTable.test.js @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import $ from 'jquery'; +import * as MonitoringTable from "../MonitoringTable" + +var wrapper = document.createElement("example") +wrapper.setAttribute("id", "engineSummary_wrapper"); +wrapper.setAttribute("class", "wrapper_borderless"); + +test("create necessary engine table", () => { + MonitoringTable.createEngineTable($(wrapper), null, null); + expect(document.getElementById("engineTableBody")).toBeDefined(); + expect(document.getElementById("engineTableHeader")).toBeDefined(); + expect(document.getElementById("engineTableHeaderRow")).toBeDefined(); + });
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringUtils.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringUtils.test.js index 45fae79..35eb297 100644 --- a/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringUtils.test.js +++ b/gui-pdp-monitoring/src/webapp/js/__test__/MonitoringUtils.test.js @@ -1,19 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + import $ from 'jquery'; -import { ajax_get, ajax_get_statistics } from "../MonitoringUtils"; - -$.ajax = jest.fn().mockImplementation(() => { - const fakeResponse = { - data: { - id: 1, - name: "All", - value: "Dummy Data" +import * as sut from "../MonitoringUtils"; +import * as PdpInformation from "../PdpInformation"; +import * as PdpStatisticsSummary from "../PdpStatisticsSummary"; +import * as PdpListView from '../PdpListView'; + +const requestURL = "http://localhost:7979"; + +const serviceData = { + useHttps: "http", + hostname: "localhost", + port: 7979, + username: "username", + password: "password", +}; + +test('ajax_get ok', () => { + const callback = jest.fn(); + $.ajax = jest.fn().mockImplementation((args) => { args.success(); }); + sut.ajax_get(requestURL, callback, serviceData.useHttps, serviceData.hostname, serviceData.port, + serviceData.username, serviceData.password, {}, null); + expect(callback).toHaveBeenCalled(); +}); + +test('ajax_get error', () => { + const errorCallback = jest.fn(); + const jqXHR = { status: 500, responseText: "" }; + $.ajax = jest.fn().mockImplementation( + args => { + args.error(jqXHR, null, null); } - }; - return Promise.resolve(fakeResponse); + ); + sut.ajax_get(requestURL, null, serviceData.useHttps, serviceData.hostname, serviceData.port, + serviceData.username, serviceData.password, {}, errorCallback); + expect(errorCallback).toHaveBeenCalled(); }); -test('ajax_get return ok', () => { - ajax_get().then(response => { - expect(response.data.id).toBe(1); - }); -});
\ No newline at end of file +test('ajax_get_statistics ok', () => { + const callback = jest.fn(); + $.ajax = jest.fn().mockImplementation((args) => { args.success(); }); + sut.ajax_get_statistics(requestURL, callback, serviceData.useHttps, serviceData.hostname, serviceData.port, + serviceData.username, serviceData.password, "", {}, null); + expect(callback).toHaveBeenCalled(); +}); + +test('ajax_get_statistics error', () => { + const errorCallback = jest.fn(); + const jqXHR = { status: 500, responseText: "" }; + $.ajax = jest.fn().mockImplementation( + args => { + args.error(jqXHR, null, null); + } + ); + PdpInformation.createEngineServiceTable = jest.fn(); + PdpStatisticsSummary.createEngineSummaryTable = jest.fn(); + sut.ajax_get_statistics(requestURL, null, serviceData.useHttps, serviceData.hostname, serviceData.port, + serviceData.username, serviceData.password, "", {}, errorCallback); + + expect(errorCallback).toHaveBeenCalled(); + expect(PdpInformation.createEngineServiceTable).toHaveBeenCalled(); + expect(PdpStatisticsSummary.createEngineSummaryTable).toHaveBeenCalled(); +}); + +test('getEngineURL popup dialog', () => { + window.localStorage.clear(); + sut.getEngineURL("message"); + $('#submit').click(); + expect($("papDialogDiv")).toHaveLength(1); +}); + +test('getEngineURL read from localStorage', () => { + window.localStorage.setItem("pap-monitor-services", JSON.stringify(serviceData)); + const data = { + groups: [{ + pdpSubgroups: [{ + pdpType: "apex", + pdpInstances: [{ + instanceId: "apex-pdp1", + }], + }] + } + ], + }; + + $.ajax = jest.fn().mockImplementation((args) => { args.success(data); }); + PdpListView.RenderPdpList = jest.fn(); + sut.getEngineURL("message"); + expect(PdpListView.RenderPdpList.mock.calls[0][0]).toHaveLength(1); +}); diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/PdpEngineWorkerStatus.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/PdpEngineWorkerStatus.test.js new file mode 100644 index 0000000..39b74f5 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/PdpEngineWorkerStatus.test.js @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import * as PdpEngineWorkerStatus from "../PdpEngineWorkerStatus"; +import * as MonitoringChart from "../MonitoringChart"; + +test("set engine status data", () => { + var temp = MonitoringChart.generateRandomData(); + var engineStatusData = [{id : 1, lastPolicyDuration : 1, averagePolicyDuration: 1}]; + var changed = jest.fn(() => { + return false; + }); + + engineStatusData[0].lastPolicyDuration = temp; + engineStatusData[0].averagePolicyDuration = temp; + window.engineStatusTables = []; + PdpEngineWorkerStatus.setEngineStatusData(engineStatusData, changed); + + expect(window.engineStatusTables[0]).toBeDefined(); +});
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/PdpInformation.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/PdpInformation.test.js new file mode 100644 index 0000000..993eb54 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/PdpInformation.test.js @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import * as PdpInformation from "../PdpInformation" + +test("create engine service table", () => { + PdpInformation.createEngineServiceTable(); + expect(document.getElementById("string")).toBeDefined(); +}) + +test("ser engine service data", () => { + PdpInformation.setEngineServiceData("testing", "testing", "testing", "testing", "testing", null, null); + expect(document.getElementById("testing")).toBeDefined(); +})
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/PdpListView.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/PdpListView.test.js new file mode 100644 index 0000000..6152ac0 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/PdpListView.test.js @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import * as PdpListView from "../PdpListView"; +const pdpArray = []; + +test("render pdp list", () => { + const data = { + groups: [{ + pdpSubgroups: [{ + pdpType: "apex", + pdpInstances: [{ + instanceId: "apex-pdp1", + }], + }] + } + ], + }; + + for (let i = 0; i < data.groups.length; i++) { + var map = {}; + map.title = data.groups[i].name; + map.children = []; + (data.groups[i].pdpSubgroups).forEach((pdpSubgroup, index) => { + map.children[index] = {}; + map.children[index].title = pdpSubgroup.pdpType; + const instanceId = []; + pdpSubgroup.pdpInstances.forEach(pdpInstance => { + var instanceIdMap = {}; + instanceIdMap.title = pdpInstance.instanceId; + instanceId.push(instanceIdMap) + }); + map.children[index].children = instanceId; + }); + pdpArray.push(map); + }; + + document.body.innerHTML = '<ul class="pdps__list"></ul>'; + PdpListView.RenderPdpList(pdpArray, "pdps__list"); + expect(document.querySelector('a.' + 'pdps__link').innerHTML).toBe("apex-pdp1"); +}); + +test("high light selected", () => { + PdpListView.highlightSelected(1); + console.log(document.querySelector(`.pdps__link[href*="${1}"]`)); + expect(document.querySelector(`.pdps__link[href*="${1}"]`)).toBeDefined(); +})
\ No newline at end of file diff --git a/gui-pdp-monitoring/src/webapp/js/__test__/PdpStatisticsSummary.test.js b/gui-pdp-monitoring/src/webapp/js/__test__/PdpStatisticsSummary.test.js new file mode 100644 index 0000000..03404b7 --- /dev/null +++ b/gui-pdp-monitoring/src/webapp/js/__test__/PdpStatisticsSummary.test.js @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import * as PdpEngineSummary from "../PdpStatisticsSummary"; + +var data = [{averagePolicyDuration : [ + { timestamp: 1584979433034, value: 95 }, + { timestamp: 1584979428034, value: 78 }, + { timestamp: 1584979423034, value: 71 }, + { timestamp: 1584979418034, value: 79 }, + { timestamp: 1584979413034, value: 21 }]}] + +test("create engine summary table", () => { + PdpEngineSummary.createEngineSummaryTable(); + expect(document.getElementById("string")).toBeDefined(); +}) + +test("set engine service data", () => { + PdpEngineSummary.setEngineSummaryData(data, null, 1, 2, 3, 1, 2, 3) + expect(document.getElementById("engineSummaryTable")).toBeDefined(); +})
\ No newline at end of file |