[{"data":1,"prerenderedAt":431},["ShallowReactive",2],{"footer-primary":3,"footer-secondary":93,"footer-description":119,"mastering-agencyos-page-builder-agencyos":121,"mastering-agencyos-page-builder-agencyos-next":164,"sales-reps":179},{"items":4},[5,29,49,69],{"id":6,"title":7,"url":8,"page":8,"children":9},"522e608a-77b0-4333-820d-d4f44be2ade1","Solutions",null,[10,15,20,25],{"id":11,"title":12,"url":8,"page":13},"fcafe85a-a798-4710-9e7a-776fe413aae5","Headless CMS",{"permalink":14},"/solutions/headless-cms",{"id":16,"title":17,"url":8,"page":18},"79972923-93cf-4777-9e32-5c9b0315fc10","Backend-as-a-Service",{"permalink":19},"/solutions/backend-as-a-service",{"id":21,"title":22,"url":8,"page":23},"0fa8d0c1-7b64-4f6f-939d-d7fdb99fc407","Product Information",{"permalink":24},"/solutions/product-information-management",{"id":26,"title":27,"url":28,"page":8},"63946d54-6052-4780-8ff4-91f5a9931dcc","100+ Things to Build","https://directus.io/blog/100-tools-apps-and-platforms-you-can-build-with-directus",{"id":30,"title":31,"url":8,"page":8,"children":32},"8ab4f9b1-f3e2-44d6-919b-011d91fe072f","Resources",[33,37,41,45],{"id":34,"title":35,"url":36,"page":8},"f951fb84-8777-4b84-9e91-996fe9d25483","Documentation","https://docs.directus.io",{"id":38,"title":39,"url":40,"page":8},"366febc7-a538-4c08-a326-e6204957f1e3","Guides","https://docs.directus.io/guides/",{"id":42,"title":43,"url":44,"page":8},"aeb9128e-1c5f-417f-863c-2449416433cd","Community","https://directus.chat",{"id":46,"title":47,"url":48,"page":8},"da1c2ed8-0a77-49b0-a903-49c56cb07de5","Release Notes","https://github.com/directus/directus/releases",{"id":50,"title":51,"url":8,"page":8,"children":52},"d61fae8c-7502-494a-822f-19ecff3d0256","Support",[53,57,61,65],{"id":54,"title":55,"url":56,"page":8},"8c43c781-7ebd-475f-a931-747e293c0a88","Issue Tracker","https://github.com/directus/directus/issues",{"id":58,"title":59,"url":60,"page":8},"d77bb78e-cf7b-4e01-932a-514414ba49d3","Feature Requests","https://github.com/directus/directus/discussions?discussions_q=is:open+sort:top",{"id":62,"title":63,"url":64,"page":8},"4346be2b-2c53-476e-b53b-becacec626a6","Community Chat","https://discord.com/channels/725371605378924594/741317677397704757",{"id":66,"title":67,"url":68,"page":8},"26c115d2-49f7-4edc-935e-d37d427fb89d","Cloud Dashboard","https://directus.cloud",{"id":70,"title":71,"url":8,"page":8,"children":72},"49141403-4f20-44ac-8453-25ace1265812","Organization",[73,78,84,88],{"id":74,"title":75,"url":76,"page":77},"1f36ea92-8a5e-47c8-914c-9822a8b9538a","About","/about",{"permalink":76},{"id":79,"title":80,"url":81,"page":82},"b84bf525-5471-4b14-a93c-225f6c386005","Careers","#",{"permalink":83},"/careers",{"id":85,"title":86,"url":87,"page":8},"86aabc3a-433d-434b-9efa-ad1d34be0a34","Brand Assets","https://drive.google.com/drive/folders/1lBOTba4RaA5ikqOn8Ewo4RYzD0XcymG9?usp=sharing",{"id":89,"title":90,"url":8,"page":91},"8d2fa1e3-198e-4405-81e1-2ceb858bc237","Contact",{"permalink":92},"/contact",{"items":94},[95,101,107,113],{"id":96,"title":97,"url":8,"page":98,"children":100},"8a1b7bfa-429d-4ffc-a650-2a5fdcf356da","Cloud Policies",{"permalink":99},"/cloud-policies",[],{"id":102,"title":103,"url":81,"page":104,"children":106},"bea848ef-828f-4306-8017-6b00ec5d4a0c","License",{"permalink":105},"/bsl",[],{"id":108,"title":109,"url":81,"page":110,"children":112},"4e914f47-4bee-42b7-b445-3119ee4196ef","Terms",{"permalink":111},"/terms",[],{"id":114,"title":115,"url":81,"page":116,"children":118},"ea69eda6-d317-4981-8421-fcabb1826bfd","Privacy",{"permalink":117},"/privacy",[],{"description":120},"\u003Cp>A composable backend to build your Headless CMS, BaaS, and more.&nbsp;\u003C/p>",{"id":122,"slug":123,"vimeo_id":124,"description":125,"tile":126,"length":127,"resources":8,"people":128,"episode_number":132,"published":133,"title":134,"video_transcript_html":135,"video_transcript_text":136,"content":8,"status":137,"episode_people":138,"recommendations":152,"season":153,"seo":8},"cf8b1be3-2bed-45e0-b158-8dacd5afa1f7","page-builder-agencyos","894493860","In this video, you'll learn how to create dynamic pages that are on brand and look great with the page builder inside AgencyOS.","a882540d-611e-428a-9379-20cbc1d1a986",7,[129],{"name":130,"url":131},"Bryant Gillespie","https://directus.io/team/bryant-gillespie",3,"2023-10-24","Page Builder In AgencyOS","\u003Cp>Speaker 0: Hi there. Bryant here for Directus. Welcome back to the next video in our Agency OS series where we're talking about the Page Builder. When you make the move to Headless, one of the things that your team may miss most is the Page Builder functionality from WordPress or other visual CMS's where you can move things around the screen and control margins and paddings and all of that. While I would argue that's a great thing because I want my content team focused on building the best content possible, not worrying about design or how things look on the page, That can be a blocker.\u003C/p>\u003Cp>But fear not, Agency OS and Directus make this easy to build dynamic pages and still maintain a consistent design system. Let's take a look at how it works and how to build new pages. So, on the left hand you can see we've got our front end And then on the right hand side, we'll just pull up the home page. You'll notice that the home page is made up of different content blocks. I can move these blocks around on the page and save and refresh our front end to see those changes being made.\u003C/p>\u003Cp>Great. I can move stuff around on the screen. But how about adding new blocks? Very simple. I'll just go down to the create new option and you've got all the blocks that are available that you've added to your Page Builder collection inside Agent c OS.\u003C/p>\u003Cp>So we will add a title for this Rich Text block, give it a headline, add some content and save it and we can see the changes happening on the front end. One of the other great features is that you can even reuse existing blocks from other pages so that you don't have to recreate the same stuff on each individual page over and over again. So I just select a logo cloud, refresh, and boom, there it is. Sometimes you may want to hide a block without removing it from the page. It's very easy to do within Aegis CoS.\u003C/p>\u003Cp>I just pull up the block that I wanna hide, check the box, refresh on the front end, and now that block is hidden from view ready to be activated whenever I need it. With that out of the way, let's take a look at how we add blocks. We're gonna navigate to the data model within our settings. And if we just search for block, we could see that all of these blocks are just different collections within the Directus project. Now adding new ones is simple.\u003C/p>\u003Cp>We can go into our Page Builder under the Blocks section. And this is where we control all of the blocks that are available for our content editors to add and reuse on different pages. Now for adding a new block, what we're gonna do is go back and add a new collection for this block. We'll call it block new. So we'll save this block, and then we'll add some fields to control our content.\u003C/p>\u003Cp>So let's add a WYSIWYG editor. We'll just give it a key of content. That's how we're going to access it on the front end. And let's add an image as well. All right, so we've created our collection for our block data.\u003C/p>\u003Cp>Let's go back into our pages to the Blocks field and add that block to the related collections so that we can add it when we're building a Page. So I'll just check the box for it, save this, and go back to our front end, to the Home page. And now I will be able to use that block within our page content. So we just add that, we will enter some content, select an image, and add it to the page. Now that we've added it to the page, we should be able to see this on the front end.\u003C/p>\u003Cp>So we'll just drag and drop this up to the top so that it displays in the first position on the page. But when I refresh, lo and behold, I don't see that. That's because our front end isn't aware of this block. So let's open up Versus Code and actually create this block so we can render that content on the front end. I'll just, do some window management here and we'll dive into the project.\u003C/p>\u003Cp>So we're looking for the components blocks directory. And the quickest way to do this is just cloning one of the existing blocks within the project. We've got a WYSIWYG component here, so I'm just gonna duplicate rich text dot view. Now, I'm just going to do some simple clean up on our types once we've created the file because this is no longer a RichText component, it is our Block New component. Alright, so now we'll just swap out the definition for our props with the new interface and we'll remove the default props because we don't have any properties like alignment that we want to control for this block.\u003C/p>\u003Cp>Alright, so now we'll just adjust the template for this. We've got our typography pros for our content. This will render any HTML content in a nice format. And then we are also going to just use the Nuxt Image component, because it has some built in helpers for handling images from Directus. So now we've got our template.\u003C/p>\u003Cp>When I refresh the page, I don't see this block being displayed. And that is because we need to make our Page Builder component aware of this particular block. So the page builder component loops through all of the different types of blocks and renders them on the page. We'll just add a new component within the component map using the Resolve component but we don't have any images or content displaying. This is a permissions problem because we created that new collection within Directus but we forgot to set public permissions for it.\u003C/p>\u003Cp>So any collections by default have 0 permissions because we want to keep your data secure. So we'll go into the roles and permissions for the public role and we'll look for that block new collection and give read access so anyone in the general public can see our content. Great. We refresh and we're still not there yet. So we have to actually fetch that data from the API, which is happening inside the permalink page within Nuxt.\u003C/p>\u003Cp>So we'll go into our fields collection, We'll make sure that we are fetching block new. And much like GraphQL, we want to fetch only the content that we needed so our site stays fast. So we'll do id, content, and image as the keys and then we reload to see that content being rendered on our front end. Now, and that's it. So you are now an expert in all things Page Builder.\u003C/p>\u003Cp>Go forth and build your own pages, add your blocks, customize this as you see fit. Stay tuned for more videos in this series where we'll deep dive into other features of Agency OS.\u003C/p>","Hi there. Bryant here for Directus. Welcome back to the next video in our Agency OS series where we're talking about the Page Builder. When you make the move to Headless, one of the things that your team may miss most is the Page Builder functionality from WordPress or other visual CMS's where you can move things around the screen and control margins and paddings and all of that. While I would argue that's a great thing because I want my content team focused on building the best content possible, not worrying about design or how things look on the page, That can be a blocker. But fear not, Agency OS and Directus make this easy to build dynamic pages and still maintain a consistent design system. Let's take a look at how it works and how to build new pages. So, on the left hand you can see we've got our front end And then on the right hand side, we'll just pull up the home page. You'll notice that the home page is made up of different content blocks. I can move these blocks around on the page and save and refresh our front end to see those changes being made. Great. I can move stuff around on the screen. But how about adding new blocks? Very simple. I'll just go down to the create new option and you've got all the blocks that are available that you've added to your Page Builder collection inside Agent c OS. So we will add a title for this Rich Text block, give it a headline, add some content and save it and we can see the changes happening on the front end. One of the other great features is that you can even reuse existing blocks from other pages so that you don't have to recreate the same stuff on each individual page over and over again. So I just select a logo cloud, refresh, and boom, there it is. Sometimes you may want to hide a block without removing it from the page. It's very easy to do within Aegis CoS. I just pull up the block that I wanna hide, check the box, refresh on the front end, and now that block is hidden from view ready to be activated whenever I need it. With that out of the way, let's take a look at how we add blocks. We're gonna navigate to the data model within our settings. And if we just search for block, we could see that all of these blocks are just different collections within the Directus project. Now adding new ones is simple. We can go into our Page Builder under the Blocks section. And this is where we control all of the blocks that are available for our content editors to add and reuse on different pages. Now for adding a new block, what we're gonna do is go back and add a new collection for this block. We'll call it block new. So we'll save this block, and then we'll add some fields to control our content. So let's add a WYSIWYG editor. We'll just give it a key of content. That's how we're going to access it on the front end. And let's add an image as well. All right, so we've created our collection for our block data. Let's go back into our pages to the Blocks field and add that block to the related collections so that we can add it when we're building a Page. So I'll just check the box for it, save this, and go back to our front end, to the Home page. And now I will be able to use that block within our page content. So we just add that, we will enter some content, select an image, and add it to the page. Now that we've added it to the page, we should be able to see this on the front end. So we'll just drag and drop this up to the top so that it displays in the first position on the page. But when I refresh, lo and behold, I don't see that. That's because our front end isn't aware of this block. So let's open up Versus Code and actually create this block so we can render that content on the front end. I'll just, do some window management here and we'll dive into the project. So we're looking for the components blocks directory. And the quickest way to do this is just cloning one of the existing blocks within the project. We've got a WYSIWYG component here, so I'm just gonna duplicate rich text dot view. Now, I'm just going to do some simple clean up on our types once we've created the file because this is no longer a RichText component, it is our Block New component. Alright, so now we'll just swap out the definition for our props with the new interface and we'll remove the default props because we don't have any properties like alignment that we want to control for this block. Alright, so now we'll just adjust the template for this. We've got our typography pros for our content. This will render any HTML content in a nice format. And then we are also going to just use the Nuxt Image component, because it has some built in helpers for handling images from Directus. So now we've got our template. When I refresh the page, I don't see this block being displayed. And that is because we need to make our Page Builder component aware of this particular block. So the page builder component loops through all of the different types of blocks and renders them on the page. We'll just add a new component within the component map using the Resolve component but we don't have any images or content displaying. This is a permissions problem because we created that new collection within Directus but we forgot to set public permissions for it. So any collections by default have 0 permissions because we want to keep your data secure. So we'll go into the roles and permissions for the public role and we'll look for that block new collection and give read access so anyone in the general public can see our content. Great. We refresh and we're still not there yet. So we have to actually fetch that data from the API, which is happening inside the permalink page within Nuxt. So we'll go into our fields collection, We'll make sure that we are fetching block new. And much like GraphQL, we want to fetch only the content that we needed so our site stays fast. So we'll do id, content, and image as the keys and then we reload to see that content being rendered on our front end. Now, and that's it. So you are now an expert in all things Page Builder. Go forth and build your own pages, add your blocks, customize this as you see fit. Stay tuned for more videos in this series where we'll deep dive into other features of Agency OS.","published",[139],{"people_id":140},{"id":141,"first_name":142,"last_name":143,"avatar":144,"bio":145,"links":146},"791e1503-1d88-463d-9347-0b9192933576","Bryant","Gillespie","9013afc8-e8d7-4182-9b18-44db08117bb9","Developer Advocate at Directus",[147,149],{"url":131,"service":148},"website",{"service":150,"url":151},"github","https://github.com/bryantgillespie",[],{"id":154,"number":155,"year":156,"episodes":157,"show":161},"237e17bc-6e41-460f-8fe7-1d21fd865801",1,"2023",[158,159,122,160],"6ed0cf93-0868-497e-a21a-97df216f9fa7","1155c102-42e1-4cb8-8f35-3b2d2dbb0376","4298bc72-ad12-4c76-b57d-506e3d9a0c45",{"title":162,"tile":163},"Mastering AgencyOS","e8f99ff6-f500-4a05-9238-b44f2b607932",{"id":160,"slug":165,"season":154,"vimeo_id":166,"description":167,"tile":168,"length":169,"resources":8,"people":170,"episode_number":172,"published":133,"title":173,"video_transcript_html":174,"video_transcript_text":175,"content":8,"seo":8,"status":137,"episode_people":176,"recommendations":178},"stripe-agencyos","894494318","In this video you'll learn how your clients can quickly and easily pay within their portal. ","a28d2560-5990-4cfb-8441-b9942b828594",6,[171],{"name":130,"url":131},4,"Client Payments with Stripe and AgencyOS","\u003Cp>Speaker 0: Hi. Brian here for Directus. Welcome back to the next video in our Agency OS series where we're talking about the Stripe checkout or the ability to accept payments from your clients within the portal. This is a very important piece of functionality. You've got to be able to get paid on time to run a successful agency.\u003C/p>\u003Cp>So let's dive in. Alright. So we're logged into the client portal and we'll just bring up one of the invoices and you can see there's a link to pay this invoice. When we click it, nothing happens because we have the wrong Stripe API keys or we haven't set those up yet. So what we're gonna do is go into our Stripe account and go to the Developers tab and look for API Keys.\u003C/p>\u003Cp>There are several different keys that you're gonna copy here. The publishable key, which is safe to be used on the front end, and then the secret key, which is only exposed on the server. So we are going to go into our env file and paste these keys. And I'm certainly going to have to roll these keys after this video so don't try to steal my keys. The last piece of the puzzle here is our Stripe webhook secret.\u003C/p>\u003Cp>Whenever a checkout event occurs, we need to be able to catch or receive those webhooks that Stripe sends out so we can update Directus with those. So I will just follow the instructions here to test in a local environment. We'll make sure that I am logged into the Stripe CLI and then we will forward all Stripe webhook events to localhost3000/api/stripe slash webhooks. So this is the API route within the Nuxt project where we are listening for those webhooks. And once I log in, I listen to that event, it will give me my webhook secret, which we use to verify that Stripe is sending those webhooks.\u003C/p>\u003Cp>Now, once we test that out, we should be able to pay invoices. But, oops, we need to restart the dev server so those changes can take effect. Alright, so let's wait for our dev server to restart. And once it's back, then we can test out this functionality. So we just hit Pay Invoice.\u003C/p>\u003Cp>It will throw a Stripe checkout session where the user can pay and complete via card or whatever payments you've got set up in your Stripe account. So I'm just going to enter some test card information and try this payment out to verify this will work. Alright. So once the checkout is complete, Stripe should send us back to the page from whence we came and we can see that this invoice is now marked as paid because a payment was applied. So if I open up our AgencyOS back end inside Directus, we should be able to find that payment within the Billing section.\u003C/p>\u003Cp>And just like the song, whoomp, there it is. Now, one of the other pieces of functionality that's built into the platform is the Stripe customer portal. They have a great UI, this is set up on the billing page where your customer or your client can go in and update their payment methods within the Stripe customer portal. So that's it for the client functionality within the portal. Let's take a look inside our codebase to see how this operates behind the scenes.\u003C/p>\u003Cp>Behind the curtain, if you will. So we're going to open up Versus Code and look for our layers section. Within layers we will look for our portal and then you can see under the server API routes we have a Stripe folder where we have a create checkout session. Post. Ts.\u003C/p>\u003Cp>So, this will accept an invoice ID as a, inside the body of this and then this will create a checkout session and return it to the Stripe JavaScript client to, redirect us to checkout. Then we have a composable which uses the Stripe JavaScript client to actually redirect to checkout. So we've got use Stripe which just basically loads Stripe and then we have a handle checkout function and a get portal link function to send the clients to that portal link. You can also see the API route for creating that portal link. And last but not least, we have our webhooks route that receives those webhooks from Stripe whenever these checkout events occur.\u003C/p>\u003Cp>This will verify that data coming from Stripe and create those payments within our Agency OS instance. So when you get ready to go to production with this, make sure that you go in and actually create the Stripe endpoints for those webhooks. So whatever your final deployment URL is, you'll go in and set that up inside Stripe using, the API Stripe Webhooks and then you will pick the checkout events just to make sure that all those events get sent to that URL. And make sure that you toggle off Test mode and grab the live API keys on your Production Server. So that's it for this video on how to connect Stripe with AgentC OS.\u003C/p>\u003Cp>Stay tuned for other videos in the series.\u003C/p>","Hi. Brian here for Directus. Welcome back to the next video in our Agency OS series where we're talking about the Stripe checkout or the ability to accept payments from your clients within the portal. This is a very important piece of functionality. You've got to be able to get paid on time to run a successful agency. So let's dive in. Alright. So we're logged into the client portal and we'll just bring up one of the invoices and you can see there's a link to pay this invoice. When we click it, nothing happens because we have the wrong Stripe API keys or we haven't set those up yet. So what we're gonna do is go into our Stripe account and go to the Developers tab and look for API Keys. There are several different keys that you're gonna copy here. The publishable key, which is safe to be used on the front end, and then the secret key, which is only exposed on the server. So we are going to go into our env file and paste these keys. And I'm certainly going to have to roll these keys after this video so don't try to steal my keys. The last piece of the puzzle here is our Stripe webhook secret. Whenever a checkout event occurs, we need to be able to catch or receive those webhooks that Stripe sends out so we can update Directus with those. So I will just follow the instructions here to test in a local environment. We'll make sure that I am logged into the Stripe CLI and then we will forward all Stripe webhook events to localhost3000/api/stripe slash webhooks. So this is the API route within the Nuxt project where we are listening for those webhooks. And once I log in, I listen to that event, it will give me my webhook secret, which we use to verify that Stripe is sending those webhooks. Now, once we test that out, we should be able to pay invoices. But, oops, we need to restart the dev server so those changes can take effect. Alright, so let's wait for our dev server to restart. And once it's back, then we can test out this functionality. So we just hit Pay Invoice. It will throw a Stripe checkout session where the user can pay and complete via card or whatever payments you've got set up in your Stripe account. So I'm just going to enter some test card information and try this payment out to verify this will work. Alright. So once the checkout is complete, Stripe should send us back to the page from whence we came and we can see that this invoice is now marked as paid because a payment was applied. So if I open up our AgencyOS back end inside Directus, we should be able to find that payment within the Billing section. And just like the song, whoomp, there it is. Now, one of the other pieces of functionality that's built into the platform is the Stripe customer portal. They have a great UI, this is set up on the billing page where your customer or your client can go in and update their payment methods within the Stripe customer portal. So that's it for the client functionality within the portal. Let's take a look inside our codebase to see how this operates behind the scenes. Behind the curtain, if you will. So we're going to open up Versus Code and look for our layers section. Within layers we will look for our portal and then you can see under the server API routes we have a Stripe folder where we have a create checkout session. Post. Ts. So, this will accept an invoice ID as a, inside the body of this and then this will create a checkout session and return it to the Stripe JavaScript client to, redirect us to checkout. Then we have a composable which uses the Stripe JavaScript client to actually redirect to checkout. So we've got use Stripe which just basically loads Stripe and then we have a handle checkout function and a get portal link function to send the clients to that portal link. You can also see the API route for creating that portal link. And last but not least, we have our webhooks route that receives those webhooks from Stripe whenever these checkout events occur. This will verify that data coming from Stripe and create those payments within our Agency OS instance. So when you get ready to go to production with this, make sure that you go in and actually create the Stripe endpoints for those webhooks. So whatever your final deployment URL is, you'll go in and set that up inside Stripe using, the API Stripe Webhooks and then you will pick the checkout events just to make sure that all those events get sent to that URL. And make sure that you toggle off Test mode and grab the live API keys on your Production Server. So that's it for this video on how to connect Stripe with AgentC OS. Stay tuned for other videos in the series.",[177],"50893908-338e-41c7-bc9b-c2bf01bdd378",[],{"reps":180},[181,237],{"name":182,"sdr":8,"link":183,"countries":184,"states":186},"John Daniels","https://meet.directus.io/meetings/john2144/john-contact-form-meeting",[185],"United States",[187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236],"Michigan","Indiana","Ohio","West Virginia","Kentucky","Virginia","Tennessee","North Carolina","South Carolina","Georgia","Florida","Alabama","Mississippi","New York","MI","IN","OH","WV","KY","VA","TN","NC","SC","GA","FL","AL","MS","NY","Connecticut","CT","Delaware","DE","Maine","ME","Maryland","MD","Massachusetts","MA","New Hampshire","NH","New Jersey","NJ","Pennsylvania","PA","Rhode Island","RI","Vermont","VT","Washington DC","DC",{"name":238,"link":239,"countries":240},"Michelle Riber","https://meetings.hubspot.com/mriber",[241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,218,429,430],"Albania","ALB","Algeria","DZA","Andorra","AND","Angola","AGO","Austria","AUT","Belgium","BEL","Benin","BEN","Bosnia and Herzegovina","BIH","Botswana","BWA","Bulgaria","BGR","Burkina Faso","BFA","Burundi","BDI","Cameroon","CMR","Cape Verde","CPV","Central African Republic","CAF","Chad","TCD","Comoros","COM","Côte d'Ivoire","CIV","Croatia","HRV","Czech Republic","CZE","Democratic Republic of Congo","COD","Denmark","DNK","Djibouti","DJI","Egypt","EGY","Equatorial Guinea","GNQ","Eritrea","ERI","Estonia","EST","Eswatini","SWZ","Ethiopia","ETH","Finland","FIN","France","FRA","Gabon","GAB","Gambia","GMB","Ghana","GHA","Greece","GRC","Guinea","GIN","Guinea-Bissau","GNB","Hungary","HUN","Iceland","ISL","Ireland","IRL","Italy","ITA","Kenya","KEN","Latvia","LVA","Lesotho","LSO","Liberia","LBR","Libya","LBY","Liechtenstein","LIE","Lithuania","LTU","Luxembourg","LUX","Madagascar","MDG","Malawi","MWI","Mali","MLI","Malta","MLT","Mauritania","MRT","Mauritius","MUS","Moldova","MDA","Monaco","MCO","Montenegro","MNE","Morocco","MAR","Mozambique","MOZ","Namibia","NAM","Niger","NER","Nigeria","NGA","North Macedonia","MKD","Norway","NOR","Poland","POL","Portugal","PRT","Republic of Congo","COG","Romania","ROU","Rwanda","RWA","San Marino","SMR","São Tomé and Príncipe","STP","Senegal","SEN","Serbia","SRB","Seychelles","SYC","Sierra Leone","SLE","Slovakia","SVK","Slovenia","SVN","Somalia","SOM","South Africa","ZAF","South Sudan","SSD","Spain","ESP","Sudan","SDN","Sweden","SWE","Tanzania","TZA","Togo","TGO","Tunisia","TUN","Uganda","UGA","United Kingdom","GBR","Vatican City","VAT","Zambia","ZMB","Zimbabwe","ZWE","UK","Germany","Netherlands","Switzerland","CH","NL",1773850432980]