diff --git a/create_zip.sh b/create_zip.sh
new file mode 100755
index 0000000..a34fd27
--- /dev/null
+++ b/create_zip.sh
@@ -0,0 +1,97 @@
+version=$(grep "version=" module/module.prop | cut -d "=" -f 2)
+
+echo "BeeSrv ZIP Builder"
+echo "=================="
+echo ""
+
+# Check if zip is installed
+if ! command -v zip &> /dev/null; then
+ echo "[!] zip is not installed"
+ exit 1
+fi
+
+# Check if bun is installed
+if ! command -v bun &> /dev/null; then
+ echo "[!] bun is not installed"
+ exit 1
+fi
+
+# Check if filename to be created already exists
+if [ -f "BeeSrv-$version.zip" ]; then
+ echo "[i] BeeSrv-$version.zip already exists, would you like to overwrite it? (y/n)"
+ read overwrite
+ if [ "$overwrite" != "y" ]; then
+ echo "[!] Aborting..."
+ exit 1
+ else
+ rm -rf BeeSrv-$version.zip
+ echo "[✔] Overwriting BeeSrv-$version.zip..."
+ fi
+fi
+
+# Check for leftover tmp dir
+if [ -d "tmp" ]; then
+ echo "[i] tmp directory already exists, would you like to overwrite it? (y/n)"
+ read overwrite
+ if [ "$overwrite" != "y" ]; then
+ echo "[!] Aborting..."
+ exit 1
+ else
+ rm -rf tmp
+ fi
+fi
+
+# Copy module to tmp
+cp -r module tmp
+echo "[✔] Created working directory"
+
+# Clean any unnecessary files
+rm -rf tmp/module/webroot/dist
+rm -rf tmp/module/webroot/.gitignore
+rm -rf tmp/module/webroot/package-lock.json
+echo "[✔] Completed cleanup"
+
+# Build webroot
+echo "[i] Building webroot..."
+cd tmp/webroot
+echo "[i] Installing dependencies..."
+bun install
+echo ""
+echo "[✔] Installed dependencies"
+echo ""
+echo "[i] Building with parcel..."
+echo ""
+bunx parcel build src/index.html
+echo ""
+echo "[✔] Built webroot"
+
+# Clean up for zip
+rm -rf .parcel-cache
+rm -rf src
+rm -rf node_modules
+rm bun.lock*
+rm package*
+rm .gitignore
+echo "[✔] Completed cleanup"
+
+# Move built files to webroot
+cd ..
+cp -r webroot/dist/* webroot
+echo "[✔] Moved built files to webroot"
+
+# Remove build dir
+rm -rf webroot/dist
+echo "[✔] Completed cleanup"
+
+# Create zip
+echo "[i] Creating zip..."
+zip -r ../BeeSrv-$version.zip *
+cd ..
+echo "[✔] Created zip"
+
+# Clean up
+rm -rf tmp
+echo "[✔] Completed cleanup"
+
+echo ""
+echo "BeeSrv-$version.zip created successfully!"
diff --git a/module/customize.sh b/module/customize.sh
index 47d9aa9..9207f25 100644
--- a/module/customize.sh
+++ b/module/customize.sh
@@ -2,7 +2,8 @@ ui_print ""
ui_print "=== BEESRV ==="
ui_print "Version: $(grep_prop version $MODPATH/module.prop)"
ui_print "Made with ❤️ by ihatenodejs"
-ui_print "================================"
+ui_print "==========================="
+ui_print ""
sleep 0.4
# Environment checks
@@ -31,14 +32,33 @@ fi
# Create config
ui_print "[i] Creating config..."
mkdir -p /data/adb/beesrv
-touch /data/adb/beesrv/config.txt
-chmod 664 /data/adb/beesrv/config.txt
-echo "SERVER=" >> /data/adb/beesrv/config.txt
+# Check if config file exists, and check if required variables are set
+config_modified=false
+if [ ! -f "/data/adb/beesrv/config.txt" ]; then
+ echo "SERVER=" >> /data/adb/beesrv/config.txt
+ ui_print "[✔] Config created"
+ ui_print ""
+else
+ ui_print "[i] Config file found, checking..."
-ui_print "[✔] Config created"
+ # Check SERVER var
+ if ! grep -q "SERVER=" /data/adb/beesrv/config.txt; then
+ ui_print "[i] SERVER variable not found, adding..."
+ echo "SERVER=" >> /data/adb/beesrv/config.txt
+ config_modified=true
+ fi
+
+ if [ "$config_modified" = true ]; then
+ ui_print "[✔] Config modified successfully"
+ ui_print ""
+ else
+ ui_print "[✔] Config already valid, skipping update..."
+ ui_print ""
+ fi
+fi
-ui_print ""
ui_print "== INSTALLATION COMPLETE! =="
+ui_print ""
ui_print "Join our Telegram channel: t.me/pontushub"
sleep 0.4
\ No newline at end of file
diff --git a/module/webroot/.gitignore b/module/webroot/.gitignore
new file mode 100644
index 0000000..867940f
--- /dev/null
+++ b/module/webroot/.gitignore
@@ -0,0 +1,5 @@
+.parcel-cache/
+dist/
+node_modules/
+package-lock.json
+bun.lock*
\ No newline at end of file
diff --git a/module/webroot/package.json b/module/webroot/package.json
new file mode 100644
index 0000000..cbc3762
--- /dev/null
+++ b/module/webroot/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "parcel-vanilla-starter",
+ "private": true,
+ "version": "0.0.0",
+ "source": "src/index.html",
+ "scripts": {
+ "start": "parcel",
+ "build": "bunx @tailwindcss/cli -i ./src/css/style-pre.css -o ./src/css/style.css && parcel build",
+ "build:css:watch": "bunx @tailwindcss/cli -i ./src/css/style-pre.css -o ./src/css/style.css --watch"
+ },
+ "dependencies": {
+ "@tailwindcss/cli": "^4.1.3",
+ "kernelsu": "^1.0.6",
+ "tailwindcss": "^4.1.3"
+ },
+ "devDependencies": {
+ "buffer": "^6.0.3",
+ "events": "^3.3.0",
+ "os-browserify": "^0.3.0",
+ "parcel": "^2.14.0",
+ "process": "^0.11.10",
+ "util": "^0.12.5",
+ "vm-browserify": "^1.1.2"
+ }
+}
diff --git a/module/webroot/src/css/style-pre.css b/module/webroot/src/css/style-pre.css
new file mode 100644
index 0000000..a461c50
--- /dev/null
+++ b/module/webroot/src/css/style-pre.css
@@ -0,0 +1 @@
+@import "tailwindcss";
\ No newline at end of file
diff --git a/module/webroot/src/css/style.css b/module/webroot/src/css/style.css
new file mode 100644
index 0000000..84533b9
--- /dev/null
+++ b/module/webroot/src/css/style.css
@@ -0,0 +1,409 @@
+/*! tailwindcss v4.1.3 | MIT License | https://tailwindcss.com */
+@layer properties;
+@layer theme, base, components, utilities;
+@layer theme {
+ :root, :host {
+ --font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
+ "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
+ "Courier New", monospace;
+ --color-red-400: oklch(70.4% 0.191 22.216);
+ --color-green-400: oklch(79.2% 0.209 151.711);
+ --color-blue-500: oklch(62.3% 0.214 259.815);
+ --color-slate-500: oklch(55.4% 0.046 257.417);
+ --color-slate-600: oklch(44.6% 0.043 257.281);
+ --color-slate-700: oklch(37.2% 0.044 257.287);
+ --color-gray-300: oklch(87.2% 0.01 258.338);
+ --color-gray-600: oklch(44.6% 0.03 256.802);
+ --color-gray-700: oklch(37.3% 0.034 259.733);
+ --color-gray-800: oklch(27.8% 0.033 256.848);
+ --color-gray-900: oklch(21% 0.034 264.665);
+ --color-white: #fff;
+ --spacing: 0.25rem;
+ --text-xl: 1.25rem;
+ --text-xl--line-height: calc(1.75 / 1.25);
+ --text-2xl: 1.5rem;
+ --text-2xl--line-height: calc(2 / 1.5);
+ --font-weight-semibold: 600;
+ --font-weight-bold: 700;
+ --radius-md: 0.375rem;
+ --animate-spin: spin 1s linear infinite;
+ --default-transition-duration: 150ms;
+ --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ --default-font-family: var(--font-sans);
+ --default-mono-font-family: var(--font-mono);
+ }
+}
+@layer base {
+ *, ::after, ::before, ::backdrop, ::file-selector-button {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ border: 0 solid;
+ }
+ html, :host {
+ line-height: 1.5;
+ -webkit-text-size-adjust: 100%;
+ tab-size: 4;
+ font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");
+ font-feature-settings: var(--default-font-feature-settings, normal);
+ font-variation-settings: var(--default-font-variation-settings, normal);
+ -webkit-tap-highlight-color: transparent;
+ }
+ hr {
+ height: 0;
+ color: inherit;
+ border-top-width: 1px;
+ }
+ abbr:where([title]) {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+ }
+ h1, h2, h3, h4, h5, h6 {
+ font-size: inherit;
+ font-weight: inherit;
+ }
+ a {
+ color: inherit;
+ -webkit-text-decoration: inherit;
+ text-decoration: inherit;
+ }
+ b, strong {
+ font-weight: bolder;
+ }
+ code, kbd, samp, pre {
+ font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);
+ font-feature-settings: var(--default-mono-font-feature-settings, normal);
+ font-variation-settings: var(--default-mono-font-variation-settings, normal);
+ font-size: 1em;
+ }
+ small {
+ font-size: 80%;
+ }
+ sub, sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+ }
+ sub {
+ bottom: -0.25em;
+ }
+ sup {
+ top: -0.5em;
+ }
+ table {
+ text-indent: 0;
+ border-color: inherit;
+ border-collapse: collapse;
+ }
+ :-moz-focusring {
+ outline: auto;
+ }
+ progress {
+ vertical-align: baseline;
+ }
+ summary {
+ display: list-item;
+ }
+ ol, ul, menu {
+ list-style: none;
+ }
+ img, svg, video, canvas, audio, iframe, embed, object {
+ display: block;
+ vertical-align: middle;
+ }
+ img, video {
+ max-width: 100%;
+ height: auto;
+ }
+ button, input, select, optgroup, textarea, ::file-selector-button {
+ font: inherit;
+ font-feature-settings: inherit;
+ font-variation-settings: inherit;
+ letter-spacing: inherit;
+ color: inherit;
+ border-radius: 0;
+ background-color: transparent;
+ opacity: 1;
+ }
+ :where(select:is([multiple], [size])) optgroup {
+ font-weight: bolder;
+ }
+ :where(select:is([multiple], [size])) optgroup option {
+ padding-inline-start: 20px;
+ }
+ ::file-selector-button {
+ margin-inline-end: 4px;
+ }
+ ::placeholder {
+ opacity: 1;
+ }
+ @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {
+ ::placeholder {
+ color: currentcolor;
+ @supports (color: color-mix(in lab, red, red)) {
+ color: color-mix(in oklab, currentcolor 50%, transparent);
+ }
+ }
+ }
+ textarea {
+ resize: vertical;
+ }
+ ::-webkit-search-decoration {
+ -webkit-appearance: none;
+ }
+ ::-webkit-date-and-time-value {
+ min-height: 1lh;
+ text-align: inherit;
+ }
+ ::-webkit-datetime-edit {
+ display: inline-flex;
+ }
+ ::-webkit-datetime-edit-fields-wrapper {
+ padding: 0;
+ }
+ ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {
+ padding-block: 0;
+ }
+ :-moz-ui-invalid {
+ box-shadow: none;
+ }
+ button, input:where([type="button"], [type="reset"], [type="submit"]), ::file-selector-button {
+ appearance: button;
+ }
+ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {
+ height: auto;
+ }
+ [hidden]:where(:not([hidden="until-found"])) {
+ display: none !important;
+ }
+}
+@layer utilities {
+ .visible {
+ visibility: visible;
+ }
+ .mt-4 {
+ margin-top: calc(var(--spacing) * 4);
+ }
+ .mr-1 {
+ margin-right: calc(var(--spacing) * 1);
+ }
+ .mr-2 {
+ margin-right: calc(var(--spacing) * 2);
+ }
+ .mb-2 {
+ margin-bottom: calc(var(--spacing) * 2);
+ }
+ .mb-4 {
+ margin-bottom: calc(var(--spacing) * 4);
+ }
+ .ml-2 {
+ margin-left: calc(var(--spacing) * 2);
+ }
+ .block {
+ display: block;
+ }
+ .flex {
+ display: flex;
+ }
+ .hidden {
+ display: none;
+ }
+ .table {
+ display: table;
+ }
+ .h-4 {
+ height: calc(var(--spacing) * 4);
+ }
+ .h-5 {
+ height: calc(var(--spacing) * 5);
+ }
+ .w-4 {
+ width: calc(var(--spacing) * 4);
+ }
+ .w-5 {
+ width: calc(var(--spacing) * 5);
+ }
+ .w-full {
+ width: 100%;
+ }
+ .border-collapse {
+ border-collapse: collapse;
+ }
+ .transform {
+ transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
+ }
+ .animate-spin {
+ animation: var(--animate-spin);
+ }
+ .resize {
+ resize: both;
+ }
+ .flex-wrap {
+ flex-wrap: wrap;
+ }
+ .items-center {
+ align-items: center;
+ }
+ .gap-2 {
+ gap: calc(var(--spacing) * 2);
+ }
+ .rounded-md {
+ border-radius: var(--radius-md);
+ }
+ .border {
+ border-style: var(--tw-border-style);
+ border-width: 1px;
+ }
+ .border-gray-600 {
+ border-color: var(--color-gray-600);
+ }
+ .bg-gray-700 {
+ background-color: var(--color-gray-700);
+ }
+ .bg-gray-800 {
+ background-color: var(--color-gray-800);
+ }
+ .bg-gray-900 {
+ background-color: var(--color-gray-900);
+ }
+ .bg-slate-500 {
+ background-color: var(--color-slate-500);
+ }
+ .bg-slate-600 {
+ background-color: var(--color-slate-600);
+ }
+ .p-2 {
+ padding: calc(var(--spacing) * 2);
+ }
+ .p-4 {
+ padding: calc(var(--spacing) * 4);
+ }
+ .px-3 {
+ padding-inline: calc(var(--spacing) * 3);
+ }
+ .px-4 {
+ padding-inline: calc(var(--spacing) * 4);
+ }
+ .py-1 {
+ padding-block: calc(var(--spacing) * 1);
+ }
+ .py-2 {
+ padding-block: calc(var(--spacing) * 2);
+ }
+ .text-center {
+ text-align: center;
+ }
+ .text-left {
+ text-align: left;
+ }
+ .text-2xl {
+ font-size: var(--text-2xl);
+ line-height: var(--tw-leading, var(--text-2xl--line-height));
+ }
+ .font-bold {
+ --tw-font-weight: var(--font-weight-bold);
+ font-weight: var(--font-weight-bold);
+ }
+ .font-semibold {
+ --tw-font-weight: var(--font-weight-semibold);
+ font-weight: var(--font-weight-semibold);
+ }
+ .text-gray-300 {
+ color: var(--color-gray-300);
+ }
+ .text-green-400 {
+ color: var(--color-green-400);
+ }
+ .text-red-400 {
+ color: var(--color-red-400);
+ }
+ .text-white {
+ color: var(--color-white);
+ }
+ .underline {
+ text-decoration-line: underline;
+ }
+ .outline {
+ outline-style: var(--tw-outline-style);
+ outline-width: 1px;
+ }
+ .transition-colors {
+ transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
+ }
+ .hover\:bg-slate-600 {
+ &:hover {
+ @media (hover: hover) {
+ background-color: var(--color-slate-600);
+ }
+ }
+ }
+ .hover\:bg-slate-700 {
+ &:hover {
+ @media (hover: hover) {
+ background-color: var(--color-slate-700);
+ }
+ }
+ }
+}
+@property --tw-rotate-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateX(0);
+}
+@property --tw-rotate-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateY(0);
+}
+@property --tw-rotate-z {
+ syntax: "*";
+ inherits: false;
+ initial-value: rotateZ(0);
+}
+@property --tw-skew-x {
+ syntax: "*";
+ inherits: false;
+ initial-value: skewX(0);
+}
+@property --tw-skew-y {
+ syntax: "*";
+ inherits: false;
+ initial-value: skewY(0);
+}
+@property --tw-border-style {
+ syntax: "*";
+ inherits: false;
+ initial-value: solid;
+}
+@property --tw-font-weight {
+ syntax: "*";
+ inherits: false;
+}
+@property --tw-outline-style {
+ syntax: "*";
+ inherits: false;
+ initial-value: solid;
+}
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+@layer properties {
+ @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
+ *, ::before, ::after, ::backdrop {
+ --tw-rotate-x: rotateX(0);
+ --tw-rotate-y: rotateY(0);
+ --tw-rotate-z: rotateZ(0);
+ --tw-skew-x: skewX(0);
+ --tw-skew-y: skewY(0);
+ --tw-border-style: solid;
+ --tw-font-weight: initial;
+ --tw-outline-style: solid;
+ }
+ }
+}
diff --git a/module/webroot/src/index.html b/module/webroot/src/index.html
new file mode 100644
index 0000000..bf711af
--- /dev/null
+++ b/module/webroot/src/index.html
@@ -0,0 +1,104 @@
+
+
+
+
+
+ BeeSrv WebUI
+
+
+
+
+
+
+
+
+
+
+ Self-Check
+
+
+
+ Internet Connection |
+
+
+
+
+ Connected
+
+
+
+ Error
+
+ |
+
+
+
+
+
+
+ Module
+
+
+
+ Version |
+
+
+
+ Loading...
+
+ |
+
+
+ Server |
+
+
+
+ Loading...
+
+ |
+
+
+
+
+ Join Us
+
+ Made with ❤️ by ihatenodejs
+
+
+
diff --git a/module/webroot/src/js/app.js b/module/webroot/src/js/app.js
new file mode 100644
index 0000000..2941a66
--- /dev/null
+++ b/module/webroot/src/js/app.js
@@ -0,0 +1,146 @@
+import { exec } from "kernelsu"
+
+const modules_dir = "/data/adb/modules/BeeSrv"
+const persist_dir = "/data/adb/beesrv"
+
+function showError(message) {
+ const errorBox = document.getElementById("errorBox")
+ const errorMessage = document.getElementById("errorMessage")
+ errorMessage.textContent = message
+ errorBox.classList.remove("hidden")
+}
+
+function hideError() {
+ const errorBox = document.getElementById("errorBox")
+ errorBox.classList.add("hidden")
+}
+
+async function getVersion() {
+ try {
+ const { errno, stdout, stderr } = await exec(`cat ${modules_dir}/module.prop`)
+ if (errno !== 0) {
+ showError("Failed to read module version")
+ return "Unknown"
+ }
+ const version = stdout.split("\n").find(line => line.startsWith("version="))
+ if (!version) {
+ showError("Module version not found")
+ return "Unknown"
+ }
+ return version.split("=")[1]
+ } catch (error) {
+ showError("Error reading module version")
+ return "Unknown"
+ }
+}
+
+async function getServer() {
+ try {
+ const { errno, stdout, stderr } = await exec(`cat ${persist_dir}/config.txt`)
+ if (errno !== 0) {
+ showError("Failed to read server configuration")
+ return "Unknown"
+ }
+ const server = stdout.split("\n").find(line => line.startsWith("SERVER="))
+ if (!server) {
+ showError("Server configuration not found")
+ return "Unknown"
+ }
+ return server.split("=")[1]
+ } catch (error) {
+ showError("Error reading server configuration")
+ return "Unknown"
+ }
+}
+
+async function checkConnection() {
+ try {
+ const response = await fetch('https://httpbin.org/get', {
+ method: 'GET',
+ signal: AbortSignal.timeout(5000)
+ });
+
+ return response.ok;
+ } catch (error) {
+ if (error.name === 'AbortError') {
+ throw new Error('Connection check timed out. Please try again.');
+ } else if (error.name === 'TypeError' && error.message.includes('Failed to fetch')) {
+ throw new Error('Unable to reach the internet. Please check your network connection.');
+ } else {
+ throw new Error('Connection check failed. Please try again later.');
+ }
+ }
+}
+
+document.addEventListener("DOMContentLoaded", async () => {
+ const versionText = document.getElementById("versionText")
+ const serverText = document.getElementById("serverText")
+ const versionLoader = document.getElementById("versionLoader")
+ const serverLoader = document.getElementById("serverLoader")
+
+ try {
+ const version = await getVersion()
+ const server = await getServer()
+
+ versionLoader.classList.add("hidden")
+ serverLoader.classList.add("hidden")
+ versionText.textContent = version
+ serverText.textContent = server
+ } catch (error) {
+ versionLoader.classList.add("hidden")
+ serverLoader.classList.add("hidden")
+ versionText.textContent = "Error"
+ serverText.textContent = "Error"
+ }
+
+ const checkConnectionBtn = document.getElementById("checkConnection")
+ const testBtn = document.getElementById("testBtn")
+ const testBtnLoading = document.getElementById("testBtnLoading")
+ const connectionStatus = document.getElementById("connectionStatus")
+ const connectionError = document.getElementById("connectionError")
+
+ function resetButtonState() {
+ testBtnLoading.classList.add("hidden")
+ testBtn.classList.remove("hidden")
+ checkConnectionBtn.disabled = false
+ }
+
+ function setLoadingState() {
+ testBtn.classList.add("hidden")
+ testBtnLoading.classList.remove("hidden")
+ connectionStatus.classList.add("hidden")
+ connectionError.classList.add("hidden")
+ checkConnectionBtn.disabled = true
+ hideError()
+ }
+
+ function showSuccessState() {
+ connectionStatus.classList.remove("hidden")
+ connectionError.classList.add("hidden")
+ // Hide the button after successful test
+ checkConnectionBtn.classList.add("hidden")
+ }
+
+ function showErrorState(message) {
+ connectionStatus.classList.add("hidden")
+ connectionError.classList.remove("hidden")
+ showError(message)
+ checkConnectionBtn.classList.add("hidden")
+ }
+
+ checkConnectionBtn.addEventListener("click", async () => {
+ setLoadingState()
+ try {
+ const isConnected = await checkConnection()
+ resetButtonState()
+ if (isConnected) {
+ showSuccessState()
+ } else {
+ showErrorState("No internet connection detected")
+ }
+ } catch (error) {
+ resetButtonState()
+ showErrorState(error.message)
+ }
+ })
+})