style: run linter
This commit is contained in:
parent
de3862bf77
commit
4853e1ec63
26 changed files with 502 additions and 631 deletions
|
@ -1,15 +1,15 @@
|
|||
/* eslint-env node */
|
||||
require("@rushstack/eslint-patch/modern-module-resolution");
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"@vue/eslint-config-typescript",
|
||||
"@vue/eslint-config-prettier",
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
},
|
||||
};
|
||||
ecmaVersion: 'latest'
|
||||
}
|
||||
}
|
||||
|
|
65
src/App.vue
65
src/App.vue
|
@ -1,41 +1,41 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, provide } from "vue";
|
||||
import { RouterView } from "vue-router";
|
||||
import { modalResultKey, nsfwKey, showModalKey } from "@/keys";
|
||||
import { version } from "../package.json";
|
||||
import RefModal from "@/components/RefModal.vue";
|
||||
import ButtonGroup from "@/components/ButtonGroup.vue";
|
||||
import Button from "@/components/RefButton.vue";
|
||||
import SiteHeader from "@/components/SiteHeader.vue";
|
||||
import SiteFooter from "@/components/SiteFooter.vue";
|
||||
import SiteNavigation from "@/components/SiteNavigation.vue";
|
||||
import { ref, provide } from 'vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import { modalResultKey, nsfwKey, showModalKey } from '@/keys'
|
||||
import { version } from '../package.json'
|
||||
import RefModal from '@/components/RefModal.vue'
|
||||
import ButtonGroup from '@/components/ButtonGroup.vue'
|
||||
import Button from '@/components/RefButton.vue'
|
||||
import SiteHeader from '@/components/SiteHeader.vue'
|
||||
import SiteFooter from '@/components/SiteFooter.vue'
|
||||
import SiteNavigation from '@/components/SiteNavigation.vue'
|
||||
|
||||
const isNsfw = ref(false);
|
||||
const isConfirmedHorny = ref(false);
|
||||
const isNsfw = ref(false)
|
||||
const isConfirmedHorny = ref(false)
|
||||
|
||||
const nsfwmodal = ref<InstanceType<typeof RefModal>>();
|
||||
const nsfwmodal = ref<InstanceType<typeof RefModal>>()
|
||||
|
||||
const showModal = (): void => {
|
||||
if (!isConfirmedHorny.value) {
|
||||
nsfwmodal.value?.showModal();
|
||||
nsfwmodal.value?.showModal()
|
||||
|
||||
setTimeout(() => {
|
||||
isNsfw.value = false;
|
||||
}, 1);
|
||||
isNsfw.value = false
|
||||
}, 1)
|
||||
} else {
|
||||
isNsfw.value = !isNsfw.value;
|
||||
isNsfw.value = !isNsfw.value
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const modalResult = (value: boolean): void => {
|
||||
isNsfw.value = value;
|
||||
isConfirmedHorny.value = value;
|
||||
nsfwmodal.value?.close();
|
||||
};
|
||||
isNsfw.value = value
|
||||
isConfirmedHorny.value = value
|
||||
nsfwmodal.value?.close()
|
||||
}
|
||||
|
||||
provide(modalResultKey, modalResult);
|
||||
provide(nsfwKey, isNsfw);
|
||||
provide(showModalKey, showModal);
|
||||
provide(modalResultKey, modalResult)
|
||||
provide(nsfwKey, isNsfw)
|
||||
provide(showModalKey, showModal)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -46,18 +46,13 @@ provide(showModalKey, showModal);
|
|||
</template>
|
||||
|
||||
<template #message>
|
||||
By enabling NSFW mode you confirm that you are of legal age to view adult
|
||||
content.
|
||||
By enabling NSFW mode you confirm that you are of legal age to view adult content.
|
||||
</template>
|
||||
|
||||
<template #buttons>
|
||||
<ButtonGroup col>
|
||||
<Button positive @click.prevent="modalResult(true)">
|
||||
Yes, show me the goods 👀
|
||||
</Button>
|
||||
<Button negative @click.prevent="modalResult(false)">
|
||||
NO, STAHP 😱
|
||||
</Button>
|
||||
<Button positive @click.prevent="modalResult(true)"> Yes, show me the goods 👀 </Button>
|
||||
<Button negative @click.prevent="modalResult(false)"> NO, STAHP 😱 </Button>
|
||||
</ButtonGroup>
|
||||
</template>
|
||||
</RefModal>
|
||||
|
@ -81,9 +76,7 @@ provide(showModalKey, showModal);
|
|||
/>
|
||||
<img
|
||||
class="nav-logo"
|
||||
srcset="
|
||||
@/assets/sebin-smug-icon.png?w=36;40;48;56;72;80;96;112;108;120;144;168&png&srcset
|
||||
"
|
||||
srcset="@/assets/sebin-smug-icon.png?w=36;40;48;56;72;80;96;112;108;120;144;168&png&srcset"
|
||||
sizes="(min-width: 120em) 56px, (min-width: 80em) 48px, (min-width: 35em) 40px, 36px"
|
||||
alt="Sebin Avatar"
|
||||
/>
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
width: 100%;
|
||||
max-width: var(--attack-list-max-width);
|
||||
margin: auto;
|
||||
padding: 0 var(--container-spacing-right-safe) 0
|
||||
var(--container-spacing-left-safe);
|
||||
padding: 0 var(--container-spacing-right-safe) 0 var(--container-spacing-left-safe);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
col?: boolean;
|
||||
grid?: boolean;
|
||||
col?: boolean
|
||||
grid?: boolean
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import type { ColorDict } from "@/interfaces";
|
||||
import type { ColorDict } from '@/interfaces'
|
||||
|
||||
interface Props {
|
||||
colors: ColorDict[];
|
||||
colors: ColorDict[]
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -21,10 +21,7 @@ defineProps<Props>();
|
|||
<tr class="color-table__row" v-for="(color, idx) in colors" :key="idx">
|
||||
<td class="color-table__cell name">{{ color.name }}</td>
|
||||
<td class="color-table__cell value">{{ color.value }}</td>
|
||||
<td
|
||||
class="color-table__cell color"
|
||||
:style="{ 'background-color': color.value }"
|
||||
></td>
|
||||
<td class="color-table__cell color" :style="{ 'background-color': color.value }"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
headings: string[];
|
||||
data: string[][];
|
||||
headings: string[]
|
||||
data: string[][]
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="data-table">
|
||||
<thead class="data-table__head">
|
||||
<tr class="data-table__row">
|
||||
<th
|
||||
class="data-table__heading"
|
||||
v-for="(heading, idx) in headings"
|
||||
:key="idx"
|
||||
>
|
||||
<th class="data-table__heading" v-for="(heading, idx) in headings" :key="idx">
|
||||
{{ heading }}
|
||||
</th>
|
||||
</tr>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
cols?: number;
|
||||
cols?: number
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -32,7 +32,7 @@ defineProps<Props>();
|
|||
&:before {
|
||||
display: block;
|
||||
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 1.375rem;
|
||||
right: 1.375rem;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
positive?: boolean;
|
||||
negative?: boolean;
|
||||
href?: string;
|
||||
download?: boolean | any;
|
||||
positive?: boolean
|
||||
negative?: boolean
|
||||
href?: string
|
||||
download?: boolean | any
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,32 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
import { inject } from "vue";
|
||||
import { nsfwKey, showModalKey } from "@/keys";
|
||||
import RefToggle from "@/components/RefToggle.vue";
|
||||
import { inject } from 'vue'
|
||||
import { nsfwKey, showModalKey } from '@/keys'
|
||||
import RefToggle from '@/components/RefToggle.vue'
|
||||
|
||||
interface Props {
|
||||
polaroidBorder?: boolean;
|
||||
dropshadow?: boolean;
|
||||
nsfw?: boolean;
|
||||
id: string;
|
||||
polaroidBorder?: boolean
|
||||
dropshadow?: boolean
|
||||
nsfw?: boolean
|
||||
id: string
|
||||
}
|
||||
|
||||
const isNsfw = inject<boolean>(nsfwKey, false);
|
||||
const showModal = inject<Function>(showModalKey, Function);
|
||||
const isNsfw = inject<boolean>(nsfwKey, false)
|
||||
const showModal = inject<Function>(showModalKey, Function)
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<figure class="figure">
|
||||
<div
|
||||
class="figure__border"
|
||||
:class="{ 'figure__border--polaroid': polaroidBorder }"
|
||||
>
|
||||
<div class="figure__border" :class="{ 'figure__border--polaroid': polaroidBorder }">
|
||||
<template v-if="!nsfw || isNsfw">
|
||||
<div
|
||||
class="figure__image"
|
||||
:class="{ 'figure__image--dropshadow': dropshadow }"
|
||||
>
|
||||
<div class="figure__image" :class="{ 'figure__image--dropshadow': dropshadow }">
|
||||
<slot name="img"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -79,8 +73,7 @@ defineProps<Props>();
|
|||
text-align: center;
|
||||
|
||||
margin: 1em auto;
|
||||
padding: 0 var(--container-spacing-right-safe) 0
|
||||
var(--container-spacing-left-safe);
|
||||
padding: 0 var(--container-spacing-right-safe) 0 var(--container-spacing-left-safe);
|
||||
|
||||
&__border {
|
||||
display: flex;
|
||||
|
@ -101,7 +94,7 @@ defineProps<Props>();
|
|||
}
|
||||
|
||||
&__border--polaroid &__meta {
|
||||
font-family: "Permanent Marker", fantasy;
|
||||
font-family: 'Permanent Marker', fantasy;
|
||||
color: var(--color-figure-polaroid-text);
|
||||
|
||||
max-width: 35rem;
|
||||
|
|
|
@ -1,78 +1,68 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { debounce } from "@/helpers";
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { debounce } from '@/helpers'
|
||||
|
||||
const activeImage = ref(0);
|
||||
const images = ref<Element[]>([]);
|
||||
const element = document.createElement("div");
|
||||
const galleryViewport = ref<HTMLElement>(element);
|
||||
const galleryItemWidth = ref<number>(1);
|
||||
const activeImage = ref(0)
|
||||
const images = ref<Element[]>([])
|
||||
const element = document.createElement('div')
|
||||
const galleryViewport = ref<HTMLElement>(element)
|
||||
const galleryItemWidth = ref<number>(1)
|
||||
|
||||
const resizeObserverCallback = (entries: ResizeObserverEntry[]): void => {
|
||||
for (const entry of entries) {
|
||||
galleryItemWidth.value = entry.contentRect.width;
|
||||
galleryItemWidth.value = entry.contentRect.width
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(
|
||||
debounce(resizeObserverCallback, 1000)
|
||||
);
|
||||
const resizeObserver = new ResizeObserver(debounce(resizeObserverCallback, 1000))
|
||||
|
||||
const setActiveImage = (index: number): void => {
|
||||
activeImage.value = index;
|
||||
activeImage.value = index
|
||||
galleryViewport.value.scrollTo({
|
||||
left: galleryItemWidth.value * index,
|
||||
behavior: "smooth",
|
||||
});
|
||||
};
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
|
||||
const getActiveImage = (gallery: HTMLElement, itemWidth: number): number => {
|
||||
return gallery.scrollLeft / itemWidth;
|
||||
};
|
||||
return gallery.scrollLeft / itemWidth
|
||||
}
|
||||
|
||||
const prev = (): void => {
|
||||
if (activeImage.value > 0) {
|
||||
galleryViewport.value.scrollBy({
|
||||
left: galleryItemWidth.value * -1,
|
||||
behavior: "smooth",
|
||||
});
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const next = (): void => {
|
||||
if (activeImage.value < images.value.length - 1) {
|
||||
galleryViewport.value.scrollBy({
|
||||
left: galleryItemWidth.value,
|
||||
behavior: "smooth",
|
||||
});
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const onScroll = (): void => {
|
||||
const newImg = Math.floor(
|
||||
getActiveImage(galleryViewport.value, galleryItemWidth.value)
|
||||
);
|
||||
setActiveImage(newImg);
|
||||
};
|
||||
const newImg = Math.floor(getActiveImage(galleryViewport.value, galleryItemWidth.value))
|
||||
setActiveImage(newImg)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
resizeObserver.observe(galleryViewport.value);
|
||||
images.value = Array.from(galleryViewport.value.children);
|
||||
galleryItemWidth.value =
|
||||
galleryViewport.value.scrollWidth / images.value.length;
|
||||
galleryViewport.value.addEventListener("scroll", debounce(onScroll, 500));
|
||||
});
|
||||
resizeObserver.observe(galleryViewport.value)
|
||||
images.value = Array.from(galleryViewport.value.children)
|
||||
galleryItemWidth.value = galleryViewport.value.scrollWidth / images.value.length
|
||||
galleryViewport.value.addEventListener('scroll', debounce(onScroll, 500))
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gallery">
|
||||
<div class="gallery__images">
|
||||
<a
|
||||
href="#"
|
||||
class="gallery__prev"
|
||||
@click.prevent="prev()"
|
||||
v-show="activeImage > 0"
|
||||
></a>
|
||||
<a href="#" class="gallery__prev" @click.prevent="prev()" v-show="activeImage > 0"></a>
|
||||
<a
|
||||
href="#"
|
||||
class="gallery__next"
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { ref } from 'vue'
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
id: string
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
defineProps<Props>()
|
||||
|
||||
const modal = ref<HTMLDialogElement>();
|
||||
const modal = ref<HTMLDialogElement>()
|
||||
|
||||
const showModal = () => {
|
||||
modal.value?.showModal();
|
||||
document.body.inert = true;
|
||||
document.body.classList.add("scroll-lock");
|
||||
};
|
||||
modal.value?.showModal()
|
||||
document.body.inert = true
|
||||
document.body.classList.add('scroll-lock')
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
modal.value?.close();
|
||||
document.body.inert = false;
|
||||
document.body.classList.remove("scroll-lock");
|
||||
};
|
||||
modal.value?.close()
|
||||
document.body.inert = false
|
||||
document.body.classList.remove('scroll-lock')
|
||||
}
|
||||
|
||||
defineExpose({ showModal, close });
|
||||
defineExpose({ showModal, close })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean;
|
||||
id: string;
|
||||
name?: string;
|
||||
modelValue: boolean
|
||||
id: string
|
||||
name?: string
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
|
||||
const checked = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
return props.modelValue
|
||||
},
|
||||
set(value) {
|
||||
emit("update:modelValue", value);
|
||||
},
|
||||
});
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -37,9 +37,8 @@ const checked = computed({
|
|||
|
||||
<style lang="scss">
|
||||
.toggle {
|
||||
font-family: "apple color emoji", "noto color emoji", "segoe ui emoji",
|
||||
"android emoji", "emojisymbols", "emojione mozilla", "twemoji mozilla",
|
||||
"segoe ui symbol";
|
||||
font-family: 'apple color emoji', 'noto color emoji', 'segoe ui emoji', 'android emoji',
|
||||
'emojisymbols', 'emojione mozilla', 'twemoji mozilla', 'segoe ui symbol';
|
||||
|
||||
padding: 0.5em;
|
||||
|
||||
|
@ -84,7 +83,7 @@ const checked = computed({
|
|||
|
||||
&:before,
|
||||
&:after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 1.1em;
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { RouterLink } from "vue-router";
|
||||
import router from "@/router";
|
||||
import { RouterLink } from 'vue-router'
|
||||
import router from '@/router'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="nav">
|
||||
<ul class="nav__list">
|
||||
<li
|
||||
class="nav__item"
|
||||
v-for="(route, idx) in router.options.routes"
|
||||
:key="idx"
|
||||
>
|
||||
<li class="nav__item" v-for="(route, idx) in router.options.routes" :key="idx">
|
||||
<RouterLink class="nav__link" :to="route.path">
|
||||
{{ route.name }}
|
||||
</RouterLink>
|
||||
|
@ -75,7 +71,7 @@ import router from "@/router";
|
|||
|
||||
&:before,
|
||||
&:after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
&__mainline,
|
||||
&__subline {
|
||||
font-family: "Exo", sans-serif;
|
||||
font-family: 'Exo', sans-serif;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
|
|
|
@ -1,76 +1,67 @@
|
|||
const debounce = (fn: Function, delay: number = 300): any => {
|
||||
let timer = 0;
|
||||
let timer = 0
|
||||
const debounced = (...args: any[]): void => {
|
||||
if (!args) args = [];
|
||||
clearTimeout(timer);
|
||||
if (!args) args = []
|
||||
clearTimeout(timer)
|
||||
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(fn, args);
|
||||
}, delay);
|
||||
};
|
||||
fn.apply(fn, args)
|
||||
}, delay)
|
||||
}
|
||||
|
||||
return debounced;
|
||||
};
|
||||
return debounced
|
||||
}
|
||||
|
||||
const getClientLocale = (): string => {
|
||||
return navigator.languages.length > 0 ? navigator.languages[0] : "en-US";
|
||||
};
|
||||
return navigator.languages.length > 0 ? navigator.languages[0] : 'en-US'
|
||||
}
|
||||
|
||||
const getAge = (dateOfBirth: Date): number => {
|
||||
const today = new Date();
|
||||
const today = new Date()
|
||||
|
||||
const thisYear = today.getFullYear();
|
||||
const thisMonth = today.getMonth();
|
||||
const thisDay = today.getDate();
|
||||
const thisYear = today.getFullYear()
|
||||
const thisMonth = today.getMonth()
|
||||
const thisDay = today.getDate()
|
||||
|
||||
const dobYear = dateOfBirth.getFullYear();
|
||||
const dobMonth = dateOfBirth.getMonth();
|
||||
const dobDay = dateOfBirth.getDate();
|
||||
const dobYear = dateOfBirth.getFullYear()
|
||||
const dobMonth = dateOfBirth.getMonth()
|
||||
const dobDay = dateOfBirth.getDate()
|
||||
|
||||
let age = thisYear - dobYear;
|
||||
let age = thisYear - dobYear
|
||||
|
||||
if (thisMonth < dobMonth) age--;
|
||||
if (thisMonth === dobMonth && thisDay < dobDay) age--;
|
||||
if (thisMonth < dobMonth) age--
|
||||
if (thisMonth === dobMonth && thisDay < dobDay) age--
|
||||
|
||||
return age;
|
||||
};
|
||||
return age
|
||||
}
|
||||
|
||||
const toImperial = (cm: number): string => {
|
||||
const realFeet = (cm * 0.3937) / 12;
|
||||
const feet = Math.floor(realFeet);
|
||||
const inches = Math.round((realFeet - feet) * 12);
|
||||
const realFeet = (cm * 0.3937) / 12
|
||||
const feet = Math.floor(realFeet)
|
||||
const inches = Math.round((realFeet - feet) * 12)
|
||||
|
||||
return `${feet}'${inches}"`;
|
||||
};
|
||||
return `${feet}'${inches}"`
|
||||
}
|
||||
|
||||
const toInch = (cm: number): string => {
|
||||
return `${Math.round(cm / 2.45)} in`;
|
||||
};
|
||||
return `${Math.round(cm / 2.45)} in`
|
||||
}
|
||||
|
||||
const toLbs = (kg: number): number => {
|
||||
const nearExact = kg / 0.45359237;
|
||||
const lbs = Math.floor(nearExact);
|
||||
const nearExact = kg / 0.45359237
|
||||
const lbs = Math.floor(nearExact)
|
||||
|
||||
return lbs;
|
||||
};
|
||||
return lbs
|
||||
}
|
||||
|
||||
const toFahrenheit = (celsius: number): number => {
|
||||
return celsius * 1.8 + 32;
|
||||
};
|
||||
return celsius * 1.8 + 32
|
||||
}
|
||||
|
||||
const dateFormat = new Intl.DateTimeFormat(getClientLocale(), {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "2-digit",
|
||||
});
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: '2-digit'
|
||||
})
|
||||
|
||||
export {
|
||||
debounce,
|
||||
getClientLocale,
|
||||
getAge,
|
||||
toImperial,
|
||||
toInch,
|
||||
toLbs,
|
||||
toFahrenheit,
|
||||
dateFormat,
|
||||
};
|
||||
export { debounce, getClientLocale, getAge, toImperial, toInch, toLbs, toFahrenheit, dateFormat }
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
interface ColorDict {
|
||||
name: string;
|
||||
value: string;
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
|
||||
interface Kink {
|
||||
name: string;
|
||||
receive: boolean;
|
||||
give: boolean;
|
||||
name: string
|
||||
receive: boolean
|
||||
give: boolean
|
||||
}
|
||||
|
||||
export type { ColorDict, Kink };
|
||||
export type { ColorDict, Kink }
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { InjectionKey, Ref } from "vue";
|
||||
import type { InjectionKey, Ref } from 'vue'
|
||||
|
||||
export const nsfwKey: InjectionKey<Ref<boolean>> = Symbol("nsfwKey");
|
||||
export const showModalKey: InjectionKey<Function> = Symbol("showModalKey");
|
||||
export const modalResultKey: InjectionKey<Function> = Symbol("modalResultKey");
|
||||
export const nsfwKey: InjectionKey<Ref<boolean>> = Symbol('nsfwKey')
|
||||
export const showModalKey: InjectionKey<Function> = Symbol('showModalKey')
|
||||
export const modalResultKey: InjectionKey<Function> = Symbol('modalResultKey')
|
||||
|
|
16
src/main.ts
16
src/main.ts
|
@ -1,12 +1,12 @@
|
|||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
import "normalize.css";
|
||||
import "@/scss/main.scss";
|
||||
import 'normalize.css'
|
||||
import '@/scss/main.scss'
|
||||
|
||||
const app = createApp(App);
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router);
|
||||
app.use(router)
|
||||
|
||||
app.mount("body");
|
||||
app.mount('body')
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
import { createRouter, createWebHistory } from "vue-router";
|
||||
import HomeView from "@/views/HomeView.vue";
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import HomeView from '@/views/HomeView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
scrollBehavior() {
|
||||
return { top: 0, behavior: "smooth" };
|
||||
return { top: 0, behavior: 'smooth' }
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
path: "/",
|
||||
name: "home",
|
||||
component: HomeView,
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: "/general",
|
||||
name: "general",
|
||||
component: () => import("@/views/GeneralView.vue"),
|
||||
path: '/general',
|
||||
name: 'general',
|
||||
component: () => import('@/views/GeneralView.vue')
|
||||
},
|
||||
{
|
||||
path: "/anatomy",
|
||||
name: "anatomy",
|
||||
component: () => import("@/views/AnatomyView.vue"),
|
||||
path: '/anatomy',
|
||||
name: 'anatomy',
|
||||
component: () => import('@/views/AnatomyView.vue')
|
||||
},
|
||||
{
|
||||
path: "/clothing",
|
||||
name: "clothing",
|
||||
component: () => import("@/views/ClothingView.vue"),
|
||||
path: '/clothing',
|
||||
name: 'clothing',
|
||||
component: () => import('@/views/ClothingView.vue')
|
||||
},
|
||||
{
|
||||
path: "/abilities",
|
||||
name: "abilities",
|
||||
component: () => import("@/views/AbilitiesView.vue"),
|
||||
path: '/abilities',
|
||||
name: 'abilities',
|
||||
component: () => import('@/views/AbilitiesView.vue')
|
||||
},
|
||||
{
|
||||
path: "/overdrive",
|
||||
name: "overdrive",
|
||||
component: () => import("@/views/OverdriveView.vue"),
|
||||
},
|
||||
],
|
||||
});
|
||||
path: '/overdrive',
|
||||
name: 'overdrive',
|
||||
component: () => import('@/views/OverdriveView.vue')
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
export default router;
|
||||
export default router
|
||||
|
|
80
src/sebin.ts
80
src/sebin.ts
|
@ -1,51 +1,51 @@
|
|||
export const firstName = "Sebin",
|
||||
middleName = "Antario",
|
||||
lastName = "Nyshkim",
|
||||
dateOfBirth = new Date("1993-10-17"),
|
||||
gender = "male ♂️",
|
||||
orientation = "gay",
|
||||
position = "vers, prefers top",
|
||||
export const firstName = 'Sebin',
|
||||
middleName = 'Antario',
|
||||
lastName = 'Nyshkim',
|
||||
dateOfBirth = new Date('1993-10-17'),
|
||||
gender = 'male ♂️',
|
||||
orientation = 'gay',
|
||||
position = 'vers, prefers top',
|
||||
height = 210, // cm
|
||||
weight = 124, // kg
|
||||
tailLength = 104, // cm
|
||||
wingspan = 417, // cm
|
||||
colors = {
|
||||
hairPrimary: "#4b608f",
|
||||
hairSecondary: "#6684c0",
|
||||
eyes: "#31c215",
|
||||
scalesPrimary: "#c64c35",
|
||||
scalesSecondary: "#eda958",
|
||||
eyebrows: "#eda958",
|
||||
tailspikes: "#7f4539",
|
||||
horns: "#413a3a",
|
||||
claws: "#413a3a",
|
||||
nipples: "#413a3a",
|
||||
penis: "#413a3a",
|
||||
hairPrimary: '#4b608f',
|
||||
hairSecondary: '#6684c0',
|
||||
eyes: '#31c215',
|
||||
scalesPrimary: '#c64c35',
|
||||
scalesSecondary: '#eda958',
|
||||
eyebrows: '#eda958',
|
||||
tailspikes: '#7f4539',
|
||||
horns: '#413a3a',
|
||||
claws: '#413a3a',
|
||||
nipples: '#413a3a',
|
||||
penis: '#413a3a'
|
||||
},
|
||||
hobbies = ["working out", "travels", "camping", "video games", "tech"],
|
||||
hobbies = ['working out', 'travels', 'camping', 'video games', 'tech'],
|
||||
penis = {
|
||||
shape: "humanoid",
|
||||
type: "grower",
|
||||
special: "ridged, no foreskin",
|
||||
shape: 'humanoid',
|
||||
type: 'grower',
|
||||
special: 'ridged, no foreskin',
|
||||
size: 20, // cm
|
||||
girth: 5, // cm
|
||||
girth: 5 // cm
|
||||
},
|
||||
kinks = [
|
||||
{ name: "Oral", receive: true, give: true },
|
||||
{ name: "Anal", receive: true, give: true },
|
||||
{ name: "Facial", receive: true, give: true },
|
||||
{ name: "Creampie", receive: true, give: true },
|
||||
{ name: "Bukkake", receive: true, give: true },
|
||||
{ name: "Biting", receive: true, give: true },
|
||||
{ name: "Nipple Play", receive: true, give: true },
|
||||
{ name: "Rough", receive: true, give: true },
|
||||
{ name: "Toys", receive: true, give: true },
|
||||
{ name: 'Oral', receive: true, give: true },
|
||||
{ name: 'Anal', receive: true, give: true },
|
||||
{ name: 'Facial', receive: true, give: true },
|
||||
{ name: 'Creampie', receive: true, give: true },
|
||||
{ name: 'Bukkake', receive: true, give: true },
|
||||
{ name: 'Biting', receive: true, give: true },
|
||||
{ name: 'Nipple Play', receive: true, give: true },
|
||||
{ name: 'Rough', receive: true, give: true },
|
||||
{ name: 'Toys', receive: true, give: true },
|
||||
|
||||
{ name: "Frotting", receive: true, give: true },
|
||||
{ name: "Muscle Worship", receive: true, give: true },
|
||||
{ name: "Filled Condoms", receive: true, give: true },
|
||||
{ name: "Growth/Macro", receive: true, give: true },
|
||||
{ name: "Size Difference", receive: true, give: true },
|
||||
{ name: "Underwear", receive: true, give: true },
|
||||
{ name: "Chubbies", receive: true, give: true },
|
||||
];
|
||||
{ name: 'Frotting', receive: true, give: true },
|
||||
{ name: 'Muscle Worship', receive: true, give: true },
|
||||
{ name: 'Filled Condoms', receive: true, give: true },
|
||||
{ name: 'Growth/Macro', receive: true, give: true },
|
||||
{ name: 'Size Difference', receive: true, give: true },
|
||||
{ name: 'Underwear', receive: true, give: true },
|
||||
{ name: 'Chubbies', receive: true, give: true }
|
||||
]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import AttackItem from "@/components/AttackItem.vue";
|
||||
import AttackList from "@/components/AttackList.vue";
|
||||
import AttackItem from '@/components/AttackItem.vue'
|
||||
import AttackList from '@/components/AttackList.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -8,8 +8,8 @@ import AttackList from "@/components/AttackList.vue";
|
|||
<h1>{{ $route.name }}</h1>
|
||||
|
||||
<p>
|
||||
Since Sebin is a fire dragon there's a myriad of abilities he has at his
|
||||
disposal to defend himself.
|
||||
Since Sebin is a fire dragon there's a myriad of abilities he has at his disposal to defend
|
||||
himself.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -48,12 +48,10 @@ import AttackList from "@/components/AttackList.vue";
|
|||
</template>
|
||||
<template #name>Fire Breath</template>
|
||||
<template #desc>
|
||||
Like most fire dragons, Sebin can breathe fire. In order to do this, he
|
||||
takes a deep breath to enrich the oxygen in his lungs with gases, which,
|
||||
together with special glands in his mouth, produce a combustible
|
||||
mixture. The resulting jet of fire, reaching several hundred degrees
|
||||
Celsius, spreads out on its way to its target, scorching everything in
|
||||
its path.
|
||||
Like most fire dragons, Sebin can breathe fire. In order to do this, he takes a deep breath
|
||||
to enrich the oxygen in his lungs with gases, which, together with special glands in his
|
||||
mouth, produce a combustible mixture. The resulting jet of fire, reaching several hundred
|
||||
degrees Celsius, spreads out on its way to its target, scorching everything in its path.
|
||||
</template>
|
||||
</AttackItem>
|
||||
|
||||
|
@ -87,11 +85,10 @@ import AttackList from "@/components/AttackList.vue";
|
|||
</template>
|
||||
<template #name>Flame Toss</template>
|
||||
<template #desc>
|
||||
By spitting fire into his hands, Sebin can form it into a ball and use
|
||||
it as a projectile. His scales are fireproof and can withstand the high
|
||||
temperatures. Due to their high concentration, the projectiles explode
|
||||
upon impact. By combining two fireballs the explosion radius increases
|
||||
dramatically.
|
||||
By spitting fire into his hands, Sebin can form it into a ball and use it as a projectile.
|
||||
His scales are fireproof and can withstand the high temperatures. Due to their high
|
||||
concentration, the projectiles explode upon impact. By combining two fireballs the explosion
|
||||
radius increases dramatically.
|
||||
</template>
|
||||
</AttackItem>
|
||||
|
||||
|
@ -125,10 +122,9 @@ import AttackList from "@/components/AttackList.vue";
|
|||
</template>
|
||||
<template #name>Kindled Fist</template>
|
||||
<template #desc>
|
||||
Apart from throwing projectiles, Sebin can also use the fireballs to
|
||||
wrap his fists in fire. This allows him to inflict severe burns on his
|
||||
opponent with each blow. In addition, he can release the fire from his
|
||||
fists with aimed blows and hurl it at his opponents.
|
||||
Apart from throwing projectiles, Sebin can also use the fireballs to wrap his fists in fire.
|
||||
This allows him to inflict severe burns on his opponent with each blow. In addition, he can
|
||||
release the fire from his fists with aimed blows and hurl it at his opponents.
|
||||
</template>
|
||||
</AttackItem>
|
||||
|
||||
|
@ -162,9 +158,8 @@ import AttackList from "@/components/AttackList.vue";
|
|||
</template>
|
||||
<template #name>Burning Twister</template>
|
||||
<template #desc>
|
||||
A technique used in aerial combat, Sebin uses his fire breath to engulf
|
||||
his body in flames while spinning to become a fire tornado that singes
|
||||
opponents.
|
||||
A technique used in aerial combat, Sebin uses his fire breath to engulf his body in flames
|
||||
while spinning to become a fire tornado that singes opponents.
|
||||
</template>
|
||||
</AttackItem>
|
||||
</AttackList>
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
<script setup lang="ts">
|
||||
import { inject } from "vue";
|
||||
import { nsfwKey, showModalKey } from "@/keys";
|
||||
import type { ColorDict } from "@/interfaces";
|
||||
import { tailLength, wingspan, penis, colors } from "@/sebin";
|
||||
import { toImperial, toFahrenheit } from "@/helpers";
|
||||
import RefToggle from "@/components/RefToggle.vue";
|
||||
import RefGallery from "@/components/RefGallery.vue";
|
||||
import RefFigure from "@/components/RefFigure.vue";
|
||||
import ColorTable from "@/components/ColorTable.vue";
|
||||
import DataTable from "@/components/DataTable.vue";
|
||||
import QuickFacts from "@/components/QuickFacts.vue";
|
||||
import { inject } from 'vue'
|
||||
import { nsfwKey, showModalKey } from '@/keys'
|
||||
import type { ColorDict } from '@/interfaces'
|
||||
import { tailLength, wingspan, penis, colors } from '@/sebin'
|
||||
import { toImperial, toFahrenheit } from '@/helpers'
|
||||
import RefToggle from '@/components/RefToggle.vue'
|
||||
import RefGallery from '@/components/RefGallery.vue'
|
||||
import RefFigure from '@/components/RefFigure.vue'
|
||||
import ColorTable from '@/components/ColorTable.vue'
|
||||
import DataTable from '@/components/DataTable.vue'
|
||||
import QuickFacts from '@/components/QuickFacts.vue'
|
||||
|
||||
const sebinColors: ColorDict[] = [
|
||||
{ name: "Scales", value: colors.scalesPrimary },
|
||||
{ name: "Chest, Wings (front)", value: colors.scalesSecondary },
|
||||
{ name: "Hair", value: colors.hairPrimary },
|
||||
{ name: "Hair Streaks (optional)", value: colors.hairSecondary },
|
||||
{ name: "Eyes", value: colors.eyes },
|
||||
{ name: "Facial Spikes", value: colors.eyebrows },
|
||||
{ name: "Horns/Claws/Nipples", value: colors.horns },
|
||||
{ name: "Tail Spikes", value: colors.tailspikes },
|
||||
];
|
||||
{ name: 'Scales', value: colors.scalesPrimary },
|
||||
{ name: 'Chest, Wings (front)', value: colors.scalesSecondary },
|
||||
{ name: 'Hair', value: colors.hairPrimary },
|
||||
{ name: 'Hair Streaks (optional)', value: colors.hairSecondary },
|
||||
{ name: 'Eyes', value: colors.eyes },
|
||||
{ name: 'Facial Spikes', value: colors.eyebrows },
|
||||
{ name: 'Horns/Claws/Nipples', value: colors.horns },
|
||||
{ name: 'Tail Spikes', value: colors.tailspikes }
|
||||
]
|
||||
|
||||
const sebinPenisHeadings = ["Key", "Value"];
|
||||
const sebinPenisHeadings = ['Key', 'Value']
|
||||
const sebinPenisData = [
|
||||
["Shape", penis.shape],
|
||||
["Type", penis.type],
|
||||
["Special Traits", penis.special],
|
||||
["Color", colors.penis],
|
||||
["Length", `${penis.size} cm (${toImperial(penis.size)})`],
|
||||
["Girth", `${penis.girth} cm (${toImperial(penis.girth)})`],
|
||||
];
|
||||
['Shape', penis.shape],
|
||||
['Type', penis.type],
|
||||
['Special Traits', penis.special],
|
||||
['Color', colors.penis],
|
||||
['Length', `${penis.size} cm (${toImperial(penis.size)})`],
|
||||
['Girth', `${penis.girth} cm (${toImperial(penis.girth)})`]
|
||||
]
|
||||
|
||||
const isNsfw = inject<boolean>(nsfwKey, false);
|
||||
const showModal = inject<Function>(showModalKey, Function);
|
||||
const isNsfw = inject<boolean>(nsfwKey, false)
|
||||
const showModal = inject<Function>(showModalKey, Function)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -137,11 +137,7 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</template>
|
||||
|
||||
<template #caption>
|
||||
<RefToggle
|
||||
id="sebin-fullbody-ref"
|
||||
v-model="isNsfw"
|
||||
@click.prevent="showModal()"
|
||||
>
|
||||
<RefToggle id="sebin-fullbody-ref" v-model="isNsfw" @click.prevent="showModal()">
|
||||
<template #off>😇</template>
|
||||
<template #on>😈</template>
|
||||
</RefToggle>
|
||||
|
@ -165,24 +161,19 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
<li>Athletic to body builder physique</li>
|
||||
<li>Sharp, black claws on fingers and toes</li>
|
||||
<li>Brown blunt spikes running over back and top-side of tail</li>
|
||||
<li>
|
||||
Tail about {{ tailLength / 100 }} meter ({{ toImperial(tailLength) }})
|
||||
in length
|
||||
</li>
|
||||
<li>Tail about {{ tailLength / 100 }} meter ({{ toImperial(tailLength) }}) in length</li>
|
||||
</ul>
|
||||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
As the offspring of a union between human and dragon, Sebin is a bipedal
|
||||
plantigrade. The majority of his body is covered in red scales. A strip of
|
||||
yellow scales runs from the underside of his jaw, extending down his chest
|
||||
through his legs to the underside of the tip of his tail. The scales on
|
||||
his chest are characterized by a special toughness to better protect vital
|
||||
organs. He also has an athletic to muscular physique that he continuously
|
||||
tends to keep in shape. Finger and toe tips are armed with sharp, black
|
||||
claws, which serve him equally as tools and weapons. Brown spines run from
|
||||
head to spine to tip of tail, though they are too blunt to pose a risk of
|
||||
injury. His tail is about
|
||||
As the offspring of a union between human and dragon, Sebin is a bipedal plantigrade. The
|
||||
majority of his body is covered in red scales. A strip of yellow scales runs from the
|
||||
underside of his jaw, extending down his chest through his legs to the underside of the tip of
|
||||
his tail. The scales on his chest are characterized by a special toughness to better protect
|
||||
vital organs. He also has an athletic to muscular physique that he continuously tends to keep
|
||||
in shape. Finger and toe tips are armed with sharp, black claws, which serve him equally as
|
||||
tools and weapons. Brown spines run from head to spine to tip of tail, though they are too
|
||||
blunt to pose a risk of injury. His tail is about
|
||||
{{ tailLength / 100 }} meters ({{ toImperial(tailLength) }}) in length.
|
||||
</p>
|
||||
</section>
|
||||
|
@ -192,9 +183,7 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
|
||||
<QuickFacts :cols="2">
|
||||
<ul>
|
||||
<li>
|
||||
Wingspan {{ wingspan / 100 }} meters ({{ toImperial(wingspan) }})
|
||||
</li>
|
||||
<li>Wingspan {{ wingspan / 100 }} meters ({{ toImperial(wingspan) }})</li>
|
||||
<li>Closed when on the ground</li>
|
||||
<li>Function like a second pair of arms</li>
|
||||
<li>Pointy talon on end of "hand"</li>
|
||||
|
@ -202,17 +191,14 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
Sebin's wings have a span of about {{ wingspan / 100 }} meters ({{
|
||||
toImperial(wingspan)
|
||||
}}). They function very much like a second pair of arms: two
|
||||
interconnected limbs that form a bendable arm, at the end of which sits a
|
||||
hand-like structure, adorned with a talon in exchange for a thumb, with a
|
||||
sturdy membrane stretched between its long fingers. On solid ground, he
|
||||
keeps his wings closed so as not to accidentally bump into anything with
|
||||
them. Sebin also pays a lot of attention to his wings when working out, so
|
||||
that they can keep carrying him reliably through the air. Though, he only
|
||||
travels short to medium distances through the air before he has to take a
|
||||
rest - as long as the airspace in the area has been declared open for wing
|
||||
Sebin's wings have a span of about {{ wingspan / 100 }} meters ({{ toImperial(wingspan) }}).
|
||||
They function very much like a second pair of arms: two interconnected limbs that form a
|
||||
bendable arm, at the end of which sits a hand-like structure, adorned with a talon in exchange
|
||||
for a thumb, with a sturdy membrane stretched between its long fingers. On solid ground, he
|
||||
keeps his wings closed so as not to accidentally bump into anything with them. Sebin also pays
|
||||
a lot of attention to his wings when working out, so that they can keep carrying him reliably
|
||||
through the air. Though, he only travels short to medium distances through the air before he
|
||||
has to take a rest - as long as the airspace in the area has been declared open for wing
|
||||
bearers.
|
||||
</p>
|
||||
</section>
|
||||
|
@ -291,20 +277,17 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
Despite what one might expect with reptilians, Sebin's pupils are rounded
|
||||
instead of slit-shaped. Yellow spikes running above his eyelids serve as
|
||||
eyebrows. These spikes are also found along his jaw bone. Two pointed,
|
||||
slightly curved, black horns protrude from his head. He usually wears his
|
||||
medium-length, blue hair loose. His long, pointed ears are very flexible,
|
||||
allowing him to hear sounds around him without having to turn his head.
|
||||
They are also used for non-verbal communication, to express emotions
|
||||
through body language. His hearing perceives a wider range of frequencies,
|
||||
making it superior to that of a human. His jaws are equipped with
|
||||
razor-sharp teeth that effortlessly sink into anything he manages to bite,
|
||||
be it nourishment or adversaries. Embedded between them lies his tongue,
|
||||
which is typically pointed for reptilians. Glands in his throat produce a
|
||||
mixture which he uses to spit fire, which can reach up to around 100 °C
|
||||
({{ toFahrenheit(100) }} °F).
|
||||
Despite what one might expect with reptilians, Sebin's pupils are rounded instead of
|
||||
slit-shaped. Yellow spikes running above his eyelids serve as eyebrows. These spikes are also
|
||||
found along his jaw bone. Two pointed, slightly curved, black horns protrude from his head. He
|
||||
usually wears his medium-length, blue hair loose. His long, pointed ears are very flexible,
|
||||
allowing him to hear sounds around him without having to turn his head. They are also used for
|
||||
non-verbal communication, to express emotions through body language. His hearing perceives a
|
||||
wider range of frequencies, making it superior to that of a human. His jaws are equipped with
|
||||
razor-sharp teeth that effortlessly sink into anything he manages to bite, be it nourishment
|
||||
or adversaries. Embedded between them lies his tongue, which is typically pointed for
|
||||
reptilians. Glands in his throat produce a mixture which he uses to spit fire, which can reach
|
||||
up to around 100 °C ({{ toFahrenheit(100) }} °F).
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -318,18 +301,17 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
<li>Defined abs</li>
|
||||
<li>Black nipples</li>
|
||||
<li>
|
||||
Any muscle mass from athletic to body builder is fine, with a
|
||||
preference towards body builder
|
||||
Any muscle mass from athletic to body builder is fine, with a preference towards body
|
||||
builder
|
||||
</li>
|
||||
</ul>
|
||||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
At the age of 17, Sebin gradually began to keep his body in shape on a
|
||||
regular basis. His favorite exercises include weightlifting (with both
|
||||
dumbbells and barbells), lat pulldown, leg press and cable curls. He works
|
||||
out three days a week with one day off between training days, rotating the
|
||||
body regions he trains each day.
|
||||
At the age of 17, Sebin gradually began to keep his body in shape on a regular basis. His
|
||||
favorite exercises include weightlifting (with both dumbbells and barbells), lat pulldown, leg
|
||||
press and cable curls. He works out three days a week with one day off between training days,
|
||||
rotating the body regions he trains each day.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -369,10 +351,9 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
|
||||
<section>
|
||||
<p>
|
||||
Sebin is very concerned with an even distribution of muscle mass, but pays
|
||||
particular attention to his back, chest and arms. A strong chest with
|
||||
strong arms helps to throw fire projectiles as far as possible. A strong
|
||||
back guarantees a longer stay in the air.
|
||||
Sebin is very concerned with an even distribution of muscle mass, but pays particular
|
||||
attention to his back, chest and arms. A strong chest with strong arms helps to throw fire
|
||||
projectiles as far as possible. A strong back guarantees a longer stay in the air.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -510,9 +491,7 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</template>
|
||||
<template #caption>Sebin flexing</template>
|
||||
<template #copyright>
|
||||
<a href="https://www.furaffinity.net/user/Marsel-Defender">
|
||||
Marsel-Defender
|
||||
</a>
|
||||
<a href="https://www.furaffinity.net/user/Marsel-Defender"> Marsel-Defender </a>
|
||||
</template>
|
||||
</RefFigure>
|
||||
<RefFigure id="sebin-muscle-ref4" polaroidBorder nsfw>
|
||||
|
@ -791,16 +770,12 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
<template #img>
|
||||
<picture>
|
||||
<source
|
||||
srcset="
|
||||
@/assets/refs/sebin-ref-penis.png?w=480;720;0&avif&quality=75&srcset
|
||||
"
|
||||
srcset="@/assets/refs/sebin-ref-penis.png?w=480;720;0&avif&quality=75&srcset"
|
||||
sizes="(min-width: 45em) 1155px, (min-width: 30em) 720px, 480px"
|
||||
type="image/avif"
|
||||
/>
|
||||
<source
|
||||
srcset="
|
||||
@/assets/refs/sebin-ref-penis.png?w=480;720;0&webp&quality=100&srcset
|
||||
"
|
||||
srcset="@/assets/refs/sebin-ref-penis.png?w=480;720;0&webp&quality=100&srcset"
|
||||
sizes="(min-width: 45em) 1155px, (min-width: 30em) 720px, 480px"
|
||||
type="image/webp"
|
||||
/>
|
||||
|
@ -827,24 +802,20 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
<ul>
|
||||
<li>Human-shaped with ridges</li>
|
||||
<li>Ring-like sheath surrounding shaft</li>
|
||||
<li>
|
||||
Extends from sheath when erect, lives inside sheath when not erect
|
||||
</li>
|
||||
<li>Extends from sheath when erect, lives inside sheath when not erect</li>
|
||||
<li>External balls</li>
|
||||
</ul>
|
||||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
Despite his reptilian appearance, Sebin has nipples, a feature of the
|
||||
human side of his family. Furthermore, his external testicles represent
|
||||
another humanized feature. Where relatives of his ilk possess a slit in
|
||||
which the penis lies protectively, Sebin possesses a pouch-like sheath
|
||||
from which the tip of the penis protrudes slightly. The shape of his
|
||||
shaft is predominantly humanoid, but it is surrounded by ridges and has
|
||||
no equivalent of a foreskin. When aroused, the coal-black shaft swells
|
||||
and pushes out of the sheath until fully erect, the sheath wrapping
|
||||
around the root of the shaft like a ring. However, he can also push it
|
||||
out in a flaccid state, e.g. when needing to pass water.
|
||||
Despite his reptilian appearance, Sebin has nipples, a feature of the human side of his
|
||||
family. Furthermore, his external testicles represent another humanized feature. Where
|
||||
relatives of his ilk possess a slit in which the penis lies protectively, Sebin possesses a
|
||||
pouch-like sheath from which the tip of the penis protrudes slightly. The shape of his shaft
|
||||
is predominantly humanoid, but it is surrounded by ridges and has no equivalent of a
|
||||
foreskin. When aroused, the coal-black shaft swells and pushes out of the sheath until fully
|
||||
erect, the sheath wrapping around the root of the shaft like a ring. However, he can also
|
||||
push it out in a flaccid state, e.g. when needing to pass water.
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
@ -854,16 +825,12 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
<h2>But, wait! There's more...</h2>
|
||||
|
||||
<p>
|
||||
Sebin like you haven't seen him yet! Flip the switch to reveal his
|
||||
naughty secrets. If you dare...! Don't say I didn't warn you!!
|
||||
Sebin like you haven't seen him yet! Flip the switch to reveal his naughty secrets. If you
|
||||
dare...! Don't say I didn't warn you!!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<RefToggle
|
||||
id="sebin-manly-bits"
|
||||
v-model="isNsfw"
|
||||
@click.prevent="showModal()"
|
||||
>
|
||||
<RefToggle id="sebin-manly-bits" v-model="isNsfw" @click.prevent="showModal()">
|
||||
<template #off>😇</template>
|
||||
<template #on>😈</template>
|
||||
</RefToggle>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import RefFigure from "@/components/RefFigure.vue";
|
||||
import RefGallery from "@/components/RefGallery.vue";
|
||||
import RefFigure from '@/components/RefFigure.vue'
|
||||
import RefGallery from '@/components/RefGallery.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -40,9 +40,7 @@ import RefGallery from "@/components/RefGallery.vue";
|
|||
|
||||
<template #caption>
|
||||
<p>Sebin in his casual outfit</p>
|
||||
<p>
|
||||
Black tank top, flannell shirt, shorts (w/ dangling bands), sneakers
|
||||
</p>
|
||||
<p>Black tank top, flannell shirt, shorts (w/ dangling bands), sneakers</p>
|
||||
</template>
|
||||
|
||||
<template #copyright>
|
||||
|
@ -117,8 +115,7 @@ import RefGallery from "@/components/RefGallery.vue";
|
|||
<template #caption>
|
||||
<p>Sebin in his workout outfit</p>
|
||||
<p>
|
||||
<strong>Full body:</strong> Snapback hat, tank top, fingerless gloves,
|
||||
shorts, sneakers
|
||||
<strong>Full body:</strong> Snapback hat, tank top, fingerless gloves, shorts, sneakers
|
||||
</p>
|
||||
</template>
|
||||
|
||||
|
@ -157,8 +154,8 @@ import RefGallery from "@/components/RefGallery.vue";
|
|||
<template #caption>
|
||||
<p>Sebin in his workout outfit</p>
|
||||
<p>
|
||||
<strong>Close-up:</strong> Snapback hat, headphones, tank top,
|
||||
fingerless gloves, shorts, smartwatch
|
||||
<strong>Close-up:</strong> Snapback hat, headphones, tank top, fingerless gloves, shorts,
|
||||
smartwatch
|
||||
</p>
|
||||
</template>
|
||||
|
||||
|
@ -199,9 +196,8 @@ import RefGallery from "@/components/RefGallery.vue";
|
|||
<template #caption>
|
||||
<p>Tracksuit pants</p>
|
||||
<p>
|
||||
Sebin likes to wear comfortable clothes at home when he doesn't need
|
||||
to leave the house or is enjoying some leisure time after work or on
|
||||
weekends.
|
||||
Sebin likes to wear comfortable clothes at home when he doesn't need to leave the house or
|
||||
is enjoying some leisure time after work or on weekends.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
|
@ -213,23 +209,17 @@ import RefGallery from "@/components/RefGallery.vue";
|
|||
<template #img>
|
||||
<picture>
|
||||
<source
|
||||
srcset="
|
||||
@/assets/refs/clothes/lazy/undies.jpg?w=0&avif&withoutEnlargement&srcset
|
||||
"
|
||||
srcset="@/assets/refs/clothes/lazy/undies.jpg?w=0&avif&withoutEnlargement&srcset"
|
||||
sizes="333px"
|
||||
type="image/avif"
|
||||
/>
|
||||
<source
|
||||
srcset="
|
||||
@/assets/refs/clothes/lazy/undies.jpg?w=0&webp&withoutEnlargement&srcset
|
||||
"
|
||||
srcset="@/assets/refs/clothes/lazy/undies.jpg?w=0&webp&withoutEnlargement&srcset"
|
||||
sizes="333px"
|
||||
type="image/webp"
|
||||
/>
|
||||
<img
|
||||
srcset="
|
||||
@/assets/refs/clothes/lazy/undies.jpg?w=0&withoutEnlargement&srcset
|
||||
"
|
||||
srcset="@/assets/refs/clothes/lazy/undies.jpg?w=0&withoutEnlargement&srcset"
|
||||
sizes="333px"
|
||||
alt="Shorts"
|
||||
loading="lazy"
|
||||
|
@ -240,8 +230,8 @@ import RefGallery from "@/components/RefGallery.vue";
|
|||
<template #caption>
|
||||
<p>Topless w/ jockstrap/boxer briefs</p>
|
||||
<p>
|
||||
For even more comfort, Sebin tends to forgoe pants completely and save
|
||||
on laundry by only wearing the absolute necessary.
|
||||
For even more comfort, Sebin tends to forgoe pants completely and save on laundry by only
|
||||
wearing the absolute necessary.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { inject } from "vue";
|
||||
import { inject } from 'vue'
|
||||
import {
|
||||
firstName,
|
||||
middleName,
|
||||
|
@ -13,45 +13,42 @@ import {
|
|||
tailLength,
|
||||
wingspan,
|
||||
hobbies,
|
||||
kinks,
|
||||
} from "@/sebin";
|
||||
import { dateFormat, getAge, toImperial, toLbs } from "@/helpers";
|
||||
import { nsfwKey, showModalKey } from "@/keys";
|
||||
import type { Kink } from "@/interfaces";
|
||||
import DataTable from "@/components/DataTable.vue";
|
||||
import QuickFacts from "@/components/QuickFacts.vue";
|
||||
import RefToggle from "@/components/RefToggle.vue";
|
||||
kinks
|
||||
} from '@/sebin'
|
||||
import { dateFormat, getAge, toImperial, toLbs } from '@/helpers'
|
||||
import { nsfwKey, showModalKey } from '@/keys'
|
||||
import type { Kink } from '@/interfaces'
|
||||
import DataTable from '@/components/DataTable.vue'
|
||||
import QuickFacts from '@/components/QuickFacts.vue'
|
||||
import RefToggle from '@/components/RefToggle.vue'
|
||||
|
||||
const generalHeadings = ["Key", "Value"];
|
||||
const generalHeadings = ['Key', 'Value']
|
||||
const generalData = [
|
||||
["Full Name", `${firstName} ${middleName} ${lastName} `],
|
||||
[
|
||||
"Date of Birth",
|
||||
`${dateFormat.format(dateOfBirth)} (${getAge(dateOfBirth)})`,
|
||||
],
|
||||
["Sex/Gender", gender],
|
||||
["Height", `${height} cm (${toImperial(height)})`],
|
||||
["Weight", `${weight} kg (${toLbs(weight)} lbs)`],
|
||||
["Tail Length", `${tailLength / 100} m (${toImperial(tailLength)})`],
|
||||
["Wingspan", `${wingspan / 100} m (${toImperial(wingspan)})`],
|
||||
];
|
||||
['Full Name', `${firstName} ${middleName} ${lastName} `],
|
||||
['Date of Birth', `${dateFormat.format(dateOfBirth)} (${getAge(dateOfBirth)})`],
|
||||
['Sex/Gender', gender],
|
||||
['Height', `${height} cm (${toImperial(height)})`],
|
||||
['Weight', `${weight} kg (${toLbs(weight)} lbs)`],
|
||||
['Tail Length', `${tailLength / 100} m (${toImperial(tailLength)})`],
|
||||
['Wingspan', `${wingspan / 100} m (${toImperial(wingspan)})`]
|
||||
]
|
||||
|
||||
const nsfwHeadings = ["Key", "Value"];
|
||||
const nsfwHeadings = ['Key', 'Value']
|
||||
const nsfwData = [
|
||||
["Orientation", orientation],
|
||||
["Position", position],
|
||||
];
|
||||
['Orientation', orientation],
|
||||
['Position', position]
|
||||
]
|
||||
|
||||
const kinksHeadings = ["Kink", "Receive", "Give"];
|
||||
const kinksHeadings = ['Kink', 'Receive', 'Give']
|
||||
const kinksData = kinks.map((kink: Kink): string[] => {
|
||||
const receive = kink.receive ? "✅" : "🚫";
|
||||
const give = kink.give ? "✅" : "🚫";
|
||||
const receive = kink.receive ? '✅' : '🚫'
|
||||
const give = kink.give ? '✅' : '🚫'
|
||||
|
||||
return [kink.name, receive, give];
|
||||
});
|
||||
return [kink.name, receive, give]
|
||||
})
|
||||
|
||||
const isNsfw = inject<boolean>(nsfwKey, false);
|
||||
const showModal = inject<Function>(showModalKey, Function);
|
||||
const isNsfw = inject<boolean>(nsfwKey, false)
|
||||
const showModal = inject<Function>(showModalKey, Function)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -78,38 +75,34 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
Sebin is a warm-hearted guy who cares a lot about the well-being of his
|
||||
loved ones. Bad vibes rarely escape him and he offers his help without
|
||||
hesitation. He also won't avoid difficult conversations in the process.
|
||||
Not being able to help a friend in need is synonymous with failing them, a
|
||||
realization that can leave him feeling uneasy long after the fact.
|
||||
Sebin is a warm-hearted guy who cares a lot about the well-being of his loved ones. Bad vibes
|
||||
rarely escape him and he offers his help without hesitation. He also won't avoid difficult
|
||||
conversations in the process. Not being able to help a friend in need is synonymous with
|
||||
failing them, a realization that can leave him feeling uneasy long after the fact.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
At the same time, he is very open and honest about his feelings. He does
|
||||
not mince words and finds clear words when speaking his mind.
|
||||
Unfortunately, Sebin sometimes forgets his good manners in the heat of the
|
||||
moment, once he gets invested into a quarrel — especially when it comes to
|
||||
topics that are near and dear to his heart. Anyone looking to have a bad
|
||||
time can try their luck at pissing him off even once. This includes an
|
||||
equally vulgar vocabulary. It is not uncommon to hear him swear.
|
||||
At the same time, he is very open and honest about his feelings. He does not mince words and
|
||||
finds clear words when speaking his mind. Unfortunately, Sebin sometimes forgets his good
|
||||
manners in the heat of the moment, once he gets invested into a quarrel — especially when it
|
||||
comes to topics that are near and dear to his heart. Anyone looking to have a bad time can try
|
||||
their luck at pissing him off even once. This includes an equally vulgar vocabulary. It is not
|
||||
uncommon to hear him swear.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Nevertheless, Sebin strives to put his best foot forward at all times. He
|
||||
is of the sociable type and likes to laugh a lot, as he is easily amused.
|
||||
Sometimes to a degree where it can become very childish and immature very
|
||||
quickly.
|
||||
Nevertheless, Sebin strives to put his best foot forward at all times. He is of the sociable
|
||||
type and likes to laugh a lot, as he is easily amused. Sometimes to a degree where it can
|
||||
become very childish and immature very quickly.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Physical strength is not the only thing that plays a big role for Sebin.
|
||||
He is of a firm believe that a healthy body must also have a healthy mind
|
||||
in order to find a balance. But he only came to this realization at the
|
||||
end of a rocky road. While a setback in the past could easily throw him
|
||||
off track, today he stands much more firmly in life. Not only for his own
|
||||
sake, but also to be a kind of anchor for others. He always keeps his
|
||||
cool, so he can be a tower of strenth for others.
|
||||
Physical strength is not the only thing that plays a big role for Sebin. He is of a firm
|
||||
believe that a healthy body must also have a healthy mind in order to find a balance. But he
|
||||
only came to this realization at the end of a rocky road. While a setback in the past could
|
||||
easily throw him off track, today he stands much more firmly in life. Not only for his own
|
||||
sake, but also to be a kind of anchor for others. He always keeps his cool, so he can be a
|
||||
tower of strenth for others.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -125,18 +118,16 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
Sebin is passionate about his hobbies. If he notices even the smallest
|
||||
spark of interest in his hobbies you should bring a lot of time, as he
|
||||
will chew your ear off first. Patience is known to be a virtue — one
|
||||
unknown to this dragon.
|
||||
Sebin is passionate about his hobbies. If he notices even the smallest spark of interest in
|
||||
his hobbies you should bring a lot of time, as he will chew your ear off first. Patience is
|
||||
known to be a virtue — one unknown to this dragon.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When he indulges in his hobbies, he does so with devotion. Every move has
|
||||
to be right and everything has to be in perfect harmony. Once he is in his
|
||||
flow, he must not be disturbed, otherwise he can sometimes become quite
|
||||
eccentric in expressing his dismay of being disrupted, possibly losing a
|
||||
very important train of thought.
|
||||
When he indulges in his hobbies, he does so with devotion. Every move has to be right and
|
||||
everything has to be in perfect harmony. Once he is in his flow, he must not be disturbed,
|
||||
otherwise he can sometimes become quite eccentric in expressing his dismay of being disrupted,
|
||||
possibly losing a very important train of thought.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -161,21 +152,19 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
Sebin's day starts with a strong cup of black coffee and sandwiches. He's
|
||||
also a massive sweet tooth which sounds like a big detriment to his
|
||||
fitness routine. That's because it is and it's often very hard for him to
|
||||
resist.
|
||||
Sebin's day starts with a strong cup of black coffee and sandwiches. He's also a massive sweet
|
||||
tooth which sounds like a big detriment to his fitness routine. That's because it is and it's
|
||||
often very hard for him to resist.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Besides snacking, Sebin also likes to eat hearty and savory things. He
|
||||
doesn't disdain a cheese platter with a wide selection, nor a medium-rare
|
||||
steak.
|
||||
Besides snacking, Sebin also likes to eat hearty and savory things. He doesn't disdain a
|
||||
cheese platter with a wide selection, nor a medium-rare steak.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sebin rarely says no to a good beer with friends, just as he rarely says
|
||||
no to a bar tour to try new and interesting cocktails.
|
||||
Sebin rarely says no to a good beer with friends, just as he rarely says no to a bar tour to
|
||||
try new and interesting cocktails.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
|
@ -198,17 +187,14 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
</QuickFacts>
|
||||
|
||||
<p>
|
||||
But above all Sebin is a very naughty hornball. He knows what he's got
|
||||
and he's not afraid to flaunt it. He is a generally dominant lover who
|
||||
likes to have it rough. But he is not lacking in tenderness. He
|
||||
considers himself somewhat of a "service top", who doesn't only have his
|
||||
own fun in mind. His job is only done if he's benn able to satisfy.
|
||||
However, that doesn't mean that he doesn't let others have their fun
|
||||
with him too from time to time. It always depends on his playmates,
|
||||
which makes him effectively a switch. He loves to wear bottomless
|
||||
jockstraps and boxer briefs to direct the attention of onlookers exactly
|
||||
where he wants it. After all he is well endowed enough to peddle it
|
||||
around.
|
||||
But above all Sebin is a very naughty hornball. He knows what he's got and he's not afraid
|
||||
to flaunt it. He is a generally dominant lover who likes to have it rough. But he is not
|
||||
lacking in tenderness. He considers himself somewhat of a "service top", who doesn't only
|
||||
have his own fun in mind. His job is only done if he's benn able to satisfy. However, that
|
||||
doesn't mean that he doesn't let others have their fun with him too from time to time. It
|
||||
always depends on his playmates, which makes him effectively a switch. He loves to wear
|
||||
bottomless jockstraps and boxer briefs to direct the attention of onlookers exactly where he
|
||||
wants it. After all he is well endowed enough to peddle it around.
|
||||
</p>
|
||||
|
||||
<DataTable class="kinks" :headings="kinksHeadings" :data="kinksData" />
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { inject } from "vue";
|
||||
import { nsfwKey, showModalKey } from "@/keys";
|
||||
import RefToggle from "@/components/RefToggle.vue";
|
||||
import WelcomeHeader from "@/components/WelcomeHeader.vue";
|
||||
import ButtonGroup from "@/components/ButtonGroup.vue";
|
||||
import Button from "@/components/RefButton.vue";
|
||||
import { inject } from 'vue'
|
||||
import { nsfwKey, showModalKey } from '@/keys'
|
||||
import RefToggle from '@/components/RefToggle.vue'
|
||||
import WelcomeHeader from '@/components/WelcomeHeader.vue'
|
||||
import ButtonGroup from '@/components/ButtonGroup.vue'
|
||||
import Button from '@/components/RefButton.vue'
|
||||
|
||||
const isNsfw = inject<boolean>(nsfwKey, false);
|
||||
const showModal = inject<Function>(showModalKey, Function);
|
||||
const isNsfw = inject<boolean>(nsfwKey, false)
|
||||
const showModal = inject<Function>(showModalKey, Function)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -18,44 +18,33 @@ const showModal = inject<Function>(showModalKey, Function);
|
|||
|
||||
<section>
|
||||
<h3>Welcome to Sebin's Ref Page</h3>
|
||||
<p>
|
||||
On this page your can learn all about Sebin, your friendly neighborhood
|
||||
dragon!
|
||||
</p>
|
||||
<p>On this page your can learn all about Sebin, your friendly neighborhood dragon!</p>
|
||||
|
||||
<p>
|
||||
I started this page to have a single point of truth with all the info
|
||||
artists I commission can possibly need. If you're missing some crucial
|
||||
info, or you would like to give me some general feedback about this page,
|
||||
feel free to reach out!
|
||||
I started this page to have a single point of truth with all the info artists I commission can
|
||||
possibly need. If you're missing some crucial info, or you would like to give me some general
|
||||
feedback about this page, feel free to reach out!
|
||||
</p>
|
||||
|
||||
<ButtonGroup grid class="social">
|
||||
<Button href="https://twitter.com/SebinNyshkim" class="twitter">
|
||||
Twitter
|
||||
</Button>
|
||||
<Button href="https://meow.social/@SebinNyshkim" class="mastodon" rel="me" >
|
||||
Mastodon
|
||||
</Button>
|
||||
<Button href="https://t.me/SebinNyshkim" class="telegram">
|
||||
Telegram
|
||||
</Button>
|
||||
<Button href="https://twitter.com/SebinNyshkim" class="twitter"> Twitter </Button>
|
||||
<Button href="https://meow.social/@SebinNyshkim" class="mastodon" rel="me"> Mastodon </Button>
|
||||
<Button href="https://t.me/SebinNyshkim" class="telegram"> Telegram </Button>
|
||||
<Button href="https://www.furaffinity.net/user/sonofdragons" class="furaffinity">
|
||||
Fur Affinity
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
|
||||
<blockquote>
|
||||
<strong>Note:</strong> This page is still under heavy construction, as
|
||||
indicated by the 0.x.x version number in the footer. I'm continously
|
||||
updating the site and adding details and information to it. In case you
|
||||
run into something weird, definitely let me know!
|
||||
<strong>Note:</strong> This page is still under heavy construction, as indicated by the 0.x.x
|
||||
version number in the footer. I'm continously updating the site and adding details and
|
||||
information to it. In case you run into something weird, definitely let me know!
|
||||
</blockquote>
|
||||
|
||||
<h3>Complete Ref Sheet</h3>
|
||||
<p>
|
||||
Just here to fetch the ref sheet? Click the button with the ref sheet you
|
||||
need and get started!
|
||||
Just here to fetch the ref sheet? Click the button with the ref sheet you need and get
|
||||
started!
|
||||
</p>
|
||||
|
||||
<ButtonGroup>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
// import AttackItem from "@/components/AttackItem.vue";
|
||||
// import AttackList from "@/components/AttackList.vue";
|
||||
import RefFigure from "@/components/RefFigure.vue";
|
||||
import RefFigure from '@/components/RefFigure.vue'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -45,34 +45,30 @@ import RefFigure from "@/components/RefFigure.vue";
|
|||
|
||||
<section>
|
||||
<p>
|
||||
Sebin can enter an Overdrive Form which greatly increases his strength and
|
||||
abilities but it comes at a cost.
|
||||
Sebin can enter an Overdrive Form which greatly increases his strength and abilities but it
|
||||
comes at a cost.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
He enters Overdrive by engulfing himself in a pillar of flames which
|
||||
transforms his exterior physique. During Overdrive transformation his hair
|
||||
ignites and flickers with blue flames. The corners of his eyes flicker
|
||||
with long green flames. His arms and legs become part carbon black and are
|
||||
crossed by several glowing veins which pulsate like flowing lava. Fire in
|
||||
this form burns several degrees hotter than usual because his body becomes
|
||||
a living blast furnace, which is why his limbs have to be of more
|
||||
fire-proof material to withstand the increased heat.
|
||||
He enters Overdrive by engulfing himself in a pillar of flames which transforms his exterior
|
||||
physique. During Overdrive transformation his hair ignites and flickers with blue flames. The
|
||||
corners of his eyes flicker with long green flames. His arms and legs become part carbon black
|
||||
and are crossed by several glowing veins which pulsate like flowing lava. Fire in this form
|
||||
burns several degrees hotter than usual because his body becomes a living blast furnace, which
|
||||
is why his limbs have to be of more fire-proof material to withstand the increased heat.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To complete the transformation he inhales the flames from the pillar
|
||||
surrounding him which heats up his body from within. Even if Sebin is a
|
||||
fire dragon who can sustain high degrees of heat he is essentially
|
||||
overheating himself from the inside. Because of this he can't maintain
|
||||
this form for more than a few hours before he does permanent damage to his
|
||||
own body.
|
||||
To complete the transformation he inhales the flames from the pillar surrounding him which
|
||||
heats up his body from within. Even if Sebin is a fire dragon who can sustain high degrees of
|
||||
heat he is essentially overheating himself from the inside. Because of this he can't maintain
|
||||
this form for more than a few hours before he does permanent damage to his own body.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Direct body contact with Sebin during overdrive causes 3rd degree burns as
|
||||
he emits an extreme temperature, although less than he keeps inside his
|
||||
body. His immediate surroundings are likely to burn or melt.
|
||||
Direct body contact with Sebin during overdrive causes 3rd degree burns as he emits an extreme
|
||||
temperature, although less than he keeps inside his body. His immediate surroundings are
|
||||
likely to burn or melt.
|
||||
</p>
|
||||
|
||||
<h2>Attacks</h2>
|
||||
|
@ -88,75 +84,69 @@ import RefFigure from "@/components/RefFigure.vue";
|
|||
<tr>
|
||||
<td>Fire Breath (improved)</td>
|
||||
<td>
|
||||
The reach of Sebin's Fire Breath increases as well as the frequency
|
||||
at which he can fire shots from his mouth.
|
||||
The reach of Sebin's Fire Breath increases as well as the frequency at which he can fire
|
||||
shots from his mouth.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Flame Toss (improved)</td>
|
||||
<td>
|
||||
Overdrive Form eliminates the need for Sebin to spit fire into his
|
||||
palms. It instead enables him to fire the shots directly from the
|
||||
palm palm of his hands, as the firey veins crossing his arms act as
|
||||
an orifice to do so. The explosion radius of the burning projectiles
|
||||
that explode on impact is greatly increased.
|
||||
Overdrive Form eliminates the need for Sebin to spit fire into his palms. It instead
|
||||
enables him to fire the shots directly from the palm palm of his hands, as the firey
|
||||
veins crossing his arms act as an orifice to do so. The explosion radius of the burning
|
||||
projectiles that explode on impact is greatly increased.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Kindled Fist (improved)</td>
|
||||
<td>
|
||||
As his arms and legs are infused with fire his punches and kicks
|
||||
exert trails of flames while doing so. Landing a punch or kick sears
|
||||
enemies.
|
||||
As his arms and legs are infused with fire his punches and kicks exert trails of flames
|
||||
while doing so. Landing a punch or kick sears enemies.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Searing Discus</td>
|
||||
<td>
|
||||
Overdrive allows Sebin to form rings of fire by igniting flames from
|
||||
his fingertips and swirling them in a circle motion. He can use them
|
||||
for both close quarters or ranged combat.
|
||||
Overdrive allows Sebin to form rings of fire by igniting flames from his fingertips and
|
||||
swirling them in a circle motion. He can use them for both close quarters or ranged
|
||||
combat.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Combustion Flare</td>
|
||||
<td>
|
||||
Clinking both of his wrists against each other like flints unleashes
|
||||
a devestating fire blast from both of his fire-infused hands. A
|
||||
secure foothold is needed to prevent Sebin from being thrown back by
|
||||
the recoil of the attack. Using this technique in the air is
|
||||
Clinking both of his wrists against each other like flints unleashes a devestating fire
|
||||
blast from both of his fire-infused hands. A secure foothold is needed to prevent Sebin
|
||||
from being thrown back by the recoil of the attack. Using this technique in the air is
|
||||
therefore highly risky.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Blazing Pandemonium</td>
|
||||
<td>
|
||||
A heavy impact into the ground from a great height with both fists,
|
||||
tearing deep cracks in the ground around the impact crater. Combined
|
||||
with
|
||||
A heavy impact into the ground from a great height with both fists, tearing deep cracks
|
||||
in the ground around the impact crater. Combined with
|
||||
<strong><em>Kindled Fist</em></strong>
|
||||
the heat in Sebin's arms are forced through the newly created
|
||||
furrows, transforming the scene into an inferno.
|
||||
the heat in Sebin's arms are forced through the newly created furrows, transforming the
|
||||
scene into an inferno.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Scorching Edge</td>
|
||||
<td>
|
||||
A fiery blade towering several meters into the air that Sebin sends
|
||||
careening towards his enemies from his fire-infused legs with a
|
||||
backflip kick, leaving a swath of destruction in its wake. Upon
|
||||
impact the force of the attack is distributed sideways.
|
||||
A fiery blade towering several meters into the air that Sebin sends careening towards
|
||||
his enemies from his fire-infused legs with a backflip kick, leaving a swath of
|
||||
destruction in its wake. Upon impact the force of the attack is distributed sideways.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Circling Fire Shield</td>
|
||||
<td>
|
||||
A rather defensive technique. By spinning around with stretched out
|
||||
arms Sebin creates fire balls, which he usually hurls towards
|
||||
enemies, that circle around his body diagonally. They act as a
|
||||
shield while he can still move his arms relatively freely. Enemies
|
||||
would be well advised to keep their distance to this spinning
|
||||
shield, as the fire balls will still explode on contact.
|
||||
A rather defensive technique. By spinning around with stretched out arms Sebin creates
|
||||
fire balls, which he usually hurls towards enemies, that circle around his body
|
||||
diagonally. They act as a shield while he can still move his arms relatively freely.
|
||||
Enemies would be well advised to keep their distance to this spinning shield, as the
|
||||
fire balls will still explode on contact.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue