This challenge was part of 2019's qualifiers, but should still be solvable.

Welcome to this year's **code golf** challenge! As a golfer, your task will be to implement an **image filter** in JavaScript, using the **shortest code** you can possibly write.

You're encouraged to break every coding best-practice, use every obscure trick in the book, and sneak through holes in the quizmaster's test suite (while avoiding its traps), but you **cannot** use any external code or make remote connections of any kind.

### The Context

Inside most image processing software, and many machine learning pipelines, lies an operation called a **convolution**, a fancy name for a bunch of multiplications and sums to produce effects such as blurring, sharpening, embossing, or edge detection.

Given an image and a small two-dimensional array of numbers – called a **convolution matrix** or a **kernel** – center the matrix on a pixel and **multiply** that pixel and each of its neighbors by their corresponding matrix positions. Then, the new center pixel is the **sum** of these individual multiplications, **divided** by the sum of the matrix's values.

Doing this to all the pixels in an image is called an **image convolution**, and the final division step is called **normalization**.

These are the basics, enough to get you through this challenge, but you should also watch this short computerphile video or check out this wikipedia article for more technical details. But first, let's find out what's **required** for this challenge…

### The Challenge

For this challenge you must write a JavaScript function "`f`" taking four parameters and returning a new image filtered according to some arbitrary convolution matrix:

function f(width, height, image, matrix) { return image; }

The `image` is an `Uint8Array` of colors in RGB order, the `matrix` is a 3x3 array of **floats**, and the return value is an `Uint8Array` matching the input `image`.

The convolution should be applied to each color channel **separately** and out-of-image positions in the convolution matrix should be matched with the the **nearest** edge pixel.

Skip normalization if the convolution matrix sums to **zero** and **clamp** values that end up too small or too big to fit an 8-bit range.

### Testing Your Code

The image and convolution matrix below are run against whatever code you enter into the answer box. The quizmaster will check your answer using more than just one input image and convolution matrix, so devise your own tests to catch possible corner cases.

The simplest convolution matrix is called the identity and does nothing. Other known matrices include shift down, mean blur, sharpen, gaussian blur, edges, or emboss.

Remember that **nothing** will happen until **you** make it happen by writing some code below. Also, keep an eye on the JavaScript console, as messages will appear there.

**Note:** The execution engine used to validate answers is **unspecified** and support for bleeding edge features and syntax is **not guaranteed**. The only thing you can assume is that the testing environment will remain **unchanged** throughout the whole challenge.

### Challenge Answer

Submit your code for review using the form below. Since this a competition for the shortest answer, you can override previous submissions until the challenge closes, but beware: at that point only your **last answer** will count. Avoid dying on the beach!

If you have questions, go to the `#quizshow` channel on Slack and ask away (sign up if you're not there yet). This page may get updated as well, with hints or clarifications.