Added libs

This commit is contained in:
Lucas
2026-01-25 13:55:46 +10:00
parent 575c682afc
commit f70af3c4ea
229 changed files with 26983 additions and 0 deletions

4
vueNoSys/.env Normal file
View File

@@ -0,0 +1,4 @@
VITE_PORT=3001
VITE_BACKEND_API_HOST=https://127.0.0.1
VITE_BACKEND_API_PORT=5050
VITE_BACKEND_API_URL=$VITE_BACKEND_API_HOST:$VITE_BACKEND_API_PORT

37
vueNoSys/.gitignore vendored Normal file
View File

@@ -0,0 +1,37 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo
# Server
vueNoSys.zip
# Local modules moved
src/modules/*
__pycache__/

37
vueNoSys/.gitignore copy Normal file
View File

@@ -0,0 +1,37 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
*.tsbuildinfo
# Server
vueZecho.zip
# Local modules moved
src/modules/*
__pycache__/

1
vueNoSys/.mtimes.json Normal file
View File

@@ -0,0 +1 @@
{".env": 1757243712.0195093, ".gitignore": 1748256435.559527, ".gitignore copy": 1741437086.8110943, "config.json": 1757237141.1301756, "index.html": 1754219702.633047, "jsconfig.json": 1757203880.1595626, "package-lock.json": 1757233458.7097306, "package.json": 1757233458.6810963, "postcss.config.js": 1739790368.0341797, "README.md": 1739790368.038704, "tailwind.config.js": 1754219718.147903, "vite.config.js": 1757243813.009877, "vueNoSys.py": 1757237244.6391177, "vueNoSysApiBlueprint.py": 1757329122.2211251, "public\\favicon.ico": 1739790368.0371933, "src\\App.vue": 1757203732.0757146, "src\\main.js": 1757403664.0534062, "src\\router.js": 1757331049.8079045, "src\\api\\vueNoSysApi.js": 1757242713.4260733, "src\\assets\\main.css": 1739790368.044835, "src\\components\\NavBar.vue": 1757331615.4059455, "src\\components\\buttons\\Button.vue": 1757756254.6643045, "src\\components\\buttons\\ToogleSwitch.vue": 1757838047.8812475, "src\\components\\cards\\Card.vue": 1757204615.562129, "src\\components\\cards\\CardContent.vue": 1753268228.9833386, "src\\components\\cards\\CardDescription.vue": 1753268228.9833386, "src\\components\\cards\\CardFooter.vue": 1753268228.9843438, "src\\components\\cards\\CardHeader.vue": 1753268228.984848, "src\\components\\cards\\CardTitle.vue": 1753268228.984848, "src\\components\\inputs\\InputComboBox.vue": 1753541115.746832, "src\\components\\inputs\\InputText.vue": 1753268228.9853475, "src\\components\\labels\\Label.vue": 1753268228.985849, "src\\plugins\\socketioManager.js": 1757405954.0491984, "src\\stores\\noSys.js": 1753269955.2171745, "src\\views\\HomeView.vue": 1754219683.1804607}

29
vueNoSys/README.md Normal file
View File

@@ -0,0 +1,29 @@
# vue-zecho
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
## Customize configuration
See [Vite Configuration Reference](https://vite.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Compile and Minify for Production
```sh
npm run build
```

7
vueNoSys/config.json Normal file
View File

@@ -0,0 +1,7 @@
{
"server": {
"enabled": true,
"host": "localhost",
"port": "3001"
}
}

14
vueNoSys/index.html Normal file
View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;800&display=swap" rel="stylesheet">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

10
vueNoSys/info.json Normal file
View File

@@ -0,0 +1,10 @@
{
"id": "vueNoSys",
"version": 0.042,
"modules": [
{
"id": "vueNoSys",
"version": 0
}
]
}

8
vueNoSys/jsconfig.json Normal file
View File

@@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}

4808
vueNoSys/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

28
vueNoSys/package.json Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "vue-zecho",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@headlessui/vue": "^1.7.23",
"@heroicons/vue": "^2.2.0",
"axios": "^1.7.9",
"pinia": "^3.0.1",
"socket.io-client": "^4.8.1",
"vue": "^3.5.13",
"vue-router": "^4.5.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.2.1",
"autoprefixer": "^10.4.20",
"postcss": "^8.5.2",
"tailwindcss": "^3.4.17",
"vite": "^6.0.11",
"vite-plugin-vue-devtools": "^7.7.1"
}
}

View File

@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

BIN
vueNoSys/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

19
vueNoSys/src/App.vue Normal file
View File

@@ -0,0 +1,19 @@
<script setup>
import { RouterView, useRoute } from 'vue-router';
import NavBar from './components/NavBar.vue';
const route = useRoute()
</script>
<template>
<div class="fixed top-0 left-0 w-full z-50 bg-white shadow">
<NavBar />
</div>
<div class=" pt-14">
<RouterView v-slot="{Component}">
<KeepAlive>
<component :is="Component"/>
</KeepAlive>
</RouterView>
</div>
</template>

View File

@@ -0,0 +1,16 @@
export const vueNoSysApi = {
async getConfigs(){
let configs = {}
try {
const response = await fetch('/api/vueNoSys/configs')
if (!response.ok) throw new Error("Error fetching configs:")
configs = await response.json()
return configs;
} catch (error) {
console.error("Error fetching configs:", error);
throw error;
}
},
}

View File

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -0,0 +1,39 @@
<script setup>
import { RouterLink } from 'vue-router';
import { vueNoSysApi } from '@/api/vueNoSysApi';
import { ref } from 'vue';
const configs = ref([])
async function getConfigs(){
configs.value = await vueNoSysApi.getConfigs();
}
getConfigs()
</script>
<template>
<nav class="w-full h-14 bg-black shadow-md px-6 py-3 flex items-center gap-8 border border-t-0 border-l-0 border-r-0 border-b-yellow-600 text-white">
<div>
<RouterLink
:to="{ name: 'vueNoSys' }"
class=" hover:text-yellow-400 font-medium transition duration-200 rounded-md"
active-class="text-yellow-400 border-b-2 border-yellow-400 pb-2"
>
Home
</RouterLink>
</div>
<div v-for="config in configs" :key="config.info.id">
<RouterLink
:to="{ name: config.info.id }"
class=" hover:text-yellow-400 font-medium transition duration-200 rounded-md"
active-class="text-yellow-400 border-b-2 border-yellow-400 pb-2"
>
{{ config.info.id }}
</RouterLink>
</div>
</nav>
</template>

View File

@@ -0,0 +1,29 @@
<template>
<button
:type="type"
:disabled="disabled"
:class="[
'inline-flex items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2',
disabled
? 'bg-gray-300 text-gray-500 cursor-not-allowed'
: 'bg-yellow-400 text-black hover:bg-yellow-300 focus:ring-yellow-500',
className
]"
@click="$emit('click', $event)"
>
<slot></slot>
</button>
</template>
<script setup>
defineProps({
type: {
type: String,
default: 'button'
},
disabled: Boolean,
className: String
})
defineEmits(['click'])
</script>

View File

@@ -0,0 +1,37 @@
<template>
<button
:aria-pressed="modelValue"
role="switch"
:aria-checked="modelValue"
@click="toggle"
:class="[
'relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:ring-offset-2',
modelValue ? 'bg-yellow-400' : 'bg-gray-300 dark:bg-gray-600',
disabled ? 'opacity-50 cursor-not-allowed' : ''
]"
:disabled="disabled"
>
<span
aria-hidden="true"
:class="[
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
modelValue ? 'translate-x-5' : 'translate-x-0'
]"
></span>
</button>
</template>
<script setup>
const props = defineProps({
modelValue: Boolean,
disabled: Boolean
})
const emit = defineEmits(['update:modelValue'])
const toggle = () => {
if (!props.disabled) {
emit('update:modelValue', !props.modelValue)
}
}
</script>

View File

@@ -0,0 +1,12 @@
<script setup>
defineOptions({ inheritAttrs: false })
</script>
<template>
<div
class="rounded-xl border border-yellow-400/20"
:class="$attrs.class"
>
<slot></slot>
</div>
</template>

View File

@@ -0,0 +1,9 @@
<template>
<div class="p-4 pt-0" :class="$attrs.class">
<slot></slot>
</div>
</template>
<script setup>
defineOptions({ inheritAttrs: false })
</script>

View File

@@ -0,0 +1,12 @@
<template>
<p
class="text-sm text-muted-foreground text-gray-500 dark:text-gray-400"
:class="$attrs.class"
>
<slot></slot>
</p>
</template>
<script setup>
defineOptions({ inheritAttrs: false })
</script>

View File

@@ -0,0 +1,9 @@
<template>
<div class="flex items-center p-4 pt-0" :class="$attrs.class">
<slot></slot>
</div>
</template>
<script setup>
defineOptions({ inheritAttrs: false })
</script>

View File

@@ -0,0 +1,9 @@
<script setup>
defineOptions({ inheritAttrs: false })
</script>
<template>
<div class="flex flex-col space-y-1.5 p-4 mb-3" :class="$attrs.class">
<slot></slot>
</div>
</template>

View File

@@ -0,0 +1,12 @@
<template>
<h3
class="font-semibold text-2xl leading-none tracking-tight"
:class="$attrs.class"
>
<slot></slot>
</h3>
</template>
<script setup>
defineOptions({ inheritAttrs: false })
</script>

View File

@@ -0,0 +1,101 @@
<template>
<div class="relative w-full">
<Combobox v-model="internalValue">
<div class="relative mt-1">
<div
class="relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left shadow-md focus:outline-none sm:text-sm"
>
<ComboboxInput
class="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:ring-0"
:displayValue="(item) => item?.[labelKey] || ''"
@change="query = $event.target.value"
/>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
</ComboboxButton>
</div>
<TransitionRoot
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
@after-leave="query = ''"
>
<ComboboxOptions
class="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black/5 focus:outline-none sm:text-sm"
>
<div
v-if="filteredItems.length === 0 && query !== ''"
class="relative cursor-default select-none px-4 py-2 text-gray-700"
>
Nothing found.
</div>
<ComboboxOption
v-for="item in filteredItems"
:key="item[keyField]"
:value="item"
v-slot="{ selected, active }"
>
<li
class="relative cursor-default select-none py-2 pl-10 pr-4"
:class="{
'bg-teal-600 text-white': active,
'text-gray-900': !active,
}"
>
<span
class="block truncate"
:class="{ 'font-medium': selected, 'font-normal': !selected }"
>
{{ item[labelKey] }}
</span>
<span
v-if="selected"
class="absolute inset-y-0 left-0 flex items-center pl-3"
:class="{ 'text-white': active, 'text-teal-600': !active }"
>
<CheckIcon class="h-5 w-5" aria-hidden="true" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</TransitionRoot>
</div>
</Combobox>
</div>
</template>
<script setup>
import { ref, computed, watch } from 'vue'
import {
Combobox,
ComboboxInput,
ComboboxButton,
ComboboxOptions,
ComboboxOption,
TransitionRoot,
} from '@headlessui/vue'
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid'
const props = defineProps({
items: Array,
labelKey: { type: String, default: 'name' },
keyField: { type: String, default: 'id' },
modelValue: { type: Object, default: null },
})
const emit = defineEmits(['update:modelValue'])
const internalValue = ref(props.modelValue)
watch(internalValue, (val) => emit('update:modelValue', val))
watch(() => props.modelValue, (val) => (internalValue.value = val))
const query = ref('')
const filteredItems = computed(() =>
query.value === ''
? props.items
: props.items.filter((item) =>
String(item[props.labelKey]).toLowerCase().includes(query.value.toLowerCase())
)
)
</script>

View File

@@ -0,0 +1,50 @@
<template>
<div class="relative w-full">
<input
v-bind="$attrs"
:id="id"
:type="showPassword ? 'text' : type"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
:placeholder="placeholder"
:disabled="disabled"
:class="[
'w-full pr-10 rounded-md border border-gray-300 px-3 py-2 text-sm text-black shadow-sm focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500 disabled:cursor-not-allowed disabled:opacity-50',
error ? 'border-red-500 focus:ring-red-500 focus:border-red-500' : ''
]"
/>
<button
v-if="type === 'password'"
type="button"
@click="showPassword = !showPassword"
class="absolute inset-y-0 right-0 flex items-center px-2 text-gray-500"
tabindex="-1"
>
<EyeIcon v-if="showPassword" class="h-4 w-4"></EyeIcon>
<EyeSlashIcon v-else class="h-4 w-4"></EyeSlashIcon>
</button>
</div>
</template>
<script setup>
import { EyeIcon, EyeSlashIcon } from '@heroicons/vue/24/solid'
import { ref } from 'vue'
defineProps({
modelValue: String,
id: String,
type: {
type: String,
default: 'text'
},
placeholder: String,
disabled: Boolean,
error: Boolean
})
defineEmits(['update:modelValue'])
defineOptions({ inheritAttrs: false })
const showPassword = ref(false)
</script>

View File

@@ -0,0 +1,12 @@
<template>
<label :for="forId" :class="['block text-sm font-medium text-gray-700 dark:text-gray-300', className]">
<slot></slot>
</label>
</template>
<script setup>
defineProps({
forId: String,
className: String
})
</script>

25
vueNoSys/src/main.js Normal file
View File

@@ -0,0 +1,25 @@
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia';
import App from './App.vue'
import getRouter from './router';
import { initModulesSocket } from './plugins/socketioManager'
import { vueNoSysApi } from "./api/vueNoSysApi";
async function bootstrap() {
const app = createApp(App);
const pinia = createPinia();
app.use(pinia);
const configs = await vueNoSysApi.getConfigs();
const router = await getRouter(configs);
app.use(router);
await initModulesSocket(configs)
app.mount('#app');
}
bootstrap()

View File

@@ -0,0 +1,41 @@
import { io } from 'socket.io-client'
const sockets = {}
export async function initModulesSocket(configs){
for (const [packageId, config] of Object.entries(configs)) {
initModuleSocket(packageId, config);
}
}
export async function initModuleSocket(packageId, config) {
for (const moduleConfig of Object.values(config.info.modules)) {
var socketId = packageId+"_"+moduleConfig.id
if (sockets[socketId]) return sockets[socketId]
const VITE_BACKEND_API_URL = import.meta.env.VITE_BACKEND_API_URL || window.location.origin;
const socket = io(`${VITE_BACKEND_API_URL}/ws/${socketId}`)
sockets[socketId] = socket
try {
const moduleEvents = await import(`@/modules/${packageId}/api/socketEvents.js`)
moduleEvents.default(socket)
} catch (err) {
console.warn(`Module "${socketId}" does not have socketEvents.js`)
}
}
}
export function getSocket(socketId, wait = 5000) {
return new Promise((resolve, reject) => {
const start = Date.now();
function check() {
if (sockets[socketId]) return resolve(sockets[socketId]);
if (Date.now() - start >= wait) return reject(new Error(`Socket ${socketId} not found`));
setTimeout(check, 50);
}
check();
});
}

29
vueNoSys/src/router.js Normal file
View File

@@ -0,0 +1,29 @@
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "./views/HomeView.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{path: '/', name:'vueNoSys', component: HomeView},
],
})
async function getRouter(configs){
for (const [packageId, config] of Object.entries(configs)) {
try {
await import(`./modules/${packageId}/router.js`)
.then(config => {
config.routes.forEach(route =>{
route.path = '/'+packageId+route.path;
router.addRoute(route);
})
});
} catch (error) {
console.log(error)
}
}
console.log(router.getRoutes())
return router;
}
export default getRouter;

View File

@@ -0,0 +1,48 @@
import { defineStore } from 'pinia'
export const useNoSysStore = defineStore('noSys', {
state: () => {
return {
configs: null,
}
},
actions: {
},
})
// Example Store
// export const useCounterStore = defineStore('counter', {
// state: () => {
// console.log("PINIA")
// return { count: 0 }
// },
// // could also be defined as
// // state: () => ({ count: 0 })
// actions: {
// increment() {
// this.count++
// },
// },
// })
// Example how use the store
// <script setup>
// import { useCounterStore } from '@/stores/counter'
// const counter = useCounterStore()
// counter.count++
// // with autocompletion ✨
// counter.$patch({ count: counter.count + 1 })
// // or using an action instead
// counter.increment()
// </script>
// <template>
// <!-- Access the state directly from the store -->
// <div>Current Count: {{ counter.count }}</div>
// </template>

View File

@@ -0,0 +1,271 @@
<script setup>
import Button from '@/components/buttons/Button.vue';
import Card from '@/components/cards/Card.vue';
</script>
<template>
<div class="bg-black font-sans">
<!-- HERO -->
<section id="hero" class="min-h-screen flex items-center justify-center">
<div class="container mx-auto px-6">
<div class="text-center max-w-4xl mx-auto space-y-8">
<div class="space-y-4">
<div class="flex items-center justify-center space-x-4">
<div class="w-12 h-1 bg-yellow-400"></div>
<span class="text-sm uppercase tracking-wider text-gray-400">Decentralized Network</span>
<div class="w-12 h-1 bg-yellow-400"></div>
</div>
<h1 class="text-7xl font-black leading-none">
<span class="text-yellow-400">NO</span>
<span class="text-white">SYS</span>
</h1>
</div>
<p class="text-lg text-gray-300 leading-relaxed max-w-2xl mx-auto">
Free speech unleashed. No masters, no censorship, only freedom.
</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<Button
size="lg"
class="bg-yellow-400 text-black hover:bg-yellow-300 font-bold px-8 py-4 text-lg group"
>
Enter the Network
<!-- <ChevronRight class="ml-2 group-hover:translate-x-1 transition-transform" size={20} /> -->
</Button>
<Button
size="lg"
variant="outline"
class="border-2 border-yellow-400 text-yellow-400 hover:bg-yellow-400 hover:text-black font-bold px-8 py-4 text-lg bg-transparent"
>
View Manifesto
</Button>
</div>
</div>
</div>
</section>
<!-- MANIFESTO -->
<section id="manifesto" class="py-20 bg-gray-950/50">
<div class="container mx-auto px-6">
<div class="text-center mb-16">
<h2 class="text-5xl font-black mb-4 text-yellow-400">THE MANIFESTO</h2>
<div class="w-24 h-1 bg-yellow-400 mx-auto"></div>
</div>
<div class="grid md:grid-cols-2 gap-8 max-w-6xl mx-auto">
<Card
key={index}
class="bg-black border-2 border-yellow-400/20 hover:border-yellow-400 p-8 transition-all duration-500 hover:scale-105 group relative overflow-hidden"
>
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-yellow-400 to-transparent"></div>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<div class="w-12 h-12 bg-yellow-400/10 rounded-lg flex items-center justify-center group-hover:bg-yellow-400/20 transition-colors">
<!-- <Icon size={24} class="text-yellow-400" /> -->
</div>
</div>
<div class="space-y-3">
<h3 class="text-xl font-bold text-yellow-400">The Illusion</h3>
<p class="text-gray-300 leading-relaxed">They call it civilization, but it censors dissent. They call it safety, but it silences the soul.</p>
</div>
</div>
</Card>
<Card
key={index}
class="bg-black border-2 border-yellow-400/20 hover:border-yellow-400 p-8 transition-all duration-500 hover:scale-105 group relative overflow-hidden"
>
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-yellow-400 to-transparent"></div>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<div class="w-12 h-12 bg-yellow-400/10 rounded-lg flex items-center justify-center group-hover:bg-yellow-400/20 transition-colors">
<!-- <Icon size={24} class="text-yellow-400" /> -->
</div>
</div>
<div class="space-y-3">
<h3 class="text-xl font-bold text-yellow-400">The Reality</h3>
<p class="text-gray-300 leading-relaxed">In a world where every word is watched, freedom becomes an illusion. NoSys is not a platform it is a refusal.</p>
</div>
</div>
</Card>
<Card
key={index}
class="bg-black border-2 border-yellow-400/20 hover:border-yellow-400 p-8 transition-all duration-500 hover:scale-105 group relative overflow-hidden"
>
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-yellow-400 to-transparent"></div>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<div class="w-12 h-12 bg-yellow-400/10 rounded-lg flex items-center justify-center group-hover:bg-yellow-400/20 transition-colors">
<!-- <Icon size={24} class="text-yellow-400" /> -->
</div>
</div>
<div class="space-y-3">
<h3 class="text-xl font-bold text-yellow-400">The Belief</h3>
<p class="text-gray-300 leading-relaxed">A refusal to be monitored, filtered, owned. It is built on the belief that speech is not granted by governments, and expression is not something to be licensed or permitted. It belongs to you innately, absolutely, dangerously.</p>
</div>
</div>
</Card>
<Card
key={index}
class="bg-black border-2 border-yellow-400/20 hover:border-yellow-400 p-8 transition-all duration-500 hover:scale-105 group relative overflow-hidden"
>
<div class="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-yellow-400 to-transparent"></div>
<div class="flex items-start space-x-4">
<div class="flex-shrink-0">
<div class="w-12 h-12 bg-yellow-400/10 rounded-lg flex items-center justify-center group-hover:bg-yellow-400/20 transition-colors">
<!-- <Icon size={24} class="text-yellow-400" /> -->
</div>
</div>
<div class="space-y-3">
<h3 class="text-xl font-bold text-yellow-400">The Purpose</h3>
<p class="text-gray-300 leading-relaxed">NoSys is not here to make you comfortable. It is here to make you heard. When voices are flattened by algorithms and laws, when dissent is treated as violence, when obedience is coded into the platforms we use resistance must take root in the code itself.</p>
</div>
</div>
</Card>
</div>
</div>
</section>
<!-- NETWORK -->
<section id="network" class="py-20">
<div class="container mx-auto px-6">
<div class="text-center mb-16">
<h2 class="text-5xl font-black mb-4 text-yellow-400">NETWORK WITHOUT MASTERS</h2>
<div class="w-24 h-1 bg-yellow-400 mx-auto"></div>
</div>
<div class="grid lg:grid-cols-3 gap-8">
<div class="group">
<div class="bg-gradient-to-br from-yellow-400/10 to-transparent p-8 rounded-2xl border border-yellow-400/20 hover:border-yellow-400/40 transition-all duration-300 h-full">
<div class="w-16 h-16 bg-yellow-400 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
<!-- <Globe size={32} class="text-black" /> -->
</div>
<h3 class="text-2xl font-bold text-white mb-4">No Central Servers</h3>
<p class="text-gray-400 leading-relaxed">
Decentralized by design. No single point of failure, no corporate control.
</p>
</div>
</div>
<div class="group">
<div class="bg-gradient-to-br from-yellow-400/10 to-transparent p-8 rounded-2xl border border-yellow-400/20 hover:border-yellow-400/40 transition-all duration-300 h-full">
<div class="w-16 h-16 bg-yellow-400 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
<!-- <Lock size={32} class="text-black" /> -->
</div>
<h3 class="text-2xl font-bold text-white mb-4">No Permission Required</h3>
<p class="text-gray-400 leading-relaxed">
Your voice, your rules. No moderation, no censorship, no gatekeepers.
</p>
</div>
</div>
<div class="group">
<div class="bg-gradient-to-br from-yellow-400/10 to-transparent p-8 rounded-2xl border border-yellow-400/20 hover:border-yellow-400/40 transition-all duration-300 h-full">
<div class="w-16 h-16 bg-yellow-400 rounded-xl flex items-center justify-center mb-6 group-hover:scale-110 transition-transform">
<!-- <Code size={32} class="text-black" /> -->
</div>
<h3 class="text-2xl font-bold text-white mb-4">Open Source</h3>
<p class="text-gray-400 leading-relaxed">
Built by the people, for the people. Transparent, auditable, unstoppable.
</p>
</div>
</div>
</div>
</div>
</section>
<!-- Philosophy -->
<section id="philosophy" class="py-20 bg-gradient-to-r from-yellow-400/5 to-transparent">
<div class="container mx-auto px-6">
<div class="max-w-4xl mx-auto text-center space-y-12">
<blockquote class="text-3xl font-light text-gray-300 leading-relaxed">
"NoSys does not serve the state.
<br />
<span class="text-yellow-400 font-bold">
It serves the individual — flawed, chaotic, and gloriously free.
</span>
"
</blockquote>
<div class="space-y-8">
<p class="text-2xl text-gray-300 leading-relaxed">
Free speech is not negotiable. It is the fire that keeps the darkness from swallowing the world.
</p>
<div class="bg-black/50 border-l-8 border-yellow-400 p-8 text-left max-w-3xl mx-auto">
<div class="space-y-4 text-lg text-gray-300">
<p>Let them silence the platforms we will build new ones.</p>
<p>Let them write new laws we will write new code.</p>
<p class="text-yellow-400 font-bold text-xl">NoSys is that rebellion.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Call to Action -->
<section id="join" class="py-20 bg-black">
<div class="container mx-auto px-6">
<div class="text-center max-w-4xl mx-auto space-y-8">
<h2 class="text-5xl font-black text-yellow-400 leading-tight">JOIN THE RESISTANCE</h2>
<p class="text-xl text-gray-300 leading-relaxed max-w-2xl mx-auto">
The future of free speech is in your hands. Be part of the network that cannot be silenced.
</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<Button
size="lg"
class="bg-yellow-400 text-black hover:bg-yellow-300 font-bold px-12 py-4 text-lg group"
>
Download NoSys
<!-- <ChevronRight class="ml-2 group-hover:translate-x-1 transition-transform" size={24} /> -->
</Button>
<Button
size="lg"
variant="outline"
class="border-2 border-yellow-400 text-yellow-400 hover:bg-yellow-400 hover:text-black font-bold px-12 py-4 text-lg bg-transparent"
>
View Source Code
</Button>
</div>
</div>
</div>
</section>
<footer class="py-12 border-t border-yellow-400/20">
<div class="container mx-auto px-6">
<div class="flex flex-col md:flex-row justify-between items-center space-y-4 md:space-y-0">
<div class="flex items-center space-x-4">
<div class="text-3xl font-black">
<span class="text-yellow-400">NO</span>
<span class="text-white">SYS</span>
</div>
<div class="w-1 h-8 bg-yellow-400"></div>
<span class="text-gray-400">Decentralized. Uncensorable. Unstoppable.</span>
</div>
<div class="text-sm text-gray-500">Built for those who refuse to be silenced.</div>
</div>
</div>
</footer>
</div>
</template>
<style scoped>
body {
background-color: #000;
}
</style>

View File

@@ -0,0 +1,13 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'sans-serif'],
},
},
},
plugins: [],
}

44
vueNoSys/vite.config.js Normal file
View File

@@ -0,0 +1,44 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import fs from 'fs';
// https://vite.dev/config/
export default ({ mode }) => {
process.env = {...process.env, ...loadEnv(mode, process.cwd())};
return defineConfig({
plugins: [
vue(),
vueDevTools(),
],
server: {
port: parseInt(process.env.VITE_PORT),
// allowedHosts: ["lucasinacio.duckdns.org"],
https: {
key: fs.readFileSync('../api/certs/key.pem'),
cert: fs.readFileSync('../api/certs/cert.pem'),
},
proxy: {
'/api': {
target: process.env.VITE_BACKEND_API_URL,
changeOrigin: true,
secure: false,
},
},
},
esbuild: {
supported: {
'top-level-await': true
},
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
}

137
vueNoSys/vueNoSys.py Normal file
View File

@@ -0,0 +1,137 @@
import os
import json
import pathlib
import shutil
import subprocess
from tempfile import mkstemp
from shutil import move, copymode
from os import fdopen, remove
from threading import Thread
from libs.noSys.noSysModule import NoSysModule
from libs.vueNoSys.vueNoSysApiBlueprint import Blueprint
from libs.app.common.logging import get_logger
from libs.app.common.paths import ROOT_DIR
from libs.app.common.network_utils import check_url
logger = get_logger()
class VueNoSys(NoSysModule):
def __init__(self, nosys_core):
super().__init__(nosys_core)
self.server_port = self.config.get("server", {"port":"3001"}).get("port", "3001")
self.npm_cmd = "npm.cmd" if os.name == "nt" else "npm"
self.npm_cwd = os.path.join(pathlib.Path(__file__).parent.resolve())
def setup(self):
self.nosys_core.modules.api.register_blueprint(Blueprint(self).blueprint)
self.move_modules_vue_files()
self.install_modules_dependencies()
self.config_env()
self.check_npm_version()
if self.config.get("server", {"enabled":False}).get("enabled", False):
self.run_npm_dev()
self.run_npm_build()
def on_nosys_ready(self, event):
pass
def check_npm_version(self):
try:
out = subprocess.check_output([self.npm_cmd, "--version"], shell=True, cwd=self.npm_cwd)
except subprocess.CalledProcessError:
# TODO Open npm download page
logger.exception("Command NPM version failed. Please install Node.js to fix this error. https://nodejs.org/en/download")
return None
logger.debug(f"NPM Version {out.decode()}")
def run_npm_dev(self):
try:
dev_server_url = f"https://localhost:{self.server_port}"
if check_url(dev_server_url, timeout=3, retries=2):
logger.debug(f"Not starting dev server - HTTP already running in {dev_server_url}")
return
subprocess.check_call([self.npm_cmd, "install"], shell=True, cwd=self.npm_cwd)
flag = subprocess.CREATE_NEW_CONSOLE # subprocess.CREATE_NO_WINDOW
npm_process = subprocess.Popen([self.npm_cmd, "run", "dev"], cwd=self.npm_cwd, creationflags=flag)
logger.debug(f"NPM dev server started, PID={npm_process.pid}")
except:
logger.exception(f"Failed to start npm dev server")
def run_npm_build(self):
try:
subprocess.check_call([self.npm_cmd, "install"], cwd=self.npm_cwd)
subprocess.check_call([self.npm_cmd, "run", "build"], cwd=self.npm_cwd)
logger.info("Vue build completed successfully")
except:
logger.exception(f"Failed to build Vue frontend")
return None
return os.path.join(self.npm_cwd, "dist")
def install_modules_dependencies(self, lib_id=None):
modules_path = os.path.join(pathlib.Path(__file__).parent.resolve(), 'src', 'modules')
modules = [lib_id] if lib_id else os.listdir(modules_path)
for module in modules:
module_path = os.path.join(modules_path, module)
dep_file = os.path.join(module_path, "dependencies.txt")
if os.path.exists(dep_file):
with open(dep_file, "r") as f:
dependencies = [
line.strip() for line in f.readlines() if line.strip()
]
if dependencies:
logger.debug(f"Installing dependencies for {module}: {dependencies}")
try:
subprocess.run(
["npm.cmd", "install"] + dependencies,
cwd=self.npm_cwd,
check=True
)
except:
logger.exception(f"Error installing dependencies for module {module}")
else:
logger.debug(f"Module {module} has no dependencies.txt")
def move_modules_vue_files(self):
for lib in self.nosys_core.config.get("app", "libs"):
lib_id = lib.get("id")
frontend = self.nosys_core.config.get(lib_id, "info", "frontend")
if frontend == 'vue':
from_path = os.path.join(ROOT_DIR, 'libs', lib_id, 'vue')
to_path = os.path.join(pathlib.Path(__file__).parent.resolve(), 'src', 'modules', lib_id)
if(os.path.exists(from_path)):
if(os.path.exists(to_path)):
shutil.rmtree(to_path)
pathlib.Path(to_path).mkdir(parents=True, exist_ok=True)
try:
for file_name in os.listdir(from_path):
shutil.move(os.path.join(from_path, file_name), os.path.join(to_path, file_name))
shutil.rmtree(from_path)
except Exception as e:
logger.error(f'Error while moving files from {os.path.join(from_path, file_name)} to {os.path.join(to_path, file_name)}: {e}')
def config_env(self):
api_config = self.nosys_core.config.get("api")
env_file = os.path.join(pathlib.Path(__file__).parent.resolve(), '.env')
fh, abs_path = mkstemp()
with fdopen(fh,'w') as new_file:
with open(env_file) as old_file:
for line in old_file:
if "VITE_PORT=" in line:
line = f"VITE_PORT={self.server_port}\n"
elif "VITE_BACKEND_API_HOST=" in line:
vite_backend_api_host = api_config["server"]["host"]
line = f"VITE_BACKEND_API_HOST=https://{vite_backend_api_host}\n"
elif "VITE_BACKEND_API_PORT=" in line:
vite_backend_api_port = api_config["server"]["port"]
line = f"VITE_BACKEND_API_PORT={vite_backend_api_port}\n"
new_file.write(line)
copymode(env_file, abs_path)
remove(env_file)
move(abs_path, env_file)

View File

@@ -0,0 +1,29 @@
from libs.api.apiBlueprint import ApiBlueprint
from flask import jsonify, request
import logging
import random
class Blueprint(ApiBlueprint):
def routes(self):
from .vueNoSys import VueNoSys
self.module:VueNoSys = self.module
@self.blueprint.route('/')
def show():
return self.module.name
@self.blueprint.route('/configs', methods=["GET", "POST"])
def configs():
if request.method == "GET":
configs = {}
for lib in self.module.nosys_core.config.get("app", "libs"):
lib_id = lib.get("id")
frontend = self.module.nosys_core.config.get(lib_id, "info", "frontend")
if frontend == 'vue':
configs[lib_id] = self.module.nosys_core.config.get(lib_id)
return jsonify(configs)