Compare commits
No commits in common. 'rebrush-2020' and 'master' have entirely different histories.
rebrush-20
...
master
@ -1,17 +0,0 @@ |
|||
# Drupal editor configuration normalization |
|||
# @see http://editorconfig.org/ |
|||
|
|||
# This is the top-most .editorconfig file; do not search in parent directories. |
|||
root = true |
|||
|
|||
# All files. |
|||
[*] |
|||
end_of_line = LF |
|||
indent_style = space |
|||
indent_size = 2 |
|||
charset = utf-8 |
|||
trim_trailing_whitespace = true |
|||
insert_final_newline = true |
|||
|
|||
[composer.{json,lock}] |
|||
indent_size = 4 |
@ -0,0 +1,16 @@ |
|||
module.exports = { |
|||
root: true, |
|||
parser: 'babel-eslint', |
|||
env: { |
|||
browser: true, |
|||
node: true |
|||
}, |
|||
extends: 'standard', |
|||
// required to lint *.vue files
|
|||
plugins: [ |
|||
'html' |
|||
], |
|||
// add your custom rules here
|
|||
rules: {}, |
|||
globals: {} |
|||
} |
@ -1,61 +0,0 @@ |
|||
# Drupal git normalization |
|||
# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html |
|||
# @see https://www.drupal.org/node/1542048 |
|||
|
|||
# Normally these settings would be done with macro attributes for improved |
|||
# readability and easier maintenance. However macros can only be defined at the |
|||
# repository root directory. Drupal avoids making any assumptions about where it |
|||
# is installed. |
|||
|
|||
# Define text file attributes. |
|||
# - Treat them as text. |
|||
# - Ensure no CRLF line-endings, neither on checkout nor on checkin. |
|||
# - Detect whitespace errors. |
|||
# - Exposed by default in `git diff --color` on the CLI. |
|||
# - Validate with `git diff --check`. |
|||
# - Deny applying with `git apply --whitespace=error-all`. |
|||
# - Fix automatically with `git apply --whitespace=fix`. |
|||
|
|||
*.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html |
|||
*.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php |
|||
*.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
*.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 |
|||
|
|||
# Define binary file attributes. |
|||
# - Do not treat them as text. |
|||
# - Include binary diff in patches instead of "binary files differ." |
|||
*.eot -text diff |
|||
*.exe -text diff |
|||
*.gif -text diff |
|||
*.gz -text diff |
|||
*.ico -text diff |
|||
*.jpeg -text diff |
|||
*.jpg -text diff |
|||
*.otf -text diff |
|||
*.phar -text diff |
|||
*.png -text diff |
|||
*.svgz -text diff |
|||
*.ttf -text diff |
|||
*.woff -text diff |
|||
*.woff2 -text diff |
@ -1,2 +1,11 @@ |
|||
/vendor/ |
|||
.vscode/ |
|||
# dependencies |
|||
node_modules |
|||
|
|||
# logs |
|||
npm-debug.log |
|||
|
|||
# Nuxt build |
|||
.nuxt |
|||
|
|||
# Nuxt generate |
|||
dist |
@ -0,0 +1,23 @@ |
|||
{ |
|||
// Verwendet IntelliSense zum Ermitteln möglicher Attribute. |
|||
// Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. |
|||
// Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 |
|||
"version": "0.2.0", |
|||
"configurations": [ |
|||
{ |
|||
"name": "Debug Hare Dev", |
|||
"type": "node", |
|||
"request": "launch", |
|||
"protocol": "inspector", |
|||
"program": "${workspaceRoot}/node_modules/nuxt/bin/nuxt", |
|||
"stopOnEntry": false, |
|||
"args": ["dev"], |
|||
"cwd": "${workspaceRoot}", |
|||
"sourceMaps": true, |
|||
"env": { |
|||
"NODE_ENV": "development", |
|||
"DEBUG": "nuxt:*,app" |
|||
} |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,8 @@ |
|||
{ |
|||
"folders": [ |
|||
{ |
|||
"path": "./../" |
|||
}, |
|||
], |
|||
"settings": {} |
|||
} |
@ -0,0 +1,34 @@ |
|||
pipeline { |
|||
agent { |
|||
docker { |
|||
image 'node:latest' |
|||
args '-v $HOME/.npm:/root/.npm -v $HOME/.cache:/root/.cache' |
|||
} |
|||
} |
|||
stages { |
|||
stage('Build') { |
|||
environment { HOME="." } |
|||
steps { |
|||
sh 'npm ci' |
|||
sh 'npm run build' |
|||
} |
|||
} |
|||
stage('Archive') { |
|||
steps { |
|||
archiveArtifacts '.nuxt/**, static/**, assets/**, package.json, package-lock.json' |
|||
} |
|||
} |
|||
stage('Deploy') { |
|||
steps { |
|||
sshPublisher(publishers: [sshPublisherDesc(configName: 'phenom@phenomic.net', transfers: [sshTransfer(cleanRemote: true, excludes: '', execCommand: '''cd ./PHENOMIC.net |
|||
npm ci |
|||
pm2 restart phenomic''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'PHENOMIC.net', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '.nuxt/**, static/**, assets/**, package.json, package-lock.json')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)]) |
|||
} |
|||
} |
|||
} |
|||
post { |
|||
always { |
|||
cleanWs() |
|||
} |
|||
} |
|||
} |
@ -1,24 +1,23 @@ |
|||
# PHENOMIC.net |
|||
# [PHENOMIC.net](https://phenomic.net) |
|||
[](https://ci.phenomic.net/job/git.phenomic.net/job/PHENOMIC.net/job/master/) |
|||
|
|||
The Main website of PHENOM powered by Drupal. |
|||
The main website for PHENOM based on Nuxt.js, Vue.js and uses the Vuetify Material Component Framework. Visit the site here https://phenomic.net |
|||
|
|||
## Prerequisites |
|||
## Build Setup |
|||
|
|||
The following Software is required: |
|||
``` bash |
|||
# install dependencies |
|||
$ npm install # Or yarn install |
|||
|
|||
- Composer |
|||
- Node.js |
|||
- cross-env |
|||
- drush |
|||
- memcached |
|||
- V8js PHP Extension for the ByteBeat Generator |
|||
# serve with hot reload at localhost:3000 |
|||
$ npm run dev |
|||
|
|||
## Installation |
|||
# build for production and launch server |
|||
$ npm run build |
|||
$ npm start |
|||
|
|||
```bash |
|||
composer install |
|||
cd web/themes/phenomic_net |
|||
npm install |
|||
npm run production |
|||
# generate static project |
|||
$ npm run generate |
|||
``` |
|||
|
|||
For detailed explanation on how things work, check out the [Nuxt.js](https://github.com/nuxt/nuxt.js) and [Vuetify.js](https://vuetifyjs.com/) documentation. |
|||
|
@ -0,0 +1,5 @@ |
|||
// Import Vuetify styling |
|||
@require '~vuetify/src/stylus/app.styl' |
|||
|
|||
.page |
|||
@extend .fade-transition |
@ -1,94 +0,0 @@ |
|||
{ |
|||
"name": "drupal/recommended-project", |
|||
"description": "Project template for Drupal 8 projects with a relocated document root", |
|||
"type": "project", |
|||
"license": "GPL-2.0-or-later", |
|||
"homepage": "https://www.drupal.org/project/drupal", |
|||
"support": { |
|||
"docs": "https://www.drupal.org/docs/user_guide/en/index.html", |
|||
"chat": "https://www.drupal.org/node/314178" |
|||
}, |
|||
"repositories": [ |
|||
{ |
|||
"type": "composer", |
|||
"url": "https://packages.drupal.org/8" |
|||
} |
|||
], |
|||
"require": { |
|||
"composer/installers": "^1.2", |
|||
"drupal/adminimal_admin_toolbar": "^1.10", |
|||
"drupal/adminimal_theme": "^1.5", |
|||
"drupal/console": "~1.0", |
|||
"drupal/core-composer-scaffold": "^8.8", |
|||
"drupal/core-project-message": "^8.8", |
|||
"drupal/core-recommended": "^8.8", |
|||
"drupal/devel": "^2.1", |
|||
"drupal/entity_browser": "^2.3", |
|||
"drupal/eu_cookie_compliance": "^1.8", |
|||
"drupal/fontawesome_menu_icons": "^1.8", |
|||
"drupal/google_analytics": "^2.4", |
|||
"drupal/honeypot": "^1.30", |
|||
"drupal/jsonapi_extras": "^3.13", |
|||
"drupal/memcache": "^2.0", |
|||
"drupal/menu_link_attributes": "^1.0", |
|||
"drupal/metatag": "^1.11", |
|||
"drupal/module_filter": "^3.1", |
|||
"drupal/paragraphs": "^1.10", |
|||
"drupal/pathauto": "^1.6", |
|||
"drupal/radix": "^4.6", |
|||
"drupal/radix_layouts": "^4.1", |
|||
"drupal/simple_sitemap": "^3.5", |
|||
"drupal/switch_page_theme": "^1.0", |
|||
"drupal/token": "^1.6", |
|||
"drupal/twig_vardumper": "^1.2", |
|||
"drupal/yaml_editor": "1.x-dev", |
|||
"drush/drush": "^10.2", |
|||
"spatie/server-side-rendering": "^0.2.6" |
|||
}, |
|||
"require-dev": { |
|||
}, |
|||
"conflict": { |
|||
"drupal/drupal": "*" |
|||
}, |
|||
"minimum-stability": "dev", |
|||
"prefer-stable": true, |
|||
"config": { |
|||
"sort-packages": true |
|||
}, |
|||
"extra": { |
|||
"drupal-scaffold": { |
|||
"locations": { |
|||
"web-root": "web/" |
|||
} |
|||
}, |
|||
"installer-paths": { |
|||
"web/core": ["type:drupal-core"], |
|||
"web/libraries/{$name}": ["type:drupal-library"], |
|||
"web/modules/contrib/{$name}": ["type:drupal-module"], |
|||
"web/profiles/contrib/{$name}": ["type:drupal-profile"], |
|||
"web/themes/contrib/{$name}": ["type:drupal-theme"], |
|||
"drush/Commands/contrib/{$name}": ["type:drupal-drush"], |
|||
"web/modules/custom/{$name}": ["type:drupal-custom-module"], |
|||
"web/themes/custom/{$name}": ["type:drupal-custom-theme"] |
|||
}, |
|||
"drupal-core-project-message": { |
|||
"include-keys": ["homepage", "support"], |
|||
"post-create-project-cmd-message": [ |
|||
"<bg=blue;fg=white> </>", |
|||
"<bg=blue;fg=white> Congratulations, you’ve installed the Drupal codebase </>", |
|||
"<bg=blue;fg=white> from the drupal/recommended-project template! </>", |
|||
"<bg=blue;fg=white> </>", |
|||
"", |
|||
"<bg=yellow;fg=black>Next steps</>:", |
|||
|
|||
" * Install the site: https://www.drupal.org/docs/8/install", |
|||
" * Read the user guide: https://www.drupal.org/docs/user_guide/en/index.html", |
|||
" * Get support: https://www.drupal.org/support", |
|||
" * Get involved with the Drupal community:", |
|||
" https://www.drupal.org/getting-involved", |
|||
" * Remove the plugin that prints this message:", |
|||
" composer remove drupal/core-project-message" |
|||
] |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,254 @@ |
|||
<template> |
|||
<v-app dark> |
|||
<v-navigation-drawer |
|||
clipped |
|||
v-model="drawer" |
|||
fixed |
|||
app |
|||
> |
|||
<v-subheader inset>Main Area</v-subheader> |
|||
<v-list> |
|||
<v-list-tile |
|||
nuxt |
|||
router |
|||
:to="item.to" |
|||
:key="i" |
|||
v-for="(item, i) in navMainItems" |
|||
exact |
|||
> |
|||
<v-list-tile-action> |
|||
<v-icon v-html="item.icon" :color="item.color"></v-icon> |
|||
</v-list-tile-action> |
|||
<v-list-tile-content> |
|||
<v-list-tile-title v-text="item.title"></v-list-tile-title> |
|||
</v-list-tile-content> |
|||
</v-list-tile> |
|||
</v-list> |
|||
<v-divider></v-divider> |
|||
<v-subheader inset>Web-Apps</v-subheader> |
|||
<v-list> |
|||
<v-list-tile |
|||
nuxt |
|||
:to="item.to" |
|||
:key="i" |
|||
v-for="(item, i) in navWebAppsItems" |
|||
exact |
|||
> |
|||
<v-list-tile-action> |
|||
<v-icon v-html="item.icon" :color="item.color"></v-icon> |
|||
</v-list-tile-action> |
|||
<v-list-tile-content> |
|||
<v-list-tile-title v-text="item.title"></v-list-tile-title> |
|||
</v-list-tile-content> |
|||
</v-list-tile> |
|||
</v-list> |
|||
<v-divider></v-divider> |
|||
<v-subheader inset>Services</v-subheader> |
|||
<v-list> |
|||
<v-list-tile |
|||
:href="item.to" |
|||
:key="i" |
|||
target="_blank" |
|||
v-for="(item, i) in navServiceItems" |
|||
exact |
|||
> |
|||
<v-list-tile-action> |
|||
<v-icon v-html="item.icon" :color="item.color"></v-icon> |
|||
</v-list-tile-action> |
|||
<v-list-tile-content> |
|||
<v-list-tile-title v-text="item.title"></v-list-tile-title> |
|||
</v-list-tile-content> |
|||
</v-list-tile> |
|||
</v-list> |
|||
<v-divider></v-divider> |
|||
<v-subheader inset>Contact</v-subheader> |
|||
<v-list> |
|||
<v-list-tile |
|||
:href="item.to" |
|||
:key="i" |
|||
target="_blank" |
|||
v-for="(item, i) in navContactItems" |
|||
exact |
|||
> |
|||
<v-list-tile-action> |
|||
<v-icon v-html="item.icon" :color="item.color"></v-icon> |
|||
</v-list-tile-action> |
|||
<v-list-tile-content> |
|||
<v-list-tile-title v-text="item.title"></v-list-tile-title> |
|||
</v-list-tile-content> |
|||
</v-list-tile> |
|||
<v-list-tile |
|||
@click="dialog = true" |
|||
> |
|||
<v-list-tile-action> |
|||
<v-icon color="indigo">mdi-discord</v-icon> |
|||
</v-list-tile-action> |
|||
<v-list-tile-content> |
|||
<v-list-tile-title> Discord: {{ discordHandle }} </v-list-tile-title> |
|||
</v-list-tile-content> |
|||
</v-list-tile> |
|||
</v-list> |
|||
</v-navigation-drawer> |
|||
<v-toolbar |
|||
fixed |
|||
app |
|||
clipped-left |
|||
> |
|||
<v-toolbar-side-icon @click="drawer = !drawer"></v-toolbar-side-icon> |
|||
<v-spacer></v-spacer> |
|||
<div class="circle-cam"> |
|||
<video playsinline autoplay muted loop> |
|||
<source src="images/avatar.webm" type="video/webm"> |
|||
</video> |
|||
</div> |
|||
<v-toolbar-title> |
|||
{{ title }} |
|||
</v-toolbar-title> |
|||
<v-spacer></v-spacer> |
|||
<v-btn |
|||
icon |
|||
@click.stop="rightDrawer = !rightDrawer" |
|||
> |
|||
</v-btn> |
|||
</v-toolbar> |
|||
<v-content> |
|||
<v-container> |
|||
<nuxt /> |
|||
</v-container> |
|||
</v-content> |
|||
|
|||
<v-footer |
|||
fixed |
|||
height="auto" |
|||
app |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
row |
|||
wrap |
|||
> |
|||
<v-btn |
|||
:key="i" |
|||
flat |
|||
:color="item.color" |
|||
target="_blank" |
|||
:href="item.to" |
|||
v-for="(item, i) in footerItems" |
|||
> |
|||
<v-icon v-html="item.icon"></v-icon> |
|||
<span v-html="item.title"></span> |
|||
</v-btn> |
|||
|
|||
<v-btn |
|||
flat |
|||
color="indigo" |
|||
@click.native.stop="dialog = true" |
|||
> |
|||
<v-icon>mdi-discord</v-icon> |
|||
<span>{{ discordHandle }}</span> |
|||
</v-btn> |
|||
|
|||
<v-flex |
|||
py-2 |
|||
text-xs-center |
|||
xs12 |
|||
> |
|||
©{{ cDate }} - <strong>PHENOM</strong> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-footer> |
|||
|
|||
<v-dialog v-model="dialog" max-width="290"> |
|||
<v-card> |
|||
<v-card-title class="headline">Add PHENOM as contact on Discord</v-card-title> |
|||
<v-card-text> |
|||
<ul> |
|||
<li>You can add me as a contact on Discord. Press on my handle to copy it to your clipboard.</li> |
|||
<li>Discord Handle: <a v-clipboard:copy="discordHandle" v-clipboard:success="onCopy" v-clipboard:error="onCopyError"><code>{{ discordHandle }}</code></a></li> |
|||
</ul> |
|||
</v-card-text> |
|||
<v-card-actions> |
|||
<v-spacer></v-spacer> |
|||
<v-btn color="green darken-1" flat="flat" @click.native="dialog = false">OK</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-dialog> |
|||
|
|||
<v-snackbar |
|||
multi-line |
|||
bottom |
|||
v-model="copiedToast" |
|||
> |
|||
{{ copyMessage }} |
|||
<v-btn dark flat @click.native="copiedToast = false">Close</v-btn> |
|||
</v-snackbar> |
|||
</v-app> |
|||
</template> |
|||
|
|||
<script> |
|||
const gitInfo = { icon: 'mdi-git', url: 'https://git.phenomic.net/PHENOM', user: 'PHENOM', color: 'grey' } |
|||
const emailInfo = { icon: 'mdi-email', url: 'mailto:phenom@phenomic.net', mail: 'phenom@phenomic.net', color: 'green' } |
|||
const ciInfo = { icon: 'mdi-wrench', url: 'https://ci.phenomic.net/job/git.phenomic.net/', color: 'amber' } |
|||
|
|||
export default { |
|||
data: () => ({ |
|||
discordHandle: 'PHENOM#7029', |
|||
drawer: false, |
|||
navMainItems: [ |
|||
{ icon: 'home', title: 'Home', to: '/', color: 'cyan lighten-3' } |
|||
], |
|||
navServiceItems: [ |
|||
{ icon: gitInfo.icon, title: 'Git Server', to: gitInfo.url, color: gitInfo.color }, |
|||
{ icon: ciInfo.icon, title: 'Jenkins CI & Nightly builds', to: ciInfo.url, color: ciInfo.color } |
|||
], |
|||
navWebAppsItems: [ |
|||
{ icon: 'mdi-music', title: 'Bytebeat Generator', to: 'bytebeat', color: 'red' } |
|||
], |
|||
navContactItems: [ |
|||
{ icon: emailInfo.icon, title: 'Mail: ' + emailInfo.mail, to: emailInfo.url, color: emailInfo.color } |
|||
], |
|||
footerItems: [ |
|||
{ icon: gitInfo.icon, title: gitInfo.user, to: gitInfo.url, color: gitInfo.color }, |
|||
{ icon: ciInfo.icon, title: 'Nightly Builds', to: ciInfo.url, color: ciInfo.color }, |
|||
{ icon: emailInfo.icon, title: emailInfo.mail, to: emailInfo.url, color: emailInfo.color } |
|||
], |
|||
title: 'PHENOMIC.net', |
|||
dialog: false, |
|||
copiedToast: false, |
|||
copyMessage: '', |
|||
cDate: new Date().getFullYear().toString() |
|||
}), |
|||
methods: { |
|||
dialogAppear () { |
|||
this.dialog = true |
|||
}, |
|||
onCopy: function (e) { |
|||
this.copyMessage = 'Copied "' + e.text + '" to your clipboard' |
|||
this.copiedToast = true |
|||
this.dialog = false |
|||
}, |
|||
onCopyError: function (e) { |
|||
this.copyMessage = 'Error when copying "' + e.text + '" to your clipboard' |
|||
this.copiedToast = true |
|||
this.dialog = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
html { |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
.circle-cam { |
|||
border-radius: 20px; |
|||
-webkit-mask-image: -webkit-radial-gradient(circle, white 100%, black 100%); |
|||
} |
|||
|
|||
video { |
|||
height: 48px; |
|||
width: 48px; |
|||
} |
|||
</style> |
|||
|
@ -0,0 +1,96 @@ |
|||
const nodeExternals = require('webpack-node-externals') |
|||
const resolve = (dir) => require('path').join(__dirname, dir) |
|||
const webpack = require('webpack') |
|||
|
|||
module.exports = { |
|||
/* |
|||
** Headers of the page |
|||
*/ |
|||
head: { |
|||
title: 'PHENOMIC.net', |
|||
meta: [ |
|||
{ charset: 'utf-8' }, |
|||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }, |
|||
{ hid: 'description', name: 'description', content: 'PHENOM\'s project site' } |
|||
], |
|||
link: [ |
|||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, |
|||
{ rel: 'shortcut icon', type: 'image/x-icon', href: '/favicon.ico' }, |
|||
{ rel: 'apple-touch-icon', href: '/apple_icon_184x184.png', sizes: '184x184' }, |
|||
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' }, |
|||
{ rel: 'stylesheet', href: '//cdn.materialdesignicons.com/2.3.54/css/materialdesignicons.min.css' } |
|||
], |
|||
script: [ |
|||
] |
|||
}, |
|||
plugins: ['~/plugins/vuetify.js', { src: '~/plugins/localStorage.js', ssr: false }], |
|||
css: [ |
|||
'~/assets/style/app.styl' |
|||
], |
|||
modules: [ |
|||
// Simple usage
|
|||
'nuxt-trailingslash-module', |
|||
|
|||
// With options
|
|||
['nuxt-trailingslash-module', { |
|||
/* module options */ |
|||
methods: [ |
|||
'GET', |
|||
'HEAD' |
|||
] |
|||
}] |
|||
], |
|||
|
|||
/* |
|||
** Customize the progress bar color |
|||
*/ |
|||
loading: { color: '#3B8070' }, |
|||
/* |
|||
** Build configuration |
|||
*/ |
|||
build: { |
|||
babel: { |
|||
plugins: [ |
|||
['transform-imports', { |
|||
'vuetify': { |
|||
'transform': 'vuetify/es5/components/${member}', /* eslint no-template-curly-in-string:0 */ |
|||
'preventFullImport': true |
|||
} |
|||
}], |
|||
['transform-es2015-modules-commonjs', { |
|||
'strictMode': false |
|||
}] |
|||
] |
|||
}, |
|||
vendor: [ |
|||
'~/plugins/vuetify.js', |
|||
'~/plugins/vue-clipboard2.js' |
|||
], |
|||
extractCSS: true, |
|||
/* |
|||
** Run ESLint on save |
|||
*/ |
|||
extend (config, ctx) { |
|||
if (ctx.isDev && ctx.isClient) { |
|||
config.module.rules.push({ |
|||
enforce: 'pre', |
|||
test: /\.(js|vue)$/, |
|||
loader: 'eslint-loader', |
|||
exclude: /(node_modules)/ |
|||
}) |
|||
} |
|||
if (ctx.isServer) { |
|||
config.externals = [ |
|||
nodeExternals({ |
|||
whitelist: [/^vuetify/] |
|||
}) |
|||
] |
|||
} |
|||
}, |
|||
plugins: [ |
|||
new webpack.ProvidePlugin({ |
|||
'_': 'lodash' |
|||
}) |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,48 @@ |
|||
{ |
|||
"name": "phenomic_net", |
|||
"version": "1.0.0", |
|||
"description": "Nuxt.js + Vuetify.js project", |
|||
"author": "PHENOMICAL <thephenom1811@gmail.com>", |
|||
"private": true, |
|||
"config": { |
|||
"nuxt": { |
|||
"host": "127.0.0.1", |
|||
"port": "3333" |
|||
} |
|||
}, |
|||
"scripts": { |
|||
"dev-debug": "node --inspect node_modules/.bin/nuxt", |
|||
"dev": "nuxt", |
|||
"build": "nuxt build", |
|||
"start": "nuxt start", |
|||
"generate": "nuxt generate" |
|||
}, |
|||
"dependencies": { |
|||
"babel-plugin-transform-remove-strict-mode": "0.0.2", |
|||
"chart.js": "^2.7.2", |
|||
"chartjs-plugin-zoom": "^0.6.5", |
|||
"lodash": "^4.17.11", |
|||
"nuxt": "^1.4.1", |
|||
"nuxt-trailingslash-module": "^1.1.0", |
|||
"vue-chartjs": "^3.4.0", |
|||
"vue-clipboard2": "^0.1.1", |
|||
"vuetify": "^1.0.0", |
|||
"vuex-persistedstate": "^2.5.4" |
|||
}, |
|||
"devDependencies": { |
|||
"@babel/plugin-transform-strict-mode": "^7.0.0", |
|||
"babel-eslint": "^7.2.3", |
|||
"babel-plugin-transform-imports": "^1.4.1", |
|||
"babel-preset-es2015-without-strict": "0.0.4", |
|||
"eslint": "^4.3.0", |
|||
"eslint-config-standard": "^10.2.1", |
|||
"eslint-loader": "^1.9.0", |
|||
"eslint-plugin-html": "^3.1.1", |
|||
"eslint-plugin-import": "^2.7.0", |
|||
"eslint-plugin-node": "^5.1.1", |
|||
"eslint-plugin-promise": "^3.5.0", |
|||
"eslint-plugin-standard": "^3.0.1", |
|||
"stylus": "^0.54.5", |
|||
"stylus-loader": "^3.0.1" |
|||
} |
|||
} |
@ -0,0 +1,303 @@ |
|||
<template> |
|||
<v-layout column justify-center align-left> |
|||
<v-flex xs12 sm8 md6> |
|||
<h3 class="display-3">Bytebeat Generator</h3> |
|||
<span class="subheading">This small tool can create music from a single JavaScript Expression using the Web Audio API.</span> |
|||
<v-divider class="my-3"></v-divider> |
|||
<v-select |
|||
v-model="exampleSelected" |
|||
prepend-icon="mdi-file-music" |
|||
:items="bytebeatSaves" |
|||
return-object |
|||
item-text="name" |
|||
> |
|||
</v-select> |
|||
<v-btn @click="load()">Load</v-btn> |
|||
<v-btn @click="saveDialog = true" :disabled="!changed">Save As...</v-btn> |
|||
<v-btn color="red" :disabled="exampleSelected.isExample" @click="deleteSave()">Delete</v-btn> |
|||
<v-divider class="my-3"></v-divider> |
|||
<v-form> |
|||
<v-select |
|||
v-model="liveByteBeat.frequency" |
|||
prepend-icon="mdi-waves" |
|||
:items="frequencies" |
|||
label="Frequency (Hz)" |
|||
> |
|||
</v-select> |
|||
<v-text-field |
|||
v-model="liveByteBeat.duration" |
|||
label="Duration (seconds)" |
|||
placeholder="30" |
|||
prepend-icon="timer" |
|||
></v-text-field> |
|||
<v-text-field |
|||
v-model="liveByteBeat.ft" |
|||
label="JavaScript function (t)=" |
|||
value='w=t>>9,k=32,m=2048,a=1-t/m%1,d=(14*t*t^t)%m*a,y=[3,3,4.7,2][p=w/k&3]*t/4,h="IQNNNN!!]]!Q!IW]WQNN??!!W]WQNNN?".charCodeAt(w/2&15|p/3<<4)/33*t-t,s=y*.98%80+y%80+(w>>7&&a*((5*t%m*a&128)*(0x53232323>>w/4&1)+(d&127)*(0xa444c444>>w/4&1)*1.5+(d*w&1)+(h%k+h*1.99%k+h*.49%k+h*.97%k-64)*(4-a-a))),s*s>>14?127:s' |
|||
hint="The variable t determines how the function behaves" |
|||
></v-text-field> |
|||
<v-slider |
|||
v-model="volume" |
|||
v-on:input="setVolume" |
|||
:disabled="!isContextAvailable()" |
|||
label="Volume" |
|||
append-icon="volume_up" |
|||
prepend-icon="volume_down" |
|||
></v-slider> |
|||
<p color="red" v-if="changed">Changes were made. Press on Generate to recompile the expression.</p> |
|||
<v-layout row wrap align-center> |
|||
<v-btn color="green" @click="regenerate()"> |
|||
<v-icon>mdi-sync</v-icon> |
|||
<span>Generate</span> |
|||
</v-btn> |
|||
<v-btn-toggle v-model="playBtn" multiple> |
|||
<v-btn flat @click="playPause()" :disabled="!isGenerated()"> |
|||
<v-icon>mdi-play-pause</v-icon> |
|||
</v-btn> |
|||
</v-btn-toggle> |
|||
<v-btn-toggle v-model="muteBtn" multiple> |
|||
<v-btn flat @click="mute()" :disabled="!isContextAvailable()"> |
|||
<v-icon>mdi-volume-off</v-icon> |
|||
</v-btn> |
|||
</v-btn-toggle> |
|||
</v-layout> |
|||
</v-form> |
|||
<v-dialog |
|||
v-model="saveDialog" |
|||
max-width="290" |
|||
> |
|||
<v-card> |
|||
<v-card-title class="headline">Saving ByteBeat...</v-card-title> |
|||
<v-layout align-content-space-between> |
|||
<v-form> |
|||
<v-text-field |
|||
v-model="newName" |
|||
placeholder="Enter a Name" |
|||
label="Name" |
|||
></v-text-field> |
|||
</v-form> |
|||
</v-layout> |
|||
<v-card-actions> |
|||
<v-spacer></v-spacer> |
|||
<v-btn |
|||
flat="flat" |
|||
@click="saveDialog = false" |
|||
> |
|||
Cancel |
|||
</v-btn> |
|||
<v-btn |
|||
color="green darken-1" |
|||
flat="flat" |
|||
@click="onSave()" |
|||
> |
|||
Save |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-dialog> |
|||
</v-flex> |
|||
</v-layout> |
|||
</template> |
|||
<script> |
|||
import { mapGetters, mapState, mapMutations } from 'vuex' |
|||
|
|||
/* eslint no-eval: 0 */ |
|||
export default { |
|||
layout: 'phenomic', |
|||
data: () => ({ |
|||
exampleSelected: { |
|||
id: 0, |
|||
isExample: true, |
|||
name: 'Default', |
|||
frequency: '8000', |
|||
duration: '30', |
|||
ft: 't * ((t>>12|t>>8)&63&t>>4)' |
|||
}, |
|||
liveByteBeat: { |
|||
id: 0, |
|||
name: 'Default', |
|||
frequency: '8000', |
|||
duration: '30', |
|||
ft: 't * ((t>>12|t>>8)&63&t>>4)' |
|||
}, |
|||
playBtn: [], |
|||
muteBtn: [], |
|||
frequencies: ['8000', '11025', '16000', '22050', '32000', '37800', '44056', '44100', '47250', '48000', '50000', '50400', '88200', '96000', '176400', '192000'], |
|||
audioCtx: null, |
|||
source: null, |
|||
gainNode: null, |
|||
volume: 50, |
|||
sampleBuffer: null, |
|||
saveDialog: false, |
|||
changed: false, |
|||
isLoading: false, |
|||
newName: '' |
|||
}), |
|||
watch: { |
|||
liveByteBeat: { |
|||
handler: function (newVal, oldVal) { |
|||
if (!this.isLoading) { |
|||
this.changed = true |
|||
} else { |
|||
this.changed = false |
|||
this.isLoading = false |
|||
} |
|||
}, |
|||
deep: true |
|||
} |
|||
}, |
|||
errorCaptured (err, vm, info) { |
|||
console.log(err) |
|||
}, |
|||
computed: { |
|||
...mapState({ |
|||
bytebeatSaves: 'bytebeatSaves' |
|||
}), |
|||
...mapGetters({ |
|||
getNewId: 'getNewId' |
|||
}) |
|||
}, |
|||
methods: { |
|||
onChange (newVal) { |
|||
console.log('Change: ' + newVal) |
|||
this.changed = true |
|||
this.liveByteBeat.isExample = false |
|||
}, |
|||
isGenerated () { |
|||
if (!(this.source === undefined || this.source === null)) { |
|||
return !(this.source.buffer === undefined || this.source.buffer === null) |
|||
} |
|||
return false |
|||
}, |
|||
isContextAvailable () { |
|||
return !(this.audioCtx === undefined || this.audioCtx === null) |
|||
}, |
|||
isExample () { |
|||
return this.liveByteBeat.isExample |
|||
}, |
|||
isPlaying () { |
|||
if (this.audioCtx.state === 'running') { |
|||
return true |
|||
} else if (this.audioCtx.state === 'suspended') { |
|||
return false |
|||
} |
|||
}, |
|||
regenerate () { |
|||
// Reset change indicator |
|||
this.changed = false |
|||
|
|||
// Reset Playbutton |
|||
this.playBtn = [] |
|||
|
|||
if (process.browser) { |
|||
// Close Audio Context if already opened |
|||
if (this.isContextAvailable()) { |
|||
this.audioCtx.close() |
|||
} |
|||
|
|||
// Create new Audio Context |
|||
this.audioCtx = new (window.AudioContext || window.webkitAudioContext)() |
|||
this.audioCtx.suspend() // Stop instant playback |
|||
this.gainNode = this.audioCtx.createGain() |
|||
this.gainNode.connect(this.audioCtx.destination) |
|||
} else { |
|||
console.error("This is not a browser! Can't continue!") |
|||
return |
|||
} |
|||
|
|||
// Create a new Audio Source |
|||
this.source = this.audioCtx.createBufferSource() |
|||
|
|||
// Determines the behaviour when the Audio has finished playing |
|||
this.source.onended = (event) => { |
|||
this.audioCtx.suspend() |
|||
this.playBtn = [] |
|||
} |
|||
|
|||
// Here is the main clear on compare match linear function of the bytebeat algorithm |
|||
this.sampleBuffer = [] |
|||
let f |
|||
eval('f = function (t) { return ' + this.liveByteBeat.ft + '}') |
|||
for (let t = 0; t < this.liveByteBeat.frequency * this.liveByteBeat.duration; t++) { |
|||
let sample = f(t) |
|||
sample = (sample & 0xff) * 256 |
|||
if (sample < 0) sample = 0 |
|||
if (sample > 65535) sample = 65535 |
|||
this.sampleBuffer.push(sample / 65535) |
|||
} |
|||
|
|||
// Fill Audio Buffer with Data |
|||
let audioBuffer = this.audioCtx.createBuffer(2, this.liveByteBeat.frequency * this.liveByteBeat.duration, this.liveByteBeat.frequency) |
|||
for (let channel = 0; channel < audioBuffer.numberOfChannels; channel++) { |
|||
let channelBuffer = audioBuffer.getChannelData(channel) |
|||
for (let i = 0; i < audioBuffer.length; i++) { |
|||
channelBuffer[i] = this.sampleBuffer[i] |
|||
} |
|||
} |
|||
|
|||
// Apply Audio Buffer to source |
|||
this.source.buffer = audioBuffer |
|||
|
|||
// Apply Gain connection for Volume control |
|||
this.source.connect(this.gainNode) |
|||
|
|||
// Start the source |
|||
this.source.start(0) |
|||
}, |
|||
playPause () { |
|||
if (this.isGenerated()) { |
|||
if (this.isPlaying()) { |
|||
this.audioCtx.suspend() |
|||
this.playBtn = [] |
|||
} else { |
|||
this.audioCtx.resume() |
|||
} |
|||
} |
|||
}, |
|||
mute () { |
|||
if (this.muteBtn.length === 0) { |
|||
this.gainNode.gain.value = 0 |
|||
} else { |
|||
this.gainNode.gain.value = this.volume / 100.0 |
|||
} |
|||
}, |
|||
setVolume (something) { |
|||
this.muteBtn = [] |
|||
this.gainNode.gain.value = something / 100.0 |
|||
}, |
|||
onSave () { |
|||
this.saveDialog = false |
|||
this.liveByteBeat.name = this.newName |
|||
this.liveByteBeat.id = this.getNewId |
|||
this.saveBeat(this.liveByteBeat) |
|||
this.exampleSelected = this.liveByteBeat |
|||
this.isCurrentExample = false |
|||
}, |
|||
load () { |
|||
this.isLoading = true |
|||
this.liveByteBeat.id = this.exampleSelected.id |
|||
this.liveByteBeat.duration = this.exampleSelected.duration |
|||
this.liveByteBeat.frequency = this.exampleSelected.frequency |
|||
this.liveByteBeat.ft = this.exampleSelected.ft |
|||
this.liveByteBeat.name = this.exampleSelected.name |
|||
this.isCurrentExample = this.exampleSelected.isExample |
|||
}, |
|||
deleteSave () { |
|||
if (!this.isCurrentExample) { |
|||
this.deleteBeat(this.exampleSelected.id) |
|||
} |
|||
}, |
|||
...mapMutations({ |
|||
saveBeat: 'saveByteBeat', |
|||
deleteBeat: 'deleteByteBeatById' |
|||
}) |
|||
}, |
|||
beforeRouteLeave (to, from, next) { |
|||
// Close Audio Context if already opened |
|||
if (this.isContextAvailable()) { |
|||
this.audioCtx.close() |
|||
} |
|||
next() |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,160 @@ |
|||
<template> |
|||
<v-layout row wrap> |
|||
<v-container> |
|||
<v-card color="blue-grey darken-3"> |
|||
<v-card-title class="display-1 text-md-center">Welcome on PHENOMIC.net</v-card-title> |
|||
<v-card-text> |
|||
<p class="subheading">Welcome to my small project website and feel free to check out the projects listed below. <br> |
|||
Press on the button in the top-left to open the Side Navigation Menu.</p> |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-container> |
|||
<v-container |
|||
fluid grid-list-md |
|||
:key="i-50" |
|||
v-for="(imageProject, i) in imageProjects" |
|||
> |
|||
<v-layout |
|||
row |
|||
wrap |
|||
> |
|||
<v-flex d-flex xs12 sm6 md4> |
|||
<v-card :color="imageProject.color" dark> |
|||
<v-card-title |
|||
primary |
|||
class="title" |
|||
>{{ imageProject.name }}</v-card-title> |
|||
<v-card-text>{{ imageProject.description }}</v-card-text> |
|||
<v-btn |
|||
:href="imageProject.url" |
|||
> |
|||
Go to Project |
|||
</v-btn> |
|||
</v-card> |
|||
</v-flex> |
|||
<v-layout column> |
|||
<v-flex d-flex xs12 sm6 md4> |
|||
<v-card> |
|||
<v-carousel> |
|||
<v-carousel-item |
|||
v-for="(imageUrl, i) in getCompleteImageUrls(imageProject)" |
|||
:key="i" |
|||
:src="imageUrl" |
|||
></v-carousel-item> |
|||
</v-carousel> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-layout> |
|||
</v-container> |
|||
<v-container |
|||
fluid grid-list-md |
|||
:key="i" |
|||
v-for="(textProject, i) in textProjects" |
|||
> |
|||
<v-layout |
|||
column |
|||
wrap |
|||
> |
|||
<v-card :color="textProject.color" dark> |
|||
<v-card-title |
|||
primary |
|||
class="title" |
|||
> |
|||
{{ textProject.name }} |
|||
</v-card-title> |
|||
<v-card-text>{{ textProject.description }}</v-card-text> |
|||
<v-btn :href="textProject.url">Go to Project</v-btn> |
|||
</v-card> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-layout> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
layout: 'phenomic', |
|||
data: () => ({ |
|||
imageBaseUrl: 'images/projects', |
|||
imageProjects: [ |
|||
{ |
|||
name: 'Propeller Parallax P8X32A DemoBoard', |
|||
color: 'red darken-3', |
|||
description: 'A Project I’ve worked on during University which demonstrates the multi-cog approach of the Parallax Propeller Multicore Microcontroller in combination with my selfbuilt DemoBoard. It emulates the C64\'s MOS Technology 6581/8580 SID (Sound Interface Device) chip and is able to emulate the data read from an micro sd card. It also displays a terminal over the VGA port which can be controlled via a PS/2 Mouse and Keyboard which allows you to chose the song you want to play. Written in a combination of SPIN and some assembler.', |
|||
url: 'https://git.phenomic.net/PHENOM/Parallax-Propeller-DemoBoard', |
|||
imageBaseUrl: 'demoboard', |
|||
imageUrls: ['1.jpg', '2.jpg'] |
|||
}, |
|||
{ |
|||
name: 'SmartHome Control', |
|||
color: 'indigo darken-3', |
|||
description: 'A small smart-home control unit. It uses the ESP8266 WiFi Module to connect to the internet and Data can be exchanged via the internet to control your home. It is also able to read out the current ambient room temperature and display it over the integrated HTTP Server.', |
|||
url: 'https://git.phenomic.net/PHENOM/SmartHome-Control', |
|||
imageBaseUrl: 'smarthome', |
|||
imageUrls: ['1.jpg', '2.jpg', '3.png', '4.png', '5.png', '6.png'] |
|||
}, |
|||
{ |
|||
name: 'Game Boy Cartridge Reader', |
|||
color: 'green darken-3', |
|||
description: 'A Game Boy Cartridge reader with an Atmel Atmega 32 Microcontroller, that is able to read out the ROM, RAM and Realtime Clock over an virtual serial RS232 Interface.', |
|||
url: 'https://git.phenomic.net/PHENOM/Gameboy-Color-Cart-Reader', |
|||
imageBaseUrl: 'gameboyreader', |
|||
imageUrls: ['1.jpg'] |
|||
}, |
|||
{ |
|||
name: 'Game Boy Emulator', |
|||
color: 'lime darken-3', |
|||
description: 'A Game Boy Emulator written in the Go programming language. It\'s still a work in progress and is being actively worked on.', |
|||
url: 'https://git.phenomic.net/PHENOM/GameBoyEmulator', |
|||
imageBaseUrl: 'gameboyemulator', |
|||
imageUrls: ['1.png'] |
|||
}, |
|||
{ |
|||
name: 'Texas Instruments CC2531 AT-Command Firmware', |
|||
color: 'purple darken-3', |
|||
description: 'A project I worked on at University for the mobile systems course. The goal was to implement an AT-styled Commandset that communicates over an virtual serial USB interface on the CC2531 using the Open Source IoT Operating System Contiki. Written in pure C.', |
|||
url: 'https://git.phenomic.net/PHENOM/Texas-Instruments-CC2531-AT-Command-Firmware', |
|||
imageBaseUrl: 'ti', |
|||
imageUrls: ['1.jpg', '2.jpg'] |
|||
}, |
|||
{ |
|||
name: 'Omegle Discord Bot', |
|||
color: 'teal darken-3', |
|||
description: 'A Discord Bot that is able to connect to Omegle and interact as a bridge between Discord and Omegle. This bot was written in C#. Sadly this project is now defunct, since Omegle uses now reCAPTCHA v2/3, which makes it impossible for me to handle the received captchas in Discord itself. This project required a MySQL Database, due to it\'s permission and multi-guild system.', |
|||
url: 'https://git.phenomic.net/PHENOM/Omegle-Discord-Bot', |
|||
imageBaseUrl: 'omeglebot', |
|||
imageUrls: ['1.png'] |
|||
} |
|||
], |
|||
textProjects: [ |
|||
{ |
|||
name: 'PHENOMIC.net', |
|||
color: 'blue-grey darken-3', |
|||
description: 'My personal website made with Nuxt.js, Vue.js and the Vuetify Material Design Component framework', |
|||
url: 'https://git.phenomic.net/PHENOM/PHENOMIC.net' |
|||
}, |
|||
{ |
|||
name: 'Bytebeat Synthesizer', |
|||
color: 'cyan darken-3', |
|||
description: 'A Bytebeat Synthesizer, that is able to make music or simple beats from a single one-line Javascript Expression using the Web Audio API. It is not completely finished yet, but basic functionality is established.', |
|||
url: 'https://git.phenomic.net/PHENOM/PHENOMIC.net/src/branch/master/pages/bytebeat.vue' |
|||
}, |
|||
{ |
|||
name: 'OpenGL Engine', |
|||
color: 'brown darken-3', |
|||
description: 'A very simple graphics engine using OpenGL. I\'ve worked on this project for computer graphics courses. It isn\'t fully functional, but can render primitive shapes, has a basic lighting and camera system.', |
|||
url: 'https://git.phenomic.net/PHENOM/OpenGL-Engine' |
|||
} |
|||
] |
|||
}), |
|||
methods: { |
|||
getCompleteImageUrls (project) { |
|||
return project.imageUrls.map(image => { |
|||
return this.imageBaseUrl + '/' + project.imageBaseUrl + '/' + image |
|||
}) |
|||
} |
|||
}, |
|||
mounted () { |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,9 @@ |
|||
import createPersistedState from 'vuex-persistedstate' |
|||
|
|||
export default ({store}) => { |
|||
window.onNuxtReady(() => { |
|||
createPersistedState({ |
|||
key: 'phenomic' |
|||
})(store) |
|||
}) |
|||
} |
@ -0,0 +1,4 @@ |
|||
import Vue from 'vue' |
|||
import VueClipboard from 'vue-clipboard2' |
|||
|
|||
Vue.use(VueClipboard) |
@ -0,0 +1,55 @@ |
|||
import Vue from 'vue' |
|||
import { |
|||
Vuetify, |
|||
VApp, |
|||
VCard, |
|||
VNavigationDrawer, |
|||
VFooter, |
|||
VList, |
|||
VBtn, |
|||
VIcon, |
|||
VGrid, |
|||
VToolbar, |
|||
VAvatar, |
|||
VDialog, |
|||
VSnackbar, |
|||
VSubheader, |
|||
VResponsive, |
|||
VDivider, |
|||
VSelect, |
|||
VTooltip, |
|||
VTextField, |
|||
VBtnToggle, |
|||
VSlider, |
|||
VForm, |
|||
VCarousel, |
|||
VParallax |
|||
} from 'vuetify' |
|||
|
|||
Vue.use(Vuetify, { |
|||
components: { |
|||
VApp, |
|||
VCard, |
|||
VNavigationDrawer, |
|||
VFooter, |
|||
VList, |
|||
VBtn, |
|||
VIcon, |
|||
VGrid, |
|||
VToolbar, |
|||
VAvatar, |
|||
VDialog, |
|||
VSnackbar, |
|||
VResponsive, |
|||
VSubheader, |
|||
VDivider, |
|||
VSelect, |
|||
VTooltip, |
|||
VTextField, |
|||
VBtnToggle, |
|||
VSlider, |
|||
VForm, |
|||
VCarousel, |
|||
VParallax |
|||
} |
|||
}) |
After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 57 KiB |
@ -0,0 +1,63 @@ |
|||
import _ from 'lodash' |
|||
|
|||
export const state = () => ({ |
|||
bytebeatSaves: [ |
|||
{ |
|||
id: 0, |
|||
isExample: true, |
|||
name: 'Default', |
|||
frequency: '8000', |
|||
duration: '30', |
|||
ft: 't * ((t>>12|t>>8)&63&t>>4)' |
|||
}, |
|||
{ |
|||
id: 1, |
|||
isExample: true, |
|||
name: 'Chaos Theory', |
|||
frequency: '8000', |
|||
duration: '30', |
|||
ft: 'w=t>>9,k=32,m=2048,a=1-t/m%1,d=(14*t*t^t)%m*a,y=[3,3,4.7,2][p=w/k&3]*t/4,h="IQNNNN!!]]!Q!IW]WQNN??!!W]WQNNN?".charCodeAt(w/2&15|p/3<<4)/33*t-t,s=y*.98%80+y%80+(w>>7&&a*((5*t%m*a&128)*(0x53232323>>w/4&1)+(d&127)*(0xa444c444>>w/4&1)*1.5+(d*w&1)+(h%k+h*1.99%k+h*.49%k+h*.97%k-64)*(4-a-a))),s*s>>14?127:s' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
isExample: true, |
|||
name: 'Dante\'s Inferno', |
|||
frequency: '8000', |
|||
duration: '30', |
|||
ft: '((t*(t>>12)&(201*t/100)&(199*t/100))&(t*(t>>14)&(t*301/100)&(t*399/100)))+((t*(t>>16)&(t*202/100)&(t*198/100))-(t*(t>>17)&(t*302/100)&(t*298/100)))' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
isExample: true, |
|||
name: 'Rick Roll\'d', |
|||
frequency: '8000', |
|||
duration: '30', |
|||
ft: '(t<<3)*[8/9,1,9/8,6/5,4/3,3/2,0][[0xd2d2c8,0xce4088,0xca32c8,0x8e4009][t>>14&3]>>(0x3dbe4688>>((t>>10&15)>9?18:t>>10&15)*3&7)*3&7]' |
|||
} |
|||
] |
|||
}) |
|||
export const mutations = { |
|||
saveByteBeat (state, payload) { |
|||
let clone = _.clone(payload, true) |
|||
state.bytebeatSaves.push(clone) |
|||
}, |
|||
deleteByteBeatById (state, payload) { |
|||
state.bytebeatSaves = _.remove(state.bytebeatSaves, (element) => { |
|||
return element.id !== payload |
|||
}) |
|||
} |
|||
} |
|||
export const getters = { |
|||
getNewId (state) { |
|||
let previousId = 0 |
|||
let highestId = 0 |
|||
state.bytebeatSaves.forEach(save => { |
|||
if (save.id > previousId) { |
|||
highestId = save.id |
|||
} |
|||
previousId = save.id |
|||
}) |
|||
highestId++ |
|||
return highestId |
|||
} |
|||
} |
@ -1,40 +0,0 @@ |
|||
--errors=box-model, |
|||
display-property-grouping, |
|||
duplicate-background-images, |
|||
duplicate-properties, |
|||
empty-rules, |
|||
ids, |
|||
import, |
|||
important, |
|||
known-properties, |
|||
outline-none, |
|||
overqualified-elements, |
|||
qualified-headings, |
|||
shorthand, |
|||
star-property-hack, |
|||
text-indent, |
|||
underscore-property-hack, |
|||
unique-headings, |
|||
unqualified-attributes, |
|||
vendor-prefix, |
|||
zero-units |
|||
--ignore=adjoining-classes, |
|||
box-sizing, |
|||
bulletproof-font-face, |
|||
compatible-vendor-prefixes, |
|||
errors, |
|||
fallback-colors, |
|||
floats, |
|||
font-faces, |
|||
font-sizes, |
|||
gradients, |
|||
import-ie-limit, |
|||
order-alphabetical, |
|||
regex-selectors, |
|||
rules-count, |
|||
selector-max, |
|||
selector-max-approaching, |
|||
selector-newline, |
|||
universal-selector |
|||
--exclude-list=core/assets, |
|||
vendor |
@ -1,8 +0,0 @@ |
|||
core/**/* |
|||
vendor/**/* |
|||
sites/**/files/**/* |
|||
libraries/**/* |
|||
sites/**/libraries/**/* |
|||
profiles/**/libraries/**/* |
|||
**/js_test_files/**/* |
|||
**/node_modules/**/* |