feat: added latex generation
3
content/articles/hiring/a4.tex.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
data:
|
||||
structure: ./index.yml
|
||||
generator: article
|
||||
BIN
content/articles/hiring/cover.png
Normal file
|
After Width: | Height: | Size: 168 KiB |
BIN
content/articles/hiring/img1.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
5
content/articles/hiring/index.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
title: How to hire engineers, by an engineer
|
||||
cover: cover.png
|
||||
published: 2022-03-16
|
||||
parts:
|
||||
- main.md
|
||||
30
content/articles/hiring/main.md
Normal file
@@ -0,0 +1,30 @@
|
||||
It has been a few years since I have been part of the recruitment process. Still, I did reasonably go through the hiring process when looking for a new job so that I will mix a bit from both sides for this article, so you get both some experience from hires and what worked and experience from the other side of the table and what caused my not to consider a company, because spoiler alert: Engineers are contacted a lot!
|
||||
|
||||
So first I need to introduce a hard truth as this will be underpining a lot of my points and is most likely the most important take away from this: Your company is not unique
|
||||
|
||||
Unless your tech brand is among the X highest regarded in the world, your company alone isn't a selling point. I have been contacted by so many companies which thought because they were leader in their field or had a "great product" that makes candidates come banging at their door. If I could disclose all those messages it would be really easy to see that except for the order of information all says almost the same thing, and chances are you job listing is the same. Sorry.
|
||||
The take away from this is that if everything is equal any misstep in your hiring process can cost you that candidate, so if you are not amongst the strongest of tech brands you need to be extremely aware or you will NOT fill the position
|
||||
|
||||
Okay after that slap in the face we can take a second to look at something...
|
||||
|
||||
A lot of people focuses on skills when hirering, and of cause the candidate should have the skills for the position, but I will make a case to put less focus on the hard skills and more focus on passion.
|
||||
|
||||
Usually screening skills through an interview is hard and techniques like code challenges has their own issues, but more on that later.
|
||||
Screening for passion is easier, usually you can get a good feeling if a candidate is passionate about a specific topic, and passionate people want to learn! So even if the candidate has limited skills, if they have passion they will learn and they will outgrow a candidate with experience but no passion.
|
||||
Filling a team with technically skills can solve an immediate requirement, but companies, teams and products change, your requirements will change along with it. Building a passionate team will adjust and evolve along where a product where a team consisting of skilled people but without passion will stay where they where when you hired them.
|
||||
|
||||
Another issue I see in many job postings is requiring a long list of skills. It would be awesome to find someone skilled in everything and who could solve all tasks. In the real world, when ever you add another skill to that list you are limiting the list of candidates that would fit so chances are you are not going to find anyone or the actual skills of any candidate in that very narrow list will be way lower than in a wider pool.
|
||||
A better way is to just add the most important skills, and learn the candidate any less important skills at the job. If you hired passionate people this should be possible (remember to screen for passion about learning new things)
|
||||
|
||||
While we are on the expected skill list: A lot of companies has this list of "it would be really nice if you had these skills". Well those could definitely be framed as learning experiences instead. If you have recruited passionate people, seeing that you will learn new cool skills count as a plus and any candidate who already have the skill will see it and think "awesome, I am already uniquely suited for the job!"
|
||||
|
||||
I promised to talk a bit about code challenges: They can be useful to screen a candidates ability to just go in and start to work from day one, and if done correctly can help a manager organise their process to best suit the teams unique skills but...
|
||||
Hiring at the moment is hard! And as stated pretty much any job listing I have seen are identical, so as in a competitive job market where a small outlier on your resumé lands you in the pile never read through, as likely is it in a competitive hiring market that your listing never gets acted upon.
|
||||
Engineers are contacted a lot by recruiters and speaking to all would require a lot of work so if a company has a prolonged process it quickly gets sorted out, especially by the best candidates whom most likely get contacted the most and most likely have a full time job so time is a scarce resource.
|
||||
So be aware that if you use time consuming processes such as the code challenge you might miss out on the best candidates.
|
||||
|
||||

|
||||
|
||||
Please just disclose the salary range. From being connected to a few hundred recruiters here on LinkedIn I can see that this isn't just me but a general issue. As mentioned before, it takes very little to have your listings ignored and most likely most of your strongest potential candidates already has full time jobs, and would not want to move to a position paying less unless the position where absolutely unique (which again, yours most likely isn't). Therefore if you choose not to disclose the salary range be aware that you miss out on most of the best candidates. A company will get an immediate no from me if not disclosing the salary range.
|
||||
|
||||
Lastly, I have spend a lot of words telling your that your company or position isn't unique, and well we both know that is not accurate, your company most likely has something unique to offer! Be that soft values or hard benefits. Be sure to put them in your job listing, to bring out this uniqueness, it is what is going to set you apart from the other listing. There are lot of other companies with the same tech stack, using an agile approach, with a high degree of autonomy, with a great team... But what can you offer that no one else can? Get it front and center... Recruiting is marketing and good copy writing
|
||||
3
content/articles/hyperconnect/a4.tex.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
data:
|
||||
structure: ./index.yml
|
||||
generator: article
|
||||
10
content/articles/hyperconnect/authentication.md
Normal file
@@ -0,0 +1,10 @@
|
||||
we will need a way for our devices to identify with one and another, and since we might not have access to any particular node in the system at the time of authentication, this needs to work without a trusted third party at the time of connection.
|
||||
|
||||
The best way I can think of here is to use a signing authority.
|
||||
|
||||
Our authentication will consist of two main concept; a passport and a passport authority.
|
||||
|
||||
Each device will create a passport, which contains some various information but most important is a public key coresponding to a private key stored on the device. A device then has to go through a "claim process" where a user assign it as their device. this happens by that uses passport authority uses a private key to sign the device's passport, and giving it the authorities public key.
|
||||
|
||||
Now our device has a signed passport, and the oublic key of the authority, so when two devices needs to connect they can now go through an authentication process to verify each others passport. If both devices verifies the other device's passport as valid the connection can be established.
|
||||
|
||||
6
content/articles/hyperconnect/definition.md
Normal file
@@ -0,0 +1,6 @@
|
||||
What does hyper-connectivity mean? Well, a common interpretation is to be available on multiple different channels. We al know that one guy whom you contact on text message only to get a reply on Signal, just to get a follow up using email.
|
||||
|
||||
Then what does it mean for devices to be hyper connected? In this case it means using all available forms of communication in order to get data from one place to another, which is what this article is about.
|
||||
|
||||
Today, when a developer want a system to send data from one place to another he needs to pick a transport protocol such as http. Then connect
|
||||
|
||||
25
content/articles/hyperconnect/index.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
title: Creating a hyper connectivity framework
|
||||
parts:
|
||||
- title: definition
|
||||
file: definition.md
|
||||
- title: reason
|
||||
- title: target
|
||||
- title: design
|
||||
notes: |
|
||||
onion based stream
|
||||
4 way streams
|
||||
- title: connection
|
||||
notes: |
|
||||
peerjs, tcp, ble(?)
|
||||
session id
|
||||
- title: reconnection
|
||||
- title: authentication
|
||||
file: authentication.md
|
||||
notes: |
|
||||
passport service
|
||||
- title: security
|
||||
notes: |
|
||||
diff-hellman
|
||||
- title: transport-nodes
|
||||
- title: proof-of-concept
|
||||
- title: conclusion
|
||||
3
content/articles/my-home-runs-redux/a4.tex.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
data:
|
||||
structure: ./index.yml
|
||||
generator: article
|
||||
BIN
content/articles/my-home-runs-redux/cover.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
content/articles/my-home-runs-redux/graph.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
5
content/articles/my-home-runs-redux/index.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
title: My home runs Redux
|
||||
cover: cover.png
|
||||
published: 2022-03-15
|
||||
parts:
|
||||
- main.md
|
||||
83
content/articles/my-home-runs-redux/main.md
Normal file
@@ -0,0 +1,83 @@
|
||||
I have been playing around with smart homes for a long time; I have used most of the platforms out there, I have developed quite a few myself, and one thing I keep coming back to is Redux.
|
||||
|
||||
Those who know what Redux is may find this a weird choice, but for those who don't know Redux, I'll give a brief introduction to get up to speed.
|
||||
|
||||
Redux is a state management framework, initially built for a React talk by Dan Abramov and is still primarily associated with managing React applications. Redux has a declarative state derived through a "reducer"-function. This reducer function takes in the current state and an event, and, based on that event, it gives back an updated state. So you have an initial state inside Redux, and then you dispatch events into it, each getting the current state and updating it. That means that the resulting state will always be the same given the same set of events.
|
||||
|
||||
So why is a framework primarily used to keep track of application state for React-based frontends a good fit for a smart home? Well, your smart home platform most likely closely mimics this architecture already!
|
||||
|
||||
First, an event goes in, such as a motion sensor triggering, or you set the bathroom light to 75% brightness in the interface. This event then goes into the platform and hits some automation or routine, resulting in an update request getting sent to the correct devices, which then change the state to correspond to the new state.
|
||||
|
||||
...But that is not quite what happens on most platforms. Deterministic events may go into the system, but this usually doesn't cause a change to a deterministic state. Instead, it gets dispatched to the device, the devices updates, the platform sees this change, and then it updates its state to represent that new state.
|
||||
|
||||
This distinction is essential because it comes with a few drawbacks:
|
||||
|
||||
* Because the event does not change the state but sends a request to the device that does it, everything becomes asynchronous and can happen out of order. This behaviour can be seen either as an issue or a feature, but it does make integrating with it a lot harder from a technical point of view.
|
||||
* The request is sent to the device as a "fire-and-forget" event. It then relies on the success of that request and the subsequent state change to be reported back from the device before the state gets updated. This behaviour means that if this request fails (something you often see with ZigBee-based devices), the device and the state don't get updated.
|
||||
* Since the device is responsible for reporting the state change, you are dependent on having that actual device there to make the change. Without sending the changes to the actual device, you cannot test the setup.
|
||||
|
||||
So can we create a setup that gets away from these issues?
|
||||
|
||||
Another thing to add here is more terminology/philosophy, but most smart home setups are, in my opinion, not really smart, just connected and, to some extent, automated. I want a design that has some actual smartness to it. In this article, I will outline a setup closer to that of the connected, automated home, and at the end, I will give some thoughts on how to take this to the next level and make it smart.
|
||||
|
||||
We know what we want to achieve, and Redux can help us solve this. Remember that Redux takes actions and applies them in a deterministic way to produce a deterministic state.
|
||||
|
||||
Time to go a bit further down the React rabbit hole because another thing from React-land comes in handy here: the concept of reconciliation.
|
||||
|
||||
Instead of dispatching events to the devices waiting for them to update and report their state back, we can rely on reconciliation to update our device. For example, let's say we have a device state for our living room light that says it is at 80% brightness in our Redux store. So now we dispatch an event that sets it to 20% brightness.
|
||||
|
||||
Instead of sending this event to the device, we update the Redux state.
|
||||
|
||||
We have a state listener that detects when the state changes and compares it to the state of the actual device. In our case, it seems that the state indicates that the living room light should be at 20% but are, in fact, at 80%, so it sends a request to the actual device to update it to the correct value.
|
||||
|
||||
We can also do schedule reconciliation to compare our Redux state to that of the actual devices. If a device fails to update its state after a change, it will automatically get updated on our next scheduled run, ensuring that our smart home devices always reflect our state.
|
||||
|
||||
_Sidenote: Yes, of course, I have done a proof of concept using React with a home build reconciliation that reflected the virtual dom unto physical devices, just to have had a house that ran React-Redux_
|
||||
|
||||
Let's go through our list of issues with how most platforms handle this. We can see that we have eliminated all of them by switching to this Redux-reconciliation approach: we update the state directly to run it synchronously. We can re-run the reconciliation so failed or dropped device updates get re-run. We don't require any physical devices as our state is directly updated.
|
||||
|
||||
We now have a robust, reliable, state management mechanism for our smart home, time to add some smarts to it. It is a little outside the article's main focus as this is just my way of doing it; there may be way better ways, so use it at your discretion.
|
||||
|
||||
Redux has the concept of middlewares which are stateful functions that live between the event going into Redux and the reducer updating the state. These middlewares allow Redux to deal with side effects and do event transformations.
|
||||
|
||||
Time for another piece of my smart home philosophy: Most smart homes act on events, and I have used the word throughout this article, but to me, events are not the most valuable thing when creating a smart home, instead I would argue that the goal is to deal with intents rather than events. For instance, an event could be that I started to play a video on the TV. But, that state a fact, what we want to do is instead capture what I am trying to achieve, the "intent", so lets split this event into two intents; if the video is less than one hour, I want to watch a TV show, if it is more I want to watch a movie.
|
||||
|
||||
These intents allow us to not deal with weak-meaning events to do complex operations but instead split our concern into two separate concepts: intent classification and intent execution.
|
||||
|
||||
So last thing we need is a direct way of updating devices, as we can not capture everything through our intent classifier. For instance, if I sit down to read a book that does not generate any sensor data for our system to react to, I will still need a way to adjust device states manually. (I could add a button that would dispatch a reading intent)
|
||||
|
||||
I have separated the events going into Redux into two types:
|
||||
|
||||
* control events, which directly controls a device
|
||||
* environment events represent sensor data coming in (push on a button, motion sensor triggering, TV playing, etc.)
|
||||
|
||||
Now comes the part I have feared, where I need to draw a diagram.
|
||||
|
||||
...sorry
|
||||
|
||||
|
||||

|
||||
|
||||
So this shows our final setup.
|
||||
|
||||
Events go into our Redux setup, either environment or control.
|
||||
|
||||
Control events go straight to the reducer, and the state is updated.
|
||||
|
||||
Environment events first go to the intent classifier, which uses previous events, the current state, and the incoming event to derive the correct intent. The intent then goes into our intent executor, which converts the intent into a set of actual device changes, which gets sent to our reducer, and the state is then updated.
|
||||
|
||||
Lastly, we invoke the reconciliation to update our real devices to reflect our new state.
|
||||
|
||||
There we go! Now we have ended up with a self-contained setup. We can run it without the reconciliation or mock it to create tests for our setup and work without changing any real devices, and we can re-run the reconciliation on our state to ensure our state gets updated correctly, even if a device should miss an update.
|
||||
|
||||
**Success!!!**
|
||||
|
||||
But I promised to give an idea of how to take this smart home and make it actually "smart."
|
||||
|
||||
Let's imagine that we did not want to "program" our smart home. Instead, we wanted to use it; turning the lights on and off using the switches when we entered and exited a room, dimming the lights for movie time, and so on, and over time we want our smart home to pick up on those routines and start to do them for us.
|
||||
|
||||
We have a setup where we both have control events and environments coming in. Control events represent how we want the state of our home to be in a given situation. Environment events represent what happened in our home. So we could store those historically with some machine learning and look for patterns.
|
||||
|
||||
Let's say you always dim the light when playing a movie that is more than one hour long; your smart home would be able to recognize this pattern and automatically start to do this routine for you.
|
||||
|
||||
Would this work? I don't know. I am trying to get more skilled at machine learning to find out.
|
||||
3
content/articles/npm-safety/index.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
title: NPM safety
|
||||
parts:
|
||||
- main.md
|
||||
12
content/articles/npm-safety/main.md
Normal file
@@ -0,0 +1,12 @@
|
||||
The NPM eco system has hade a long list of stories about major dependencies turning evil lately, either by direct involvment from the package maintainer or due to the maintainer being compromised. What ever the reason, it does bring in to focus the dangers of package managers!
|
||||
|
||||
The threat landscaoe being what it is it is tine that we as developers start ti apply a little extra operational security to mitigate some of the risk that comes from installing unaudited oackages, which are in essence just arbitrary executing code which can conceil a viper virus or a remote access token as easily as a random email attachment.
|
||||
|
||||
So what can we do to protect ourselfs? we can split the attacks into to groups, one which attacks the users of our application and one that attacks our selves and our CI/CD pipelines
|
||||
|
||||
Combating the former is hard and here the only thing short of manually auditing every change in every depebdebcy is to set up monitoring of dependencies with vulnerabilities and freeze dependencies versions to known good versions
|
||||
|
||||
The later attack type is the one this article is going to focus on.
|
||||
|
||||
A NPM oackage has the ability to run post install hooks, which essentially allow it to execute any code as the current user upon installing the dependency. This allows a malicius oackage to infect your system upon installation by also installing malware or running malicious commands. This can be mitigated by disable install hooks, but some packages have legitinate use cases for these install hooks.
|
||||
|
||||
3
content/experiences/bilzonen/description.md
Normal file
@@ -0,0 +1,3 @@
|
||||
I work as a part-time web developer on bilzonen.dk. I have worked with both day-to-day maintenance and large scale projects (new search module, integration of new data catalog, mobile site, new-car-catalog and the entire dealer solution).
|
||||
|
||||
The page is an Umbraco solution, with all .NET (C#) code. I have introduced a new custom build provider-model system, which allows data-providers to move data between data stores, external services, and the site. (search, caching and external car date is running through the provider system). Also, i have set up the development environment, from setting up virtual server hosts to building custom tool for building and unit testing.
|
||||
6
content/experiences/bilzonen/index.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
company:
|
||||
name: BilZonen
|
||||
webpage: http://www.bilzonen.dk
|
||||
title: Web developer
|
||||
startDate: '2010'
|
||||
endDate: '2012'
|
||||
3
content/experiences/haastrup-it/description.md
Normal file
@@ -0,0 +1,3 @@
|
||||
I have worked as a part time project koordinator and systems developer, sitting with responsibility for a wide variety of projects including projects for "Københavns Kommune" (Navision reporting software) and "Syddanmarks kommune" (Electronic application processing system).
|
||||
|
||||
Most projects were made in C#, but also PHP, VB, ActionScript. In addtion to that i maintained the in-house hosting setup.
|
||||
5
content/experiences/haastrup-it/index.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
company:
|
||||
name: Haastrup IT
|
||||
title: Web Developer
|
||||
startDate: '2009'
|
||||
endDate: '2010'
|
||||
8
content/experiences/sampension/description.md
Normal file
@@ -0,0 +1,8 @@
|
||||
Sampension is a danish pension fund.
|
||||
Initially, I was hired to help build the frontend and the architecture of their new digital self-service product ("Sampension" on Apple App Store or Google Play Store).
|
||||
|
||||
The project was to create a single code base that could handle both iOS, Android and web and be responsive/adaptive to be able to give a great UX on both mobile, tablets as well as desktop computers. The product is created using React Native and React Native Web and currently has around 96% shared code between the different platforms.
|
||||
|
||||
Additionally, I have been working on CI/CD and various DevOps related tasks to build up the tooling around the product (AWS S3, AWS Lambda, AWS Cloudfront, Github, Github Actions, Azure DevOps, Azure, etc.)
|
||||
|
||||
I am also currently working with some initial project analysis for new projects and I have begun maintaining some of our backend code (C#)
|
||||
6
content/experiences/sampension/index.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
company:
|
||||
name: Sampension
|
||||
website: https://www.sampension.dk
|
||||
title: Senior Frontend Developer
|
||||
startDate: '2018-01'
|
||||
endDate: '2020-12'
|
||||
1
content/experiences/sydbank/description.md
Normal file
@@ -0,0 +1 @@
|
||||
I work as a part-time supporter of customers (private and business) and staff, on Sydbanks different electronic banking systems. Mostly telephonic bug finding and PC setup.
|
||||
6
content/experiences/sydbank/index.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
company:
|
||||
name: Sydbank
|
||||
website: https://www.sydbank.dk
|
||||
title: IT Hotline
|
||||
startDate: '2007'
|
||||
endDate: '2009'
|
||||
@@ -0,0 +1,9 @@
|
||||
I became responsible for the iOS platform, which was a task that required a new app to be built from the ground up using _Xamarin_.
|
||||
|
||||
In addition to that, a new API to support the app along with support for our larger vendors was needed which had to be build using something closely similar to _Microsoft MVC_ so that other people could join the project at a later stage.
|
||||
|
||||
The project started in October with the initial version available to our users in late December.
|
||||
|
||||
This project represented my first adventure into mobile development and became an app with more than 15 million screen views and 1.5 million sessions per month.
|
||||
|
||||
After that, I joined two other colleagues, who were working on an Android version of the app, to form a join mobile development team. Throughout the period I also worked on the backend for the web page from time to time.
|
||||
6
content/experiences/trendsales-app-developer/index.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
company:
|
||||
name: Trendsales
|
||||
website: https://www.trendsales.dk
|
||||
title: iOS and Android Developer
|
||||
startDate: '2012'
|
||||
endDate: '2015'
|
||||
8
content/experiences/trendsales-tech-lead/description.md
Normal file
@@ -0,0 +1,8 @@
|
||||
In 2015 Trendsales decided to build an entirely new platform. It became my responsibility to create a modernized frontend architecture. The work began in 2016 with just me on the project and consisted of a proof of concept version containing everything from framework selection, structure, style guides build chain, continuous deployment, and an actual initial working version. The result where the platform which I was given technical ownership over and which I, along with two others, worked on expanding over the next year. The platform is currently powering _m.trendsales.dk_.
|
||||
|
||||
The project is build using React and state management are done using Redux. In addition to the of the shelve frameworks, we also needed to develop quite a few bespoke frameworks, in order to meet demands. Among others, these were created to solve the following issues:
|
||||
|
||||
* Introducing a new navigational paradigm
|
||||
* Create a more flexible routing mechanism
|
||||
* Be able to serve skeleton page, for page transitions while still being able to create complete server-side pages
|
||||
* Ensure project flows between multiple systems such as Github, Jira, Octopus Deploy, AppVeyor and Docker
|
||||
6
content/experiences/trendsales-tech-lead/index.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
company:
|
||||
name: Trendsales
|
||||
website: https://www.trendsales.dk
|
||||
title: Frontend Technical Lead
|
||||
startDate: '2016'
|
||||
endDate: '2018'
|
||||
@@ -0,0 +1 @@
|
||||
I got a part-time job at Trendsales, where my primary responsibility was maintaining the API which powered the iOS app. Quickly my tasks became more diverse, and I ended using about 25-50% of my time on the API, while the remaining was spend doing work on the platform in general.
|
||||
6
content/experiences/trendsales-web-developer/index.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
company:
|
||||
name: Trendsales
|
||||
website: https://www.trendsales.dk
|
||||
title: Web Developer
|
||||
startDate: '2012'
|
||||
endDate: '2012'
|
||||
0
content/experiences/zeronorth/description.md
Normal file
5
content/experiences/zeronorth/index.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
company:
|
||||
name: ZeroNorth
|
||||
website: https://www.zeronorth.com
|
||||
title: Senior software engineer
|
||||
startDate: '2021'
|
||||
1
content/profile/a4.tex.yml
Normal file
@@ -0,0 +1 @@
|
||||
generator: resume
|
||||
22
content/profile/index.yml
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Morten Olsen
|
||||
tagline: “...One part genius, one part crazy”
|
||||
avatar: me.jpg
|
||||
email: hello@buy-me.coffee
|
||||
location: Copenhagen, DK
|
||||
social:
|
||||
- name: Github
|
||||
link: https://github.com/morten-olsen
|
||||
logo: logos/github.svg
|
||||
- name: HackTheBox
|
||||
link: https://app.hackthebox.eu/profile/174098
|
||||
logo: logos/htb.svg
|
||||
- name: Stack Overflow
|
||||
link: https://stackoverflow.com/users/1689055/morten-olsen
|
||||
logo: logos/stackoverflow.svg
|
||||
- name: Codingame
|
||||
link: https://www.codingame.com/profile/8b34b1812baa75715c972bfe190c0aed4552622
|
||||
logo: logos/codingame.svg
|
||||
- name: Linkedin
|
||||
link: https://www.linkedin.com/in/mortenolsendk
|
||||
logo: logos/linkedin.svg
|
||||
|
||||
1
content/profile/logos/codingame.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 2083 2083" xmlns="http://www.w3.org/2000/svg" width="2500" height="2500"><path d="M0 0h2083v2083H0z" fill="transparent"/><g fill="#1f2528"><path d="M0 1636c411.554-97.771 692.897-283.177 724-637 10.714-131.212 67.364-243.777 216-319 207.675-80.617 305.728-52.164 390-10 92.668 81.722 119.468 199.94 50 371.5-31.914 100.266-291.001 223.867-410 258.5-392.539 175.893-595.504 430.282-561 783H0z"/><ellipse cx="1666.5" cy="408" rx="196.5" ry="192"/></g></svg>
|
||||
|
After Width: | Height: | Size: 559 B |
1
content/profile/logos/github.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="2500" viewBox="0 0 999.937 999.937"><path d="M0 499.968c0-138.012 48.825-255.843 146.476-353.493C244.125 48.825 361.956 0 499.969 0 637.98 0 755.811 48.825 853.462 146.475c97.649 97.65 146.475 215.481 146.475 353.493s-48.825 255.843-146.475 353.493c-97.65 97.65-215.481 146.476-353.493 146.476-138.013 0-255.844-48.825-353.493-146.476C48.825 755.812 0 637.979 0 499.968zm54.684 0c0 122.389 43.617 227.199 130.851 314.434 87.234 87.233 192.045 130.851 314.434 130.851 122.388 0 227.199-43.617 314.433-130.851 87.234-87.234 130.851-192.045 130.851-314.434 0-122.388-43.616-227.199-130.851-314.433C727.168 98.301 622.356 54.684 499.969 54.684c-122.389 0-227.199 43.617-314.434 130.851C98.301 272.769 54.684 377.58 54.684 499.968zm140.617 107.415c-2.604-2.604-2.604-5.208 0-7.812 5.207-5.208 11.718-7.161 19.529-5.859 7.812 1.302 12.369 2.604 13.671 3.906 9.114 3.906 19.205 12.694 30.271 26.366 11.066 13.671 19.855 23.11 26.366 28.318 31.248 26.04 63.146 27.993 95.696 5.859 2.604-9.114 6.836-16.926 12.694-23.437 5.858-6.51 11.393-11.066 16.601-13.671 5.209-2.604 14.323-6.51 27.343-11.718-42.967-3.906-77.795-11.393-104.486-22.46s-47.849-25.063-63.473-41.989c-20.832-23.436-33.527-54.033-38.084-91.791-4.558-37.758-1.628-72.261 8.789-103.509 7.812-19.53 18.879-37.106 33.2-52.731-10.416-32.55-8.463-69.657 5.859-111.321 41.664 2.604 79.422 16.926 113.274 42.966 65.1-16.926 132.804-17.577 203.111-1.953 9.114-6.51 23.111-14.647 41.989-24.413 18.879-9.765 42.641-15.299 71.285-16.601 5.208 14.322 8.789 31.248 10.742 50.778s.977 37.758-2.929 54.684c29.945 31.248 45.569 72.912 46.871 124.992 0 41.664-7.16 76.167-21.482 103.509s-39.711 50.127-76.167 68.354c-24.738 11.719-57.288 18.879-97.65 21.483 18.229 9.114 31.574 18.554 40.037 28.319 8.464 9.765 13.997 25.063 16.602 45.895v61.521l1.952 59.566c3.906 6.511 8.464 12.044 13.672 16.602 5.208 4.557 9.765 7.812 13.671 9.765 3.905 1.953 5.208 4.883 3.905 8.789-1.302 3.906-6.51 5.859-15.623 5.859-22.135 0-39.711-7.812-52.731-23.437-3.906-6.51-5.859-14.321-5.859-23.436v-93.744c0-10.416-2.604-17.903-7.812-22.46-5.208-4.558-10.416-7.487-15.624-8.789v123.039c0 22.134 2.604 36.456 7.812 42.966s8.463 13.021 9.766 19.53c1.302 1.302.325 2.278-2.93 2.929-3.254.65-8.788-.325-16.601-2.929-16.926-3.906-28.644-12.695-35.154-26.366-6.51-13.671-9.765-28.319-9.765-43.943V667.926H488.25v121.086c0 15.624-3.256 30.598-9.766 44.919-9.113 18.229-26.04 27.993-50.777 29.295-3.906-1.302-5.859-2.604-5.859-3.905 1.302-1.303 5.208-7.812 11.718-19.53 1.302-2.604 2.93-7.812 4.883-15.624 1.954-7.812 2.93-16.926 2.93-27.342v-123.04c-5.208 1.302-10.091 4.231-14.648 8.789s-6.836 12.044-6.836 22.46v93.744c0 9.113-1.953 16.926-5.859 23.436-11.718 15.624-29.295 23.437-52.73 23.437-9.114 0-14.322-1.953-15.624-5.859-1.303-2.604-.977-4.883.977-6.836s4.883-4.232 8.789-6.836c3.906-2.604 6.51-4.558 7.812-5.859 5.208-3.906 9.113-9.114 11.718-15.624 3.906-5.208 4.882-18.879 2.929-41.013s-2.279-36.456-.977-42.966c-33.853 11.718-68.355 5.858-103.51-17.577-10.416-10.416-20.832-25.39-31.248-44.919-7.812-14.323-23.436-31.249-46.871-50.779z"/></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
9
content/profile/logos/htb.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 33 33" style="enable-background:new 0 0 176 33;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#000;}
|
||||
</style>
|
||||
<path class="st1" d="M28.6,9.3C28.6,9.3,28.6,9.3,28.6,9.3c0-0.3-0.1-0.6-0.4-0.8c0,0,0,0,0,0c0,0,0,0-0.1-0.1c0,0-0.1,0-0.1-0.1 c0,0,0,0,0,0L15.6,1.2c0,0-0.1,0-0.1,0C15.3,1,15.1,1,14.9,1c-0.1,0-0.2,0-0.3,0.1c-0.1,0-0.1,0.1-0.2,0.1L2,8.3c0,0,0,0,0,0 c0,0,0,0,0,0c0,0,0,0,0,0C1.8,8.4,1.7,8.5,1.7,8.6c0,0,0,0,0,0C1.5,8.8,1.4,9,1.4,9.3c0,0,0,0,0,0c0,0,0,0,0,0v14.3 c0,0.4,0.2,0.8,0.6,1l12.4,7.2c0,0,0,0,0.1,0c0,0,0,0,0,0c0.1,0,0.1,0.1,0.2,0.1c0,0,0,0,0,0c0.1,0,0.2,0,0.2,0s0.2,0,0.2,0 c0,0,0,0,0,0c0.1,0,0.1,0,0.2-0.1c0,0,0,0,0,0c0,0,0,0,0.1,0l12.4-7.2c0.4-0.2,0.6-0.6,0.6-1L28.6,9.3C28.6,9.4,28.6,9.3,28.6,9.3z M6.3,8.9L14.7,4c0.2-0.1,0.4-0.1,0.5,0l8.4,4.9c0.4,0.2,0.4,0.7,0,0.9l-8.4,4.9c-0.2,0.1-0.4,0.1-0.5,0L6.3,9.8 C5.9,9.6,5.9,9.1,6.3,8.9z M13.5,27.4c0,0.4-0.4,0.7-0.8,0.5L4.3,23C4.1,22.9,4,22.7,4,22.5v-9.7c0-0.4,0.4-0.7,0.8-0.5l8.4,4.9 c0.2,0.1,0.3,0.3,0.3,0.5V27.4z M25.9,22.5c0,0.2-0.1,0.4-0.3,0.5l-8.4,4.9c-0.4,0.2-0.8-0.1-0.8-0.5v-9.7c0-0.2,0.1-0.4,0.3-0.5 l8.4-4.9c0.4-0.2,0.8,0.1,0.8,0.5V22.5z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
42
content/profile/logos/linkedin.svg
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="93.06px" height="93.06px" viewBox="0 0 93.06 93.06" style="enable-background:new 0 0 93.06 93.06;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M11.185,0.08C5.004,0.08,0.001,5.092,0,11.259c0,6.173,5.003,11.184,11.186,11.184c6.166,0,11.176-5.011,11.176-11.184 C22.362,5.091,17.351,0.08,11.185,0.08z"/>
|
||||
<rect x="1.538" y="30.926" width="19.287" height="62.054"/>
|
||||
<path d="M69.925,29.383c-9.382,0-15.673,5.144-18.248,10.022h-0.258v-8.479H32.921H32.92v62.053h19.27V62.281 c0-8.093,1.541-15.932,11.575-15.932c9.89,0,10.022,9.256,10.022,16.451v30.178H93.06V58.942 C93.06,42.235,89.455,29.383,69.925,29.383z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
content/profile/logos/logo.svg
Normal file
|
After Width: | Height: | Size: 12 KiB |
36
content/profile/logos/resume.svg
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="windows-1252"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 370.123 370.123" style="enable-background:new 0 0 370.123 370.123;" xml:space="preserve">
|
||||
<path d="M321.321,18.74H310.78c0-10.352-8.39-18.74-18.74-18.74H78.083c-10.352,0-18.74,8.389-18.74,18.74H48.802 c-10.351,0-18.74,8.389-18.74,18.74c0,10.351,8.39,18.74,18.74,18.74h12.279l22.132,296.557c0.73,9.781,8.879,17.346,18.688,17.346 h166.322c9.809,0,17.957-7.564,18.686-17.346l22.133-296.557h12.279c10.351,0,18.74-8.39,18.74-18.74 C340.061,27.129,331.672,18.74,321.321,18.74z M119.297,332.643l-7.47-100.061h34.125c8.242,17.324,22.939,28.11,39.109,28.11 c16.17,0,30.867-10.786,39.109-28.11h34.125l-7.471,100.061H119.297z M263.007,169.469h-38.836 c-8.242-17.324-22.939-28.114-39.109-28.114c-16.17,0-30.867,10.79-39.109,28.114h-38.836L98.665,56.221h172.793L263.007,169.469z"/>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
content/profile/logos/stackoverflow.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 333333 333333" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"><path d="M322831 117669l-25376 33059-2-2-17596 37756-4-2-9020 40667-203391-45092-2 2 9020-40681 203308 45065-188724-88000v-2l17606-37772 188714 87992L132160 23894 150493 0h18967l153372 117669zM62501 229173h208330v41665l-208330-4v-41661z" fill="#000"/><path fill="#000" d="M333333 208338v124995H0V208338h41665v83330h250003v-83330z"/></svg>
|
||||
|
After Width: | Height: | Size: 553 B |
BIN
content/profile/me.jpg
Normal file
|
After Width: | Height: | Size: 558 KiB |