# A Complete Guide to Managing Arrays with React's useState Hook

%%[kempo] 

The introduction of hooks made state management much easier in React.

With the `useState` hook, you're given a tuple where the first element is the current state and the second element is a function used to update that state. For primitive types like strings, using this hook to manage the state is straightforward.

But what about complex data types, like *arrays*?

The main thing to remember when working with arrays in React is that you don't want to *mutate* the array. React can't detect the change, so your UI won't update how you expect it to:

<iframe src="https://kempo.io/view/eyJpZCI6ImtsX2lyYTR5Mmhjdmx6MWllazdjdnQxNnN0byIsIm5hbWUiOiJSZWFjdCB1c2VTdGF0ZSBBcnJheSBFeGFtcGxlIiwiY29yZSI6eyJmaWxlcyI6eyIvc3R5bGVzLmNzcyI6eyJjb2RlIjoiYm9keSB7XG4gIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmO1xuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhdXRvO1xuICAtbW96LWZvbnQtc21vb3RoaW5nOiBhdXRvO1xuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xuICBmb250LXNtb290aGluZzogYXV0bztcbiAgdGV4dC1yZW5kZXJpbmc6IG9wdGltaXplTGVnaWJpbGl0eTtcbiAgZm9udC1zbW9vdGg6IGFsd2F5cztcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgLXdlYmtpdC10b3VjaC1jYWxsb3V0OiBub25lO1xufVxuXG4uYnRuIHtcbiAgQGFwcGx5IGZvbnQtYm9sZCBweS0yIHB4LTQgcm91bmRlZDtcbn1cbi5idG4tYmx1ZSB7XG4gIEBhcHBseSBiZy1ibHVlLTUwMCB0ZXh0LXdoaXRlO1xufVxuLmJ0bi1ibHVlOmhvdmVyIHtcbiAgQGFwcGx5IGJnLWJsdWUtNzAwO1xufVxuIn0sIi9BcHAuanMiOnsiY29kZSI6ImltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBCdXR0b24gfSBmcm9tIFwiLi9CdXR0b25cIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkge1xuICBjb25zdCBbbGlzdCwgc2V0TGlzdF0gPSB1c2VTdGF0ZShbMV0pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJmbGV4IGZsZXgtY29sIGdhcC0yXCI+XG4gICAgICA8c3BhbiBjbGFzc05hbWU9XCJ0ZXh0LWNlbnRlciB0ZXh0LWxnXCI+e2xpc3RbMF19PC9zcGFuPlxuXG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXgganVzdGlmeS1jZW50ZXIgZ2FwLTRcIj5cbiAgICAgICAgPEJ1dHRvblxuICAgICAgICAgIG9uQ2xpY2s9eygpID0+IHtcbiAgICAgICAgICAgIGxpc3RbMF0gPSBsaXN0WzBdICogMjtcbiAgICAgICAgICAgIHNldExpc3QobGlzdCk7XG4gICAgICAgICAgfX1cbiAgICAgICAgPlxuICAgICAgICAgIE11dGF0ZSBBcnJheSAoQmFkKVxuICAgICAgICA8L0J1dHRvbj5cblxuICAgICAgICA8QnV0dG9uXG4gICAgICAgICAgb25DbGljaz17KCkgPT4ge1xuICAgICAgICAgICAgc2V0TGlzdChbbGlzdFswXSAqIDJdKTtcbiAgICAgICAgICB9fVxuICAgICAgICA+XG4gICAgICAgICAgVXBkYXRlIEFycmF5IChHb29kKVxuICAgICAgICA8L0J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICApO1xufVxuIn0sIi9pbmRleC5qcyI6eyJjb2RlIjoiaW1wb3J0IFJlYWN0LCB7IFN0cmljdE1vZGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IGNyZWF0ZVJvb3QgfSBmcm9tIFwicmVhY3QtZG9tL2NsaWVudFwiO1xuaW1wb3J0IFwiLi9zdHlsZXMuY3NzXCI7XG5cbmltcG9ydCBBcHAgZnJvbSBcIi4vQXBwXCI7XG5cbmNvbnN0IHJvb3QgPSBjcmVhdGVSb290KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKFwicm9vdFwiKSk7XG5yb290LnJlbmRlcihcbiAgPFN0cmljdE1vZGU+XG4gICAgPEFwcCAvPlxuICA8L1N0cmljdE1vZGU+XG4pOyJ9LCIvcHVibGljL2luZGV4Lmh0bWwiOnsiY29kZSI6IjwhRE9DVFlQRSBodG1sPlxuPGh0bWwgbGFuZz1cImVuXCI+XG4gIDxoZWFkPlxuICAgIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICAgIDxtZXRhIG5hbWU9XCJ2aWV3cG9ydFwiIGNvbnRlbnQ9XCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wXCI+XG4gICAgPHRpdGxlPkRvY3VtZW50PC90aXRsZT5cbiAgPC9oZWFkPlxuICA8Ym9keT5cbiAgICA8ZGl2IGlkPVwicm9vdFwiPjwvZGl2PlxuICA8L2JvZHk+XG48L2h0bWw+In0sIi9wYWNrYWdlLmpzb24iOnsiY29kZSI6IntcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwicmVhY3RcIjogXCJeMTguMC4wXCIsXG4gICAgXCJyZWFjdC1kb21cIjogXCJeMTguMC4wXCIsXG4gICAgXCJyZWFjdC1zY3JpcHRzXCI6IFwiXjUuMC4wXCJcbiAgfSxcbiAgXCJtYWluXCI6IFwiL2luZGV4LmpzXCIsXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHt9XG59In0sIi9CdXR0b24udHN4Ijp7ImNvZGUiOiJleHBvcnQgY29uc3QgQnV0dG9uID0gKHByb3BzKSA9PiAoXG4gIDxidXR0b25cbiAgICB7Li4ucHJvcHN9XG4gICAgY2xhc3NOYW1lPVwiYmctc2t5LTUwMCBob3ZlcjpiZy1za3ktNzAwIHRleHQtc2xhdGUtMTAwIGZvbnQtYm9sZCBweS0yIHB4LTQgcm91bmRlZFwiXG4gIC8+XG4pO1xuIn19LCJ0ZW1wbGF0ZSI6InJlYWN0In0sImRpc3BsYXkiOnsiY29tcG9uZW50cyI6eyJFZGl0b3IiOnsidHlwZSI6ImVkaXRvciIsImRhdGEiOnsic2hvd1RhYnMiOnRydWUsInNob3dMaW5lTnVtYmVycyI6dHJ1ZSwic2hvd0lubGluZUVycm9ycyI6ZmFsc2UsInNob3dSdW5CdXR0b24iOnRydWUsIndyYXBDb250ZW50Ijp0cnVlLCJjbG9zYWJsZVRhYnMiOnRydWUsInJlYWRPbmx5IjpmYWxzZSwic2hvd1JlYWRPbmx5IjpmYWxzZX19LCJQcmV2aWV3Ijp7InR5cGUiOiJwcmV2aWV3IiwiZGF0YSI6eyJzaG93TmF2aWdhdG9yIjpmYWxzZSwic2hvd09wZW5JbkNvZGVTYW5kYm94IjpmYWxzZSwic2hvd1JlZnJlc2hCdXR0b24iOnRydWUsInNob3dTYW5kcGFja0Vycm9yT3ZlcmxheSI6ZmFsc2V9fX0sImdlbmVyYWwiOnsidmlzaWJsZUZpbGVzIjpbIi9BcHAuanMiXSwidGhlbWUiOiJrZW1wb0RhcmsiLCJleHRlcm5hbFJlc291cmNlcyI6WyJodHRwczovL2Nkbi50YWlsd2luZGNzcy5jb20iXX0sImxheW91dHMiOnsic21hbGwiOiInRWRpdG9yJ1xuJ0VkaXRvcidcbidFZGl0b3InXG4nUHJldmlldycifX19" height="750px" width="100%"></iframe>

In this example, each button is supposed to double the value shown. But when you click the **Mutate Array** button, nothing seems to happen. This is because we're mutating the state and then calling `setList` with the same array *reference*. Because the reference is the *same*, React *thinks* the array hasn't changed and bails out of the re-render.

This is an optimization that React does internally where if you pass the *same* state as the current state to the updater function, React ignores the update.

> Note: If you click the Mutate Button a few times and then click the Update Button, you'll notice that the value more than doubles. This is because both buttons reference the same list variable.
> 
> Technically the Mutate Button does update the value, React just doesn't know about it until the Update Button is clicked and setList is called with a new array reference.

So how do you handle this?

## When updating arrays in React state, create a new array.

Instead of mutating the existing array, use it as the starting point to create a new array.

Let's take a look at a few examples:

### How to add an element to an array

```javascript
function ListOfNumbers() {
    const [list, setList] = useState([1]);
    return (
        <div>
            {/**
              * It's not a good practice to use the index
              * as the key, but hey this is just an example.
              */}
            {list.map((item, index) => <span key={index}>{item}</span>)}
            <button onClick={() => setList([...list, Math.random()])}>
                Add Item
            </button>
        </div>
    );
}
```

In this example, when you click the button element, we:

1. Create a new list
    
2. [Spread the existing list into the new list](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
    
3. Append a random number to the end of the list
    

The spread operator is a quick way to create a new array using the values of an existing array.

### How to remove an element from a list

```javascript
function ListOfNumbers() {
    const [list, setList] = useState([1, 2, 3, 4]);
    return (
        <div>
            {list.map((item, index) => <span key={index}>{item}</span>)}
            <button onClick={() => setList(list.slice(1))}>
                Remove First Item
            </button>
        </div>
    );
}
```

This time when the button is clicked, we *slice* off the first element. The [slice array method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) returns a *copy* of the original array, which makes it safe to use with React state.

> Note: On the other hand, the [splice array method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)*mutates* the existing array and is therefore not a good fit for React state management.

### How to update elements in an array

Let's say we have a list of numbers and want to double each array element when you click a button. In this case, we can use the `map` function to handle this:

```javascript
function ListOfNumbers() {
    const [list, setList] = useState([1, 2, 3, 4]);
    return (
        <div>
            {list.map((item, index) => <span key={index}>{item}</span>)}
            <button onClick={() => setList(list.map(item => item * 2))}>
                Double Items
            </button>
        </div>
    );
}
```

What if we wanted to update a *specific* array element? Luckily you can use the `map` function for this too!

```javascript
function ListOfNumbers() {
    const [list, setList] = useState([1, 2, 3, 4]);
    return (
        <div>
            {list.map((item, index) => <span key={index}>{item}</span>)}
            <button onClick={() => {
                setList(list.map(
                    (item, index) => index === 2 ? item * 2 : item
                ));
            }}>
                Double Items
            </button>
        </div>
    );
}
```

Notice how we're checking the `index` in our `map` function and we only double the item if it's the 3rd element (arrays start with the index `0`).

### How to safely mutate an array

Let's say you're trying to update your array and the easiest option to solve your problem is to reach for a built-in utility that mutates your array. For example, maybe you want to reverse the order of your array using the [reverse array method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse). Since I said don't *mutate* your arrays, what should you do?

**Make a copy of your array first!**

The easiest thing to do is to use the spread operator to create a new copy of the array *first*. After you make the copy, you're free to mutate it however you want:

```javascript
function ListOfNumbers() {
    const [list, setList] = useState([1, 2, 3, 4]);
    return (
        <div>
            {list.map((item, index) => <span key={index}>{item}</span>)}
            <button onClick={() => {
                const listCopy = [...list];
                listCopy.reverse(); // It's safe to mutate the copy
                setList(listCopy);
            }}>
                Reverse Items
            </button>
        </div>
    );
}
```

While the approach above will work in most cases, there's one major flaw.

The spread operator only creates a *shallow* clone of the original array. In other words, if you have an array of *objects*, each object within the cloned array will still reference the same object as the original array.

**So how do you update objects within an array?**

You do the same thing you did to update the array. You make a *copy* of the object you want to update using the spread operator:

```javascript
function ListOfPeople() {
    const [list, setList] = useState([
        { id: 1, name: 'Jack' },
        { id: 2, name: 'Jill' }
    ]);

    return (
        <div>
            {list.map((item) => <span key={item.id}>{item.name}</span>)}
            <button onClick={() => {
                // This creates a new object for each item,
                // copies the old object, and updates the name.
                setList(list.map(item => ({
                    ...item,
                    name: item.name.toUpperCase()
                })));
            }}>
                Capitalize Names
            </button>
        </div>
    );
}
```

Awesome!

Now let's put all that together and take a look at a live running example:

<iframe src="https://kempo.io/view/eyJpZCI6ImtsX2lyYTR5Mmhjdmx6MWllazdjdnQxNnN0byIsIm5hbWUiOiJSZWFjdCB1c2VTdGF0ZSBBcnJheSBFeGFtcGxlIiwiY29yZSI6eyJmaWxlcyI6eyIvc3R5bGVzLmNzcyI6eyJjb2RlIjoiYm9keSB7XG4gIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmO1xuICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhdXRvO1xuICAtbW96LWZvbnQtc21vb3RoaW5nOiBhdXRvO1xuICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1xuICBmb250LXNtb290aGluZzogYXV0bztcbiAgdGV4dC1yZW5kZXJpbmc6IG9wdGltaXplTGVnaWJpbGl0eTtcbiAgZm9udC1zbW9vdGg6IGFsd2F5cztcbiAgLXdlYmtpdC10YXAtaGlnaGxpZ2h0LWNvbG9yOiB0cmFuc3BhcmVudDtcbiAgLXdlYmtpdC10b3VjaC1jYWxsb3V0OiBub25lO1xufVxuXG4uYnRuIHtcbiAgQGFwcGx5IGZvbnQtYm9sZCBweS0yIHB4LTQgcm91bmRlZDtcbn1cbi5idG4tYmx1ZSB7XG4gIEBhcHBseSBiZy1ibHVlLTUwMCB0ZXh0LXdoaXRlO1xufVxuLmJ0bi1ibHVlOmhvdmVyIHtcbiAgQGFwcGx5IGJnLWJsdWUtNzAwO1xufVxuIn0sIi9BcHAuanMiOnsiY29kZSI6ImltcG9ydCB7IHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBCdXR0b24sIEljb25CdXR0b24gfSBmcm9tIFwiLi9CdXR0b25cIjtcblxubGV0IGlkID0gMTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwKCkge1xuICBjb25zdCBbY291bnRlcnMsIHNldENvdW50ZXJzXSA9IHVzZVN0YXRlKFt7IGlkOiAwLCB2YWx1ZTogMCB9XSk7XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXggZmxleC1jb2wgZ2FwLTIgcC00XCI+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXgganVzdGlmeS1jZW50ZXIgZ2FwLTRcIj5cbiAgICAgICAgPEJ1dHRvblxuICAgICAgICAgIG9uQ2xpY2s9eygpID0+IHNldENvdW50ZXJzKFsuLi5jb3VudGVycywgeyBpZDogaWQrKywgdmFsdWU6IDAgfV0pfVxuICAgICAgICA+XG4gICAgICAgICAgQWRkIENvdW50ZXJcbiAgICAgICAgPC9CdXR0b24+XG5cbiAgICAgICAgPEJ1dHRvbiBvbkNsaWNrPXsoKSA9PiBzZXRDb3VudGVycyhjb3VudGVycy5zbGljZSgxKSl9PlxuICAgICAgICAgIFJlbW92ZSBGaXJzdCBDb3VudGVyXG4gICAgICAgIDwvQnV0dG9uPlxuXG4gICAgICAgIDxCdXR0b25cbiAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB7XG4gICAgICAgICAgICAvLyBDcmVhdGUgYSBjbG9uZSBvZiB0aGUgY291bnRlcnNcbiAgICAgICAgICAgIC8vIGFycmF5IGJlZm9yZSByZXZlcnNpbmcgaXQuXG4gICAgICAgICAgICBjb25zdCBjb3VudGVyc0Nsb25lID0gWy4uLmNvdW50ZXJzXTtcbiAgICAgICAgICAgIGNvdW50ZXJzQ2xvbmUucmV2ZXJzZSgpO1xuICAgICAgICAgICAgc2V0Q291bnRlcnMoY291bnRlcnNDbG9uZSk7XG4gICAgICAgICAgfX1cbiAgICAgICAgPlxuICAgICAgICAgIFJldmVyc2UgQ291bnRlcnNcbiAgICAgICAgPC9CdXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDx1bCBjbGFzc05hbWU9XCJmbGV4IGZsZXgtY29sIGdhcC0yXCI+XG4gICAgICAgIHtjb3VudGVycy5tYXAoKGNvdW50ZXIsIGluZGV4KSA9PiAoXG4gICAgICAgICAgPGxpXG4gICAgICAgICAgICBjbGFzc05hbWU9XCJmbGV4IGdhcC0yIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlclwiXG4gICAgICAgICAgICBrZXk9e2NvdW50ZXIuaWR9XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxnXCI+XG4gICAgICAgICAgICAgIENvdW50ZXIgKHtjb3VudGVyLmlkfSkge2NvdW50ZXIudmFsdWV9XG4gICAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgIG9uQ2xpY2s9eygpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBjbG9uZSBvZiB0aGUgY291bnRlclxuICAgICAgICAgICAgICAgIC8vIG9iamVjdCB3ZSB3YW50IHRvIHVwZGF0ZS5cbiAgICAgICAgICAgICAgICBzZXRDb3VudGVycyhcbiAgICAgICAgICAgICAgICAgIGNvdW50ZXJzLm1hcCgoYywgaSkgPT5cbiAgICAgICAgICAgICAgICAgICAgaSA9PT0gaW5kZXggPyB7IC4uLmMsIHZhbHVlOiBjLnZhbHVlICsgMSB9IDogYyxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgKyBJbmNyZW1lbnRcbiAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICA8L2xpPlxuICAgICAgICApKX1cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gICk7XG59XG4ifSwiL2luZGV4LmpzIjp7ImNvZGUiOiJpbXBvcnQgUmVhY3QsIHsgU3RyaWN0TW9kZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgY3JlYXRlUm9vdCB9IGZyb20gXCJyZWFjdC1kb20vY2xpZW50XCI7XG5pbXBvcnQgXCIuL3N0eWxlcy5jc3NcIjtcblxuaW1wb3J0IEFwcCBmcm9tIFwiLi9BcHBcIjtcblxuY29uc3Qgcm9vdCA9IGNyZWF0ZVJvb3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXCJyb290XCIpKTtcbnJvb3QucmVuZGVyKFxuICA8U3RyaWN0TW9kZT5cbiAgICA8QXBwIC8+XG4gIDwvU3RyaWN0TW9kZT5cbik7In0sIi9wdWJsaWMvaW5kZXguaHRtbCI6eyJjb2RlIjoiPCFET0NUWVBFIGh0bWw+XG48aHRtbCBsYW5nPVwiZW5cIj5cbiAgPGhlYWQ+XG4gICAgPG1ldGEgY2hhcnNldD1cIlVURi04XCI+XG4gICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjBcIj5cbiAgICA8dGl0bGU+RG9jdW1lbnQ8L3RpdGxlPlxuICA8L2hlYWQ+XG4gIDxib2R5PlxuICAgIDxkaXYgaWQ9XCJyb290XCI+PC9kaXY+XG4gIDwvYm9keT5cbjwvaHRtbD4ifSwiL3BhY2thZ2UuanNvbiI6eyJjb2RlIjoie1xuICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJyZWFjdFwiOiBcIl4xOC4wLjBcIixcbiAgICBcInJlYWN0LWRvbVwiOiBcIl4xOC4wLjBcIixcbiAgICBcInJlYWN0LXNjcmlwdHNcIjogXCJeNS4wLjBcIlxuICB9LFxuICBcIm1haW5cIjogXCIvaW5kZXguanNcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge31cbn0ifSwiL0J1dHRvbi50c3giOnsiY29kZSI6ImV4cG9ydCBjb25zdCBCdXR0b24gPSAocHJvcHMpID0+IChcbiAgPGJ1dHRvblxuICAgIHsuLi5wcm9wc31cbiAgICBjbGFzc05hbWU9XCJiZy1za3ktNTAwIGhvdmVyOmJnLXNreS03MDAgdGV4dC1zbGF0ZS0xMDAgZm9udC1ib2xkIHB5LTIgcHgtNCByb3VuZGVkXCJcbiAgLz5cbik7XG5cbmV4cG9ydCBjb25zdCBJY29uQnV0dG9uID0gKHByb3BzKSA9PiAoXG4gIDxidXR0b25cbiAgICB7Li4ucHJvcHN9XG4gICAgY2xhc3NOYW1lPVwiYmctZ3JheS0zMDAgaG92ZXI6YmctZ3JheS00MDAgdGV4dC1ncmF5LTgwMCBmb250LWJvbGQgcHktMiBweC00IHJvdW5kZWQgaW5saW5lLWZsZXggaXRlbXMtY2VudGVyXCJcbiAgLz5cbik7XG4ifX0sInRlbXBsYXRlIjoicmVhY3QifSwiZGlzcGxheSI6eyJjb21wb25lbnRzIjp7IkVkaXRvciI6eyJ0eXBlIjoiZWRpdG9yIiwiZGF0YSI6eyJzaG93VGFicyI6dHJ1ZSwic2hvd0xpbmVOdW1iZXJzIjp0cnVlLCJzaG93SW5saW5lRXJyb3JzIjpmYWxzZSwic2hvd1J1bkJ1dHRvbiI6dHJ1ZSwid3JhcENvbnRlbnQiOnRydWUsImNsb3NhYmxlVGFicyI6dHJ1ZSwicmVhZE9ubHkiOmZhbHNlLCJzaG93UmVhZE9ubHkiOmZhbHNlfX0sIlByZXZpZXciOnsidHlwZSI6InByZXZpZXciLCJkYXRhIjp7InNob3dOYXZpZ2F0b3IiOmZhbHNlLCJzaG93T3BlbkluQ29kZVNhbmRib3giOmZhbHNlLCJzaG93UmVmcmVzaEJ1dHRvbiI6dHJ1ZSwic2hvd1NhbmRwYWNrRXJyb3JPdmVybGF5IjpmYWxzZX19fSwiZ2VuZXJhbCI6eyJ2aXNpYmxlRmlsZXMiOlsiL0FwcC5qcyJdLCJ0aGVtZSI6ImtlbXBvRGFyayIsImV4dGVybmFsUmVzb3VyY2VzIjpbImh0dHBzOi8vY2RuLnRhaWx3aW5kY3NzLmNvbSJdfSwibGF5b3V0cyI6eyJzbWFsbCI6IidFZGl0b3InXG4nRWRpdG9yJ1xuJ0VkaXRvcidcbidQcmV2aWV3JyJ9fX0=" height="750px" width="100%"></iframe>
