WEBVTT 00:00.000 --> 00:10.240 Fair while now, or alternatively have been kicking outside, so yeah, thanks for making 00:10.240 --> 00:16.880 the effort. I do appreciate that. Bit about me, so my name is James Milner. I'm a staff 00:16.880 --> 00:23.280 software engineer at a company called Nearform. I live in London, working remotely. Nearforms 00:23.280 --> 00:27.880 like a digital consultancy has a big history and opensource specifically in the kind of 00:27.880 --> 00:34.680 like Node.js ecosystem. And yeah, this is my terror drawer's my personal project, but they're 00:34.680 --> 00:41.640 very supportive and they've helped me to come here today, so yeah, shout out to them. So, 00:41.640 --> 00:46.280 let's get started. What is terror drawer? So, terror drawer is an open source JavaScript 00:46.280 --> 00:52.680 library for drawing on web maps. So, the source is MIT licensed, and yeah, it's a JavaScript 00:52.680 --> 00:58.840 library, so it runs in the front end in your browser alongside your map, in your front end code, 01:00.200 --> 01:07.080 and it's for drawing on web maps. So, drawing is maybe a bit of a loaded term, or a loaded concept, 01:07.080 --> 01:13.960 so sometimes I think it just helps to have a tangible example to point to. So, the one that I give 01:13.960 --> 01:20.120 is, if in the UK, we have two companies who apply right move, they might also be present in 01:20.120 --> 01:25.480 other parts of Europe and beyond, but essentially their property search websites, so you can go 01:25.480 --> 01:31.080 to these websites, you can type in what you're looking for, you know, number of bedrooms, or 01:31.080 --> 01:36.760 the location, and you can find places to buy or rent. And they also have a tool, both of them 01:36.760 --> 01:42.840 have a tool for allowing you to draw an area of interest on the map, and then only return polygon, 01:42.840 --> 01:48.040 oh sorry, only return properties that exist within that polygon or in that area of interest. 01:48.920 --> 01:52.840 So, that's the kind of thing that I'm talking about when I'm saying drawing on a web map like 01:52.840 --> 01:59.640 literally the user inputting and drawing on the web map. And there's some prior art here, there's 01:59.640 --> 02:09.880 a few libraries that do this in varying degrees of functionality and like how up to date, like how 02:09.880 --> 02:15.880 well maintained they are. The one that I was probably the most familiar with before starting to 02:15.960 --> 02:25.800 draw was MapboxGL Draw, which is for MapboxGL.js, a mapping library, and so in my previous role 02:25.800 --> 02:32.040 I was working on indoor mapping, indoor positioning, and we needed a way to basically create 02:33.080 --> 02:39.560 indoor maps, and so I was using MapboxGL Draw, and then after I left that company I kind of had 02:39.560 --> 02:45.080 some thoughts about like potentially like a different approach, or another way of kind of structuring 02:45.080 --> 02:51.000 like a drawing library, or things that I thought could potentially be worked on or improved on 02:51.000 --> 03:01.000 kind of the pie art. So, the kind of the goals of Taro Draw are that it's cross library support, 03:01.000 --> 03:07.320 so kind of takes the approach of having like an adaptor pattern, so there's an adaptor for a bunch 03:07.320 --> 03:12.840 of different mapping libraries, which I'll come on to in more detail in a minute, but 90% of the code 03:12.920 --> 03:19.560 is in the core, and then these adapters just a kind of like a little like an interstitial bit 03:19.560 --> 03:26.200 between the core Taro Draw library and the mapping library. I wanted it to be customizable, so what 03:26.200 --> 03:32.360 I mean by that is you could create your own complex drawing modes, so people have all sorts of 03:32.360 --> 03:37.080 weird and wonderful requirements, and basically I wanted to be able to allow support for that, 03:37.080 --> 03:42.040 and similarly if a new mapping library comes along, I wanted to be able to allow 03:42.120 --> 03:48.520 to create an adaptor for that fairly easily. So yeah, just customizability and 03:48.520 --> 03:54.600 extensibility was kind of one of the initial goals. Keep styling, so basically being able to 03:54.600 --> 04:00.520 style every aspect of like the drawing experience, some of my previous experiences were like 04:00.520 --> 04:05.800 you couldn't get a consistent look and feel because you could only style like certain aspects 04:05.800 --> 04:11.960 of the drama trees that were being rendered, and so that was kind of something that I wanted 04:11.960 --> 04:17.720 to support from the outset was being able to style kind of everything that's going on in the 04:17.720 --> 04:24.280 kind of drawing experience, and then the last thing is it had like was just kind of this approach 04:24.280 --> 04:29.720 of like not having any additional like run time dependencies, not necessarily saying that 04:29.720 --> 04:35.160 that's like a better or you know, isn't a superior approach, but it was more just like 04:35.160 --> 04:39.560 historically I've worked on a lot of projects where just you try and build something or you try 04:40.520 --> 04:44.760 install something and something just breaks because of some especially in the like kind of 04:44.760 --> 04:51.720 nodes ecosystem, there's a lot of just like you can end up in dependency how and so just taking 04:51.720 --> 04:57.480 that approach kind of simplifies that and reduces the possibility of having those kind of issues. 05:03.080 --> 05:06.600 So there's a bunch of different, as I was kind of saying, territorial supports a bunch of different 05:06.600 --> 05:14.200 mapping libraries out the box, so the the six that are supported in the kind of I guess core 05:14.920 --> 05:22.840 library of territorial, so open there's a leaflet, map lever, jl, js, google maps, mapbox, jl, js, 05:22.840 --> 05:30.040 and js, maps SDK for JavaScript. So the top three are open source and the bottom three are like 05:30.040 --> 05:38.120 proprietary, but yeah so they're support for these these mapping libraries out the box and as I 05:38.120 --> 05:44.680 said it's possible if you have your own custom map rendering library then it should in theory 05:44.680 --> 05:52.040 be possible to write your own adapter as long as you can fulfill some basic criteria for the 05:52.040 --> 06:01.640 light interface for that adapter. And so it's quite rare but there are scenarios where that kind of 06:01.640 --> 06:06.920 decoupling can be quite helpful. So say for example you are using a mapping library and the 06:06.920 --> 06:12.200 underpinning services that power it change their pricing model and it no longer becomes viable for 06:12.200 --> 06:17.000 you to like financially it's not possible for you to keep using that library. Having that decoupling 06:17.160 --> 06:22.120 can be quite useful. Similarly if the license changes for the underlying library and that's no 06:22.120 --> 06:28.280 longer compatible with your business or like your project or whatever you're trying to do then that is 06:28.280 --> 06:32.680 another reason why you might want to swap that out and then the other like I guess more obvious 06:32.680 --> 06:38.680 thing is that different mapping libraries have different limitations or different feature sets 06:38.680 --> 06:43.000 and so if there's something you need to do and then you realize like two or three years into a 06:43.000 --> 06:50.280 project that you can't do that in that specific mapping library then just having that decoupling 06:50.280 --> 06:57.400 can be potentially quite useful. So this is the architecture or the kind of a basic overview of the 06:57.400 --> 07:01.720 architecture of Taugeau so as I was saying we've kind of got this these adapters which are the kind of 07:01.720 --> 07:12.120 the Stinlayer at the front they take in inputs like user input from the user that goes into the mode 07:12.120 --> 07:15.880 so there's we have a bunch of different built-in modes for different geometry types so 07:17.160 --> 07:23.720 point polygard, line string, circle, rectangle and then there's some more sort of like exotic ones 07:23.720 --> 07:29.960 that I will come onto later and so those are just the modes and that's contains all the logic for like 07:29.960 --> 07:37.160 handling you know drawing drawing those geometry types and then it's all just backed by what was just 07:37.240 --> 07:42.680 called a store which is essentially where all the geojation geometries are stored and then retrieved 07:42.680 --> 07:49.800 or and then updated so yeah it's just kind of like this three tier approach which I think works 07:49.800 --> 07:59.480 quite nicely and kind of isolates things quite nicely. We there's no runtime dependencies but we do 07:59.480 --> 08:05.880 rely on a bunch of other open source tools for a lot of the development time functionality so it's 08:05.880 --> 08:12.440 the whole library is written more or less exclusively in TypeScript I just like types and I think 08:12.440 --> 08:16.120 it's kind of become a maybe a bit of an industry standard on JavaScript projects now. 08:18.440 --> 08:22.280 We use just which is potentially maybe going like a little bit of fashion it's the 08:22.280 --> 08:28.920 tech testing library but for me it works and has been relatively popular and people understand 08:28.920 --> 08:35.480 how it works so that was kind of the choice there webpack for local development so there's like a 08:35.480 --> 08:39.720 local environment where you can just experiment with all the different drawing modes and all the 08:39.720 --> 08:47.880 different adapters locally if you just want to like change something and play around with things 08:47.880 --> 08:53.480 then that all is backed by like webpack just bundles at all and makes it all possible and then 08:53.480 --> 08:58.840 lastly use a thing called micro bundle which is quite a niche project but I find it really 08:58.840 --> 09:03.720 useful it's just for like it does the actual it creates the actual end bundle that gets put onto 09:03.720 --> 09:10.760 MPM like the node package manager but it just sorts out a lot of the complicated aspects of like 09:10.760 --> 09:18.440 delivering like a JavaScript package on MPM essentially so that's what we use that 09:20.840 --> 09:25.880 let's have a little look at like how you can get started with tow drawer so the simplest thing 09:26.840 --> 09:33.160 probably is well if you have an existing project you can use MPM to install tow drawer into your 09:33.160 --> 09:39.480 project just MPM installed tow drawer you also need an adaptor which will be like a separate package 09:39.480 --> 09:44.360 which I'll show you like how you install those different adapters later on but the core library is just 09:44.360 --> 09:50.920 towred our scroll or you can use yarn or like other node JavaScript package managers if you 09:50.920 --> 09:57.960 what does you know whichever one you're using is fine the actual project is available at my 09:57.960 --> 10:04.680 GitHub handle which is James Elmina for slash tow drawer there's docks in there there's API documentation 10:04.680 --> 10:11.000 there's the whole project basically lives in there and then lastly there's the website it's just 10:11.000 --> 10:16.680 towredraw.io it looks a little something like this but it's essentially quite similar to 10:19.320 --> 10:26.440 if you've ever used geojson.io kind of a fairly comparable sort of set of functionality but helps just 10:26.520 --> 10:36.200 demonstrate how taradraw would like work in like an end project so at the top is like the bunch 10:36.200 --> 10:42.040 the different modes and then the the geometries that you're seeing on the screen are the output of 10:42.040 --> 10:46.920 like using those modes there's also some other modes that we a bit more like are saying a bit more 10:46.920 --> 10:52.360 exotic that aren't like on here that will come on too later but it's just showing you the basic 10:52.360 --> 10:57.240 functionality of like point line polygon we have like a free hand mode if you want to draw like a 10:57.240 --> 11:03.240 free hand polygon yeah so that's that's and that's just something you can just if you just want to 11:03.240 --> 11:07.640 get a high level sense of like what taradraw does you can just go on that website and just 11:07.640 --> 11:17.560 play around with it and then at like a code level this is just an example using map libera 11:18.520 --> 11:26.840 so lines one to six we're just instantiating a map libera map you know give it like a center some 11:26.840 --> 11:32.920 styling give it a specific zoom level that instantiates them out and then once that's finished 11:32.920 --> 11:40.520 loading then we can instantiate taradraw so we start a new taradraw instance we give it an adaptor in 11:40.520 --> 11:45.720 this case the map libera adaptor and then we just give it an array of all the modes that we want to 11:45.720 --> 11:52.200 instantiate it with so in this case on line 11 we just instantiate light just to keep things 11:52.200 --> 11:59.480 simple we just instantiate polygom mode and that will in this case we just have snapping which is 11:59.480 --> 12:04.520 like a piece of functionality that we support so you know snapping to whilst you're drawing 12:04.520 --> 12:10.280 snapping to other polygon vertices that you've drawn and then the end we just start the whole 12:11.240 --> 12:21.240 instance and that kicks everything off that's like a simplified version of what that looks 12:21.240 --> 12:25.560 like but it's hard to you know fit too much code on one slide so hopefully you'll forgive me 12:29.000 --> 12:35.240 so the project's been going for about two and just over two and a half years and all of that time 12:35.240 --> 12:40.760 it's kind of been in alpha and then beta as kind of just for a long time like tinkering with a 12:40.760 --> 12:46.120 lot of stuff and just trying to make trying to get things right and so this month we finally just 12:46.120 --> 12:52.680 released like a version one and that kind of like solidifies the foundation for the kind of the future 12:52.680 --> 12:58.120 of the project and hopefully like give some signal to other people that it's like you can 12:58.440 --> 13:06.280 you can rely on it to some extent to in your in your projects and so like one of the big changes 13:06.280 --> 13:14.920 in version one is essentially previously all the adapters were like baked into the core 13:14.920 --> 13:24.120 territorial module or the core territorial package sorry but that has like some that was essentially 13:24.120 --> 13:31.080 causing issues for certain people things like um type script types or like missing for like 13:31.080 --> 13:35.960 somebody would be using I don't know the leaflet adapter and they'd be getting complaints about 13:35.960 --> 13:42.360 like missing type script types for like the open layers adapter and it's like well that person doesn't 13:42.360 --> 13:46.760 care about open layers like they shouldn't have to right so it's basically like the thought process 13:46.760 --> 13:52.920 was just a basically terrible of that out and then just have a module per adapter and so now you 13:53.000 --> 13:57.160 just install the adapter with the map library that you're using and then you installed 13:57.160 --> 14:03.640 territorial on side that and then you can just use those those two together um yeah it also just 14:03.640 --> 14:13.560 helps like enforce like decoupling between the adapters and territorial itself which is a nice side 14:13.560 --> 14:19.000 effect I think um the other thing was like I was saying earlier about this kind of a bit more like 14:19.080 --> 14:25.960 exotic modes can I use this laser yes I can and so there's a few extra modes that have just 14:25.960 --> 14:31.000 come in and like recently so one of them is this is set to mode which is a bit like allows you to 14:31.000 --> 14:35.640 draw like a sector of a circle basically like like you know a control like a semi circle 14:37.880 --> 14:42.840 and then also sense mode which is similar like kind of the same premise but like a doughnut so you can 14:42.920 --> 14:50.120 draw like a doughnut essentially and these two were kind of actually requested on the basis of like 14:51.480 --> 14:58.760 this was for like there's one of the guys using the project like mountain rescue and one of the 14:58.760 --> 15:04.760 things that they do is like they want to know they have like various CCTV cameras that have like 15:04.760 --> 15:10.760 certain field of view like vision and so basically they can draw out and say like the field of view 15:10.760 --> 15:19.000 of a given camera in in the in the mountains basically and so this basically helps the map out 15:19.000 --> 15:22.200 so it sounds quite niche and like why would you have any of that but so I just wanted to kind of 15:22.200 --> 15:26.200 try and give some reasoning whether um so they use it for that essentially which is quite cool 15:27.000 --> 15:32.440 and the last one is uh those are the diamonds bits actually we call this like angled rectangle mode 15:32.440 --> 15:39.000 so territorial for long time has had like a rectangle mode where you can draw a rectangle but it's always 15:39.080 --> 15:46.360 oriented from like north like because the map is generally oriented north unless you've like rotated 15:46.360 --> 15:54.200 it or something and so angled rectangle mode just allows you to draw like a rectangle or any 15:54.200 --> 16:00.040 like arbitrary orientation essentially so that's just like another mode that there's kind of now baked 16:00.040 --> 16:06.280 into towsraw and yeah as I was saying like there's also opportunity to build your own custom modes 16:06.280 --> 16:11.880 if you want to do kind of weird and wacky things so I've built some modes for like doing 16:13.400 --> 16:19.160 client side routing so if you have like a complex so you could use if for example the 16:19.160 --> 16:25.960 example I had was like basically just converted a bunch of OSM roads data into geojson and then 16:25.960 --> 16:31.800 was basically just doing like clients allowing you to draw out client side routes using territorial 16:31.880 --> 16:40.520 as like a kind of custom mode and then another example was like using the um there's a there's a 16:40.520 --> 16:46.200 model called like segment anything model which like matter released which is can basically like 16:46.200 --> 16:51.240 pull out features essentially from like an image and so then using that to like being able to 16:51.240 --> 16:55.480 like pull out you could click on a building and it would generate the like polygon for the building 16:55.480 --> 17:02.680 essentially um again there's like a kind of custom mode integral um so yeah that's uh new modes and 17:02.680 --> 17:13.720 then at custom modes um also some like uh new kind of additions to uh configuration of existing 17:13.720 --> 17:18.520 modes that were potentially quite interesting so one of them is like called like validation and so 17:18.520 --> 17:26.840 validation is basically sometimes you want to prohibit users from creating polygons or points or like 17:26.840 --> 17:34.680 any kind of geometry that doesn't add here to some sort of like uh like validity rules or 17:34.680 --> 17:38.840 best practice or whatever it might be so in this case it's about like you don't want to have a 17:38.840 --> 17:43.160 polygon that self intersecting um there's various reasons why you probably wouldn't want 17:43.880 --> 17:50.280 self intersecting polygons in your like database or whatever it might be um but you can actually 17:50.280 --> 17:54.920 like this is just free form so you could essentially just do anything in here and this just allows you 17:54.920 --> 18:05.720 to prevent creating deal is um invalid essentially um and then the next one is about like snapping 18:05.720 --> 18:10.440 so total support is snapping for a little while but there's kind of been some improvements to 18:11.320 --> 18:16.280 um kind of how that works so like one of the nice things is you've always been able to snap to 18:17.000 --> 18:25.000 the um coordinates of a polygon so like the vertices of a polygon so for example like 18:25.000 --> 18:32.200 basically the corners here um but now we also just support snapping to like an arbitrary place 18:32.200 --> 18:36.920 on any of the lines of the polygon as well um so for example here this is just snap to like 18:37.800 --> 18:43.960 somewhere along this line here essentially um and so a lot of people find that useful um so 18:44.920 --> 18:53.000 that's something that we added support for um the other thing that we've kind of been working on 18:53.480 --> 18:58.280 it's it's tricky I wouldn't say it's perfect but it's at least kind of like the foundation for 18:58.360 --> 19:07.800 supporting like drawing on essentially like globes um which basically just requires you to um like when you're 19:07.800 --> 19:12.920 drawing on a web Macator map and you draw a square or a circle or whatever it might be when you actually 19:12.920 --> 19:21.720 place that on a globe because like you if you yeah it's just you end up with a scenario where 19:21.720 --> 19:26.520 like it's no longer circular it's no longer rectangular because when you project like something 19:26.600 --> 19:31.480 that's been drawn on a 2D web Macator map onto a globe it loses the property of 19:31.480 --> 19:36.120 being circular or a rectangular and vice versa if you draw a circle on a globe and you project 19:36.120 --> 19:42.440 it down onto a map it's going to look like more like an oval basically um and so now 19:43.480 --> 19:51.880 tarot draw has basic support in its modes for um drawing on on globe essentially but yeah it's 19:51.960 --> 20:00.280 not perfect but we're working on it uh community um it's been really lucky to have like quite a few 20:00.280 --> 20:07.720 people uh getting involved so it had 24 unique contributors over the last two and a half years 20:08.920 --> 20:15.160 there's 48 this is just some data I just pulled out of like GitHub insights but there's 48 20:15.880 --> 20:22.120 repositories that are depending on it um 509 stars yeah obviously it's a bit of a vanity 20:22.120 --> 20:26.840 metric but it's just always nice to see people taking an interest in something you're working on 20:26.840 --> 20:34.360 and similarly 64 forks again just nice to see people checking out the code um but yeah if you want 20:34.360 --> 20:41.960 to get involved um appreciate like any feedback you might have either on this talk or the um on any 20:42.040 --> 20:46.680 of the functionality of tarot draw itself I feel free to just you know you can kind of speak to 20:46.680 --> 20:54.360 me afterwards um or yeah feel free to write an issue on GitHub if you find bugs or you find there's 20:54.360 --> 20:59.240 a feature that you feel is missing um yeah feel free to share it if you know people that might benefit 20:59.240 --> 21:07.080 from using the project and yeah obviously we always welcome contributors um to tarot draw itself so 21:07.160 --> 21:12.600 please feel free to check out the code um start hacking around and if there's something that you 21:12.600 --> 21:21.240 feel like you could fix then uh just encourage you to have a go um yeah I think that's me thanks 21:21.240 --> 21:51.000 yeah at the moment it only supports um to do 21:51.080 --> 21:57.240 to do uh and well there's multiple reasons for that one of which is the geojson specification 21:57.240 --> 22:04.920 only supports two dimensional data by default I think um so it would be because it all backed 22:04.920 --> 22:10.200 the like the whole store concept is like everything is stored in geojson like everything is exported 22:10.200 --> 22:18.200 in geojson so did have to come up with a way to like represent that data uh but that kind of third 22:18.280 --> 22:24.920 what uh said coordinate it's like you can't do that without breaking the geojson specification really 22:24.920 --> 22:29.400 um so you'd have to come up with it like it could be put like you could add it as like a property 22:29.400 --> 22:35.800 in the property like basically as metadata like that said property but um yeah by default it doesn't 22:35.880 --> 22:54.360 support like three dimensional drawing out the box yeah so the question was um do you 22:54.360 --> 23:02.680 panel adding support for uh translating rotating scaling um so it does actually we do it does actually 23:02.760 --> 23:06.760 have support I didn't show it but we do actually have support for so there's one of the modes 23:06.760 --> 23:12.760 is select mode and you can select polygon and then you can then you can modify all the coordinates 23:12.760 --> 23:19.960 but you can also do scaling, rotating uh and just move like translation like just moving as well 23:19.960 --> 23:25.240 so it does support it but you have to enter like a select mode select the polygon and then 23:26.120 --> 23:34.280 start playing it so yeah yeah thanks there's a great question yeah sure 23:42.280 --> 23:49.160 yeah no it's a it's a good question so the question is do does tarot draw do the rendering or is it kind 23:49.160 --> 23:55.800 of um does it offload it to the mapping library to render the actual data so yeah as I say all 23:55.800 --> 24:03.160 the data is in um geojson and so essentially what happens is each of the adapters has a way to 24:04.280 --> 24:12.120 render geojson data via the underlying library so if you use like leaflet it will use the leaflet 24:12.760 --> 24:18.840 method for like rendering geojson um so yeah it's offloaded to the the library itself like we 24:18.920 --> 24:36.600 don't overlay like a webGL canvas and start doing stuff or anything like that no yeah it's really it's 24:36.600 --> 24:45.480 a really yeah that is really interesting so the question is about um like styling across multiple 24:45.560 --> 24:52.680 different mapping libraries is that like a good summary yeah they're like how do you so the the the 24:52.680 --> 24:57.480 the answer is um it's actually like it's quite fortunate really because a lot of the mapping libraries 24:57.480 --> 25:03.640 actually have quite similar levels of functionality so you can generally fill out the basic styling 25:03.640 --> 25:10.200 you can style consistently across like all the different mapping libraries quite like relatively 25:10.200 --> 25:15.240 easily it gets more complicated when you do like more obviously like more complex styling so 25:15.240 --> 25:22.120 if you have things like like one example is that we've wanted to do for ages is like dashed lines 25:22.120 --> 25:29.320 and so there's just one it's like for some reason like map map libre doesn't support dashed lines 25:29.320 --> 25:33.960 or it doesn't support dashed lines but it doesn't support like dashed lines that are 25:34.840 --> 25:41.160 based like powered by data if that makes sense so you can't dynamically change the 25:42.120 --> 25:47.320 how the gaps between all the dashes and all this kind of stuff so yeah you're kind of the 25:47.320 --> 25:52.600 problem is it's like one of the side effects of supporting all the libraries is you're kind of 25:52.600 --> 25:57.160 tied to like the lowest common denominator if that makes sense because you have to you can't just 25:57.160 --> 26:02.040 add support for like things that the other libraries don't also support so yeah it's a bit of a problem 26:02.040 --> 26:19.640 but it seems to work okay for the basic stuff yeah 26:20.600 --> 26:29.480 I missed the like first part of the question so with snapping like how much can you 26:29.800 --> 26:36.200 the question is like how much can you configure it so yeah good question so you can do 26:36.920 --> 26:42.200 coordinate snapping so that's a snapping to the vertices of like other let's say like polygons 26:42.200 --> 26:47.000 that you're you've drawn you can snap to the line kind of like as I was sharing but there's also 26:47.000 --> 26:52.680 we have a thing called like two custom and so two custom is essentially like a function and then 26:53.560 --> 27:00.680 it just expects you to return some coordinate so in two custom you could snap to an external 27:00.680 --> 27:05.880 data set or you could snap to let's say or you could snap to like right angles there's an example 27:05.880 --> 27:13.160 like if you just wanted to only draw like right angled polygons and so there is a way to allow 27:13.160 --> 27:18.040 if you really want like really bespoke custom snapping behavior then they have this like two 27:18.040 --> 27:29.960 custom function that allows you to snap to like anything you want basically so two custom is 27:29.960 --> 27:36.200 like a is a feature within tarot draw but then if you want to then it's up to you to decide like 27:36.200 --> 27:48.520 the minutia of like how what you want to snap to basically yeah thanks