nfp_is: moved nfpis over here
All checks were successful
/ nfp_moe (push) Successful in -83h47m27s
continuous-integration/appveyor/branch AppVeyor build succeeded
/ saproxy (push) Successful in -83h47m29s
/ discord_embed (push) Successful in -83h47m28s
/ nfp_is (push) Successful in -83h46m7s

This commit is contained in:
Jonatan Nilsson 2023-11-05 05:37:29 +00:00
parent ddb66d9836
commit 972dde2c74
71 changed files with 44717 additions and 0 deletions

View file

@ -0,0 +1,59 @@
on:
push:
branches:
- master
jobs:
nfp_is:
runs-on: alpine
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Check for new release
run: |
cd ${{ gitea.job }}
CURR_VER="$(cat package.json | jq -r .name)_v$(cat package.json | jq -r .version)"
CURR_NAME="$(cat package.json | jq -r .name) v$(cat package.json | jq -r .version)"
echo "Checking https://git.nfp.is/api/v1/repos/${{ gitea.repository }}/releases for name ${CURR_NAME}"
if curl -s -X GET -H "Authorization: token ${{ secrets.deploytoken }}" https://git.nfp.is/api/v1/repos/${{ gitea.repository }}/releases | grep -o "\"name\"\:\"${CURR_NAME}\"" > /dev/null; then
echo "Skipping ${{ gitea.job }} since $CURR_NAME already exists";
exit 0
fi
echo "New release ${CURR_VER} found, running npm install..."
mv package.json fuck-you-npm-package.json
mv build-package.json package.json
npm install && npm run build
mv package.json build-package.json
mv fuck-you-npm-package.json package.json
chmod +x ../7zas
../7zas a -xr!*.xcf -mx9 "${CURR_VER}_build-sc.7z" package.json index.mjs api base public
echo "Creating ${CURR_VER} release on gitea"
RELEASE_RESULT=$(curl \
-X POST \
-H "Authorization: token ${{ secrets.deploytoken }}" \
-H "Content-Type: application/json" \
https://git.nfp.is/api/v1/repos/${{ gitea.repository }}/releases \
-d "{\"tag_name\":\"${CURR_VER}\",\"name\":\"${CURR_NAME}\",\"body\":\"Automatic release from Appveyor from ${{ gitea.sha }} :\n\n${{ gitea.event.head_commit.message }}\"}")
RELEASE_ID=$(echo $RELEASE_RESULT | jq -r .id)
echo "Adding ${CURR_VER}_build-sc.7z to release ${RELEASE_ID}"
curl \
-X POST \
-H "Authorization: token ${{ secrets.deploytoken }}" \
-F "attachment=@${CURR_VER}_build-sc.7z" \
https://git.nfp.is/api/v1/repos/${{ gitea.repository }}/releases/$RELEASE_ID/assets
MAN_PORT=$(cat package.json | jq -r .port)
MAN_NAME=$(cat package.json | jq -r .name)
echo "Deplying to production"
echo "curl -X POST http://192.168.93.50:$MAN_PORT/update/$MAN_NAME"
curl -X POST http://192.168.93.50:$MAN_PORT/update/$MAN_NAME

1
nfp_is/.npmrc Normal file
View file

@ -0,0 +1 @@
package-lock=false

20
nfp_is/api/serve.mjs Normal file
View file

@ -0,0 +1,20 @@
import path from 'path'
import Parent from '../base/serve.mjs'
import fs from 'fs/promises'
import config from '../base/config.mjs'
export default class ServeHandler extends Parent {
loadTemplate(indexFile) {
this.template = indexFile.toString()
}
async serveIndex(ctx) {
if (config.get('NODE_ENV') === 'development') {
let indexFile = await fs.readFile(path.join(this.root, 'index.html'))
this.loadTemplate(indexFile)
}
ctx.body = this.template
ctx.type = 'text/html; charset=utf-8'
}
}

27
nfp_is/api/server.mjs Normal file
View file

@ -0,0 +1,27 @@
import config from '../base/config.mjs'
import Parent from '../base/server.mjs'
import StaticRoutes from '../base/static_routes.mjs'
import ServeHandler from './serve.mjs'
export default class Server extends Parent {
init() {
super.init()
let localUtil = new this.core.sc.Util(import.meta.url)
delete this.flaskaOptions.appendHeaders['Content-Security-Policy']
this.flaskaOptions.nonce = []
this.routes = {
static: new StaticRoutes(),
}
this.routes.serve = new ServeHandler({
root: localUtil.getPathFromRoot('../public'),
version: this.core.app.running,
frontend: config.get('frontend:url'),
})
}
runCreateDatabase() {
return {}
}
}

51
nfp_is/app/footer.js Normal file
View file

@ -0,0 +1,51 @@
var m = require('mithril')
var Helper = require('./helper')
var Footer = {
oninit: function(vnode) {
vnode.state.scrollListenerWaiting = []
},
view: function(vnode) {
return [
m('div.outerbox', [
m('div.innerbox', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/contact.svg',
})
},
}),
m('aside', [
m('h3', 'Hafðu samband'),
m('p', `
Sendu okkur tölvupóst og lýstu þínum þörfum. Við munum setja okkur
inn í málin og finna lausnir. Við bjóðum persónulega og
metnaðarfulla þjónustu fyrir alla okkar viðskiptavini.
`),
m('h5', 'nfp@nfp.is'),
]),
]),
m('div.meta', [
m('span', 'Nordic Freelance Partners ehf.'),
m('span', 'nfp@nfp.is'),
m('span', 'kt. 420623-0110'),
m('span', [
'Bakgrunnsmyndir frá ',
m('a', { href: 'https://www.freepik.com/pikisuperstar' }, 'pikisuperstar úr freepik.com'),
]),
]),
]),
]
},
}
/*
<a href="https://www.freepik.com/free-photos-vectors/background">Background vector created by pikisuperstar - www.freepik.com</a>
*/
module.exports = Footer

138
nfp_is/app/front/front.styl Normal file
View file

@ -0,0 +1,138 @@
article {
&.solution {
box-shadow: 0 5px 50px #0005;
background: #e9e9e9;
margin: 0 0 5vh;
height: 800px;
h3 {
font-size: 5vh;
padding: 5vh 20px;
font-weight: bold;
text-align: center;
position: relative;
align-self: center;
.left, .right {
position: absolute;
top: 50%;
margin-top: 0px;
border-bottom: 2px solid #29688c;
}
.left {
right: 100%;
left: -9999px;
}
.right {
left: 100%;
right: -9999px;
}
}
}
&.hosting {
height: 600px;
}
&.programming {
background: #29688c;
background: linear-gradient(150deg, #020024 15%, #29688c 100%);
color: white;
position: relative;
min-height: auto;
height: 70vw;
max-height: 80vh;
min-height: 600px;
section {
}
aside {
align-self: flex-start;
position: relative;
z-index: 2;
margin-top: 5vh;
flex: 1 1 auto;
width: 90%;
max-width: 1440px;
.item {
width: 50%;
min-width: 500px;
text-align: left;
}
}
h3 {
align-self: flex-start;
padding: 10px 0 40px;
}
a {
border-color: white;
color: white;
align-self: flex-start;
}
.image {
position: absolute;
right: 0;
bottom: 0;
width: 87%;
height: 90%;
max-width: none;
background-position: right bottom;
background-size: contain;
}
}
&.video {
min-height: 70vh;
}
}
@media only screen and (max-width: 810px) {
article.solution h3 {
font-size: 2em;
}
}
@media only screen and (max-width: 800px) {
article.programming {
max-height: none;
min-height: auto;
padding: 0 40px 300px;
section {
}
aside {
margin-top: 10px;
width: 100%;
.item {
width: 100%;
min-width: auto;
}
}
h3 {
align-self: center;
}
.image {
width: 100%;
height: 300px;
max-width: none;
background-position: right bottom;
background-size: contain;
transform: translate(50%, 0);
}
.visible.image {
transform: translate(0px, 0px);
}
}
}

239
nfp_is/app/front/index.js Normal file
View file

@ -0,0 +1,239 @@
var m = require('mithril')
var Helper = require('../helper')
var Front = {
oninit: function(vnode) {
Helper.init(vnode, 'frontpage', {
ratio: 0.91,
})
},
view: function(vnode) {
return [
m('header', {
oncreate: function(subnode) {
vnode.state.domContainer = subnode.dom
Helper.checkCreated(vnode)
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
})
},
}, m('div.container', [
!vnode.state.isMobile ? m('video', {
oncreate: function(subnode) {
vnode.state.domVideo = subnode.dom
Helper.checkCreated(vnode)
},
preload: 'none',
loop: true,
muted: true,
playsinline: true,
}, [
m('source', {
src: vnode.state.videoUrl,
type: 'video/mp4',
}),
m('source', {
src: '/assets/cover/frontpage.webm',
type: 'video/webm',
}),
]
) : m('div', {
oncreate: function(subnode) {
vnode.state.domVideo = subnode.dom
Helper.checkCreated(vnode)
},
}),
m('div',
m('img', {
oncreate: function(subnode) {
vnode.state.domImg = subnode.dom
Helper.lazyLoadImage(vnode, 'domImg', '/assets/cover/frontpage.jpg')
Helper.checkCreated(vnode)
},
src: 'data:image/jpeg;base64,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',
})
),
m('nav', [
m(m.route.Link, { class: 'title', href: '/' }, m('span', 'NFP')),
m('div.filler'),
m(m.route.Link, { href: '/hosting-solutions' }, [ 'Hýsingarlausnir', m('div') ]),
m(m.route.Link, { href: '/programming-solutions' }, [ 'Forritunarlausnir', m('div') ]),
m(m.route.Link, { href: '/video-solutions' }, [ 'Videólausnir', m('div') ]),
]),
m('div.content', [
m('h1', 'Nýjir tímar kalla á nýjar lausnir'),
m('h2', '...og við erum með þær'),
]),
])
),
m('main', [
// Solutions
m('article.solution', [
m('h3', [
'Hvað getum við gert fyrir þig?',
m('div.left'),
m('div.right'),
]),
m('section', [
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h5', 'Þínar þarfir'),
m('p', `
Þarfir fólks og fyrirtækja eru margvíslegar og krefjast
oft sérstæðrar nálgunar. Starfslið okkar hefur víðtæka
reynslu í þarfagreiningu og útfærslum á ýmsum sviðum
hins stafræna nútíma.
`),
]),
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h5', 'Okkar lausnir'),
m('p', `
Hvort sem þú ert leitast eftir hýsingu, hugbúnaðargerð,
vefhönnun, streymi- eða upptökulausnum, þá erum við með
þekkinguna og reynsluna. Við erum alltaf tilbúnir til
leiks og elskum taka okkur krefjandi verkefni.
`),
]),
]),
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/solutions.svg',
})
},
}),
]),
]),
// Solutions
m('article.hosting', [
m('section', [
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Hýsingarlausnir'),
m('p', `
Hvort heldur sem þig vantar vefhýsingu, sýndarvélar eða
geymslu og meðhöndlun gagna þá getum við fundið lausn sem
hentar þér.
`),
m(m.route.Link, { class: 'next', href: '/hosting-solutions' }, 'Lesa meira'),
]),
]),
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/hosting.svg',
})
},
}),
]),
]),
// Programming
m('article.programming', [
m('section', [
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Forritunarlausnir'),
m('p', `
Ef þig vantar sérlausn eða aðstoð með þín verkefni þá
getum við hjálpað þér. Við höfum yfir 20 ára reynslu í
forritun og hugbúnaðargerð.
`),
m(m.route.Link, { class: 'next', href: '/programming-solutions' }, 'Lesa meira'),
]),
]),
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/programming.svg',
})
},
}),
]),
]),
// Programming
m('article.video', [
m('section', [
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Streymi- og upptökulausnir'),
m('p', `
Hvort sem er ræða fundi eða ráðstefnur þá tökum við
okkur upptökur og streymingu á þeim. Við höfum margra ára
reynslu og getum unnið í hvaða sal sem er.
`),
m(m.route.Link, { class: 'next', href: '/video-solutions' }, 'Lesa meira'),
]),
]),
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/video.svg',
})
},
}),
]),
]),
]),
]
},
}
/*
<a href="https://www.freepik.com/free-photos-vectors/background">Background vector created by macrovector - www.freepik.com</a>
*/
module.exports = Front

249
nfp_is/app/helper.js Normal file
View file

@ -0,0 +1,249 @@
var Helper = {
init: function(vnode, filename, options) {
vnode.state.domImg = null
vnode.state.domVideo = null
vnode.state.domContainer = null
vnode.state.isMobile = Helper.isMobile()
vnode.state.videoShow = false
vnode.state.videoFilename = filename
vnode.state.resizePauseTimeout = null
vnode.state.resizeTimeout = null
vnode.state.videoResizeThrottler = Helper.resizeThrottler.bind(vnode.state, vnode)
vnode.state.scrollListener = null
vnode.state.scrollListenerWaiting = []
vnode.state.videoVisibilityHidden = ''
vnode.state.videoVisibilityEvent = null
vnode.state.videoVisibilityChanged = null
vnode.state.videoResizeRatio = options && options.ratio || 1
vnode.state.videoUrl = screen.width > 1280
? '/assets/cover/' + filename + '_1080.mp4'
: '/assets/cover/' + filename + '_720.mp4'
},
isMobile: function() {
var check = false;
(function(a) {
if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true
})(navigator.userAgent || navigator.vendor || window.opera);
return check
},
clear: function(vnode) {
vnode.state.scrollListenerWaiting.splice(0, vnode.state.scrollListenerWaiting.length)
window.removeEventListener('resize', vnode.state.videoResizeThrottler)
window.removeEventListener('scroll', vnode.state.scrollListener, false)
window.removeEventListener(vnode.state.videoVisibilityEvent, vnode.state.videoVisibilityChanged)
},
scrollListener: function(vnode) {
if (!vnode.state.scrollListenerWaiting.length) return
var scrollTop = window.pageYOffset
var height = window.innerHeight
for (var i = 0; i < vnode.state.scrollListenerWaiting.length; i++) {
Helper.scrollItemIsVisible(vnode, vnode.state.scrollListenerWaiting[i], scrollTop, height)
}
},
scrollCheckEmpty: function(vnode) {
if (vnode.state.scrollListenerWaiting.length) return
vnode.state.scrollListener = null
window.removeEventListener('scroll', vnode.state.scrollListener, false)
},
scrollAddItem: function(vnode, options) {
var bound = options.dom.getBoundingClientRect()
var scrollTop = window.pageYOffset
var item = {
dom: options.dom,
threshold: options.threshold || 100,
top: Math.round(bound.top) + Math.round(scrollTop),
bottom: Math.round(bound.bottom) + Math.round(scrollTop),
className: ' ' + options.className,
img: options.img || null,
ticking: false,
}
vnode.state.scrollListenerWaiting.push(item)
if (!vnode.state.scrollListener) {
vnode.state.scrollListener = Helper.scrollListener.bind(vnode.state, vnode)
window.addEventListener('scroll', vnode.state.scrollListener, false)
}
Helper.scrollItemIsVisible(vnode, item, window.pageYOffset, window.innerHeight)
},
scrollResetBound: function(vnode) {
var scrollTop = window.pageYOffset
vnode.state.scrollListenerWaiting.forEach(function (item) {
var bound = item.dom.getBoundingClientRect()
item.top = Math.round(bound.top) + Math.round(scrollTop)
})
},
scrollItemIsVisible: function(vnode, item, scrollTop, height) {
if (item.ticking) return
if (item.top - item.threshold < scrollTop + height) {
item.ticking = true
if (item.img) {
Helper.lazyLoadImage(vnode, null, item.img, function() {
item.dom.style.backgroundImage = 'url("' + item.img + '")'
requestAnimationFrame(function() {
item.dom.className += item.className
var index = vnode.state.scrollListenerWaiting.indexOf(item)
if (index >= 0) {
vnode.state.scrollListenerWaiting.splice(index, 1)
}
Helper.scrollCheckEmpty(vnode)
})
})
} else {
requestAnimationFrame(function() {
item.dom.className += item.className
var index = vnode.state.scrollListenerWaiting.indexOf(item)
if (index >= 0) {
vnode.state.scrollListenerWaiting.splice(index, 1)
}
Helper.scrollCheckEmpty(vnode)
})
}
}
},
checkCreated: function(vnode) {
if (!vnode.state.domImg || !vnode.state.domVideo || !vnode.state.domContainer) return
vnode.state.videoShow = Boolean(vnode.state.domVideo.play)
window.addEventListener('resize', vnode.state.videoResizeThrottler, false)
Helper.resizeHandler(vnode)
if (vnode.state.videoShow) {
vnode.state.domVideo.play()
if (typeof document.hidden !== 'undefined') { // Opera 12.10 and Firefox 18 and later support
vnode.state.videoVisibilityHidden = 'hidden'
vnode.state.videoVisibilityEvent = 'visibilitychange'
} else if (typeof document.msHidden !== 'undefined') {
vnode.state.videoVisibilityHidden = 'msHidden'
vnode.state.videoVisibilityEvent = 'msvisibilitychange'
} else if (typeof document.webkitHidden !== 'undefined') {
vnode.state.videoVisibilityHidden = 'webkitHidden'
vnode.state.videoVisibilityEvent = 'webkitvisibilitychange'
}
if (vnode.state.videoVisibilityHidden && vnode.state.videoVisibilityEvent) {
vnode.state.videoVisibilityChanged = Helper.visibilityChanged.bind(this, vnode)
document.addEventListener(vnode.state.videoVisibilityEvent, vnode.state.videoVisibilityChanged, false)
}
}
},
visibilityChanged: function(vnode) {
if (document[vnode.state.videoVisibilityHidden]) {
vnode.state.domVideo.pause()
} else {
vnode.state.domVideo.play()
}
},
resizeThrottler: function(vnode) {
if (vnode.state.videoShow) {
if (!vnode.state.resizePauseTimeout) {
vnode.state.domVideo.pause()
}
clearTimeout(vnode.state.resizePauseTimeout)
vnode.state.resizePauseTimeout = setTimeout(function () {
vnode.state.resizePauseTimeout = null
requestAnimationFrame(function() {
Helper.scrollResetBound(vnode)
vnode.state.domVideo.play()
})
}, 250)
}
if (!vnode.state.resizeTimeout) {
vnode.state.resizeTimeout = setTimeout(function () {
vnode.state.resizeTimeout = null
Helper.resizeHandler(vnode)
}, 66)
}
},
resizeHandler: function(vnode) {
var height = Helper.getHeight(vnode)
var width = document.documentElement.clientWidth
Helper.scaleContainer(vnode, height)
Helper.scaleContainerContent(vnode, 'domImg', true, width, height)
Helper.scaleContainerContent(vnode, 'domVideo', false, width, height)
},
lazyLoadImage: function(vnode, name, url, cb) {
if (!vnode.state[name] && !cb) return
var img = document.createElement('img')
img.onload = function() {
if (cb) {
cb()
} else {
vnode.state[name].src = url
}
}
img.src = url
},
scaleContainer: function(vnode, height) {
if (!vnode.state.domContainer) return
vnode.state.domContainer.setAttribute('style', 'height: ' + height + 'px;')
},
scaleContainerContent: function(vnode, name, forceHeight, width, height) {
if (!vnode.state[name]) return
var videoRatio = 0.5625
var windowRatio = height / width
if (windowRatio > videoRatio) {
var videoWidth = height / videoRatio
var marginFromLeft = -(videoWidth - width) / 2 + 'px'
vnode.state[name].setAttribute('style',
'margin-top: 0; margin-left: ' + marginFromLeft + ';' +
'width: ' + videoWidth + 'px; height: ' + height + 'px')
} else {
if (forceHeight) {
vnode.state[name].setAttribute('style',
'width: ' + width + 'px; height: ' + height + 'px')
} else {
vnode.state[name].setAttribute('style',
'width: ' + width + 'px;')
}
}
},
getHeight: function(vnode) {
var height = document.documentElement.clientHeight + 5
if (height < 485) {
height = 485
} else {
height = height * vnode.state.videoResizeRatio
}
return height
},
}
window.helper = Helper
module.exports = Helper

View file

@ -0,0 +1,202 @@
header.hosting {
h1 {
font-size: 4.3vw;
margin-bottom: 10px;
}
h2 {
font-size: 2.5vw;
}
}
article {
&.hostintro {
.image {
transform: translate(-50%, 0px);
}
.visible.image {
transform: translate(0px, 0px);
}
}
&.hoststorage {
background: #29688c;
background: linear-gradient(150deg, #020024 15%, #29688c 100%);
color: white;
position: relative;
height: 80vh;
min-height: 600px;
section {
justify-content: flex-end;
}
aside {
align-items: center;
max-width: none;
.item {
width: 100%;
max-width: 600px;
text-align: left;
}
}
h3 {
align-self: flex-start;
padding: 10px 0 40px;
}
.image {
position: absolute;
left: 0;
bottom: 0;
width: 50%;
height: 90%;
max-width: none;
background-position: left center;
background-size: contain;
transform: translate(-50%, 0px);
}
.visible.image {
transform: translate(0px, 0px);
}
}
&.hostmanaged {
position: relative;
height: 80vh;
min-height: 600px;
section {
justify-content: flex-end;
}
aside {
align-items: center;
max-width: none;
.item {
padding-left: 20px;
width: 100%;
max-width: 600px;
text-align: left;
}
}
h3 {
align-self: flex-start;
padding: 10px 0 40px;
}
.image {
position: absolute;
left: 0;
bottom: 0;
width: 50%;
height: 90%;
max-width: none;
background-position: left center;
background-size: contain;
transform: translate(-50%, 0px);
}
.visible.image {
transform: translate(0px, 0px);
}
}
}
@media only screen and (max-width: 800px) {
header.hosting {
h1 {
font-size: 2.3em;
}
h2 {
font-size: 1.5em;
}
}
article {
&.hostintro {
h3 {
padding: 30px 0 30px;
}
.image {
transform: translate(0, 50%);
}
.visible.image {
transform: translate(0px, 0px);
}
}
&.hoststorage {
min-height: auto;
padding: 0;
section {
justify-content: flex-start;
padding-bottom: 0;
}
aside {
order: 1;
padding: 0 50px;
}
.image {
width: 100%;
height: auto;
background-position: center;
padding-top: 66%;
position: relative;
order: 2;
}
}
&.hostmanaged {
min-height: auto;
padding: 0;
section {
justify-content: flex-start;
padding-bottom: 0;
}
aside {
order: 1;
padding: 0 50px;
}
aside .item {
padding-left: 0;
}
.image {
position: relative;
width: 100%;
padding-top: 68%;
height: auto;
order: 2;
}
}
}
}
@media only screen and (max-width: 500px) {
article {
&.hoststorage {
aside {
padding: 0 10px;
}
}
&.hostmanaged {
aside {
padding: 0 10px;
}
}
}
}

207
nfp_is/app/hosting/index.js Normal file
View file

@ -0,0 +1,207 @@
var m = require('mithril')
var Helper = require('../helper')
var Hosting = {
oninit: function(vnode) {
Helper.init(vnode, 'hosting')
},
onremove: function(vnode) {
Helper.clear(vnode)
},
view: function(vnode) {
return [
m('header.hosting', {
oncreate: function(subnode) {
vnode.state.domContainer = subnode.dom
Helper.checkCreated(vnode)
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
})
},
}, m('div.container', [
!vnode.state.isMobile ? m('video', {
oncreate: function(subnode) {
vnode.state.domVideo = subnode.dom
Helper.checkCreated(vnode)
},
preload: 'none',
loop: true,
muted: true,
playsinline: true,
}, [
m('source', {
src: vnode.state.videoUrl,
type: 'video/mp4',
}),
m('source', {
src: '/assets/cover/hosting.webm',
type: 'video/webm',
}),
]
) : m('div', {
oncreate: function(subnode) {
vnode.state.domVideo = subnode.dom
Helper.checkCreated(vnode)
},
}),
m('div',
m('img', {
oncreate: function(subnode) {
vnode.state.domImg = subnode.dom
Helper.lazyLoadImage(vnode, 'domImg', '/assets/cover/hosting.jpg')
Helper.checkCreated(vnode)
},
src: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wgARCABaAKADASIAAhEBAxEB/8QAGgAAAwEBAQEAAAAAAAAAAAAAAQIDAAQFBv/EABcBAQEBAQAAAAAAAAAAAAAAAAEAAgP/2gAMAwEAAhADEAAAAfisu652ITFMJkZ5vRZXzRl0L0OdOmc8y1nmutJtHFctzBsVtFkoYmgpWfSeLxpsnSIyaFhWOXqRxm5g0mLo2HEGARqGAr0GiylNNKqobSZB6TNtE+e8am2cUJKJmBDbZexpmih2gBhU0pOqmTZRNptWibplyoihkIrIIVzPc+l25h1x0rz5qxyCzyfDkKJQA406jIQ5WIZSttiy5NTBcRQoT0lUlV0D/8QAHRAAAgMBAQEBAQAAAAAAAAAAAAEQESACMRJBMP/aAAgBAQABBQKy82fvPh0VLEIYznbF7z4OKGhwhjFNlyzn3mHhn6joYi4ssuV7zDw45GP+PPqhllw45GMZe16oeuRsYxZss5FD0hwxFFFFFFCFtilizRQ82WNjFLiyyyz6PoubLLwpYoQ5YtWXCliwoYpelLP/xAAaEQACAwEBAAAAAAAAAAAAAAABEQAQIDBA/9oACAEDAQE/AbVv0vTyjAC6Ii7f/8QAHREAAwEBAQADAQAAAAAAAAAAAAEREBICEyAhMf/aAAgBAgEBPwH8JnWIhBeof3KzoueVRqDYspS6nBu4oMXg+M4H5mcnJzkLDo6G1MXo6LlyE+lLv//EABQQAQAAAAAAAAAAAAAAAAAAAHD/2gAIAQEABj8CcP/EABsQAQEBAQEBAQEAAAAAAAAAAAEAERAhIDFB/9oACAEBAAE/ISepLObM3qExJ4HsPPjb8bxfNMngMft+PibD02ez8d7bL2/PT9cb8BZeS8hnxnn+347jjHwSy+Sj8tnHBZX9l53/AFwNpbx7Py2dtsstsuC4UsMsMxi9l5bK22WeOU8ifMRhGMOMvLZ9sskk4cs8HOBZtlixDGGGG0kSODlb1vHq89memG2Zq1bLPG2ylLLrOP1HG23hiy+R+Dx+o+z83//aAAwDAQACAAMAAAAQQxMUBpQhhWsZvsfymwhtADDvcnRC6d2P9ahJ5zPOwQHzNBJeJ9ae+/zQ637l/8QAGhEAAwEBAQEAAAAAAAAAAAAAAAERECEgMf/aAAgBAwEBPxDpfBuCFIfBKeWLolrqKyl2Y8bxUJrKirVOtHYNglWNbylkyeYTf//EABoRAQEBAQEBAQAAAAAAAAAAAAEAESEQMUH/2gAIAQIBAT8Q24/J58lfPAJO5zJxMBiBXT43BI8bjl1JkcQMsWnn4Jfpvt27YXkqbfEqTwJtygg1tl2wbG5sCd4yPDuzHwdY6nEngypUtrf/xAAbEAEBAQEBAQEBAAAAAAAAAAABABEhEDFBIP/aAAgBAQABPxBCQOwrGJ5ckX7ATl8JLXxU8jw5ehWcjL8nZWy8uU9N8I+2ZDF44+79w0uGcfviqOLOyM8PmfMPZz150mZ46od8KDYyTuMEdXG0L53D6pjcSly2vnz8eDu3l3ZeS74JNJyx50J147ep0Q43EAwn2W+WM7CbIycy5nBF2j+AkbcbhC2d8E/JNllk2TLS8keI9Byu3K4Slbvg3bM8V2fJuvgIIO363Hjp66JdMsHwCM5bCEHG4XSH9uXqQQ+TxL4CzhjC6TF5kp+w74eEPJjfg5zxPl4XazOy1jUlQ8ly2VmTPo+19JIXx4Pfz7PiPD6+h6//2Q==',
})
),
m('nav', [
m(m.route.Link, { class: 'title', href: '/' }, m('span', 'NFP')),
m('div.filler'),
m(m.route.Link, { class: 'active', href: '/hosting-solutions' }, [ 'Hýsingarlausnir', m('div') ]),
m(m.route.Link, { href: '/programming-solutions' }, [ 'Forritunarlausnir', m('div') ]),
m(m.route.Link, { href: '/video-solutions' }, [ 'Videólausnir', m('div') ]),
]),
m('div.content', [
m('h1', 'Hýsingarlausnir sem þú getur treyst'),
m('h2', 'SÝNDARVÉLAR, WORDPRESS, GEYMSLUHÝSING, OG HVAÐ EINA!'),
]),
])
),
m('main', [
// Solutions
m('article.hostintro', [
m('section', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/hostintro.svg',
})
},
}),
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Vefhýsing'),
m('p', `
Við getum boðið okkar viðskiptavinum upp á margskonar
lausnir þegar kemur hýsa þeirra vefi. Meðal þess sem
við höfum reynslu af er setja upp sýndarvélar sem þú
getur haft fulla umsjá með og gert hvað svo sem þig lystir
með en einnig sérhæfum okkur í bjóða upp á
alsherjarlausnir þar sem við sjáum um alla uppsetningu og
umsjón svo þú getir haft athyglina á öðrum þáttum
reksturs þíns.
`),
m('p', `
Ef þig vantar Wordpress/PHP uppsetningu eða hefur sérhæfða
síðu og vilt nota docker eða node þá munar okkur ekki um
það. Okkar kerfi geta séð um mæta þínum þörfum hverjar
sem þær eru.
`),
]),
]),
]),
]),
m('article.hoststorage', [
m('section', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/hostfile.svg',
})
},
}),
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Gagnageymslur og skölun myndefnis'),
m('p', `
Örugg geymsla gagna er sífellt mikilvægari þáttur fyrir
fyrirtæki. NFP hefur boðið upp á gagnageymslu fyrir
fyrirtæki til geyma sín afrit eða vinnslugögn sem
starfsmenn geta haft aðgang og unnið með hvar sem
þeir eru staddir í heiminum.
`),
m('p', `
Við getum einnig séð um hvers kyns meðhöndlun myndgagna
svo sem endurkóðun upptökuefnis til lágmarka rýmisþörf
með bestu mögulegu gæðum eða skölun á myndum fyrir
vefsíðubirtingar. Lausnir okkar eru skilvirkar og
afkastamiklar.
`),
]),
]),
]),
]),
m('article.hostmanaged', [
m('section', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/hostmanaged.svg',
})
},
}),
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Láttu okkur sjá um viðhaldið'),
m('p', `
Það getur verið kúnst viðhalda sýndarvélum og
heimasíðum og Það er ekki á allra hendi framkvæma
Wordpress uppfærslur eða prófanir á öryggisafritum.
`),
m('p', `
Þú átt geta einbeitt þér þínu sérsviði. Þess vegna
bjóðum við upp á sjá um allt sem kemur viðhaldi og
gæðaeftirliti. Við fylgjumst vel með þróuninni, gerum
reglulegar uppfærslur og tryggjum allt virki sem
skildi.
`),
]),
]),
]),
]),
]),
]
},
}
/*
<a href="https://www.freepik.com/free-photos-vectors/background">Background vector created by macrovector - www.freepik.com</a>
*/
module.exports = Hosting

42
nfp_is/app/index.js Normal file
View file

@ -0,0 +1,42 @@
/**
* @license
* NFP <https://nfp.is>
* Copyright 2018 Jonatan Nilsson <http://jonatan.nilsson.is/>
*
* Available under WTFPL License (http://www.wtfpl.net/txt/copying/)
*/
'use strict'
//Add debug components to window. Allows us to play with controls
//in the console.
window.components = {}
var m = require('mithril')
m.route.setOrig = m.route.set
m.route.set = function(path, data, options){
m.route.setOrig(path, data, options)
window.scrollTo(0, 0)
}
m.route.linkOrig = m.route.link
m.route.link = function(vnode){
m.route.linkOrig(vnode)
window.scrollTo(0, 0)
}
var Front = require('./front')
var Hosting = require('./hosting')
var Programming = require('./programming')
var Streaming = require('./streaming')
var Footer = require('./footer')
m.route.prefix = ''
m.route(document.getElementById('container'), '/', {
'/': Front,
'/hosting-solutions': Hosting,
'/programming-solutions': Programming,
'/video-solutions': Streaming,
})
m.mount(document.getElementById('footer'), Footer)

View file

@ -0,0 +1,205 @@
var m = require('mithril')
var Helper = require('../helper')
var Programming = {
oninit: function(vnode) {
Helper.init(vnode, 'programming')
},
onremove: function(vnode) {
Helper.clear(vnode)
},
view: function(vnode) {
return [
m('header.programming', {
oncreate: function(subnode) {
vnode.state.domContainer = subnode.dom
Helper.checkCreated(vnode)
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
})
},
}, m('div.container', [
!vnode.state.isMobile ? m('video', {
oncreate: function(subnode) {
vnode.state.domVideo = subnode.dom
Helper.checkCreated(vnode)
},
preload: 'none',
loop: true,
muted: true,
playsinline: true,
}, [
m('source', {
src: vnode.state.videoUrl,
type: 'video/mp4',
}),
m('source', {
src: '/assets/cover/programming.webm',
type: 'video/webm',
}),
]
) : m('div', {
oncreate: function(subnode) {
vnode.state.domVideo = subnode.dom
Helper.checkCreated(vnode)
},
}),
m('div',
m('img', {
oncreate: function(subnode) {
vnode.state.domImg = subnode.dom
Helper.lazyLoadImage(vnode, 'domImg', '/assets/cover/programming.jpg')
Helper.checkCreated(vnode)
},
src: ' data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pLSwzOko+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0//wgARCABaAKADASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAQIDAAQF/8QAFwEBAQEBAAAAAAAAAAAAAAAAAQACA//aAAwDAQACEAMQAAAB8adF6cJioGIqprZ2RWdHICE0FoBe/PXXNpOqQleOO3YCmuZyGXA0F50gqyICGNYOsEgpObzztZUnnp1HDfPBhSYqaLzeHDFyuc0qNKnE0NUmozsqcPVhPfOw58NxHTXSNdTSOudMi00gpoqQaG2HY6qCra5846lnnFgMxUUrYVRAKzK7bNnKFtShsVWiUrkKKApqtefocvLoVxzC6G5CoGaXgKhBno4XT//EABsQAAMBAQEBAQAAAAAAAAAAAAABERAgMBIC/9oACAEBAAEFAnkITqlHixof5GvN8TaUfcITiE4ePKPaUomXwePxXVPo+hsvknkyD8aUvCFtGy+DKUpcQtflCEIQmXqEIQhMhCE2HzyvC9JHyP8AJCEJtKUvaPzr5fP/xAAaEQADAAMBAAAAAAAAAAAAAAAAAREQEiAC/9oACAEDAQE/AUUpS4oxU88PlC4eKI1EsQ1NSEIJcU2KXLKXEz6EylEQh//EABkRAAIDAQAAAAAAAAAAAAAAAAARASAwEP/aAAgBAgEBPwG8cnKcGPrGO6EIWUUkYz//xAAUEAEAAAAAAAAAAAAAAAAAAABw/9oACAEBAAY/AnD/xAAcEAEBAQEBAQADAAAAAAAAAAABABEQICEwMUH/2gAIAQEAAT8hWyeFkFkFudvqD7OPAKT4SyILISQWcBDnLXLZPMsmEJk2RwyDrZTwrbeWnKxeDxifdnHgemz5CXxlknN8DODJZPneuLS+Xzwb0M2fLLyGyl8t4pss9Jw+cZkQbZeB6AwNjm1mWX3asT8LZY4GZ4ZFI4PN4JLnnDhx8H8np4/rl8f/2gAMAwEAAgADAAAAEBr/AJK106M1iZzHPUQsF7qTyBHmplEJPpqBT2lWE8Kfxs8s7ywQsqGwhiTaN5D/xAAbEQEBAQEBAAMAAAAAAAAAAAABABEQITFRYf/aAAgBAwEBPxBZCiMNWHB+rCSxtljajZ2Gb4djEHoDAYSI1yR8zDUJAW23mKX92jAStWoXjPYIZJDhT1g2L//EABkRAQEBAQEBAAAAAAAAAAAAAAEAERAhIP/aAAgBAgEBPxBsLIJL2zhyBNt5GT8PwY5krKlcXPibbLPfU9nssWFhIW2y8IWWXi1av//EAB0QAQEBAQEBAAMBAAAAAAAAAAEAERAhMSBBUWH/2gAIAQEAAT8QSas1/wATi1suQt4mEid8MoBey14Z2LIttJx4Pq+YmBl/OXeDfqQZxObQtb25ARjYgpBBycQkrwfEHYJAJk8S96BWyMdEGC0t9ivEvDOHkJyzMXjIkhlm3rBJ+Q+yeRoxk9jgE3eXK8YHbUqaVIZaQaRC4sfk0q2TtlllggFjktKpiNkZacOIYJq28sssmWPyVatWrcu8R7l4NbTKkbIGxsySG8XrPM6SE6z5tbdtJ4vqDln8FDrhhxvLS+SH6hk7YsD15YXgWCHJhYIWZZvLaVIPkH8hP1A35CRiTJ1aJq5bJl5edl+EFnvOQn2/i//Z',
})
),
m('nav', [
m(m.route.Link, { class: 'title', href: '/' }, m('span', 'NFP')),
m('div.filler'),
m(m.route.Link, { href: '/hosting-solutions' }, [ 'Hýsingarlausnir', m('div') ]),
m(m.route.Link, { class: 'active', href: '/programming-solutions' }, [ 'Forritunarlausnir', m('div') ]),
m(m.route.Link, { href: '/video-solutions' }, [ 'Videólausnir', m('div') ]),
]),
m('div.content', [
m('h1', 'Sérfræðingar í forritun'),
m('h2', 'Meira en 20 ára reynsla!'),
]),
])
),
m('main', [
// Solutions
m('article.programmingintro', [
m('section', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/programmingintro.svg',
})
},
}),
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Vefsíðuforritun'),
m('p', `
Með margra ára reynslu í forritun og yfirgripsmikla
þekkingu þegar kemur vefsíðugerð, er ekkert sem stoppar
okkur í leysa krefjandi verkefni. Hvort heldur sem um
er ræða útfærslu á hönnun og innleiðing hennar í
HTML/CSS eða uppsetningu greiðslugátta og áskriftaleiða
hjá mismunandi aðilum þá erum við sérfræðingar á því
sviði.
`),
m('p', `
Við getum unnið með hvaða forritunartungumál sem er.
Hvaða tækni sem þú notar, node, python, C# eða hvað
annað tungumál, þá látum við ekkert stoppa okkur.
`),
]),
]),
]),
]),
m('article.programmingstore', [
m('section', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/programmingstore.svg',
})
},
}),
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Sölukerfi og vefverslun'),
m('p', `
Við höfum hannað og þróað sölukerfi frá grunni í síðuformi.
Það er byggt til vera einfalt í notkun og henta fyrir
lítil og meðalstór fyrirtæki. Sölukerfið býður upp á
pantanakerfi, verkbókhald og birgðakerfi sem og
vefverslunarframenda og tengingu við posa.
`),
m('p', `
Við getum aðlagað vefverslunarframendanum til passa
fyrir hvert fyrirtæki og þeirra vöruframboði. Við vinnum
náið með hverjum og einum viðskiptavini og skilum af okkur
lausn sem uppfyllir þarfir þeirra.
`),
]),
]),
]),
]),
m('article.programmingcontracting', [
m('section', [
m('div.image', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
img: '/assets/images/programmingcontractor.svg',
})
},
}),
m('aside', [
m('div.item', {
oncreate: function(subnode) {
Helper.scrollAddItem(vnode, {
dom: subnode.dom,
className: 'visible',
threshold: -100,
})
},
}, [
m('h3', 'Verktakavinna'),
m('p', `
Ef það er tímapressa hjá þér, þá getum við komið beint
til ykkar og unnið verktakavinnu á ykkar vinnustað. Við
getum unnið náið með ykkar fólki og aðlagast hvaða
vinnureglum sem er.
`),
m('p', `
Okkar fólki hefur verið vel tekið hvert sem við förum og
við höfum ætíð kappkostað skila frá okkur góðu verki.
Hverjar svo sem sem vandamálin kunna liggja þá
geturðu treyst því við munum finna lausn á þeim
saman og redda málunum.
`),
]),
]),
]),
]),
]),
]
},
}
/*
<a href="https://www.freepik.com/free-photos-vectors/background">Background vector created by macrovector - www.freepik.com</a>
*/
module.exports = Programming