<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="clipper_unminified.js"></script> <script src="raphael-min.js"></script> <script src="jquery.min.js"></script> <script> /* * jQuery repeatedclick v1.0.5 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * Written by: Alexandr Zykov <alexandrz@gmail.com> */ if (typeof (jQuery) != "undefined") jQuery.fn.hold = function (h, j) { var c = jQuery.extend( { duration: 350, speed: 0.85, min: 50 }, j); "undefined" === typeof jQuery.repeatedEvents && (jQuery.repeatedEvents = []); jQuery.repeatedEvents.push(h); var k = jQuery.repeatedEvents.length - 1, d, e; return this.each(function () { d = function (f, b, a) { var g = this; jQuery.repeatedEvents[f].call(g, a); e = setTimeout(function () { d.call(g, f, b > c.min ? b * c.speed : b, a) }, b) }; jQuery(this).mousedown(function (a) { d.call(this, k, c.duration, a) }); var a = function () { "undefined" !== typeof e && clearInterval(e) }; jQuery(this).mouseout(a); jQuery(this).mouseup(a) }) }; </script> <script> /* * TotalStorage v. 1.1.2 * Copyright (c) 2012 Jared Novack & Upstatement (upstatement.com) * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * @author Jared Novack/jared@upstatement.com * @url http://upstatement.com/blog/2012/01/jquery-local-storage-done-right-and-easy/ */ if (typeof (jQuery) != "undefined") (function (c) { var e = window.localStorage, f; f = "undefined" == typeof e || "undefined" == typeof window.JSON ? !1 : !0; c.totalStorage = function (b, a) { return c.totalStorage.impl.init(b, a) }; c.totalStorage.setItem = function (b, a) { return c.totalStorage.impl.setItem(b, a) }; c.totalStorage.getItem = function (b) { return c.totalStorage.impl.getItem(b) }; c.totalStorage.getAll = function () { return c.totalStorage.impl.getAll() }; c.totalStorage.deleteItem = function (b) { return c.totalStorage.impl.deleteItem(b) }; c.totalStorage.impl = { init: function (b, a) { return "undefined" != typeof a ? this.setItem(b, a) : this.getItem(b) }, setItem: function (b, a) { if (!f) try { return c.cookie(b, a), a } catch (d) { console.log("Local Storage not supported by this browser. Install the cookie plugin on your site to take advantage of the same functionality. You can get it at https://github.com/carhartl/jquery-cookie") } var g = JSON.stringify(a); e.setItem(b, g); return this.parseResult(g) }, getItem: function (b) { if (!f) try { return this.parseResult(c.cookie(b)) } catch (a) { return null } return this.parseResult(e.getItem(b)) }, deleteItem: function (b) { if (!f) try { return c.cookie(b, null), !0 } catch (a) { return !1 } e.removeItem(b); return !0 }, getAll: function () { var b = []; if (f) for (d in e) d.length && b.push( { key: d, value: this.parseResult(e.getItem(d)) }); else try { for (var a = document.cookie.split(";"), d = 0; d < a.length; d++) { var g = a[d].split("=")[0]; b.push( { key: g, value: this.parseResult(c.cookie(g)) }) } } catch (h) { return null } return b }, parseResult: function (b) { var a; try { a = JSON.parse(b), "true" == a && (a = !0), "false" == a && (a = !1), parseFloat(a) == a && "object" != typeof a && (a = parseFloat(a)) } catch (c) {} return a } } })(jQuery); </script> <meta charset=utf-8 /> <title>Javascript Clipper Main Demo</title> <style> #outer_div { display:table; } #clipper_version { text-align: center; font-weight: bold; font-size: 19px; } .textarea_hide_buttons { margin-bottom: 6px; margin-top: 4px; } body { background-color: #F8F8F8; } p { margin: 0px; padding: 0px; } th { background-color: #DDDDDD; font-weight: bold; padding: 0px; } body, th, td, input, legend, fieldset, p, b, button, select, textarea { font-size: 13px; font-family: Arial, Helvetica, sans-serif; } #p, #_p { background-color: #ffffff; border: 2px solid #AAAAAA; } .svg_mypath { stroke: black; stroke-width: 1; fill: black; fill-opacity: 0.3; pointer-events: none; } #p1, #_p1 { fill: #00009C; fill-opacity: 0.06; stroke: #D3D3DA; stroke-opacity: 1.0; stroke-width: 0.8; } .openpath { fill: none !important; // to allow open paths no-fill } #p2, #_p2 { fill: #9C0000; fill-opacity: 0.06; stroke: #FFA07A; stroke-opacity: 1.0; stroke-width: 0.8; } #p3, #_p3 { fill: #80ff9C; fill-opacity: 0.5; stroke: #003300; stroke-opacity: 1.0; stroke-width: 0.8; } #svg_source_textarea { width: 1215px; height: 300px; } #benchmark_exports_textarea { width: 1215px; height: 300px; } div#svgcontainer { margin-right: 2px; margin-top: 6px; } div#benchmark_div_outer { width: 100%; } div#benchmark_div { width: 100%; } #benchmark_fieldset { width: 367px; min-width: 367px; height: 350px; } .buttons { display: inline-block; padding: 0px; padding-left: 12px; padding-right: 12px; background-color: #666666; color: white; border-radius: 10px; text-align: center; line-height: 20px; font-size: 13px; cursor: pointer; margin-bottom: 2px; margin-top: 2px; font-family: Helvetica, Arial, sans-serif; white-space: nowrap; } span { font-weight: normal; } .span_title { font-weight: bold; } LEGEND { font-weight: bold; } FIELDSET { background-color: #EEEEEE; /* border-radius: 4px 4px 7px 7px; -moz-border-radius: 4px 4px 7px 7px; -webkit-border-radius: 4px 4px 7px 7px; */ border: 2px solid #AAAAAA; white-space: nowrap; } table { border: 0px; } .subpolylinks { cursor: pointer; font-size: 13px; padding: 2px; } .subpolylinks: hover { background-color: #BBBBBB; } .subpolylinks_disabled { font-size: 13px; padding: 2px; } /* To prevent odd text resizing in mobile Safari */ @media only screen and (max-device-width: 480px) { .body, p, fieldset, td, th { -webkit-text-size-adjust: 100% } } .polygon_explorer { text-align: left; border-collapse: collapse; white-space: normal; width: 461px; } .polygon_explorer th { font-weight: bold; } .polygon_explorer>tr>th, .polygon_explorer>tr>td, .polygon_explorer>tbody>tr>th, .polygon_explorer>tbody>tr>td { border: 1px solid #666666; padding: 3px 4px 3px 4px; vertical-align: top; } .polygons_fieldset { border-collapse: collapse; width: 100%; } .polygons_fieldset td { vertical-align: top; white-space: nowrap; padding: 0px; padding-right: 10px; } .polygons_fieldset input[type=radio] { margin-left: 0px; } .random { border-collapse: collapse; width: 100%; } .random td { padding: 0px; padding-right: 10px; } .random_inputs { width: 25px } .transform_inputs { width: 27px } .random th { padding: 0px; padding-right: } .random th { background-color: transparent; } .random_new_th { background-color: transparent; } .random_new_th button { margin: 0px; } .random button, .random input { margin-bottom: 0px; margin-top: 0px; } #subj_polygon_count { margin-bottom: 2px; } .filltype_cliptype { border-collapse: collapse; } .filltype_cliptype td { vertical-align: top; padding: 0px; } .offset_outer { border-collapse: collapse; width: 100%; } .offset_outer td { vertical-align: top; white-space: nowrap; padding: 0px; } .offset_outer input[type=radio] { margin-left: 0px; } .offset_inner input[type=text] { margin-bottom: 2px; } .offset_inner { border-collapse: collapse; } .offset_inner td { vertical-align: middle; height: 100%; padding-right: 2px; } #custom_polygons_fieldset { display: none; } #random_polygons_fieldset { display: none; } #misc_fieldset { min-height: 81px; } .custom_polygon_input { width: 285px; height: 15px; padding: 2px; line-height: 15px; } #polygon_explorer_string_inp { margin: 0px; height: 15px; width: 323px; padding: 2px; line-height: 15px; } #custom_polygon_inputs { display: block; } #custom_poly_message_box_green { display: none; opacity: 0; position: absolute; top: 0px; left: 0px; height: 0px; width: 200px; vertical-align: middle; text-align: center; border: 2px solid #106712; background-color: #A3F1A5; padding: 8px; padding-left: 11px; padding-right: 11px; border-radius: 6px; font-size: 16px; z-index: 2; } .custom_polygon_inputs_table { border-collapse: collapse; } #help_builtin_polygon_sets, #help_output_format, #help_custom_polygon { padding-left: 7px; padding-right: 7px; } #misc_fieldset { white-space: normal; } .subpolylinks_selected { color:red; } /* #outertable > tbody > tr > td { border:1px solid red; } */ </style> </head> <body> <div id="outer_div"> <div id="clipper_version">Javascript Clipper</div> <table id="outertable" style="margin-bottom:5px"> <tr> <td id="td0" style="vertical-align:top;width:353px;min-width:353px"> <FIELDSET id="PolygonsFieldset"> <LEGEND title="Builtin polygons">Polygons</LEGEND> <table class="polygons_fieldset"> <tr> <td> <input type="radio" name="polygons" value="0">Arrows <br> <input type="radio" name="polygons" value="1">Texts <br> <input type="radio" name="polygons" value="2">Rects <br> </td> <td> <input type="radio" name="polygons" value="3">ZigZag <br> <input type="radio" name="polygons" value="4" title="Random rectangles">RandRects <br> <input type="radio" name="polygons" value="5" title="Random polygons">Random <br> </td> <td> <input type="radio" name="polygons" value="11" title="Random Grids">RandGrid <br> <input type="radio" name="polygons" value="6">Star & rect <br> <input type="radio" name="polygons" value="7">Spiral <br> </td> <td style="padding-right:0px"> <input type="radio" name="polygons" value="8">Grid & star <br> <input type="radio" name="polygons" value="9">Glyph <br> <input type="radio" name="polygons" value="10" title="Your own custom polygon sets">Custom <br> </td> </tr> </table> </FIELDSET> <FIELDSET id="custom_polygons_fieldset" style="position:relative"> <LEGEND>Your own custom polygons</LEGEND> <select name="custom_polygons_select" id="custom_polygons_select" title="Saved custom polygon sets"></select> <select name="sample_custom_polygon" id="sample_custom_polygon" title="Get Builtin polygon set"> <option value="">- Builtin -</option> <option value="0">Arrows</option> <option value="1">Texts</option> <option value="2">Rects</option> <option value="3">ZigZag</option> <option value="4">RandRects</option> <option value="5">Random</option> <option value="6">Star & rect</option> <option value="7">Spiral</option> <option value="8">Grid & star</option> <option value="9">Glyph</option> <option value="12">Collinear test</option> </select> <button id="help_builtin_polygon_sets" title="Get help about Builtin polygon sets">?</button> <div id="custom_polygon_inputs"> <table class="custom_polygon_inputs_table"> <tr> <td> <b title="Here you can type or paste custom subject polygons. Click the '?' button below to get help about string formats.">Subj</b> </td> <td> <textarea class="custom_polygon_input" id="custom_polygon_subj" value=''></textarea> </td> </tr> <tr> <td> <b title="Here you can type or paste custom clip polygons. Click the '?' button below to get help about string formats.">Clip</b> </td> <td> <textarea class="custom_polygon_input" id="custom_polygon_clip" value=''></textarea> </td> </tr> </table> <button id="save_custom_polygon" title="Update polygon set">Save</button> <button id="add_as_new_custom_polygon" title="Save as a new custom polygon set">Save as new</button> <button id="remove_custom_polygon" title="Remove selected custom polygon set">Del</button> <button id="removeall_custom_polygon" title="Remove all custom polygon sets">Del all</button> <button id="help_custom_polygon" title="Get help about custom polygons">?</button> </div> <div id="custom_poly_message_box_green"></div> </FIELDSET> <FIELDSET id="random_polygons_fieldset"> <LEGEND>Random polygon settings</LEGEND> <table class="random"> <thead> <tr> <th class="random_new_th"> <button id="generate_random_polygons" title="Generate random polygons">New</button> </th> <th>Polygon count</th> <th style="padding-right:0px">Point count</th> </tr> </thead> <tbody> <tr> <td><b>Subject</b> </td> <td> <button id="subj_polygon_count_minus"> - </button> <input class="random_inputs" type="text" id="subj_polygon_count" value="1"> <button id="subj_polygon_count_plus"> + </button> </td> <td style="padding-right:0px"> <button id="subj_point_count_minus"> - </button> <input class="random_inputs" type="text" id="subj_point_count" value="1"> <button id="subj_point_count_plus"> + </button> </td> </tr> <tr> <td><b>Clip</b> </td> <td> <button id="clip_polygon_count_minus"> - </button> <input class="random_inputs" type="text" id="clip_polygon_count" value="1"> <button id="clip_polygon_count_plus"> + </button> </td> <td style="padding-right:0px"> <button id="clip_point_count_minus"> - </button> <input class="random_inputs" type="text" id="clip_point_count" value="1"> <button id="clip_point_count_plus"> + </button> </td> </tr> </tbody> </table> </FIELDSET> <FIELDSET id="random_grids_fieldset"> <LEGEND>Random grid settings</LEGEND> <table class="random_grid_table"> <thead> <tr> <th class="random_new_th"></th> <th>Grid Type</th> </tr> </thead> <tbody> <tr> <td class="random_new_th"> <button id="generate_random_grids" title="Generate random grids">New</button> </td> <td> <button id="random_grid_type_minus"> - </button> <input class="random_inputs" type="text" id="random_grid_type" value="1"> <button id="random_grid_type_plus"> + </button> </td> </tr> </tbody> </table> </FIELDSET> <FIELDSET id="transform_fieldset"> <LEGEND>Transform</LEGEND> <table class="transforms_table"> <thead> <tr> <th style="text-align:center;"><b title="Rotate paths around center">Rotate</b> </th> <th style="text-align:center;"><b title="Make perspective distort to paths">Distort</b> </th> </tr> </thead> <tbody> <tr> <td style="padding-right:0px"> <button id="transform_rotation_minus"> - </button> <input class="transform_inputs" type="text" id="transform_rotation" value="0"> <button id="transform_rotation_plus"> + </button> </td> <td style="padding-right:0px"> <button id="transform_distort" title="Generate new random Distort">New</button> <button id="transform_distort_sample1" title="Distort Sample 1">S1</button> <button id="transform_distort_sample2" title="Distort Sample 2">S2</button> </td> <td style="padding-right:0px"> <button id="transform_reset"><span title="Remove transformations">Reset</span> </button> </td> </tr> </tbody> </table> </FIELDSET> <table id="filltype_cliptype_table" class="filltype_cliptype" style="width:100%"> <tr> <td> <FIELDSET> <LEGEND>Subject FillType</LEGEND> <input type="radio" name="subject_fillType" value="0">EvenOdd <input type="radio" name="subject_fillType" value="1">NonZero</FIELDSET> </td> <td> <FIELDSET> <LEGEND>Clip FillType</LEGEND> <input type="radio" name="clip_fillType" value="0">EvenOdd <input type="radio" name="clip_fillType" value="1">NonZero</FIELDSET> </td> </tr> </table> <FIELDSET id="ClipTypeFieldset"> <LEGEND>Clip type (operation)</LEGEND> <p> <input type="radio" name="clipType" value="">No <input type="radio" name="clipType" value="0">Intersect <input type="radio" name="clipType" value="1">Union <input type="radio" name="clipType" value="2">Difference <input type="radio" name="clipType" value="3" checked>Xor</p> </FIELDSET> <FIELDSET id="CleaningFieldset"> <LEGEND>Cleaning , Simplifying, Lightening and Parameters</LEGEND> <p title=""> <b> <span class="span_title" title="Clean. Removes vertices: A) that join co-linear edges, or join edges that are almost co-linear (such that if the vertex was moved no more than the specified distance the edges would be co-linear), B) that are within the specified distance of an adjacent vertex (this is needed for preventing polygon brekage when offsetting), C) that are within the specified distance of a semi-adjacent vertex together with their out-lying vertices. Cleaning is done before offsetting.">Clean</span> </b> <input type="checkbox" id="clean" value="1"> <input style="width:34px" type="text" value="" id="cleandelta" title="Delta. The distance used for Clean. Sequential vertices are joined if they are at or below this distance of each other."> <b><span class="span_title" title="Simplify. Convert complex (self-intersecting) polygon to simple ones. Produces multiple polygons, if there are self-intersections. Note! Not work in self-intersections that are too small, you have to remove too-near-vertices using Clean feature. This operation is done before offsetting.">Simplify</span></b> <input type="checkbox" id="Simplify" value="1"> <b><span class="span_title" title="Lighten. Removes unnecessary vertices. Not included in original Clipper. This operation is done after offsetting.">Lighten</span></b> <input type="checkbox" id="lighten" value="1"> <input style="width:34px;" type="text" value="" id="lighten_distance" title="Tolerance. The distance that is used when lightening polygon. Removes middle vertex of three sequential vertices, if the middle vertex is under (or at) this distance of the line between start and end vertex."> <br> <b><span class="span_title" title="PreserveCollinear. Prevents the removal of 'inner' vertices when three or more vertices are collinear in solution paths.">PreserveCollinear</span></b> <input type="checkbox" id="PreserveCollinear" value="1"> <b><span class="span_title" title="ReverseSolution. When this property is set to true, polygons returned in the solution parameter of the Execute() method will have orientations opposite to their normal orientations.">Reverse</span></b> <input type="checkbox" id="ReverseSolution" value="1"> <b><span class="span_title" title="StrictlySimple. Force polygons returned in the solution parameter of the Execute() method to be splitted into simple polygons.">ToSimple</span></b> <input type="checkbox" id="StrictlySimple" value="1"> </p> </FIELDSET> <FIELDSET id="OffsettingFieldset"> <LEGEND title="Offsetting polygons with positive or negative amount and offsetting open paths (lines).">Offsetting</LEGEND> <table class="offset_outer"> <tr> <td colspan="3"> <table style="width:100%;border-spacing: 0; margin:0px; margin-bottom:4px;border-bottom:1px dashed #AAA"> <tr> <td style="padding-bottom:3px"> <b style="display:inline"><span class="span_title" style="display:inline;padding-bottom:3px" title="How start and end of path are represented">EndType</span></b> <input type="radio" name="endType" value="0"><span title="OpenSquare">OpenSquare</span> <input type="radio" name="endType" value="1"><span title="OpenRound">OpenRound</span> <input type="radio" name="endType" value="2"><span title="OpenButt">OpenButt</span> <br> <input type="radio" name="endType" value="3"><span title="ClosedLine">ClosedLine</span> <input type="radio" name="endType" value="4"><span title="ClosedPolygon">ClosedPolygon</span> </td> </tr> </table> </td> </tr> <tr> <td style="padding-right:6px;"> <b><span class="span_title" style="display:block;padding-bottom:3px" title="Which of poly types is used for offsetting">PolyType</span></b> <input type="radio" name="offsettable_poly" value="1"> <span title="Subject polygon is used for offsetting">Subject</span> <br> <input type="radio" name="offsettable_poly" value="2"> <span title="Clip polygon is used for offsetting">Clip</span> <br> <input type="radio" id="offsettable_poly3" name="offsettable_poly" value="3" checked> <span title="Solution polygon (clip operation result) is used for offsetting">Solution</span> </td> <td style="padding-right:6px;"> <b><span class="span_title" style="display:block;padding-bottom:3px" title="Edge join type">JoinType</span></b> <input type="radio" name="joinType" value="0" checked> <span title="Convex edge joins are squared off at exactly delta units.">Square</span> <br> <input type="radio" name="joinType" value="1"> <span title="Convex edge joins are rounded off at exactly delta units.">Round</span> <br> <input type="radio" name="joinType" value="2"> <span title="Convex edge joins are squared off only when a new vertex would exceed limit * delta distance from the initial vertex location.">Miter</span> <br> </td> <td style="padding-right:0px"> <table class="offset_inner"> <!-- <tr> <td style="padding-right:6px;"> <b><span class="span_title" style="display:block;padding-bottom:3px" title="">Closed</span></b> </td> <td> <input type="checkbox" id="off_poly_closed" name="off_poly_closed" value="1" checked> </td> </tr> --> <tr> <td style="padding-right: 6px;"> <b id="LimitTitle" title="MiterLimit sets the maximum distance in multiples of delta that vertices can be offset from their original positions before squaring is applied.">Mlimit</b> </td> <td> <button id="miterLimit_minus"> - </button> </td> <td> <input type="text" id="miterLimit" value="" style="width:50px"> </td> <td> <button id="miterLimit_plus"> + </button> </td> </td> </tr> <tr> <td style="padding-right: 6px;"> <b id="arcToleranceTitle" title="ArcTolerance specifies the maximum distance flattened path will deviate from the 'true' arc. Only relevant when JoinType is jtRound and/or EndType is etRound.">AToler</b> </td> <td> <button id="arcTolerance_minus"> - </button> </td> <td> <input type="text" id="arcTolerance" value="" style="width:50px"> </td> <td> <button id="arcTolerance_plus"> + </button> </td> </td> </tr> <tr> <td style="padding-right: 6px;"> <b title="Amount of offset. Paths may be open or closed paths. With closed paths (polygons), positive delta values 'expand' outer contours and 'shrink' inner 'hole' contours. Negative deltas do the reverse. With open paths (lines) negative values have no effect.">Delta</b> <td> <button id="delta_minus"> - </button> </td> <td> <input type="text" id="delta" value="" style="width:50px;font-weight:bold"> </td> <td> <button id="delta_plus"> + </button> </td> </td> </tr> </table> </td> </tr> </table> </FIELDSET> <FIELDSET id="ScaleFieldset"> <LEGEND>Scale</LEGEND> <p style="width:200px;"> <button id="scale_minus"> - </button> <input type="text" id="scale" value="" style="width:80px"> <button id="scale_plus"> + </button> <span id="scaletest"></span> <b>Bigints used:</b> <span id="biginteger_used"></span> </p> </FIELDSET> <FIELDSET id="misc_fieldset"> <LEGEND>Misc</LEGEND> <button id="show_svg_source" title="Show current SVG and it's source in textarea at the bottom of the page">Show SVG, Bottom</button> <b>Bevel</b> <input type="checkbox" id="bevel" value="1" title="Uncheck this to speedup drawing"> <b>Explorer</b> <input type="checkbox" id="sub_poly_links_update" value="1" title="Enable/disable Polygon Explorer"> <br> <button id="benchmark1" title="Execute Normal benchmark">Run NB</button> <button id="benchmark1b" title="Execute Normal benchmark 5x">Run NB 5x</button> <button id="benchmark2" title="Execute Big Integer benchmark">Run BIB</button> <button id="benchmark2b" title="Execute Big Integer benchmark 5x">Run BIB 5x</button> <button id="benchmark3" title="Execute Random benchmark">Run Random Benchmark</button> </FIELDSET> </td> <td id="td1" style="vertical-align:top;width:506px;"> <div id="svgcontainer"></div> <FIELDSET id="polygon_explorer_fieldset"> <LEGEND>Polygon explorer</LEGEND> <div id="polygon_explorer_div" style="padding-left:1px;/*overflow-y:auto;overflow-x:visible;max-height:300px*/"> <table class="polygon_explorer"> <tr> <td colspan="4" style="padding:0px;white-space:nowrap; border:0px"> <table style="padding:0px;border-collapse:collapse"> <tr> <td style="padding:0px;vertical-align:middle"> <textarea id="polygon_explorer_string_inp" title="When you click the numbers below, here comes coordinates of the clicked polygon (or polygons) as string." value="">Click below to see coordinates here!</textarea> </td> <td style="padding:0px;vertical-align:middle"> <select id="output_format" title="Output format" style="width:73px;margin-left:5px"> <option value="0">Clipper</option> <option value="1">Plain</option> <option value="2">SVG</option> </select> <b>Ex</b> <input type="checkbox" id="ExPolygons" value="1" title="Show solution as ExPolygons"> </td> </tr> </table> </td> </tr> <tr> <th style="white-space:nowrap; width:31px;" title="Polygon type">Type</th> <th style="white-space:nowrap; width:35px;" title="Count of subpolygons">Polys</th> <th style="white-space:nowrap; width:40px;" title="Count of points in all sub polygons. Hover numbers below to see the whole multi-polygon highlighted. Click them to see coordinates as strings and the area of multi-polygon (sum of areas of sub polygons).">Points</th> <th style="white-space:nowrap;" title="Count of points in sub polygons. Hover numbers below to see sub polygons highlighted. Click to see coordinates as strings and the area of sub polygon.">Points in subpolygons</th> </tr> <tr> <td id="subject_box" title="Subject"> <b>Subj</b> </td> <td> <span id="subj_subpolygons"></span> </td> <td> <span id="subj_points_total" class="subpolylinks" onclick="popup_path(undefined,'1')" onmouseover="show_path(undefined,'1')" onmouseout="hide_path()"></span> </td> <td> <span id="subj_points_in_subpolygons"></span> </td> </tr> <tr> <td id="clip_box" title="Clip"> <b>Clip</b> </td> <td> <span id="clip_subpolygons"> </span> </td> <td><span id="clip_points_total" class="subpolylinks" onclick="popup_path(undefined,'2')" onmouseover="show_path(undefined,'2')" onmouseout="hide_path()"></span> </td> <td> <span id="clip_points_in_subpolygons"></span> </td> </tr> <tr> <td id="solution_box" title="Solution"> <b>Solu</b> </td> <td> <span id="solution_subpolygons"></span> </td> <td> <span id="solution_points_total" class="subpolylinks" onclick="popup_path(undefined,'3',solution_points_total)" onmouseover="show_path(undefined,'3',solution_points_total)" onmouseout="hide_path()"></span> </td> <td> <span id="solution_points_in_subpolygons"> </span> </td> </tr> <tr> <td> <b>Total</b> </td> <td> <b><span id="all_subpolygons"></span></b> </td> <td> <b><span id="points_total"></span></b> </td> <td style="padding-bottom:0px;padding-top:0px;text-align:right;white-space:nowrap"> <div id="area" style="padding:0px;display:inline-block;width:90%;text-align:left" title="Click above numbers to see the area of sub polygons.">Click above to see some polygon metrics!</div> <button id="help_output_format" title="Get help about output format">?</button> </td> </tr> </table> </div> </FIELDSET> </td> <td id="td2" style="width:353px;vertical-align:top;"> <FIELDSET id="benchmark_fieldset_f" style="min-height:517px"> <LEGEND id="#benchmark_fieldset">Benchmark</LEGEND> <div id="benchmark_div_outer"> <div id="benchmark_div"></div> <div id="benchmark_multiple_table_cont"></div> </div> </FIELDSET> </td> <td id="td3" style="vertical-align:top;"> <div id="svg_source_container2"></div> </td> </tr> </table> <div id="svg_source_container"></div> <div id="benchmark_exports_container"></div> <script> var is_float_clipper = true; function set_clipper_float_or_int() { var which; if (typeof ClipperLib !== 'undefined' && typeof ClipperLib.FPoint !== 'undefined') which = 'f'; else which = 'i'; if (which === 'f') { is_float_clipper = true; scale = 1; $('#scale').val(scale); $('#benchmark2,#benchmark2b,#ScaleFieldset').css('display', 'none'); var version; if (typeof ClipperLib !== 'undefined' && typeof ClipperLib.version !== 'undefined') version = ClipperLib.version; else version = 'Unknown version'; $('#clipper_version').html('Javascript Clipper - ' + version + ' (FPoint)'); } else if (which === 'i') { is_float_clipper = false; scale = 100; $('#scale').val(scale); $('#benchmark2,#benchmark2b,#ScaleFieldset').css('display', ''); var version; if (typeof ClipperLib !== 'undefined' && typeof ClipperLib.version !== 'undefined') version = ClipperLib.version; else version = 'Unknown version'; $('#clipper_version').html('Javascript Clipper - ' + version + ' (IntPoint)'); } } if (is_float_clipper) var scale = 1; else var scale = 100; var global_do_not_round_and_scale = false; var scale_addition = 100; var polygons_default = 1; var selected_polygon_set = 2; var joinType = 0; var endType = 4; var miterLimit = 2.0; var arcTolerance = 0.05; var delta = 0; var AutoFix = false; var ExPolygons = false; var SolutionPolygonClicked = false; var SolutionPolygonString = ""; var Simplify = false; var clean = false; var cleandelta_default = 0.1; var cleandelta = cleandelta_default; var lighten = false; var lighten_distance_default = 0.1; var lighten_distance = lighten_distance_default; var PreserveCollinear = false; var ReverseSolution = false; var StrictlySimple = false; var off_poly_closed = true; var subj_is_closed = true; var offsettable_poly = 3; var clipType = 0; var clipType_default = 0; var subject_fillType = 1; var clip_fillType = 1; var ss, cc, sss, cpr, p, ok = 1; var ss_copy; var cc_copy; var ss_transformed; var cc_transformed; var off_result; var SVG = {}, p, p1, p2, p3; var random_subj; var random_clip; var random_grid_subj; var rnd_sett = {}; var rnd_sett_defaults = {}; rnd_sett_defaults.rect = {}; rnd_sett_defaults.norm = {}; rnd_sett_defaults.rect. default = { clip_polygon_count: 1, clip_point_count: 4, subj_polygon_count: 2, subj_point_count: 8 }; rnd_sett_defaults.rect.min = { clip_polygon_count: 1, clip_point_count: 4, subj_polygon_count: 1, subj_point_count: 4 }; rnd_sett_defaults.rect.max = { clip_polygon_count: 100, clip_point_count: 100, subj_polygon_count: 100, subj_point_count: 100 }; rnd_sett_defaults.norm. default = { clip_polygon_count: 1, clip_point_count: 3, subj_polygon_count: 2, subj_point_count: 8 }; rnd_sett_defaults.norm.min = { clip_polygon_count: 1, clip_point_count: 3, subj_polygon_count: 1, subj_point_count: 3 }; rnd_sett_defaults.norm.max = { clip_polygon_count: 100, clip_point_count: 100, subj_polygon_count: 100, subj_point_count: 100 }; rnd_sett_defaults.current = "norm"; var rnd_grid_sett = { random_grid_type: 2 }; var transform = { rotation: 0, distort: null, distort_destination: null, destination1: [ { X: 100 * scale, Y: 10 * scale }, { X: 400 * scale, Y: 10 * scale }, { X: 490 * scale, Y: 340 * scale }, { X: 10 * scale, Y: 340 * scale }], destination2: [ { X: 50 * scale, Y: 10 * scale }, { X: 400 * scale, Y: 100 * scale }, { X: 490 * scale, Y: 250 * scale }, { X: 10 * scale, Y: 340 * scale }] }; var bevel = 0; var mypath = null; var scaled_paths = []; var subj_points_total = 0; var clip_points_total = 0; var solution_points_total = 0; var subj_subpolygons = 0; var clip_subpolygons = 0; var solution_subpolygons = 0; var bench; var sub_poly_links_update = 1; var benchmark1_globals = {}; var browserg; var repeat_times; var repeat = 0; var clicked_benchmark_button_id; var benchmark_exports = ""; var benchmark_running = 0; var benchmark_automatic_click = 0; var timeout_time_addition = 10; var grid_type_global = null; var polygon_id_global = null; // default_custom_subject_polygon = '[[{"X":90.58,"Y":144.44},{"X":84.83,"Y":141.55},{"X":84.84,"Y":141.56},{"X":79.29,"Y":137.67},{"X":73.79,"Y":132.61},{"X":73.8,"Y":132.62},{"X":67.31,"Y":125.14},{"X":63.22,"Y":119.64},{"X":98.93,"Y":130.63},{"X":98.91,"Y":130.61},{"X":99.02,"Y":130.66},{"X":99.02,"Y":130.65},{"X":97.46,"Y":134.4},{"X":93.93,"Y":139.6},{"X":90.86,"Y":144.22},{"X":90.87,"Y":144.21}]]'; // The Phantom image var default_custom_subject_polygon = '[[{"X":-29.42,"Y":106.23},{"X":-26.7,"Y":105.45},{"X":-11.55,"Y":101.73},{"X":0.12,"Y":99.72},{"X":9.69,"Y":98.94},{"X":17.63,"Y":99.17},{"X":24.29,"Y":100.23},{"X":23.93,"Y":92.91},{"X":24.08,"Y":81.36},{"X":25.12,"Y":70.62},{"X":26.99,"Y":60.59},{"X":29.66,"Y":51.22},{"X":33.11,"Y":42.43},{"X":37.31,"Y":34.29},{"X":42.16,"Y":26.9},{"X":47.77,"Y":20.05},{"X":53.98,"Y":13.98},{"X":60.82,"Y":8.61},{"X":68.2,"Y":4.01},{"X":76.04,"Y":0.24},{"X":84.37,"Y":-2.73},{"X":92.97,"Y":-4.8},{"X":101.89,"Y":-5.98},{"X":110.88,"Y":-6.23},{"X":120,"Y":-5.53},{"X":128.99,"Y":-3.88},{"X":137.63,"Y":-1.36},{"X":145.94,"Y":2.06},{"X":153.87,"Y":6.32},{"X":161.29,"Y":11.4},{"X":168.03,"Y":17.14},{"X":174.22,"Y":23.66},{"X":179.7,"Y":30.8},{"X":184.49,"Y":38.59},{"X":188.54,"Y":46.95},{"X":191.9,"Y":56.1},{"X":194.44,"Y":65.81},{"X":196.16,"Y":76.18},{"X":197,"Y":87.09},{"X":196.94,"Y":98.79},{"X":195.88,"Y":111.18},{"X":207.51,"Y":112.86},{"X":220.6,"Y":115.46},{"X":233.18,"Y":118.91},{"X":245.2,"Y":123.18},{"X":256.72,"Y":128.26},{"X":267.97,"Y":134.26},{"X":278.87,"Y":141.16},{"X":289.73,"Y":149.16},{"X":300.72,"Y":158.47},{"X":312.07,"Y":169.38},{"X":312.06,"Y":169.37},{"X":336.14,"Y":177.32},{"X":355.16,"Y":183.81},{"X":367.78,"Y":189},{"X":378.1,"Y":194.19},{"X":387.04,"Y":199.69},{"X":395.07,"Y":205.73},{"X":400.6,"Y":210.78},{"X":405.18,"Y":216.34},{"X":409.93,"Y":223.8},{"X":420.35,"Y":243.91},{"X":425.91,"Y":253.51},{"X":431.07,"Y":260.69},{"X":436.35,"Y":266.43},{"X":436.34,"Y":266.42},{"X":443.69,"Y":272.81},{"X":469.07,"Y":291.49},{"X":477.42,"Y":298.56},{"X":483.68,"Y":305.01},{"X":487.79,"Y":310.56},{"X":497.28,"Y":326.73},{"X":502.53,"Y":334.76},{"X":511.53,"Y":345.81},{"X":337.97,"Y":345.86},{"X":315.38,"Y":321.1},{"X":303.25,"Y":308.84},{"X":303.26,"Y":308.85},{"X":292.72,"Y":299.47},{"X":292.69,"Y":299.5},{"X":290.88,"Y":300.26},{"X":290.89,"Y":300.25},{"X":283.26,"Y":304.12},{"X":283.27,"Y":304.11},{"X":275.98,"Y":308.87},{"X":268.76,"Y":314.74},{"X":261.42,"Y":322.02},{"X":261.43,"Y":322.01},{"X":253.55,"Y":331.26},{"X":242.73,"Y":345.84},{"X":-29.42,"Y":345.86}],[{"X":127.69,"Y":269.76},{"X":127.68,"Y":269.77},{"X":133.88,"Y":268.63},{"X":133.87,"Y":268.64},{"X":139.54,"Y":266.65},{"X":139.53,"Y":266.66},{"X":144.66,"Y":263.86},{"X":144.65,"Y":263.87},{"X":149.4,"Y":260.18},{"X":149.39,"Y":260.19},{"X":153.81,"Y":255.5},{"X":158.06,"Y":249.51},{"X":162.29,"Y":241.74},{"X":166.81,"Y":231.1},{"X":166.8,"Y":231.11},{"X":176.87,"Y":202.06},{"X":182.04,"Y":188.77},{"X":182.04,"Y":188.78},{"X":182.02,"Y":188.77},{"X":181.74,"Y":188.64},{"X":181.75,"Y":188.65},{"X":179.85,"Y":188.27},{"X":178.29,"Y":188.8},{"X":178.3,"Y":188.79},{"X":176.74,"Y":190.4},{"X":176.75,"Y":190.39},{"X":173.98,"Y":196.05},{"X":173.14,"Y":196.87},{"X":172.34,"Y":196.57},{"X":171.01,"Y":194.4},{"X":174.86,"Y":188.74},{"X":180.8,"Y":179.01},{"X":185.49,"Y":169.61},{"X":185.48,"Y":169.62},{"X":188.88,"Y":160.79},{"X":188.87,"Y":160.8},{"X":191.15,"Y":152.4},{"X":191.14,"Y":152.41},{"X":192.39,"Y":144.4},{"X":192.38,"Y":144.41},{"X":192.65,"Y":136.76},{"X":192.65,"Y":136.77},{"X":191.95,"Y":129.43},{"X":191.96,"Y":129.44},{"X":190.36,"Y":122.45},{"X":189.2,"Y":126.33},{"X":186.64,"Y":132.72},{"X":183.5,"Y":138.19},{"X":179.85,"Y":142.75},{"X":175.82,"Y":146.34},{"X":171.49,"Y":149.01},{"X":166.88,"Y":150.79},{"X":162.01,"Y":151.66},{"X":157.07,"Y":151.61},{"X":152.08,"Y":150.61},{"X":147.07,"Y":148.62},{"X":142.21,"Y":145.63},{"X":137.56,"Y":141.62},{"X":133.27,"Y":136.62},{"X":129.46,"Y":130.68},{"X":129.03,"Y":130.72},{"X":129.04,"Y":130.71},{"X":124.06,"Y":131.87},{"X":124.07,"Y":131.86},{"X":119.96,"Y":133.69},{"X":116.46,"Y":136.26},{"X":116.47,"Y":136.25},{"X":113.27,"Y":139.82},{"X":107.23,"Y":149.32},{"X":104.14,"Y":153.18},{"X":101,"Y":155.72},{"X":97.49,"Y":157.4},{"X":93.11,"Y":158.38},{"X":88.02,"Y":158.61},{"X":83.43,"Y":157.91},{"X":79.22,"Y":156.35},{"X":75,"Y":153.77},{"X":70.26,"Y":149.63},{"X":60.57,"Y":138.77},{"X":54.38,"Y":132.43},{"X":54.39,"Y":132.44},{"X":49.11,"Y":128.26},{"X":43.79,"Y":125.19},{"X":43.54,"Y":126.2},{"X":43.55,"Y":126.19},{"X":43.13,"Y":133.69},{"X":43.13,"Y":133.68},{"X":43.66,"Y":140.71},{"X":43.65,"Y":140.7},{"X":45.09,"Y":147.46},{"X":45.08,"Y":147.45},{"X":47.49,"Y":154.24},{"X":47.48,"Y":154.23},{"X":51.23,"Y":161.76},{"X":63.98,"Y":182.09},{"X":67.55,"Y":189.18},{"X":69.73,"Y":195.4},{"X":70.92,"Y":201.58},{"X":71.16,"Y":207.87},{"X":70.43,"Y":214.58},{"X":68.63,"Y":221.85},{"X":68.56,"Y":221.68},{"X":68.68,"Y":203.83},{"X":68.68,"Y":203.84},{"X":68.16,"Y":197.1},{"X":68.17,"Y":197.11},{"X":67.05,"Y":192.75},{"X":67.06,"Y":192.76},{"X":65.5,"Y":189.85},{"X":65.51,"Y":189.86},{"X":63.49,"Y":187.86},{"X":60.94,"Y":186.59},{"X":60.95,"Y":186.6},{"X":57.55,"Y":186.01},{"X":57.78,"Y":189.41},{"X":57.77,"Y":189.4},{"X":59.32,"Y":201.46},{"X":59.31,"Y":201.45},{"X":61.68,"Y":212.76},{"X":61.67,"Y":212.75},{"X":64.76,"Y":223.11},{"X":64.75,"Y":223.1},{"X":68.47,"Y":232.45},{"X":72.73,"Y":240.71},{"X":77.44,"Y":247.84},{"X":82.45,"Y":253.81},{"X":82.44,"Y":253.8},{"X":87.82,"Y":258.8},{"X":93.45,"Y":262.8},{"X":93.44,"Y":262.79},{"X":99.44,"Y":265.89},{"X":99.43,"Y":265.88},{"X":105.67,"Y":268.07},{"X":105.66,"Y":268.06},{"X":112.58,"Y":269.42},{"X":112.57,"Y":269.41},{"X":120.65,"Y":270.08}],[{"X":121.49,"Y":240.71},{"X":118.05,"Y":239.68},{"X":115.54,"Y":238.06},{"X":113.86,"Y":235.97},{"X":112.96,"Y":233.43},{"X":112.86,"Y":230.29},{"X":112.9,"Y":230.33},{"X":114.24,"Y":231.32},{"X":114.23,"Y":231.31},{"X":117.3,"Y":232.52},{"X":117.29,"Y":232.51},{"X":122.05,"Y":233.17},{"X":132.1,"Y":233.03},{"X":140.49,"Y":233.06},{"X":139.8,"Y":234.49},{"X":137.79,"Y":236.7},{"X":134.63,"Y":238.72},{"X":130.41,"Y":240.25},{"X":125.83,"Y":240.94}],[{"X":90.76,"Y":219.11},{"X":91.11,"Y":218.28},{"X":92.59,"Y":216.41},{"X":95.22,"Y":214.69},{"X":99.6,"Y":213.14},{"X":106.53,"Y":211.9},{"X":117,"Y":211.2},{"X":143.09,"Y":211.3},{"X":151.49,"Y":210.93},{"X":151.31,"Y":211.49},{"X":149.72,"Y":213.46},{"X":147.43,"Y":214.88},{"X":143.97,"Y":215.82},{"X":138.58,"Y":216.09},{"X":117.5,"Y":214.37},{"X":117.51,"Y":214.38},{"X":108.81,"Y":214.35},{"X":101.81,"Y":215.22},{"X":101.82,"Y":215.21},{"X":95.89,"Y":216.85},{"X":95.9,"Y":216.84},{"X":90.72,"Y":219.22}],[{"X":131.9,"Y":198.38},{"X":131.72,"Y":195.25},{"X":132.38,"Y":192.96},{"X":133.78,"Y":191.21},{"X":136.84,"Y":189.34},{"X":140.91,"Y":187.09},{"X":142.52,"Y":185.35},{"X":143.3,"Y":183.24},{"X":143.3,"Y":183.25},{"X":143.22,"Y":183.13},{"X":141.54,"Y":180.12},{"X":139.65,"Y":174.9},{"X":138.32,"Y":168.14},{"X":137.62,"Y":158.87},{"X":137.76,"Y":144.77},{"X":142.77,"Y":159.79},{"X":145.49,"Y":170.4},{"X":146.69,"Y":178.4},{"X":146.78,"Y":184.55},{"X":146.02,"Y":189.28},{"X":144.58,"Y":192.89},{"X":142.54,"Y":195.66},{"X":139.94,"Y":197.69},{"X":136.5,"Y":199.14},{"X":132.22,"Y":199.86}],[{"X":108.17,"Y":188.43},{"X":106.35,"Y":187.41},{"X":105.13,"Y":185.72},{"X":104.56,"Y":183.25},{"X":104.61,"Y":183.31},{"X":104.81,"Y":183.53},{"X":104.8,"Y":183.52},{"X":106.39,"Y":184.64},{"X":106.38,"Y":184.63},{"X":108.44,"Y":184.92},{"X":114,"Y":183.64},{"X":116.83,"Y":183.49},{"X":119.09,"Y":184.26},{"X":121.14,"Y":185.99},{"X":120.5,"Y":186.31},{"X":114.98,"Y":188.22},{"X":110.98,"Y":188.8}],[{"X":163.89,"Y":141.31},{"X":166.4,"Y":137.22},{"X":174.87,"Y":127.72},{"X":177.63,"Y":123.62},{"X":179.28,"Y":119.59},{"X":179.28,"Y":119.6},{"X":179.24,"Y":119.6},{"X":179.25,"Y":119.59},{"X":176.7,"Y":119.79},{"X":176.71,"Y":119.78},{"X":170.65,"Y":120.87},{"X":170.66,"Y":120.86},{"X":164.55,"Y":122.95},{"X":164.56,"Y":122.94},{"X":148.93,"Y":130.62},{"X":148.93,"Y":130.61},{"X":149.21,"Y":132.61},{"X":149.2,"Y":132.6},{"X":150.57,"Y":136.41},{"X":152.55,"Y":139.41},{"X":152.54,"Y":139.4},{"X":155.11,"Y":141.71},{"X":155.1,"Y":141.7},{"X":158.43,"Y":143.41},{"X":158.42,"Y":143.4},{"X":162.62,"Y":144.5}],[{"X":90.87,"Y":144.21},{"X":90.86,"Y":144.22},{"X":93.93,"Y":139.6},{"X":97.47,"Y":134.4},{"X":99.02,"Y":130.65},{"X":99.02,"Y":130.66},{"X":98.92,"Y":130.62},{"X":98.93,"Y":130.63},{"X":63.23,"Y":119.65},{"X":67.31,"Y":125.14},{"X":73.8,"Y":132.62},{"X":73.79,"Y":132.61},{"X":79.3,"Y":137.68},{"X":84.84,"Y":141.56},{"X":84.83,"Y":141.55},{"X":90.59,"Y":144.44}],[{"X":128.47,"Y":127.41},{"X":128.46,"Y":127.42},{"X":134.55,"Y":125.73},{"X":134.54,"Y":125.74},{"X":141.57,"Y":122.7},{"X":141.56,"Y":122.71},{"X":154.9,"Y":115.21},{"X":164.19,"Y":110.32},{"X":171.16,"Y":107.57},{"X":177.57,"Y":106},{"X":183.83,"Y":105.4},{"X":190.12,"Y":105.74},{"X":182.19,"Y":101.42},{"X":182.2,"Y":101.43},{"X":175.96,"Y":98.85},{"X":175.97,"Y":98.86},{"X":170.13,"Y":97.45},{"X":170.14,"Y":97.46},{"X":164,"Y":96.98},{"X":157.13,"Y":97.46},{"X":157.08,"Y":97.55},{"X":156.47,"Y":98.59},{"X":153.09,"Y":103.35},{"X":149.58,"Y":106.83},{"X":145.83,"Y":109.3},{"X":141.79,"Y":110.89},{"X":137.21,"Y":111.67},{"X":131.97,"Y":111.55},{"X":125.78,"Y":110.38},{"X":117.8,"Y":107.78},{"X":92.32,"Y":96.78},{"X":92.33,"Y":96.79},{"X":83.94,"Y":93.95},{"X":83.95,"Y":93.96},{"X":77.47,"Y":92.65},{"X":77.48,"Y":92.66},{"X":72.09,"Y":92.45},{"X":67.49,"Y":93.16},{"X":67.5,"Y":93.15},{"X":63.28,"Y":94.72},{"X":63.29,"Y":94.71},{"X":59.49,"Y":97.13},{"X":55.9,"Y":100.53},{"X":55.91,"Y":100.52},{"X":52.52,"Y":105.09},{"X":49.25,"Y":111.18},{"X":52.77,"Y":110.06},{"X":58.91,"Y":108.7},{"X":64.9,"Y":108.31},{"X":70.86,"Y":108.86},{"X":77.27,"Y":110.42},{"X":84.53,"Y":113.27},{"X":105.04,"Y":123.87},{"X":105.03,"Y":123.86},{"X":111.74,"Y":126.51},{"X":111.73,"Y":126.5},{"X":117.29,"Y":127.77},{"X":117.28,"Y":127.76},{"X":122.82,"Y":128.06}]]'; // The Phantom Scull Ring var default_custom_clip_polygon = '[[{"X":385.77,"Y":166.95},{"X":386.68,"Y":182.21},{"X":386.15,"Y":187.13},{"X":384.96,"Y":190.99},{"X":382.95,"Y":194.32},{"X":379.91,"Y":197.42},{"X":375.8,"Y":200.17},{"X":370.59,"Y":202.47},{"X":364.37,"Y":204.13},{"X":357.67,"Y":204.95},{"X":350.93,"Y":204.85},{"X":344.71,"Y":203.87},{"X":339.59,"Y":202.19},{"X":335.52,"Y":199.95},{"X":332.61,"Y":197.37},{"X":330.67,"Y":194.53},{"X":329.62,"Y":191.41},{"X":329.4,"Y":187.83},{"X":330.02,"Y":183.99},{"X":331.34,"Y":181.14},{"X":333.27,"Y":179.05},{"X":336.11,"Y":177.4},{"X":340.71,"Y":176.05},{"X":352.22,"Y":173.98},{"X":356.3,"Y":172.51},{"X":361.25,"Y":169.4},{"X":370.03,"Y":163.12},{"X":373.94,"Y":161.22},{"X":377.01,"Y":160.6},{"X":379.53,"Y":160.94},{"X":381.9,"Y":162.19},{"X":384.3,"Y":164.67},{"X":385.77,"Y":166.93},{"X":385.77,"Y":166.95}],[{"X":270.77,"Y":163.84},{"X":273.88,"Y":163.4},{"X":276.36,"Y":163.91},{"X":280.12,"Y":166.08},{"X":285.42,"Y":169.2},{"X":291.02,"Y":171.33},{"X":299.79,"Y":173.33},{"X":307.68,"Y":175.13},{"X":311.52,"Y":176.78},{"X":314.01,"Y":178.71},{"X":315.73,"Y":181.15},{"X":316.83,"Y":184.41},{"X":317.2,"Y":188.89},{"X":316.7,"Y":192.44},{"X":315.33,"Y":195.6},{"X":313.05,"Y":198.56},{"X":309.77,"Y":201.19},{"X":305.39,"Y":203.45},{"X":299.95,"Y":205.12},{"X":293.7,"Y":205.99},{"X":287.12,"Y":205.96},{"X":280.75,"Y":205},{"X":275.02,"Y":203.24},{"X":270.05,"Y":200.77},{"X":266.08,"Y":197.81},{"X":263.1,"Y":194.47},{"X":260.95,"Y":190.7},{"X":259.68,"Y":186.54},{"X":259.29,"Y":181.92},{"X":259.86,"Y":176.86},{"X":261.36,"Y":171.68},{"X":263.13,"Y":168.56},{"X":265.48,"Y":166.25},{"X":268.64,"Y":164.55},{"X":270.77,"Y":163.84},{"X":270.77,"Y":163.84}],[{"X":303.94,"Y":227.57},{"X":303.74,"Y":222.63},{"X":304.44,"Y":218.35},{"X":305.94,"Y":214.59},{"X":308.24,"Y":211.27},{"X":311.35,"Y":208.46},{"X":315.13,"Y":206.32},{"X":319.55,"Y":204.91},{"X":324.31,"Y":204.37},{"X":329.09,"Y":204.77},{"X":333.4,"Y":206.03},{"X":337.08,"Y":208.03},{"X":339.99,"Y":210.61},{"X":342.11,"Y":213.69},{"X":343.43,"Y":217.19},{"X":343.94,"Y":221.2},{"X":343.59,"Y":225.38},{"X":342.53,"Y":228.01},{"X":340.69,"Y":230.17},{"X":337.79,"Y":232.02},{"X":333.81,"Y":233.34},{"X":328.46,"Y":234.03},{"X":322.02,"Y":233.83},{"X":315.23,"Y":232.68},{"X":309.37,"Y":230.81},{"X":305.39,"Y":228.73},{"X":303.99,"Y":227.61},{"X":303.94,"Y":227.57}],[{"X":421.16,"Y":64.34},{"X":421.16,"Y":64.45},{"X":422.7,"Y":96.81},{"X":424.28,"Y":149.29},{"X":425.26,"Y":216.18},{"X":425.57,"Y":327.02},{"X":220.65,"Y":327.02},{"X":220.41,"Y":312.05},{"X":219.69,"Y":230.46},{"X":219.9,"Y":144.66},{"X":221.01,"Y":65.92},{"X":233.74,"Y":65.34},{"X":264.63,"Y":64.78},{"X":325.38,"Y":65.31},{"X":363.93,"Y":65.31},{"X":393.46,"Y":64.48},{"X":420.05,"Y":62.8},{"X":420.8,"Y":62.92},{"X":421.16,"Y":64.34}],[{"X":404.57,"Y":215.13},{"X":404.58,"Y":215.08},{"X":405.83,"Y":205.87},{"X":406.55,"Y":194.49},{"X":406.3,"Y":183.7},{"X":405.16,"Y":173.57},{"X":403.17,"Y":164.03},{"X":400.34,"Y":155.01},{"X":396.73,"Y":146.61},{"X":392.34,"Y":138.76},{"X":387.23,"Y":131.54},{"X":381.47,"Y":125.02},{"X":375.05,"Y":119.16},{"X":368.04,"Y":114.01},{"X":360.39,"Y":109.58},{"X":352.3,"Y":105.99},{"X":343.88,"Y":103.28},{"X":335.22,"Y":101.47},{"X":326.42,"Y":100.59},{"X":317.57,"Y":100.64},{"X":308.77,"Y":101.63},{"X":300.3,"Y":103.53},{"X":292.06,"Y":106.33},{"X":284.32,"Y":109.94},{"X":277.01,"Y":114.36},{"X":270.11,"Y":119.65},{"X":263.83,"Y":125.67},{"X":258.83,"Y":131.66},{"X":253.44,"Y":139.77},{"X":248.35,"Y":149.13},{"X":244.11,"Y":158.88},{"X":241,"Y":168.28},{"X":239,"Y":177.21},{"X":238.09,"Y":185.4},{"X":238.17,"Y":192.9},{"X":239.13,"Y":199.57},{"X":240.91,"Y":205.61},{"X":243.45,"Y":211.04},{"X":246.09,"Y":214.67},{"X":249.63,"Y":217.9},{"X":254.56,"Y":221.04},{"X":270.07,"Y":228.23},{"X":275.76,"Y":231.57},{"X":279.77,"Y":234.93},{"X":282.82,"Y":238.64},{"X":285.08,"Y":242.87},{"X":286.61,"Y":247.72},{"X":287.31,"Y":253.67},{"X":287.19,"Y":274.82},{"X":287.8,"Y":281.39},{"X":288.94,"Y":285.57},{"X":290.57,"Y":288.43},{"X":292.56,"Y":290.24},{"X":295.1,"Y":291.3},{"X":295.83,"Y":283.75},{"X":296,"Y":265.6},{"X":296.31,"Y":250.76},{"X":297.29,"Y":241.67},{"X":299.29,"Y":240.75},{"X":303.08,"Y":239.94},{"X":307.26,"Y":240},{"X":307.66,"Y":242.7},{"X":309.02,"Y":256.43},{"X":310.57,"Y":291.19},{"X":311.49,"Y":291.54},{"X":314.95,"Y":293.31},{"X":316.6,"Y":294.82},{"X":316.6,"Y":295.52},{"X":315.35,"Y":295.94},{"X":315.99,"Y":296.02},{"X":317.2,"Y":295.47},{"X":318.2,"Y":293.99},{"X":319.04,"Y":290.81},{"X":319.39,"Y":284.37},{"X":318.41,"Y":262.35},{"X":318.37,"Y":251.85},{"X":319.08,"Y":245.75},{"X":320.27,"Y":242.05},{"X":321.29,"Y":240.77},{"X":323.08,"Y":240.08},{"X":328.27,"Y":240},{"X":329.31,"Y":244.13},{"X":330.19,"Y":252.03},{"X":330.63,"Y":273.92},{"X":331.25,"Y":284.25},{"X":332.33,"Y":289.99},{"X":333.7,"Y":293.31},{"X":335.26,"Y":295.12},{"X":337.01,"Y":295.94},{"X":337.81,"Y":294.94},{"X":339.33,"Y":291.52},{"X":340.32,"Y":286.68},{"X":340.61,"Y":279.64},{"X":339.38,"Y":260.18},{"X":339.31,"Y":251.49},{"X":340.05,"Y":245.84},{"X":341.39,"Y":241.87},{"X":342.36,"Y":240.75},{"X":344.31,"Y":240.04},{"X":351.49,"Y":240},{"X":351.67,"Y":240.9},{"X":352.45,"Y":248.35},{"X":352.58,"Y":274.14},{"X":353.27,"Y":282.2},{"X":354.5,"Y":287.31},{"X":356.13,"Y":290.68},{"X":358.13,"Y":292.86},{"X":359.27,"Y":289.89},{"X":360.62,"Y":284.2},{"X":361.32,"Y":276.58},{"X":361.16,"Y":258.89},{"X":361.45,"Y":247.8},{"X":365.47,"Y":242.21},{"X":370.89,"Y":236.4},{"X":377.72,"Y":230.54},{"X":385.94,"Y":224.78},{"X":395.31,"Y":219.41},{"X":404.57,"Y":215.13}]]'; var output_format = 1; var ClipperLib_MaxSteps_original; // this hold the original ClipperLib.MaxSteps value // during benchmarks, ClipperLib.MaxSteps is set to 10 // to make benchmarks comparable var ismousedown = false; // Not yet in use var bench_glob = []; var bench_elapsed_time = 0; window.onerror = function (message, url, linenumber) { console.log("JavaScript error: " + message + " on line " + linenumber + " for " + url); } window.onload = function () { "use strict"; if (typeof (jQuery) == "undefined") alert("Failed to load jQuery. Please reload the page. If this fails repeatedly, please check the path of the jQuery library or use an own copy of jQuery."); else if (typeof (Raphael) == "undefined") alert("Failed to load Raphael. Please reload the page. If this fails repeatedly, please check the path of the Raphael library or use an own copy of Raphael."); else if (typeof (ClipperLib) == "undefined") alert("Failed to load ClipperLib. Please check that ClipperLib is loaded correctly."); else { set_clipper_float_or_int(); ClipperLib_MaxSteps_original = ClipperLib.MaxSteps; browserg = get_browser(); bench = new benchmark("bench"); p = SVG.create(); main(); } } function get_browser() { var nav = navigator.userAgent.toString().toLowerCase(); var browser = {}; if (nav.indexOf("chrome") != -1 && nav.indexOf("chromium") == -1) browser.chrome = 1; else browser.chrome = 0; if (nav.indexOf("chromium") != -1) browser.chromium = 1; else browser.chromium = 0; if (nav.indexOf("safari") != -1 && nav.indexOf("chrome") == -1 && nav.indexOf("chromium") == -1) browser.safari = 1; else browser.safari = 0; if (nav.indexOf("firefox") != -1) browser.firefox = 1; else browser.firefox = 0; if (nav.indexOf("firefox/17") != -1) browser.firefox17 = 1; else browser.firefox17 = 0; if (nav.indexOf("firefox/15") != -1) browser.firefox15 = 1; else browser.firefox15 = 0; if (nav.indexOf("firefox/3") != -1) browser.firefox3 = 1; else browser.firefox3 = 0; if (nav.indexOf("opera") != -1) browser.opera = 1; else browser.opera = 0; if (nav.indexOf("msie 10") != -1) browser.msie10 = 1; else browser.msie10 = 0; if (nav.indexOf("msie 9") != -1) browser.msie9 = 1; else browser.msie9 = 0; if (nav.indexOf("msie 8") != -1) browser.msie8 = 1; else browser.msie8 = 0; if (nav.indexOf("msie 7") != -1) browser.msie7 = 1; else browser.msie7 = 0; if (nav.indexOf("msie ") != -1) browser.msie = 1; else browser.msie = 0; for (var i in browser) { if (browser[i] === 1 && !i.match(/[0-9]/)) browser["browser"] = i; } browser.version = $.browser.version; return browser; } /* Normalizes inputted polygon string Input can be JSON-stringified version of the following: - Array of arrays of points [[{"X":10,"Y":10},{"X":10,"Y":10},{"X":10,"Y":10}][{"X":10,"Y":10},{"X":10,"Y":10},{"X":10,"Y":10}]] - Array of points [{"X":10,"Y":10},{"X":10,"Y":10},{"X":10,"Y":10}] - The aboves in lowercase - Array of x,y-coordinates eg. [0, 10, 20, 30, 40, 50] or [0 10 20 30 40 50] or [0 10, 20 30, 40 50]; - The above without [] - SVG path string with commands MLVHZ and mlvhz Returns normalized Clipper Polygons object stringified or false in failure */ function normalize_clipper_poly(polystr, quiet) { if (typeof (polystr) != "string") return false; polystr = polystr.trim(); var np, txt; if (polystr.substr(0, 1).toUpperCase() === "M") { np = svgpath_to_clipper_polygons(polystr); if (np === false) { txt = "Unable to parse SVG path string.\n"; txt += "Click OK to continue.\n"; if (!quiet) alert(txt); return false; } else return JSON.stringify(np); } polystr = polystr.replace(/\s+,/g, ",").replace(/x/g, 'X').replace(/y/g, 'Y'); if (polystr.substr(0, 1) !== "[") polystr = "[" + polystr; if (polystr.substr(-1, 1) !== "]") polystr = polystr + "]"; try { polystr = polystr.replace(/[\r\n]/g, ' ').replace(/X/gi, '"X"').replace(/Y/gi, '"Y"').replace(/""/g, '"').replace(/"X":\s+/gi, '"X":').replace(/"Y":\s+/gi, '"Y":'); // if " is missing //console.log(polystr); var poly = JSON.parse(polystr); } catch (err) { txt = "Unable to parse polygon string.\n"; txt += "Error: " + err.message + "\n"; txt += "Click OK to continue.\n"; if (!quiet) alert(txt); return false; } // if only points without "X" and "Y" var temp_n = [], i; if (isArray(poly) && poly.length && typeof (poly[0]) == "number") { var len = poly.length; for (i = 0; i < len; i = i + 2) { temp_n.push( { X: poly[i], Y: poly[i + 1] }); } poly = temp_n; } // if an array of array of points without "X" and "Y" var temp_n2 = [], i, j, len, len2; if (isArray(poly) && poly.length && isArray(poly[0]) && typeof (poly[0][0]) != "undefined" && typeof (poly[0][0].X) == "undefined" && typeof (poly[0][0].x) == "undefined") { len2 = poly.length; for (j = 0; j < len2; j++) { temp_n = []; len = poly[j].length; for (i = 0; i < len; i = i + 2) { temp_n.push( { X: poly[j][i], Y: poly[j][i + 1] }); } temp_n2.push(temp_n); } poly = temp_n2; } // if not array of arrays, convert to array of arrays if (isArray(poly) && poly.length > 0 && !isArray(poly[0])) poly = [poly]; var pp, n = [ [] ], m, pm, x, y; np = [ [] ]; for (i = 0, m = poly.length; i < m; i++) { np[i] = []; for (j = 0, pm = poly[i].length; j < pm; j++) { pp = {}; y = null; x = null; if (typeof (poly[i][j].X) != "undefined" && !isNaN(Number(poly[i][j].X))) x = Number(poly[i][j].X); else if (typeof (poly[i][j].x) != "undefined" && !isNaN(Number(poly[i][j].x))) x = Number(poly[i][j].x); if (typeof (poly[i][j].Y) != "undefined" && !isNaN(Number(poly[i][j].Y))) y = Number(poly[i][j].Y); else if (typeof (poly[i][j].y) != "undefined" && !isNaN(Number(poly[i][j].y))) y = Number(poly[i][j].y); if (y !== null && x !== null) { pp.X = x; pp.Y = y; np[i].push(pp); } else { txt = "Unable to parse polygon string.\n"; txt += "Error: Coordinates are not in a right form.\n"; txt += "Click OK to continue.\n"; if (!quiet) alert(txt); return false; }; } } return JSON.stringify(np); } // helper function for normalize_clipper_poly() function svgpath_to_clipper_polygons(d) { var arr; d = d.trim(); arr = Raphael.parsePathString(d); // str to array arr = Raphael._pathToAbsolute(arr); // mahvstcsqz -> uppercase var str = Array.prototype.concat.apply([], arr).join(" "); var paths = str.replace(/M/g, '|M').split("|"); var k, polygons_arr = [], polygon_arr = []; for (k = 0; k < paths.length; k++) { if (paths[k].trim() === "") continue; arr = Raphael.parsePathString(paths[k].trim()); polygon_arr = []; var i = 0, j, m = arr.length, letter = "", x = 0, y = 0, pt = {}, subpath_start = {}; subpath_start.x = ""; subpath_start.y = ""; for (; i < m; i++) { letter = arr[i][0].toUpperCase(); if (letter != "M" && letter != "L" && letter != "Z") continue; if (letter != "Z") { for (j = 1; j < arr[i].length; j = j + 2) { if (letter == "V") y = arr[i][j]; else if (letter == "H") x = arr[i][j]; else { x = arr[i][j]; y = arr[i][j + 1]; } pt = {}; pt.X = null; pt.Y = null; if (typeof (x) != "undefined" && !isNaN(Number(x))) pt.X = Number(x); if (typeof (y) != "undefined" && !isNaN(Number(y))) pt.Y = Number(y); if (pt.X !== null && pt.Y !== null) { polygon_arr.push(pt); } else { return false; } } } if ((letter != "Z" && subpath_start.x === "") || letter == "M") { subpath_start.x = x; subpath_start.y = y; } if (letter == "Z") { x = subpath_start.x; y = subpath_start.y; } } polygons_arr.push(polygon_arr); } return polygons_arr; } function format_output(polystr, ExPolygonsOrNot) { var txt, returnAsExPolygons = false; if (typeof (polystr) != "string" || polystr === "") return ""; if (ExPolygonsOrNot == "ExPolygons" && ExPolygons) returnAsExPolygons = true; try { var poly = JSON.parse(polystr); } catch (err) { txt = "Unable to parse polygon for output.\n"; txt += "Error: " + err.message + "\n"; txt += "Click OK to continue.\n"; alert(txt); return ""; } var i, j, m, n, newpolystr = ""; if (output_format === 0) // Clipper { //return polystr; } else if (output_format == 1) // Plain { m = poly.length; for (i = 0; i < m; i++) { newpolystr += "["; n = poly[i].length; for (j = 0; j < n; j++) { newpolystr += poly[i][j].X + "," + poly[i][j].Y; if (j !== n - 1) newpolystr += ", "; } newpolystr += "]"; if (i !== m - 1) newpolystr += ","; } //return "[" + newpolystr + "]"; polystr = "[" + newpolystr + "]"; } else if (output_format == 2) // SVG { m = poly.length; for (i = 0; i < m; i++) { n = poly[i].length; for (j = 0; j < n; j++) { if (j === 0) newpolystr += "M"; else newpolystr += "L"; newpolystr += poly[i][j].X + "," + poly[i][j].Y; if (j !== n - 1) newpolystr += " "; } newpolystr += "Z"; if (i !== m - 1) newpolystr += " "; } if (newpolystr.trim() == "Z") newpolystr = ""; //return newpolystr; polystr = newpolystr; } if (!returnAsExPolygons) return polystr; else { if (!cpr) cpr = new ClipperLib.Clipper(); else cpr.Clear(); cpr.AddPaths(poly, ClipperLib.PolyType.ptSubject, subj_is_closed); sss = new ClipperLib.PolyTree(); cpr.Execute(ClipperLib.ClipType.ctUnion, sss, subject_fillType, clip_fillType); var solution_Polygons = new ClipperLib.Paths(); var solution_exPolygons = ClipperLib.JS.PolyTreeToExPolygons(sss); polystr = JSON.stringify(solution_exPolygons); sss = []; return polystr; } /* var solution_polygons_tree = new ClipperLib.PolyTree(); var solution_polygons = new ClipperLib.Paths(); cpr.Execute(clipTypes[i], solution_polygons_tree, subject_fillType, clip_fillType); //cpr.Execute(clipTypes[i], solution_polygons, subject_fillType, clip_fillType); var solution_exPolygons = new ClipperLib.ExPolygons(); ClipperLib.PolyTreeToExPolygons(solution_polygons_tree, solution_exPolygons); //ClipperLib.PolyTreeToExPolygons(solution_polygons, solution_exPolygons); //console.log(i); ClipperLib.Clipper.PolyTreeToPolygons(solution_polygons_tree, solution_polygons); */ /* else if (output_format == 3) // ExPolygons { m = poly.length; for(i = 0; i < m; i++) { newpolystr += "["; n = poly[i].length; for(j = 0; j < n; j++) { newpolystr += poly[i][j].X + "," + poly[i][j].Y; if (j !== n - 1) newpolystr += ", "; } newpolystr += "]"; if (i !== m - 1) newpolystr += ","; } return "[" + newpolystr + "]"; } */ }; function get_gb_and_arrow() { var gb_poly = '[[{"X":189,"Y":154},{"X":192,"Y":155},{"X":193,"Y":154},{"X":194,"Y":151},{"X":194,"Y":150},{"X":196,"Y":151},{"X":199,"Y":151},{"X":200,"Y":150},{"X":203,"Y":149},{"X":204,"Y":149},{"X":205,"Y":149},{"X":206,"Y":149},{"X":209,"Y":150},{"X":211,"Y":149},{"X":212,"Y":149},{"X":212,"Y":152},{"X":212,"Y":155},{"X":213,"Y":156},{"X":213,"Y":156},{"X":213,"Y":159},{"X":214,"Y":159},{"X":216,"Y":161},{"X":216,"Y":161},{"X":216,"Y":163},{"X":217,"Y":163},{"X":218,"Y":166},{"X":218,"Y":166},{"X":217,"Y":163},{"X":217,"Y":162},{"X":218,"Y":162},{"X":218,"Y":163},{"X":220,"Y":165},{"X":218,"Y":167},{"X":218,"Y":167},{"X":215,"Y":168},{"X":214,"Y":170},{"X":214,"Y":171},{"X":215,"Y":170},{"X":217,"Y":168},{"X":220,"Y":168},{"X":221,"Y":168},{"X":222,"Y":170},{"X":223,"Y":172},{"X":223,"Y":174},{"X":224,"Y":176},{"X":223,"Y":178},{"X":223,"Y":179},{"X":223,"Y":179},{"X":223,"Y":180},{"X":222,"Y":180},{"X":222,"Y":180},{"X":221,"Y":178},{"X":222,"Y":177},{"X":222,"Y":174},{"X":221,"Y":174},{"X":220,"Y":172},{"X":218,"Y":172},{"X":218,"Y":174},{"X":220,"Y":174},{"X":218,"Y":174},{"X":220,"Y":176},{"X":220,"Y":178},{"X":217,"Y":180},{"X":221,"Y":179},{"X":221,"Y":180},{"X":222,"Y":181},{"X":221,"Y":182},{"X":218,"Y":183},{"X":218,"Y":183},{"X":217,"Y":182},{"X":214,"Y":184},{"X":214,"Y":187},{"X":214,"Y":189},{"X":211,"Y":191},{"X":210,"Y":191},{"X":210,"Y":190},{"X":209,"Y":189},{"X":207,"Y":189},{"X":206,"Y":189},{"X":207,"Y":189},{"X":209,"Y":191},{"X":209,"Y":191},{"X":210,"Y":191},{"X":207,"Y":192},{"X":205,"Y":191},{"X":204,"Y":191},{"X":204,"Y":191},{"X":204,"Y":192},{"X":204,"Y":194},{"X":204,"Y":195},{"X":206,"Y":195},{"X":206,"Y":198},{"X":206,"Y":199},{"X":206,"Y":200},{"X":206,"Y":202},{"X":206,"Y":203},{"X":210,"Y":206},{"X":209,"Y":207},{"X":207,"Y":211},{"X":209,"Y":212},{"X":210,"Y":212},{"X":210,"Y":213},{"X":207,"Y":212},{"X":207,"Y":213},{"X":206,"Y":213},{"X":207,"Y":215},{"X":209,"Y":216},{"X":209,"Y":218},{"X":210,"Y":222},{"X":209,"Y":226},{"X":211,"Y":226},{"X":209,"Y":231},{"X":207,"Y":232},{"X":206,"Y":234},{"X":205,"Y":237},{"X":205,"Y":240},{"X":202,"Y":246},{"X":201,"Y":247},{"X":200,"Y":247},{"X":200,"Y":247},{"X":200,"Y":248},{"X":201,"Y":249},{"X":201,"Y":248},{"X":201,"Y":250},{"X":202,"Y":251},{"X":201,"Y":254},{"X":200,"Y":254},{"X":201,"Y":253},{"X":199,"Y":254},{"X":199,"Y":253},{"X":199,"Y":253},{"X":196,"Y":254},{"X":194,"Y":251},{"X":192,"Y":253},{"X":193,"Y":251},{"X":192,"Y":251},{"X":192,"Y":251},{"X":191,"Y":251},{"X":192,"Y":253},{"X":191,"Y":253},{"X":190,"Y":254},{"X":189,"Y":255},{"X":189,"Y":255},{"X":190,"Y":254},{"X":190,"Y":253},{"X":190,"Y":251},{"X":189,"Y":251},{"X":189,"Y":249},{"X":189,"Y":251},{"X":189,"Y":253},{"X":189,"Y":253},{"X":188,"Y":255},{"X":185,"Y":254},{"X":187,"Y":253},{"X":185,"Y":253},{"X":185,"Y":253},{"X":185,"Y":254},{"X":184,"Y":254},{"X":183,"Y":254},{"X":179,"Y":254},{"X":177,"Y":255},{"X":177,"Y":255},{"X":176,"Y":255},{"X":174,"Y":255},{"X":176,"Y":256},{"X":177,"Y":257},{"X":176,"Y":257},{"X":176,"Y":258},{"X":172,"Y":258},{"X":172,"Y":260},{"X":171,"Y":260},{"X":170,"Y":260},{"X":169,"Y":259},{"X":169,"Y":260},{"X":168,"Y":260},{"X":169,"Y":261},{"X":167,"Y":262},{"X":166,"Y":264},{"X":166,"Y":264},{"X":162,"Y":265},{"X":161,"Y":264},{"X":161,"Y":264},{"X":162,"Y":262},{"X":163,"Y":261},{"X":160,"Y":262},{"X":158,"Y":261},{"X":158,"Y":262},{"X":159,"Y":262},{"X":160,"Y":264},{"X":160,"Y":265},{"X":160,"Y":265},{"X":158,"Y":267},{"X":157,"Y":267},{"X":156,"Y":267},{"X":155,"Y":267},{"X":155,"Y":267},{"X":154,"Y":268},{"X":154,"Y":270},{"X":154,"Y":269},{"X":151,"Y":269},{"X":150,"Y":272},{"X":149,"Y":272},{"X":149,"Y":270},{"X":147,"Y":270},{"X":147,"Y":272},{"X":146,"Y":272},{"X":146,"Y":272},{"X":144,"Y":270},{"X":143,"Y":272},{"X":141,"Y":270},{"X":141,"Y":272},{"X":140,"Y":272},{"X":140,"Y":271},{"X":140,"Y":273},{"X":139,"Y":273},{"X":139,"Y":273},{"X":139,"Y":273},{"X":138,"Y":272},{"X":138,"Y":273},{"X":137,"Y":273},{"X":137,"Y":273},{"X":136,"Y":272},{"X":137,"Y":270},{"X":136,"Y":269},{"X":136,"Y":270},{"X":135,"Y":270},{"X":134,"Y":270},{"X":134,"Y":272},{"X":133,"Y":272},{"X":133,"Y":272},{"X":132,"Y":272},{"X":132,"Y":270},{"X":129,"Y":272},{"X":130,"Y":272},{"X":128,"Y":272},{"X":128,"Y":271},{"X":127,"Y":272},{"X":127,"Y":271},{"X":127,"Y":271},{"X":129,"Y":269},{"X":132,"Y":269},{"X":134,"Y":267},{"X":134,"Y":267},{"X":128,"Y":269},{"X":127,"Y":269},{"X":128,"Y":268},{"X":129,"Y":267},{"X":136,"Y":266},{"X":136,"Y":266},{"X":136,"Y":265},{"X":136,"Y":265},{"X":135,"Y":264},{"X":135,"Y":262},{"X":135,"Y":264},{"X":134,"Y":266},{"X":126,"Y":266},{"X":126,"Y":267},{"X":124,"Y":267},{"X":123,"Y":267},{"X":122,"Y":267},{"X":122,"Y":267},{"X":122,"Y":267},{"X":122,"Y":266},{"X":123,"Y":267},{"X":123,"Y":266},{"X":123,"Y":265},{"X":123,"Y":265},{"X":125,"Y":265},{"X":126,"Y":264},{"X":125,"Y":264},{"X":125,"Y":262},{"X":127,"Y":261},{"X":127,"Y":262},{"X":127,"Y":261},{"X":129,"Y":261},{"X":128,"Y":261},{"X":130,"Y":259},{"X":133,"Y":259},{"X":134,"Y":259},{"X":132,"Y":259},{"X":129,"Y":260},{"X":128,"Y":260},{"X":127,"Y":260},{"X":127,"Y":260},{"X":122,"Y":262},{"X":122,"Y":261},{"X":121,"Y":261},{"X":121,"Y":260},{"X":122,"Y":259},{"X":121,"Y":258},{"X":119,"Y":259},{"X":118,"Y":260},{"X":118,"Y":258},{"X":117,"Y":258},{"X":117,"Y":256},{"X":119,"Y":256},{"X":121,"Y":256},{"X":119,"Y":255},{"X":119,"Y":255},{"X":121,"Y":254},{"X":121,"Y":254},{"X":126,"Y":251},{"X":127,"Y":250},{"X":127,"Y":251},{"X":127,"Y":251},{"X":128,"Y":249},{"X":129,"Y":249},{"X":132,"Y":249},{"X":128,"Y":248},{"X":127,"Y":248},{"X":127,"Y":249},{"X":126,"Y":248},{"X":123,"Y":249},{"X":122,"Y":248},{"X":121,"Y":248},{"X":119,"Y":248},{"X":121,"Y":249},{"X":121,"Y":249},{"X":118,"Y":248},{"X":119,"Y":249},{"X":117,"Y":249},{"X":116,"Y":248},{"X":116,"Y":248},{"X":116,"Y":247},{"X":117,"Y":247},{"X":116,"Y":246},{"X":117,"Y":246},{"X":117,"Y":247},{"X":118,"Y":247},{"X":118,"Y":245},{"X":119,"Y":245},{"X":121,"Y":244},{"X":123,"Y":244},{"X":123,"Y":245},{"X":125,"Y":246},{"X":126,"Y":244},{"X":125,"Y":243},{"X":126,"Y":242},{"X":126,"Y":244},{"X":127,"Y":246},{"X":129,"Y":246},{"X":129,"Y":246},{"X":129,"Y":246},{"X":132,"Y":246},{"X":132,"Y":245},{"X":128,"Y":245},{"X":128,"Y":243},{"X":129,"Y":244},{"X":129,"Y":243},{"X":130,"Y":240},{"X":128,"Y":239},{"X":128,"Y":239},{"X":133,"Y":238},{"X":134,"Y":237},{"X":135,"Y":238},{"X":135,"Y":237},{"X":134,"Y":237},{"X":134,"Y":237},{"X":135,"Y":235},{"X":136,"Y":235},{"X":138,"Y":236},{"X":138,"Y":235},{"X":141,"Y":236},{"X":147,"Y":234},{"X":147,"Y":235},{"X":148,"Y":235},{"X":149,"Y":234},{"X":151,"Y":234},{"X":151,"Y":234},{"X":154,"Y":234},{"X":150,"Y":233},{"X":149,"Y":233},{"X":149,"Y":232},{"X":148,"Y":231},{"X":147,"Y":231},{"X":147,"Y":232},{"X":144,"Y":235},{"X":143,"Y":234},{"X":141,"Y":236},{"X":140,"Y":235},{"X":141,"Y":234},{"X":139,"Y":234},{"X":137,"Y":234},{"X":137,"Y":233},{"X":136,"Y":232},{"X":137,"Y":234},{"X":134,"Y":234},{"X":134,"Y":235},{"X":129,"Y":234},{"X":128,"Y":234},{"X":132,"Y":234},{"X":135,"Y":231},{"X":136,"Y":229},{"X":138,"Y":229},{"X":138,"Y":227},{"X":139,"Y":226},{"X":139,"Y":224},{"X":141,"Y":223},{"X":140,"Y":223},{"X":138,"Y":223},{"X":138,"Y":223},{"X":139,"Y":222},{"X":143,"Y":217},{"X":146,"Y":217},{"X":147,"Y":217},{"X":147,"Y":217},{"X":149,"Y":217},{"X":147,"Y":217},{"X":149,"Y":217},{"X":149,"Y":217},{"X":150,"Y":217},{"X":150,"Y":217},{"X":150,"Y":216},{"X":151,"Y":215},{"X":150,"Y":215},{"X":149,"Y":215},{"X":149,"Y":214},{"X":150,"Y":213},{"X":150,"Y":213},{"X":150,"Y":212},{"X":148,"Y":212},{"X":146,"Y":213},{"X":139,"Y":213},{"X":138,"Y":213},{"X":138,"Y":211},{"X":138,"Y":211},{"X":137,"Y":213},{"X":137,"Y":213},{"X":137,"Y":212},{"X":137,"Y":211},{"X":137,"Y":210},{"X":137,"Y":210},{"X":138,"Y":210},{"X":137,"Y":209},{"X":137,"Y":210},{"X":137,"Y":209},{"X":137,"Y":209},{"X":137,"Y":209},{"X":137,"Y":209},{"X":136,"Y":210},{"X":135,"Y":210},{"X":134,"Y":209},{"X":133,"Y":209},{"X":133,"Y":207},{"X":133,"Y":207},{"X":135,"Y":206},{"X":135,"Y":206},{"X":135,"Y":206},{"X":135,"Y":206},{"X":133,"Y":206},{"X":133,"Y":206},{"X":133,"Y":206},{"X":133,"Y":206},{"X":132,"Y":206},{"X":132,"Y":207},{"X":129,"Y":206},{"X":128,"Y":205},{"X":127,"Y":206},{"X":127,"Y":205},{"X":126,"Y":205},{"X":127,"Y":203},{"X":129,"Y":204},{"X":128,"Y":203},{"X":128,"Y":202},{"X":127,"Y":201},{"X":126,"Y":201},{"X":128,"Y":201},{"X":128,"Y":200},{"X":132,"Y":201},{"X":129,"Y":198},{"X":134,"Y":198},{"X":134,"Y":196},{"X":134,"Y":194},{"X":136,"Y":193},{"X":138,"Y":194},{"X":139,"Y":193},{"X":138,"Y":193},{"X":139,"Y":192},{"X":138,"Y":192},{"X":139,"Y":191},{"X":139,"Y":191},{"X":139,"Y":190},{"X":136,"Y":190},{"X":135,"Y":190},{"X":134,"Y":190},{"X":134,"Y":190},{"X":134,"Y":188},{"X":136,"Y":189},{"X":136,"Y":189},{"X":136,"Y":189},{"X":136,"Y":187},{"X":136,"Y":187},{"X":136,"Y":188},{"X":136,"Y":187},{"X":136,"Y":187},{"X":135,"Y":184},{"X":135,"Y":183},{"X":136,"Y":183},{"X":135,"Y":183},{"X":136,"Y":182},{"X":135,"Y":182},{"X":135,"Y":183},{"X":134,"Y":182},{"X":134,"Y":182},{"X":134,"Y":182},{"X":135,"Y":181},{"X":134,"Y":181},{"X":135,"Y":180},{"X":134,"Y":180},{"X":135,"Y":179},{"X":135,"Y":179},{"X":133,"Y":178},{"X":133,"Y":179},{"X":133,"Y":179},{"X":133,"Y":180},{"X":132,"Y":180},{"X":132,"Y":180},{"X":132,"Y":181},{"X":132,"Y":182},{"X":130,"Y":182},{"X":132,"Y":178},{"X":132,"Y":178},{"X":130,"Y":177},{"X":132,"Y":177},{"X":132,"Y":177},{"X":134,"Y":174},{"X":134,"Y":177},{"X":135,"Y":178},{"X":135,"Y":179},{"X":134,"Y":178},{"X":134,"Y":178},{"X":136,"Y":179},{"X":136,"Y":177},{"X":136,"Y":178},{"X":136,"Y":177},{"X":136,"Y":177},{"X":136,"Y":176},{"X":136,"Y":174},{"X":138,"Y":176},{"X":143,"Y":176},{"X":144,"Y":178},{"X":146,"Y":177},{"X":147,"Y":177},{"X":147,"Y":178},{"X":148,"Y":179},{"X":148,"Y":179},{"X":148,"Y":180},{"X":148,"Y":180},{"X":149,"Y":181},{"X":149,"Y":181},{"X":151,"Y":178},{"X":154,"Y":178},{"X":156,"Y":180},{"X":157,"Y":179},{"X":157,"Y":179},{"X":158,"Y":180},{"X":160,"Y":181},{"X":161,"Y":181},{"X":160,"Y":180},{"X":160,"Y":180},{"X":161,"Y":179},{"X":162,"Y":179},{"X":161,"Y":178},{"X":161,"Y":178},{"X":162,"Y":178},{"X":162,"Y":178},{"X":161,"Y":177},{"X":160,"Y":178},{"X":159,"Y":177},{"X":161,"Y":176},{"X":161,"Y":174},{"X":161,"Y":174},{"X":163,"Y":174},{"X":162,"Y":173},{"X":163,"Y":172},{"X":163,"Y":173},{"X":167,"Y":173},{"X":168,"Y":171},{"X":168,"Y":170},{"X":170,"Y":168},{"X":170,"Y":168},{"X":171,"Y":168},{"X":170,"Y":168},{"X":168,"Y":168},{"X":167,"Y":168},{"X":167,"Y":168},{"X":167,"Y":168},{"X":166,"Y":168},{"X":163,"Y":170},{"X":163,"Y":168},{"X":166,"Y":168},{"X":166,"Y":168},{"X":163,"Y":168},{"X":163,"Y":168},{"X":161,"Y":168},{"X":160,"Y":168},{"X":157,"Y":166},{"X":158,"Y":165},{"X":157,"Y":165},{"X":158,"Y":165},{"X":158,"Y":163},{"X":160,"Y":162},{"X":165,"Y":163},{"X":163,"Y":162},{"X":162,"Y":162},{"X":163,"Y":162},{"X":166,"Y":163},{"X":162,"Y":160},{"X":163,"Y":160},{"X":167,"Y":160},{"X":166,"Y":159},{"X":166,"Y":159},{"X":167,"Y":159},{"X":168,"Y":159},{"X":167,"Y":159},{"X":166,"Y":158},{"X":166,"Y":159},{"X":165,"Y":158},{"X":165,"Y":156},{"X":167,"Y":156},{"X":166,"Y":156},{"X":165,"Y":154},{"X":166,"Y":154},{"X":166,"Y":152},{"X":167,"Y":154},{"X":167,"Y":152},{"X":168,"Y":152},{"X":168,"Y":152},{"X":168,"Y":152},{"X":168,"Y":151},{"X":169,"Y":150},{"X":171,"Y":150},{"X":171,"Y":150},{"X":171,"Y":150},{"X":171,"Y":151},{"X":172,"Y":150},{"X":174,"Y":150},{"X":174,"Y":148},{"X":174,"Y":147},{"X":176,"Y":148},{"X":176,"Y":149},{"X":177,"Y":149},{"X":177,"Y":150},{"X":177,"Y":150},{"X":178,"Y":150},{"X":177,"Y":150},{"X":178,"Y":150},{"X":178,"Y":150},{"X":178,"Y":149},{"X":177,"Y":149},{"X":177,"Y":147},{"X":178,"Y":147},{"X":178,"Y":147},{"X":178,"Y":150},{"X":179,"Y":150},{"X":180,"Y":151},{"X":180,"Y":152},{"X":181,"Y":151},{"X":180,"Y":148},{"X":180,"Y":150},{"X":180,"Y":149},{"X":180,"Y":148},{"X":179,"Y":148},{"X":179,"Y":147},{"X":180,"Y":147},{"X":181,"Y":146},{"X":182,"Y":147},{"X":182,"Y":149},{"X":183,"Y":151},{"X":183,"Y":151},{"X":183,"Y":152},{"X":181,"Y":155},{"X":182,"Y":155},{"X":182,"Y":155},{"X":181,"Y":155},{"X":180,"Y":157},{"X":182,"Y":155},{"X":184,"Y":154},{"X":184,"Y":154},{"X":184,"Y":151},{"X":183,"Y":148},{"X":184,"Y":148},{"X":183,"Y":147},{"X":184,"Y":147},{"X":184,"Y":147},{"X":184,"Y":147},{"X":187,"Y":146},{"X":187,"Y":146},{"X":187,"Y":147},{"X":189,"Y":147},{"X":187,"Y":146},{"X":187,"Y":145},{"X":187,"Y":145},{"X":187,"Y":144},{"X":185,"Y":144},{"X":185,"Y":144},{"X":189,"Y":144},{"X":190,"Y":145},{"X":191,"Y":146},{"X":195,"Y":148},{"X":195,"Y":149},{"X":191,"Y":151}],[{"X":236,"Y":34},{"X":237,"Y":35},{"X":238,"Y":35},{"X":239,"Y":35},{"X":239,"Y":36},{"X":240,"Y":35},{"X":239,"Y":35},{"X":239,"Y":35},{"X":240,"Y":36},{"X":242,"Y":37},{"X":242,"Y":37},{"X":240,"Y":40},{"X":242,"Y":38},{"X":242,"Y":37},{"X":243,"Y":37},{"X":243,"Y":36},{"X":245,"Y":36},{"X":246,"Y":37},{"X":247,"Y":38},{"X":246,"Y":40},{"X":247,"Y":37},{"X":249,"Y":37},{"X":250,"Y":38},{"X":250,"Y":38},{"X":250,"Y":37},{"X":251,"Y":37},{"X":251,"Y":36},{"X":253,"Y":37},{"X":254,"Y":36},{"X":254,"Y":36},{"X":256,"Y":36},{"X":257,"Y":36},{"X":260,"Y":36},{"X":262,"Y":36},{"X":262,"Y":36},{"X":262,"Y":36},{"X":264,"Y":35},{"X":266,"Y":36},{"X":266,"Y":35},{"X":265,"Y":34},{"X":266,"Y":33},{"X":266,"Y":34},{"X":269,"Y":34},{"X":269,"Y":35},{"X":271,"Y":34},{"X":271,"Y":35},{"X":270,"Y":38},{"X":270,"Y":39},{"X":271,"Y":39},{"X":270,"Y":44},{"X":269,"Y":44},{"X":268,"Y":46},{"X":266,"Y":47},{"X":264,"Y":51},{"X":258,"Y":53},{"X":257,"Y":55},{"X":256,"Y":56},{"X":254,"Y":58},{"X":254,"Y":60},{"X":253,"Y":60},{"X":251,"Y":61},{"X":250,"Y":61},{"X":250,"Y":62},{"X":253,"Y":62},{"X":254,"Y":61},{"X":255,"Y":61},{"X":255,"Y":62},{"X":256,"Y":62},{"X":257,"Y":60},{"X":258,"Y":61},{"X":256,"Y":63},{"X":254,"Y":66},{"X":254,"Y":66},{"X":254,"Y":66},{"X":253,"Y":66},{"X":250,"Y":67},{"X":248,"Y":66},{"X":248,"Y":68},{"X":246,"Y":69},{"X":246,"Y":70},{"X":249,"Y":67},{"X":253,"Y":67},{"X":253,"Y":66},{"X":254,"Y":67},{"X":251,"Y":69},{"X":251,"Y":69},{"X":251,"Y":70},{"X":250,"Y":71},{"X":250,"Y":72},{"X":249,"Y":71},{"X":249,"Y":72},{"X":249,"Y":73},{"X":250,"Y":73},{"X":250,"Y":73},{"X":250,"Y":73},{"X":253,"Y":71},{"X":253,"Y":70},{"X":253,"Y":69},{"X":256,"Y":69},{"X":260,"Y":68},{"X":262,"Y":68},{"X":264,"Y":66},{"X":266,"Y":64},{"X":271,"Y":68},{"X":275,"Y":66},{"X":276,"Y":67},{"X":277,"Y":67},{"X":283,"Y":68},{"X":284,"Y":68},{"X":286,"Y":67},{"X":287,"Y":68},{"X":289,"Y":67},{"X":291,"Y":67},{"X":291,"Y":68},{"X":292,"Y":67},{"X":293,"Y":68},{"X":293,"Y":69},{"X":293,"Y":70},{"X":294,"Y":73},{"X":294,"Y":73},{"X":294,"Y":74},{"X":295,"Y":74},{"X":290,"Y":81},{"X":289,"Y":84},{"X":290,"Y":86},{"X":287,"Y":91},{"X":287,"Y":93},{"X":286,"Y":96},{"X":283,"Y":97},{"X":283,"Y":97},{"X":283,"Y":101},{"X":283,"Y":101},{"X":281,"Y":102},{"X":282,"Y":103},{"X":281,"Y":105},{"X":278,"Y":107},{"X":277,"Y":108},{"X":276,"Y":108},{"X":275,"Y":108},{"X":273,"Y":108},{"X":272,"Y":108},{"X":271,"Y":108},{"X":267,"Y":111},{"X":266,"Y":112},{"X":267,"Y":112},{"X":268,"Y":111},{"X":275,"Y":108},{"X":276,"Y":110},{"X":276,"Y":111},{"X":276,"Y":112},{"X":276,"Y":112},{"X":277,"Y":113},{"X":279,"Y":113},{"X":280,"Y":116},{"X":278,"Y":117},{"X":276,"Y":117},{"X":273,"Y":117},{"X":272,"Y":117},{"X":269,"Y":121},{"X":269,"Y":122},{"X":267,"Y":123},{"X":265,"Y":124},{"X":261,"Y":123},{"X":258,"Y":123},{"X":258,"Y":124},{"X":259,"Y":124},{"X":262,"Y":124},{"X":265,"Y":125},{"X":266,"Y":124},{"X":267,"Y":125},{"X":269,"Y":125},{"X":270,"Y":126},{"X":271,"Y":126},{"X":272,"Y":125},{"X":273,"Y":125},{"X":275,"Y":124},{"X":275,"Y":123},{"X":276,"Y":122},{"X":279,"Y":122},{"X":280,"Y":124},{"X":280,"Y":124},{"X":282,"Y":124},{"X":286,"Y":127},{"X":289,"Y":127},{"X":289,"Y":127},{"X":290,"Y":129},{"X":292,"Y":133},{"X":294,"Y":136},{"X":295,"Y":136},{"X":295,"Y":137},{"X":295,"Y":137},{"X":295,"Y":138},{"X":298,"Y":138},{"X":298,"Y":138},{"X":299,"Y":140},{"X":300,"Y":141},{"X":300,"Y":144},{"X":299,"Y":146},{"X":300,"Y":147},{"X":300,"Y":149},{"X":301,"Y":152},{"X":301,"Y":154},{"X":303,"Y":158},{"X":304,"Y":160},{"X":304,"Y":161},{"X":306,"Y":166},{"X":306,"Y":168},{"X":309,"Y":169},{"X":308,"Y":169},{"X":309,"Y":170},{"X":309,"Y":172},{"X":309,"Y":172},{"X":309,"Y":172},{"X":309,"Y":171},{"X":312,"Y":172},{"X":315,"Y":173},{"X":319,"Y":176},{"X":321,"Y":176},{"X":322,"Y":177},{"X":322,"Y":178},{"X":323,"Y":180},{"X":325,"Y":182},{"X":326,"Y":183},{"X":327,"Y":187},{"X":331,"Y":188},{"X":328,"Y":189},{"X":327,"Y":191},{"X":330,"Y":195},{"X":333,"Y":200},{"X":335,"Y":204},{"X":335,"Y":206},{"X":335,"Y":206},{"X":335,"Y":205},{"X":335,"Y":204},{"X":333,"Y":204},{"X":333,"Y":204},{"X":332,"Y":204},{"X":330,"Y":204},{"X":327,"Y":201},{"X":326,"Y":201},{"X":324,"Y":202},{"X":322,"Y":203},{"X":320,"Y":202},{"X":319,"Y":203},{"X":319,"Y":203},{"X":321,"Y":203},{"X":322,"Y":203},{"X":323,"Y":203},{"X":326,"Y":202},{"X":327,"Y":203},{"X":328,"Y":204},{"X":332,"Y":206},{"X":333,"Y":206},{"X":333,"Y":207},{"X":334,"Y":210},{"X":336,"Y":210},{"X":336,"Y":211},{"X":337,"Y":212},{"X":339,"Y":217},{"X":341,"Y":220},{"X":339,"Y":222},{"X":336,"Y":225},{"X":335,"Y":229},{"X":334,"Y":229},{"X":334,"Y":229},{"X":335,"Y":229},{"X":336,"Y":229},{"X":336,"Y":231},{"X":338,"Y":233},{"X":341,"Y":232},{"X":342,"Y":234},{"X":342,"Y":233},{"X":342,"Y":232},{"X":343,"Y":227},{"X":344,"Y":226},{"X":346,"Y":226},{"X":347,"Y":226},{"X":350,"Y":226},{"X":352,"Y":226},{"X":352,"Y":226},{"X":353,"Y":226},{"X":354,"Y":226},{"X":353,"Y":225},{"X":354,"Y":225},{"X":355,"Y":225},{"X":356,"Y":226},{"X":360,"Y":226},{"X":363,"Y":229},{"X":368,"Y":233},{"X":368,"Y":233},{"X":370,"Y":236},{"X":370,"Y":238},{"X":370,"Y":240},{"X":370,"Y":243},{"X":370,"Y":245},{"X":368,"Y":249},{"X":368,"Y":251},{"X":368,"Y":255},{"X":365,"Y":257},{"X":364,"Y":261},{"X":361,"Y":259},{"X":361,"Y":260},{"X":359,"Y":260},{"X":358,"Y":260},{"X":363,"Y":260},{"X":360,"Y":264},{"X":361,"Y":264},{"X":361,"Y":262},{"X":363,"Y":264},{"X":363,"Y":264},{"X":360,"Y":266},{"X":358,"Y":267},{"X":357,"Y":266},{"X":356,"Y":266},{"X":355,"Y":266},{"X":354,"Y":267},{"X":353,"Y":268},{"X":350,"Y":268},{"X":352,"Y":269},{"X":352,"Y":269},{"X":354,"Y":267},{"X":355,"Y":268},{"X":355,"Y":269},{"X":355,"Y":272},{"X":354,"Y":272},{"X":353,"Y":272},{"X":354,"Y":272},{"X":354,"Y":272},{"X":354,"Y":272},{"X":355,"Y":272},{"X":356,"Y":272},{"X":353,"Y":276},{"X":349,"Y":276},{"X":348,"Y":277},{"X":346,"Y":277},{"X":345,"Y":277},{"X":344,"Y":278},{"X":345,"Y":278},{"X":346,"Y":277},{"X":347,"Y":277},{"X":350,"Y":277},{"X":352,"Y":278},{"X":350,"Y":279},{"X":349,"Y":279},{"X":348,"Y":279},{"X":347,"Y":279},{"X":348,"Y":280},{"X":349,"Y":280},{"X":350,"Y":280},{"X":350,"Y":280},{"X":350,"Y":279},{"X":352,"Y":280},{"X":352,"Y":279},{"X":352,"Y":278},{"X":355,"Y":279},{"X":356,"Y":281},{"X":355,"Y":281},{"X":353,"Y":281},{"X":355,"Y":281},{"X":361,"Y":280},{"X":367,"Y":279},{"X":366,"Y":281},{"X":365,"Y":282},{"X":366,"Y":284},{"X":366,"Y":288},{"X":365,"Y":289},{"X":363,"Y":290},{"X":361,"Y":290},{"X":360,"Y":291},{"X":358,"Y":292},{"X":357,"Y":293},{"X":357,"Y":295},{"X":354,"Y":295},{"X":352,"Y":297},{"X":350,"Y":298},{"X":344,"Y":300},{"X":343,"Y":302},{"X":342,"Y":303},{"X":337,"Y":302},{"X":333,"Y":300},{"X":322,"Y":302},{"X":322,"Y":303},{"X":321,"Y":302},{"X":321,"Y":304},{"X":320,"Y":304},{"X":317,"Y":302},{"X":319,"Y":302},{"X":317,"Y":301},{"X":317,"Y":301},{"X":316,"Y":301},{"X":315,"Y":301},{"X":316,"Y":301},{"X":317,"Y":302},{"X":314,"Y":302},{"X":315,"Y":302},{"X":315,"Y":301},{"X":314,"Y":301},{"X":314,"Y":303},{"X":313,"Y":303},{"X":313,"Y":303},{"X":313,"Y":301},{"X":313,"Y":300},{"X":311,"Y":301},{"X":312,"Y":302},{"X":312,"Y":303},{"X":309,"Y":301},{"X":308,"Y":299},{"X":305,"Y":298},{"X":305,"Y":299},{"X":306,"Y":299},{"X":309,"Y":302},{"X":308,"Y":303},{"X":305,"Y":303},{"X":304,"Y":304},{"X":301,"Y":304},{"X":299,"Y":304},{"X":300,"Y":304},{"X":300,"Y":304},{"X":298,"Y":304},{"X":297,"Y":304},{"X":295,"Y":306},{"X":295,"Y":304},{"X":293,"Y":304},{"X":292,"Y":306},{"X":293,"Y":305},{"X":293,"Y":306},{"X":295,"Y":306},{"X":295,"Y":308},{"X":295,"Y":308},{"X":295,"Y":309},{"X":294,"Y":310},{"X":293,"Y":310},{"X":292,"Y":310},{"X":290,"Y":309},{"X":284,"Y":309},{"X":284,"Y":309},{"X":283,"Y":310},{"X":284,"Y":311},{"X":283,"Y":312},{"X":283,"Y":311},{"X":280,"Y":308},{"X":277,"Y":305},{"X":275,"Y":305},{"X":272,"Y":306},{"X":270,"Y":306},{"X":268,"Y":306},{"X":265,"Y":310},{"X":264,"Y":309},{"X":262,"Y":306},{"X":262,"Y":310},{"X":261,"Y":312},{"X":261,"Y":314},{"X":260,"Y":315},{"X":260,"Y":316},{"X":261,"Y":317},{"X":261,"Y":317},{"X":260,"Y":317},{"X":259,"Y":319},{"X":259,"Y":319},{"X":258,"Y":320},{"X":258,"Y":321},{"X":258,"Y":322},{"X":256,"Y":323},{"X":255,"Y":322},{"X":255,"Y":322},{"X":254,"Y":322},{"X":253,"Y":320},{"X":251,"Y":319},{"X":249,"Y":319},{"X":247,"Y":319},{"X":247,"Y":317},{"X":246,"Y":317},{"X":246,"Y":317},{"X":247,"Y":317},{"X":246,"Y":319},{"X":245,"Y":319},{"X":244,"Y":317},{"X":243,"Y":317},{"X":240,"Y":317},{"X":239,"Y":319},{"X":236,"Y":319},{"X":235,"Y":319},{"X":235,"Y":317},{"X":234,"Y":319},{"X":233,"Y":322},{"X":231,"Y":321},{"X":229,"Y":322},{"X":228,"Y":322},{"X":228,"Y":324},{"X":227,"Y":324},{"X":228,"Y":324},{"X":227,"Y":324},{"X":227,"Y":321},{"X":227,"Y":321},{"X":226,"Y":322},{"X":227,"Y":323},{"X":226,"Y":324},{"X":227,"Y":324},{"X":226,"Y":324},{"X":226,"Y":325},{"X":225,"Y":325},{"X":226,"Y":326},{"X":226,"Y":327},{"X":226,"Y":328},{"X":224,"Y":328},{"X":224,"Y":331},{"X":223,"Y":328},{"X":222,"Y":326},{"X":221,"Y":326},{"X":217,"Y":324},{"X":216,"Y":324},{"X":216,"Y":325},{"X":215,"Y":326},{"X":213,"Y":327},{"X":212,"Y":326},{"X":213,"Y":325},{"X":212,"Y":323},{"X":213,"Y":324},{"X":216,"Y":321},{"X":218,"Y":322},{"X":220,"Y":321},{"X":221,"Y":321},{"X":222,"Y":320},{"X":223,"Y":317},{"X":225,"Y":316},{"X":225,"Y":315},{"X":227,"Y":315},{"X":228,"Y":313},{"X":227,"Y":312},{"X":228,"Y":311},{"X":228,"Y":311},{"X":229,"Y":310},{"X":229,"Y":310},{"X":231,"Y":309},{"X":234,"Y":309},{"X":234,"Y":306},{"X":235,"Y":305},{"X":236,"Y":304},{"X":238,"Y":303},{"X":238,"Y":299},{"X":239,"Y":295},{"X":240,"Y":295},{"X":243,"Y":295},{"X":244,"Y":295},{"X":246,"Y":294},{"X":247,"Y":293},{"X":245,"Y":291},{"X":246,"Y":291},{"X":246,"Y":290},{"X":246,"Y":290},{"X":255,"Y":288},{"X":259,"Y":288},{"X":260,"Y":288},{"X":262,"Y":289},{"X":264,"Y":290},{"X":266,"Y":290},{"X":268,"Y":289},{"X":270,"Y":289},{"X":271,"Y":288},{"X":271,"Y":288},{"X":271,"Y":286},{"X":272,"Y":286},{"X":272,"Y":282},{"X":275,"Y":281},{"X":277,"Y":279},{"X":278,"Y":279},{"X":283,"Y":271},{"X":284,"Y":270},{"X":284,"Y":269},{"X":284,"Y":270},{"X":283,"Y":270},{"X":278,"Y":276},{"X":275,"Y":277},{"X":272,"Y":278},{"X":272,"Y":278},{"X":272,"Y":278},{"X":271,"Y":278},{"X":269,"Y":279},{"X":269,"Y":280},{"X":268,"Y":280},{"X":268,"Y":281},{"X":267,"Y":282},{"X":264,"Y":282},{"X":260,"Y":281},{"X":258,"Y":279},{"X":257,"Y":279},{"X":255,"Y":278},{"X":254,"Y":275},{"X":250,"Y":275},{"X":250,"Y":275},{"X":250,"Y":277},{"X":247,"Y":277},{"X":247,"Y":277},{"X":246,"Y":278},{"X":244,"Y":277},{"X":244,"Y":276},{"X":245,"Y":275},{"X":246,"Y":275},{"X":246,"Y":275},{"X":248,"Y":275},{"X":249,"Y":273},{"X":249,"Y":272},{"X":248,"Y":273},{"X":247,"Y":272},{"X":244,"Y":272},{"X":244,"Y":272},{"X":243,"Y":271},{"X":243,"Y":270},{"X":244,"Y":271},{"X":243,"Y":269},{"X":243,"Y":268},{"X":243,"Y":269},{"X":242,"Y":269},{"X":242,"Y":270},{"X":237,"Y":270},{"X":236,"Y":272},{"X":235,"Y":272},{"X":234,"Y":273},{"X":233,"Y":275},{"X":231,"Y":275},{"X":228,"Y":273},{"X":228,"Y":272},{"X":227,"Y":272},{"X":227,"Y":272},{"X":228,"Y":272},{"X":228,"Y":272},{"X":228,"Y":272},{"X":229,"Y":272},{"X":233,"Y":271},{"X":229,"Y":270},{"X":226,"Y":270},{"X":226,"Y":272},{"X":225,"Y":270},{"X":224,"Y":269},{"X":225,"Y":269},{"X":226,"Y":268},{"X":227,"Y":268},{"X":227,"Y":266},{"X":225,"Y":266},{"X":223,"Y":265},{"X":223,"Y":262},{"X":225,"Y":264},{"X":225,"Y":262},{"X":227,"Y":261},{"X":227,"Y":260},{"X":229,"Y":261},{"X":231,"Y":261},{"X":232,"Y":261},{"X":232,"Y":260},{"X":233,"Y":261},{"X":234,"Y":260},{"X":234,"Y":259},{"X":235,"Y":259},{"X":236,"Y":257},{"X":236,"Y":257},{"X":236,"Y":256},{"X":240,"Y":256},{"X":243,"Y":254},{"X":244,"Y":254},{"X":246,"Y":253},{"X":248,"Y":250},{"X":249,"Y":248},{"X":250,"Y":244},{"X":251,"Y":243},{"X":253,"Y":242},{"X":250,"Y":242},{"X":248,"Y":240},{"X":250,"Y":237},{"X":251,"Y":235},{"X":250,"Y":236},{"X":249,"Y":235},{"X":248,"Y":235},{"X":248,"Y":234},{"X":249,"Y":232},{"X":248,"Y":231},{"X":243,"Y":231},{"X":242,"Y":232},{"X":242,"Y":233},{"X":242,"Y":234},{"X":240,"Y":235},{"X":238,"Y":233},{"X":238,"Y":234},{"X":236,"Y":233},{"X":236,"Y":234},{"X":236,"Y":233},{"X":236,"Y":232},{"X":238,"Y":231},{"X":240,"Y":229},{"X":244,"Y":226},{"X":244,"Y":223},{"X":245,"Y":223},{"X":245,"Y":223},{"X":248,"Y":220},{"X":249,"Y":218},{"X":250,"Y":218},{"X":254,"Y":217},{"X":255,"Y":217},{"X":254,"Y":216},{"X":256,"Y":216},{"X":257,"Y":217},{"X":259,"Y":217},{"X":265,"Y":215},{"X":266,"Y":215},{"X":266,"Y":216},{"X":270,"Y":220},{"X":270,"Y":217},{"X":268,"Y":214},{"X":268,"Y":214},{"X":271,"Y":212},{"X":271,"Y":213},{"X":273,"Y":216},{"X":276,"Y":217},{"X":277,"Y":217},{"X":278,"Y":216},{"X":277,"Y":216},{"X":275,"Y":216},{"X":272,"Y":213},{"X":270,"Y":210},{"X":272,"Y":204},{"X":276,"Y":202},{"X":271,"Y":202},{"X":270,"Y":199},{"X":271,"Y":195},{"X":275,"Y":194},{"X":275,"Y":195},{"X":276,"Y":193},{"X":275,"Y":193},{"X":275,"Y":193},{"X":275,"Y":193},{"X":273,"Y":192},{"X":275,"Y":190},{"X":276,"Y":190},{"X":276,"Y":189},{"X":276,"Y":187},{"X":276,"Y":185},{"X":275,"Y":185},{"X":273,"Y":188},{"X":272,"Y":188},{"X":271,"Y":185},{"X":270,"Y":189},{"X":269,"Y":191},{"X":269,"Y":191},{"X":267,"Y":189},{"X":267,"Y":188},{"X":267,"Y":188},{"X":268,"Y":188},{"X":268,"Y":183},{"X":267,"Y":187},{"X":266,"Y":187},{"X":264,"Y":183},{"X":264,"Y":181},{"X":259,"Y":176},{"X":260,"Y":172},{"X":261,"Y":170},{"X":262,"Y":168},{"X":264,"Y":167},{"X":264,"Y":166},{"X":265,"Y":163},{"X":266,"Y":162},{"X":266,"Y":163},{"X":267,"Y":163},{"X":267,"Y":162},{"X":267,"Y":162},{"X":267,"Y":161},{"X":268,"Y":160},{"X":270,"Y":161},{"X":271,"Y":161},{"X":271,"Y":160},{"X":270,"Y":160},{"X":270,"Y":160},{"X":271,"Y":160},{"X":271,"Y":159},{"X":269,"Y":159},{"X":267,"Y":160},{"X":264,"Y":160},{"X":264,"Y":160},{"X":262,"Y":160},{"X":261,"Y":160},{"X":261,"Y":160},{"X":261,"Y":160},{"X":261,"Y":163},{"X":260,"Y":163},{"X":258,"Y":162},{"X":257,"Y":163},{"X":256,"Y":162},{"X":256,"Y":163},{"X":256,"Y":162},{"X":256,"Y":162},{"X":255,"Y":163},{"X":256,"Y":165},{"X":253,"Y":167},{"X":251,"Y":167},{"X":251,"Y":165},{"X":250,"Y":166},{"X":249,"Y":166},{"X":248,"Y":165},{"X":248,"Y":162},{"X":247,"Y":165},{"X":246,"Y":162},{"X":245,"Y":162},{"X":244,"Y":161},{"X":244,"Y":162},{"X":244,"Y":162},{"X":244,"Y":165},{"X":246,"Y":165},{"X":245,"Y":166},{"X":246,"Y":169},{"X":245,"Y":169},{"X":242,"Y":169},{"X":240,"Y":166},{"X":237,"Y":165},{"X":236,"Y":162},{"X":236,"Y":162},{"X":234,"Y":163},{"X":233,"Y":165},{"X":234,"Y":169},{"X":235,"Y":169},{"X":235,"Y":169},{"X":236,"Y":170},{"X":235,"Y":170},{"X":234,"Y":169},{"X":234,"Y":168},{"X":229,"Y":162},{"X":228,"Y":160},{"X":229,"Y":158},{"X":231,"Y":158},{"X":232,"Y":158},{"X":232,"Y":160},{"X":233,"Y":162},{"X":233,"Y":161},{"X":232,"Y":158},{"X":232,"Y":157},{"X":233,"Y":154},{"X":236,"Y":150},{"X":236,"Y":147},{"X":237,"Y":146},{"X":238,"Y":144},{"X":240,"Y":144},{"X":240,"Y":141},{"X":239,"Y":140},{"X":239,"Y":140},{"X":239,"Y":139},{"X":239,"Y":138},{"X":237,"Y":137},{"X":237,"Y":136},{"X":235,"Y":134},{"X":236,"Y":133},{"X":236,"Y":130},{"X":235,"Y":127},{"X":236,"Y":126},{"X":237,"Y":125},{"X":238,"Y":127},{"X":243,"Y":127},{"X":240,"Y":125},{"X":238,"Y":124},{"X":237,"Y":122},{"X":237,"Y":124},{"X":238,"Y":124},{"X":237,"Y":124},{"X":236,"Y":124},{"X":236,"Y":122},{"X":237,"Y":121},{"X":236,"Y":121},{"X":236,"Y":119},{"X":236,"Y":119},{"X":235,"Y":121},{"X":236,"Y":122},{"X":236,"Y":124},{"X":235,"Y":124},{"X":235,"Y":124},{"X":234,"Y":128},{"X":233,"Y":128},{"X":233,"Y":126},{"X":232,"Y":124},{"X":232,"Y":127},{"X":229,"Y":126},{"X":229,"Y":124},{"X":229,"Y":124},{"X":229,"Y":127},{"X":228,"Y":127},{"X":229,"Y":129},{"X":227,"Y":128},{"X":226,"Y":127},{"X":227,"Y":124},{"X":228,"Y":122},{"X":229,"Y":121},{"X":229,"Y":119},{"X":233,"Y":118},{"X":233,"Y":117},{"X":235,"Y":115},{"X":234,"Y":116},{"X":233,"Y":116},{"X":232,"Y":118},{"X":228,"Y":119},{"X":226,"Y":124},{"X":225,"Y":124},{"X":225,"Y":124},{"X":225,"Y":125},{"X":225,"Y":126},{"X":225,"Y":128},{"X":227,"Y":130},{"X":227,"Y":132},{"X":226,"Y":133},{"X":225,"Y":134},{"X":224,"Y":136},{"X":224,"Y":137},{"X":224,"Y":138},{"X":224,"Y":138},{"X":224,"Y":139},{"X":222,"Y":144},{"X":222,"Y":144},{"X":222,"Y":144},{"X":223,"Y":145},{"X":222,"Y":147},{"X":220,"Y":148},{"X":217,"Y":147},{"X":217,"Y":144},{"X":220,"Y":144},{"X":220,"Y":139},{"X":220,"Y":138},{"X":221,"Y":136},{"X":221,"Y":135},{"X":224,"Y":129},{"X":222,"Y":132},{"X":221,"Y":130},{"X":221,"Y":129},{"X":223,"Y":126},{"X":221,"Y":127},{"X":221,"Y":126},{"X":223,"Y":122},{"X":222,"Y":123},{"X":221,"Y":126},{"X":220,"Y":126},{"X":221,"Y":124},{"X":222,"Y":123},{"X":222,"Y":122},{"X":223,"Y":121},{"X":224,"Y":121},{"X":223,"Y":119},{"X":224,"Y":117},{"X":223,"Y":119},{"X":222,"Y":119},{"X":223,"Y":117},{"X":223,"Y":115},{"X":223,"Y":112},{"X":224,"Y":112},{"X":225,"Y":108},{"X":229,"Y":108},{"X":227,"Y":107},{"X":226,"Y":107},{"X":226,"Y":107},{"X":226,"Y":107},{"X":225,"Y":107},{"X":226,"Y":106},{"X":227,"Y":106},{"X":228,"Y":105},{"X":229,"Y":105},{"X":227,"Y":105},{"X":226,"Y":105},{"X":227,"Y":102},{"X":228,"Y":102},{"X":228,"Y":102},{"X":229,"Y":101},{"X":232,"Y":101},{"X":233,"Y":101},{"X":232,"Y":101},{"X":229,"Y":101},{"X":233,"Y":95},{"X":231,"Y":97},{"X":229,"Y":97},{"X":228,"Y":100},{"X":227,"Y":101},{"X":227,"Y":101},{"X":225,"Y":103},{"X":224,"Y":105},{"X":221,"Y":106},{"X":221,"Y":106},{"X":220,"Y":105},{"X":220,"Y":105},{"X":217,"Y":104},{"X":215,"Y":103},{"X":215,"Y":102},{"X":216,"Y":101},{"X":217,"Y":101},{"X":221,"Y":100},{"X":222,"Y":101},{"X":224,"Y":101},{"X":222,"Y":101},{"X":220,"Y":100},{"X":218,"Y":101},{"X":217,"Y":100},{"X":212,"Y":100},{"X":211,"Y":99},{"X":213,"Y":97},{"X":215,"Y":97},{"X":216,"Y":96},{"X":217,"Y":97},{"X":218,"Y":97},{"X":218,"Y":96},{"X":218,"Y":97},{"X":220,"Y":96},{"X":220,"Y":96},{"X":218,"Y":95},{"X":218,"Y":94},{"X":221,"Y":94},{"X":221,"Y":94},{"X":222,"Y":94},{"X":222,"Y":94},{"X":221,"Y":94},{"X":221,"Y":94},{"X":221,"Y":93},{"X":217,"Y":92},{"X":218,"Y":93},{"X":220,"Y":93},{"X":218,"Y":92},{"X":220,"Y":90},{"X":221,"Y":89},{"X":221,"Y":90},{"X":222,"Y":91},{"X":225,"Y":90},{"X":223,"Y":90},{"X":222,"Y":90},{"X":222,"Y":89},{"X":222,"Y":88},{"X":221,"Y":88},{"X":221,"Y":86},{"X":222,"Y":85},{"X":223,"Y":85},{"X":225,"Y":88},{"X":226,"Y":86},{"X":224,"Y":86},{"X":224,"Y":85},{"X":223,"Y":83},{"X":222,"Y":83},{"X":223,"Y":83},{"X":223,"Y":82},{"X":223,"Y":81},{"X":223,"Y":80},{"X":225,"Y":80},{"X":225,"Y":80},{"X":227,"Y":82},{"X":227,"Y":81},{"X":226,"Y":81},{"X":225,"Y":80},{"X":222,"Y":80},{"X":222,"Y":80},{"X":223,"Y":78},{"X":225,"Y":77},{"X":226,"Y":74},{"X":225,"Y":77},{"X":224,"Y":78},{"X":223,"Y":77},{"X":224,"Y":77},{"X":224,"Y":75},{"X":221,"Y":78},{"X":220,"Y":78},{"X":220,"Y":75},{"X":221,"Y":75},{"X":220,"Y":75},{"X":221,"Y":74},{"X":220,"Y":74},{"X":220,"Y":72},{"X":221,"Y":70},{"X":221,"Y":70},{"X":222,"Y":71},{"X":222,"Y":70},{"X":223,"Y":72},{"X":223,"Y":72},{"X":224,"Y":72},{"X":225,"Y":71},{"X":224,"Y":71},{"X":223,"Y":70},{"X":223,"Y":70},{"X":223,"Y":70},{"X":222,"Y":69},{"X":222,"Y":68},{"X":221,"Y":68},{"X":221,"Y":64},{"X":223,"Y":64},{"X":223,"Y":64},{"X":222,"Y":64},{"X":221,"Y":63},{"X":221,"Y":62},{"X":221,"Y":60},{"X":223,"Y":60},{"X":223,"Y":60},{"X":223,"Y":62},{"X":224,"Y":63},{"X":224,"Y":62},{"X":225,"Y":62},{"X":225,"Y":60},{"X":224,"Y":60},{"X":224,"Y":58},{"X":225,"Y":58},{"X":225,"Y":58},{"X":225,"Y":60},{"X":227,"Y":60},{"X":227,"Y":58},{"X":232,"Y":60},{"X":232,"Y":60},{"X":228,"Y":58},{"X":228,"Y":57},{"X":228,"Y":57},{"X":229,"Y":59},{"X":232,"Y":58},{"X":233,"Y":60},{"X":234,"Y":61},{"X":234,"Y":60},{"X":232,"Y":58},{"X":233,"Y":58},{"X":233,"Y":58},{"X":231,"Y":56},{"X":229,"Y":55},{"X":228,"Y":53},{"X":228,"Y":53},{"X":227,"Y":52},{"X":227,"Y":51},{"X":229,"Y":52},{"X":229,"Y":52},{"X":232,"Y":52},{"X":232,"Y":52},{"X":231,"Y":51},{"X":232,"Y":51},{"X":231,"Y":50},{"X":232,"Y":50},{"X":231,"Y":50},{"X":231,"Y":50},{"X":229,"Y":49},{"X":229,"Y":49},{"X":228,"Y":47},{"X":228,"Y":46},{"X":231,"Y":48},{"X":233,"Y":47},{"X":233,"Y":48},{"X":234,"Y":47},{"X":237,"Y":48},{"X":236,"Y":47},{"X":237,"Y":47},{"X":235,"Y":47},{"X":234,"Y":46},{"X":234,"Y":45},{"X":234,"Y":45},{"X":233,"Y":45},{"X":234,"Y":41},{"X":236,"Y":42},{"X":235,"Y":41},{"X":235,"Y":41},{"X":235,"Y":41},{"X":235,"Y":40},{"X":236,"Y":40},{"X":237,"Y":40},{"X":236,"Y":39},{"X":234,"Y":38},{"X":234,"Y":38},{"X":236,"Y":37}]]'; var arrow_poly = '[[{"X":246,"Y":146},{"X":313,"Y":146},{"X":290,"Y":168},{"X":335,"Y":191},{"X":290,"Y":235},{"X":268,"Y":191},{"X":246,"Y":213}],[{"X":246,"Y":57},{"X":268,"Y":79},{"X":290,"Y":35},{"X":335,"Y":79},{"X":290,"Y":102},{"X":313,"Y":124},{"X":246,"Y":124}],[{"X":224,"Y":146},{"X":224,"Y":213},{"X":201,"Y":191},{"X":179,"Y":235},{"X":134,"Y":191},{"X":179,"Y":168},{"X":157,"Y":146}],[{"X":179,"Y":102},{"X":134,"Y":79},{"X":179,"Y":35},{"X":201,"Y":79},{"X":224,"Y":57},{"X":224,"Y":124},{"X":157,"Y":124}]]'; return { "ss": deserialize_clipper_poly(gb_poly), "cc": deserialize_clipper_poly(arrow_poly) } } function get_text_polys() { var text_polygon = '[[{"X":"28.18","Y":"205.95"},{"X":"28.18","Y":"105.07"},{"X":"48.27","Y":"105.07"},{"X":"48.28","Y":"110.23"},{"X":"54.15","Y":"107.22"},{"X":"59.69","Y":"105.39"},{"X":"65.04","Y":"104.66"},{"X":"72.07","Y":"105.08"},{"X":"78.09","Y":"106.31"},{"X":"81.57","Y":"107.68"},{"X":"84.84","Y":"110.05"},{"X":"88.03","Y":"113.63"},{"X":"90.87","Y":"118.22"},{"X":"92.71","Y":"123.12"},{"X":"94.06","Y":"129.73"},{"X":"94.70","Y":"138.25"},{"X":"94.41","Y":"147.24"},{"X":"93.31","Y":"155.42"},{"X":"91.66","Y":"161.49"},{"X":"89.46","Y":"166.25"},{"X":"86.67","Y":"170.32"},{"X":"83.75","Y":"173.13"},{"X":"80.65","Y":"174.92"},{"X":"75.51","Y":"176.56"},{"X":"69.28","Y":"177.50"},{"X":"63.74","Y":"177.55"},{"X":"57.05","Y":"176.72"},{"X":"51.42","Y":"175.15"},{"X":"48.27","Y":"173.79"},{"X":"48.27","Y":"205.95"},{"X":"48.27","Y":"205.95"},{"X":"28.18","Y":"205.95"}],[{"X":"48.28","Y":"120.42"},{"X":"48.38","Y":"164.32"},{"X":"52.31","Y":"166.53"},{"X":"56.14","Y":"167.74"},{"X":"61.35","Y":"168.35"},{"X":"65.96","Y":"167.83"},{"X":"69.49","Y":"166.59"},{"X":"72.20","Y":"164.73"},{"X":"74.29","Y":"162.19"},{"X":"76.19","Y":"157.95"},{"X":"77.71","Y":"152.00"},{"X":"78.63","Y":"144.11"},{"X":"78.66","Y":"136.61"},{"X":"77.89","Y":"129.16"},{"X":"76.59","Y":"124.08"},{"X":"74.84","Y":"120.60"},{"X":"72.55","Y":"118.04"},{"X":"69.77","Y":"116.28"},{"X":"65.91","Y":"115.07"},{"X":"60.69","Y":"114.57"},{"X":"56.85","Y":"115.18"},{"X":"53.10","Y":"116.68"},{"X":"48.91","Y":"119.57"},{"X":"48.28","Y":"120.39"},{"X":"48.28","Y":"120.42"}],[{"X":"132.15","Y":"104.65"},{"X":"139.94","Y":"105.10"},{"X":"146.11","Y":"106.30"},{"X":"151.03","Y":"108.11"},{"X":"155.15","Y":"110.57"},{"X":"158.60","Y":"113.67"},{"X":"161.35","Y":"117.41"},{"X":"163.45","Y":"121.89"},{"X":"165.10","Y":"127.80"},{"X":"166.07","Y":"135.09"},{"X":"166.22","Y":"143.93"},{"X":"165.51","Y":"151.69"},{"X":"164.06","Y":"158.12"},{"X":"162.01","Y":"163.28"},{"X":"159.40","Y":"167.47"},{"X":"156.32","Y":"170.74"},{"X":"152.52","Y":"173.40"},{"X":"147.87","Y":"175.49"},{"X":"142.07","Y":"176.99"},{"X":"134.92","Y":"177.77"},{"X":"127.42","Y":"177.67"},{"X":"120.74","Y":"176.71"},{"X":"115.29","Y":"175.07"},{"X":"110.74","Y":"172.78"},{"X":"106.95","Y":"169.86"},{"X":"103.92","Y":"166.34"},{"X":"101.48","Y":"162.04"},{"X":"99.57","Y":"156.68"},{"X":"98.29","Y":"150.05"},{"X":"97.78","Y":"141.98"},{"X":"98.18","Y":"134.19"},{"X":"99.36","Y":"127.55"},{"X":"101.22","Y":"122.01"},{"X":"103.68","Y":"117.38"},{"X":"106.77","Y":"113.52"},{"X":"110.41","Y":"110.41"},{"X":"114.84","Y":"107.89"},{"X":"120.07","Y":"106.06"},{"X":"126.27","Y":"104.95"},{"X":"132.11","Y":"104.65"},{"X":"132.15","Y":"104.65"}],[{"X":"117.86","Y":"140.93"},{"X":"118.75","Y":"153.65"},{"X":"119.63","Y":"158.05"},{"X":"121.31","Y":"161.73"},{"X":"123.57","Y":"164.71"},{"X":"126.01","Y":"166.43"},{"X":"129.14","Y":"167.44"},{"X":"133.32","Y":"167.70"},{"X":"137.17","Y":"167.11"},{"X":"140.03","Y":"165.83"},{"X":"142.14","Y":"163.92"},{"X":"143.62","Y":"161.33"},{"X":"145.05","Y":"155.97"},{"X":"145.97","Y":"148.23"},{"X":"146.12","Y":"137.89"},{"X":"145.44","Y":"129.22"},{"X":"144.13","Y":"122.91"},{"X":"142.80","Y":"119.58"},{"X":"140.91","Y":"117.26"},{"X":"138.39","Y":"115.66"},{"X":"135.07","Y":"114.75"},{"X":"131.03","Y":"114.64"},{"X":"127.21","Y":"115.38"},{"X":"124.25","Y":"116.82"},{"X":"122.07","Y":"118.86"},{"X":"120.53","Y":"121.59"},{"X":"119.03","Y":"126.93"},{"X":"118.09","Y":"134.21"},{"X":"117.86","Y":"140.81"},{"X":"117.86","Y":"140.93"}],[{"X":"172.03","Y":"177.00"},{"X":"172.03","Y":"76.33"},{"X":"191.91","Y":"76.33"},{"X":"191.91","Y":"177.00"},{"X":"191.91","Y":"177.00"},{"X":"172.03","Y":"177.00"}],[{"X":"224.60","Y":"196.88"},{"X":"221.39","Y":"198.11"},{"X":"215.61","Y":"199.00"},{"X":"208.60","Y":"199.21"},{"X":"204.09","Y":"190.40"},{"X":"211.28","Y":"190.55"},{"X":"214.82","Y":"189.98"},{"X":"217.84","Y":"188.66"},{"X":"220.35","Y":"186.54"},{"X":"222.45","Y":"183.44"},{"X":"224.33","Y":"178.55"},{"X":"225.80","Y":"173.86"},{"X":"195.43","Y":"105.07"},{"X":"215.95","Y":"105.07"},{"X":"235.40","Y":"149.04"},{"X":"252.44","Y":"105.07"},{"X":"265.17","Y":"105.14"},{"X":"233.73","Y":"186.25"},{"X":"231.07","Y":"190.77"},{"X":"228.03","Y":"194.27"},{"X":"224.70","Y":"196.82"},{"X":"224.60","Y":"196.88"}],[{"X":"292.60","Y":"192.98"},{"X":"298.73","Y":"192.56"},{"X":"303.08","Y":"191.46"},{"X":"305.98","Y":"189.91"},{"X":"307.86","Y":"187.98"},{"X":"308.96","Y":"185.54"},{"X":"309.26","Y":"183.06"},{"X":"309.20","Y":"173.81"},{"X":"304.04","Y":"175.83"},{"X":"298.03","Y":"177.13"},{"X":"291.00","Y":"177.63"},{"X":"284.29","Y":"177.05"},{"X":"278.60","Y":"175.70"},{"X":"274.88","Y":"174.11"},{"X":"271.82","Y":"171.71"},{"X":"268.90","Y":"168.11"},{"X":"266.25","Y":"163.24"},{"X":"264.52","Y":"157.97"},{"X":"263.31","Y":"150.88"},{"X":"262.81","Y":"141.60"},{"X":"263.34","Y":"132.62"},{"X":"264.61","Y":"125.23"},{"X":"266.40","Y":"119.67"},{"X":"268.74","Y":"115.31"},{"X":"271.95","Y":"111.17"},{"X":"275.11","Y":"108.42"},{"X":"278.30","Y":"106.76"},{"X":"283.81","Y":"105.35"},{"X":"290.52","Y":"104.67"},{"X":"295.16","Y":"104.90"},{"X":"299.98","Y":"105.99"},{"X":"306.08","Y":"108.50"},{"X":"309.26","Y":"110.23"},{"X":"309.26","Y":"105.06"},{"X":"329.35","Y":"105.06"},{"X":"329.23","Y":"182.37"},{"X":"328.37","Y":"186.78"},{"X":"326.76","Y":"190.49"},{"X":"324.35","Y":"193.73"},{"X":"321.15","Y":"196.44"},{"X":"316.95","Y":"198.74"},{"X":"311.55","Y":"200.55"},{"X":"304.61","Y":"201.78"},{"X":"296.23","Y":"202.25"},{"X":"286.50","Y":"201.75"},{"X":"279.10","Y":"200.55"},{"X":"271.33","Y":"198.26"},{"X":"269.50","Y":"197.28"},{"X":"268.04","Y":"186.11"},{"X":"273.14","Y":"188.62"},{"X":"280.19","Y":"191.16"},{"X":"286.81","Y":"192.48"},{"X":"292.48","Y":"192.97"},{"X":"292.60","Y":"192.98"}],[{"X":"309.26","Y":"120.42"},{"X":"308.13","Y":"119.26"},{"X":"303.52","Y":"116.46"},{"X":"299.14","Y":"114.93"},{"X":"296.63","Y":"114.57"},{"X":"291.87","Y":"115.12"},{"X":"288.19","Y":"116.39"},{"X":"285.33","Y":"118.31"},{"X":"282.99","Y":"121.03"},{"X":"281.19","Y":"124.65"},{"X":"279.81","Y":"130.01"},{"X":"278.92","Y":"137.91"},{"X":"278.88","Y":"145.11"},{"X":"279.69","Y":"152.40"},{"X":"281.18","Y":"158.05"},{"X":"283.08","Y":"162.12"},{"X":"285.18","Y":"164.65"},{"X":"287.89","Y":"166.53"},{"X":"291.41","Y":"167.79"},{"X":"296.02","Y":"168.34"},{"X":"301.23","Y":"167.79"},{"X":"305.10","Y":"166.63"},{"X":"309.03","Y":"164.44"},{"X":"309.26","Y":"164.24"},{"X":"309.26","Y":"164.24"},{"X":"309.26","Y":"120.42"}],[{"X":"369.84","Y":"104.65"},{"X":"377.62","Y":"105.10"},{"X":"383.80","Y":"106.30"},{"X":"388.72","Y":"108.11"},{"X":"392.84","Y":"110.56"},{"X":"396.29","Y":"113.67"},{"X":"399.04","Y":"117.41"},{"X":"401.13","Y":"121.89"},{"X":"402.78","Y":"127.80"},{"X":"403.75","Y":"135.08"},{"X":"403.90","Y":"143.93"},{"X":"403.19","Y":"151.69"},{"X":"401.74","Y":"158.12"},{"X":"399.70","Y":"163.28"},{"X":"397.08","Y":"167.47"},{"X":"394.00","Y":"170.74"},{"X":"390.20","Y":"173.40"},{"X":"385.55","Y":"175.49"},{"X":"379.75","Y":"176.99"},{"X":"372.60","Y":"177.77"},{"X":"365.11","Y":"177.67"},{"X":"358.43","Y":"176.71"},{"X":"352.98","Y":"175.07"},{"X":"348.43","Y":"172.78"},{"X":"344.63","Y":"169.86"},{"X":"341.60","Y":"166.34"},{"X":"339.16","Y":"162.04"},{"X":"337.26","Y":"156.68"},{"X":"335.98","Y":"150.05"},{"X":"335.46","Y":"141.97"},{"X":"335.86","Y":"134.19"},{"X":"337.04","Y":"127.55"},{"X":"338.90","Y":"122.01"},{"X":"341.37","Y":"117.38"},{"X":"344.45","Y":"113.52"},{"X":"348.10","Y":"110.41"},{"X":"352.52","Y":"107.89"},{"X":"357.76","Y":"106.06"},{"X":"363.95","Y":"104.95"},{"X":"369.79","Y":"104.65"},{"X":"369.84","Y":"104.65"}],[{"X":"355.55","Y":"140.93"},{"X":"356.44","Y":"153.65"},{"X":"357.32","Y":"158.05"},{"X":"358.99","Y":"161.73"},{"X":"361.25","Y":"164.71"},{"X":"363.70","Y":"166.43"},{"X":"366.83","Y":"167.44"},{"X":"371.01","Y":"167.70"},{"X":"374.86","Y":"167.11"},{"X":"377.72","Y":"165.83"},{"X":"379.82","Y":"163.92"},{"X":"381.31","Y":"161.33"},{"X":"382.74","Y":"155.97"},{"X":"383.65","Y":"148.23"},{"X":"383.81","Y":"137.89"},{"X":"383.12","Y":"129.22"},{"X":"381.82","Y":"122.91"},{"X":"380.48","Y":"119.58"},{"X":"378.60","Y":"117.26"},{"X":"376.07","Y":"115.66"},{"X":"372.76","Y":"114.75"},{"X":"368.72","Y":"114.64"},{"X":"364.90","Y":"115.38"},{"X":"361.94","Y":"116.82"},{"X":"359.76","Y":"118.86"},{"X":"358.22","Y":"121.60"},{"X":"356.71","Y":"126.93"},{"X":"355.77","Y":"134.21"},{"X":"355.55","Y":"140.81"},{"X":"355.55","Y":"140.93"}],[{"X":"471.82","Y":"121.68"},{"X":"471.82","Y":"177.00"},{"X":"456.69","Y":"177.00"},{"X":"456.58","Y":"122.81"},{"X":"455.77","Y":"120.25"},{"X":"454.20","Y":"118.25"},{"X":"451.80","Y":"116.74"},{"X":"448.06","Y":"115.65"},{"X":"442.84","Y":"115.25"},{"X":"438.30","Y":"116.22"},{"X":"435.19","Y":"117.70"},{"X":"432.97","Y":"119.70"},{"X":"430.36","Y":"123.35"},{"X":"429.69","Y":"124.95"},{"X":"429.69","Y":"177.00"},{"X":"409.38","Y":"177.00"},{"X":"409.38","Y":"105.07"},{"X":"429.69","Y":"105.07"},{"X":"429.70","Y":"110.91"},{"X":"434.67","Y":"107.84"},{"X":"440.16","Y":"105.83"},{"X":"445.62","Y":"104.85"},{"X":"452.21","Y":"104.70"},{"X":"457.71","Y":"105.40"},{"X":"461.98","Y":"106.78"},{"X":"465.33","Y":"108.76"},{"X":"468.28","Y":"111.73"},{"X":"470.35","Y":"115.03"},{"X":"471.52","Y":"118.58"},{"X":"471.82","Y":"121.56"},{"X":"471.82","Y":"121.68"}]]'; var text_clipping = '[[{"X":"115.54","Y":"216.41"},{"X":"113.01","Y":"217.26"},{"X":"105.79","Y":"218.58"},{"X":"96.36","Y":"219.18"},{"X":"88.73","Y":"218.69"},{"X":"82.86","Y":"217.48"},{"X":"78.40","Y":"215.73"},{"X":"74.91","Y":"213.42"},{"X":"72.12","Y":"210.49"},{"X":"69.88","Y":"206.77"},{"X":"68.13","Y":"201.83"},{"X":"66.93","Y":"195.19"},{"X":"66.45","Y":"186.51"},{"X":"67.03","Y":"179.19"},{"X":"68.36","Y":"173.03"},{"X":"70.25","Y":"168.30"},{"X":"72.58","Y":"164.82"},{"X":"75.62","Y":"161.94"},{"X":"79.35","Y":"159.71"},{"X":"84.02","Y":"158.09"},{"X":"89.93","Y":"157.11"},{"X":"96.97","Y":"156.93"},{"X":"105.18","Y":"157.69"},{"X":"114.58","Y":"159.65"},{"X":"116.44","Y":"168.59"},{"X":"110.93","Y":"166.65"},{"X":"105.50","Y":"165.51"},{"X":"98.32","Y":"165.06"},{"X":"94.16","Y":"165.58"},{"X":"90.96","Y":"166.82"},{"X":"88.62","Y":"168.68"},{"X":"86.96","Y":"171.17"},{"X":"85.31","Y":"175.67"},{"X":"84.32","Y":"181.28"},{"X":"84.15","Y":"188.62"},{"X":"84.83","Y":"196.53"},{"X":"86.18","Y":"202.53"},{"X":"87.64","Y":"205.97"},{"X":"89.52","Y":"208.29"},{"X":"92.02","Y":"209.92"},{"X":"95.18","Y":"210.85"},{"X":"99.07","Y":"210.96"},{"X":"105.48","Y":"210.28"},{"X":"111.84","Y":"208.54"},{"X":"116.32","Y":"206.45"},{"X":"116.62","Y":"206.17"},{"X":"115.55","Y":"216.31"},{"X":"115.54","Y":"216.41"}],[{"X":"120.11","Y":"219.00"},{"X":"120.11","Y":"132.31"},{"X":"137.23","Y":"132.31"},{"X":"137.23","Y":"219.00"},{"X":"137.23","Y":"219.00"},{"X":"120.11","Y":"219.00"}],[{"X":"153.34","Y":"132.13"},{"X":"156.60","Y":"132.56"},{"X":"159.17","Y":"133.77"},{"X":"161.19","Y":"135.77"},{"X":"162.61","Y":"138.40"},{"X":"163.19","Y":"141.48"},{"X":"162.87","Y":"144.75"},{"X":"161.71","Y":"147.51"},{"X":"159.79","Y":"149.80"},{"X":"157.51","Y":"151.22"},{"X":"154.46","Y":"151.96"},{"X":"151.02","Y":"151.84"},{"X":"148.34","Y":"150.92"},{"X":"146.08","Y":"149.20"},{"X":"144.28","Y":"146.63"},{"X":"143.38","Y":"143.78"},{"X":"143.37","Y":"140.64"},{"X":"144.20","Y":"137.77"},{"X":"145.94","Y":"135.15"},{"X":"148.14","Y":"133.37"},{"X":"150.80","Y":"132.38"},{"X":"153.33","Y":"132.13"},{"X":"153.34","Y":"132.13"}],[{"X":"144.58","Y":"219.00"},{"X":"144.58","Y":"157.06"},{"X":"161.88","Y":"157.06"},{"X":"161.88","Y":"219.00"},{"X":"161.88","Y":"219.00"},{"X":"144.58","Y":"219.00"}],[{"X":"168.78","Y":"243.93"},{"X":"168.78","Y":"157.06"},{"X":"186.09","Y":"157.06"},{"X":"186.19","Y":"161.44"},{"X":"191.55","Y":"158.75"},{"X":"196.41","Y":"157.22"},{"X":"201.17","Y":"156.70"},{"X":"207.60","Y":"157.21"},{"X":"212.99","Y":"158.51"},{"X":"216.03","Y":"160.11"},{"X":"219.02","Y":"162.82"},{"X":"222.00","Y":"166.95"},{"X":"223.86","Y":"171.04"},{"X":"225.25","Y":"176.56"},{"X":"226.01","Y":"184.02"},{"X":"225.94","Y":"191.67"},{"X":"225.03","Y":"199.56"},{"X":"223.55","Y":"205.37"},{"X":"221.48","Y":"209.86"},{"X":"218.90","Y":"213.53"},{"X":"216.12","Y":"216.03"},{"X":"213.05","Y":"217.58"},{"X":"207.99","Y":"218.94"},{"X":"201.87","Y":"219.54"},{"X":"195.30","Y":"219.05"},{"X":"189.90","Y":"217.79"},{"X":"186.09","Y":"216.23"},{"X":"186.09","Y":"243.93"},{"X":"186.09","Y":"243.93"},{"X":"168.78","Y":"243.93"}],[{"X":"186.09","Y":"170.27"},{"X":"186.13","Y":"208.05"},{"X":"189.79","Y":"210.09"},{"X":"193.53","Y":"211.16"},{"X":"197.86","Y":"211.53"},{"X":"201.86","Y":"210.97"},{"X":"204.91","Y":"209.73"},{"X":"207.25","Y":"207.87"},{"X":"209.01","Y":"205.27"},{"X":"210.72","Y":"200.64"},{"X":"211.90","Y":"194.30"},{"X":"212.32","Y":"186.82"},{"X":"211.80","Y":"179.19"},{"X":"210.69","Y":"174.07"},{"X":"209.11","Y":"170.68"},{"X":"207.06","Y":"168.30"},{"X":"204.40","Y":"166.63"},{"X":"200.81","Y":"165.59"},{"X":"196.18","Y":"165.25"},{"X":"192.24","Y":"166.16"},{"X":"188.91","Y":"167.87"},{"X":"186.21","Y":"169.99"},{"X":"186.09","Y":"170.26"},{"X":"186.09","Y":"170.27"}],[{"X":"231.09","Y":"243.93"},{"X":"231.09","Y":"157.06"},{"X":"248.39","Y":"157.06"},{"X":"248.50","Y":"161.44"},{"X":"253.86","Y":"158.75"},{"X":"258.72","Y":"157.22"},{"X":"263.48","Y":"156.70"},{"X":"269.91","Y":"157.21"},{"X":"275.30","Y":"158.51"},{"X":"278.34","Y":"160.11"},{"X":"281.33","Y":"162.82"},{"X":"284.31","Y":"166.96"},{"X":"286.17","Y":"171.04"},{"X":"287.56","Y":"176.57"},{"X":"288.32","Y":"184.02"},{"X":"288.25","Y":"191.67"},{"X":"287.34","Y":"199.56"},{"X":"285.86","Y":"205.37"},{"X":"283.79","Y":"209.86"},{"X":"281.21","Y":"213.53"},{"X":"278.43","Y":"216.04"},{"X":"275.35","Y":"217.58"},{"X":"270.29","Y":"218.94"},{"X":"264.18","Y":"219.54"},{"X":"257.60","Y":"219.05"},{"X":"252.21","Y":"217.78"},{"X":"248.40","Y":"216.23"},{"X":"248.40","Y":"243.93"},{"X":"248.40","Y":"243.93"},{"X":"231.09","Y":"243.93"}],[{"X":"248.39","Y":"170.27"},{"X":"248.44","Y":"208.05"},{"X":"252.10","Y":"210.09"},{"X":"255.84","Y":"211.16"},{"X":"260.17","Y":"211.53"},{"X":"264.17","Y":"210.97"},{"X":"267.22","Y":"209.73"},{"X":"269.56","Y":"207.87"},{"X":"271.32","Y":"205.27"},{"X":"273.03","Y":"200.64"},{"X":"274.21","Y":"194.30"},{"X":"274.63","Y":"186.82"},{"X":"274.12","Y":"179.19"},{"X":"273.00","Y":"174.07"},{"X":"271.42","Y":"170.68"},{"X":"269.38","Y":"168.30"},{"X":"266.72","Y":"166.64"},{"X":"263.12","Y":"165.59"},{"X":"258.49","Y":"165.25"},{"X":"254.56","Y":"166.16"},{"X":"251.23","Y":"167.86"},{"X":"248.52","Y":"169.99"},{"X":"248.40","Y":"170.26"},{"X":"248.39","Y":"170.27"}],[{"X":"302.11","Y":"132.13"},{"X":"305.37","Y":"132.56"},{"X":"307.93","Y":"133.77"},{"X":"309.95","Y":"135.77"},{"X":"311.37","Y":"138.40"},{"X":"311.95","Y":"141.48"},{"X":"311.63","Y":"144.75"},{"X":"310.47","Y":"147.51"},{"X":"308.56","Y":"149.80"},{"X":"306.27","Y":"151.22"},{"X":"303.22","Y":"151.96"},{"X":"299.79","Y":"151.84"},{"X":"297.10","Y":"150.92"},{"X":"294.85","Y":"149.20"},{"X":"293.04","Y":"146.63"},{"X":"292.14","Y":"143.78"},{"X":"292.13","Y":"140.64"},{"X":"292.97","Y":"137.77"},{"X":"294.71","Y":"135.15"},{"X":"296.90","Y":"133.37"},{"X":"299.56","Y":"132.38"},{"X":"302.10","Y":"132.13"},{"X":"302.11","Y":"132.13"}],[{"X":"293.34","Y":"219.00"},{"X":"293.34","Y":"157.06"},{"X":"310.65","Y":"157.06"},{"X":"310.65","Y":"219.00"},{"X":"310.65","Y":"219.00"},{"X":"293.34","Y":"219.00"}],[{"X":"371.24","Y":"171.37"},{"X":"371.24","Y":"219.00"},{"X":"358.21","Y":"219.00"},{"X":"358.11","Y":"172.27"},{"X":"357.35","Y":"170.01"},{"X":"355.81","Y":"168.19"},{"X":"353.32","Y":"166.83"},{"X":"349.52","Y":"165.99"},{"X":"345.63","Y":"165.91"},{"X":"341.71","Y":"166.90"},{"X":"339.11","Y":"168.36"},{"X":"336.70","Y":"171.02"},{"X":"335.06","Y":"173.87"},{"X":"334.96","Y":"219.00"},{"X":"317.48","Y":"219.00"},{"X":"317.48","Y":"157.06"},{"X":"334.96","Y":"157.06"},{"X":"335.01","Y":"162.07"},{"X":"339.49","Y":"159.34"},{"X":"344.58","Y":"157.56"},{"X":"349.77","Y":"156.78"},{"X":"355.76","Y":"156.84"},{"X":"360.47","Y":"157.70"},{"X":"364.07","Y":"159.18"},{"X":"366.81","Y":"161.26"},{"X":"369.25","Y":"164.29"},{"X":"370.67","Y":"167.42"},{"X":"371.23","Y":"170.82"},{"X":"371.24","Y":"171.27"},{"X":"371.24","Y":"171.37"}],[{"X":"401.90","Y":"232.76"},{"X":"407.58","Y":"232.33"},{"X":"411.33","Y":"231.29"},{"X":"413.88","Y":"229.75"},{"X":"415.39","Y":"227.89"},{"X":"416.16","Y":"225.48"},{"X":"416.21","Y":"216.25"},{"X":"411.46","Y":"218.08"},{"X":"405.72","Y":"219.22"},{"X":"399.44","Y":"219.51"},{"X":"393.19","Y":"218.76"},{"X":"388.30","Y":"217.32"},{"X":"385.44","Y":"215.70"},{"X":"382.67","Y":"212.97"},{"X":"380.07","Y":"208.95"},{"X":"378.24","Y":"204.52"},{"X":"376.93","Y":"198.51"},{"X":"376.28","Y":"190.44"},{"X":"376.52","Y":"182.65"},{"X":"377.58","Y":"175.38"},{"X":"379.16","Y":"170.07"},{"X":"381.22","Y":"166.08"},{"X":"384.14","Y":"162.28"},{"X":"387.11","Y":"159.77"},{"X":"390.08","Y":"158.35"},{"X":"395.48","Y":"157.12"},{"X":"401.76","Y":"156.70"},{"X":"406.66","Y":"157.40"},{"X":"412.02","Y":"159.31"},{"X":"416.24","Y":"161.51"},{"X":"416.24","Y":"157.06"},{"X":"433.55","Y":"157.06"},{"X":"433.43","Y":"223.84"},{"X":"432.54","Y":"227.93"},{"X":"430.90","Y":"231.30"},{"X":"428.49","Y":"234.16"},{"X":"425.23","Y":"236.55"},{"X":"420.86","Y":"238.51"},{"X":"415.19","Y":"239.93"},{"X":"407.89","Y":"240.69"},{"X":"399.04","Y":"240.53"},{"X":"391.61","Y":"239.58"},{"X":"384.09","Y":"237.51"},{"X":"382.01","Y":"236.48"},{"X":"380.74","Y":"226.84"},{"X":"385.59","Y":"229.19"},{"X":"391.82","Y":"231.36"},{"X":"398.16","Y":"232.49"},{"X":"401.75","Y":"232.75"},{"X":"401.90","Y":"232.76"}],[{"X":"416.25","Y":"170.27"},{"X":"414.97","Y":"169.05"},{"X":"410.96","Y":"166.71"},{"X":"406.83","Y":"165.39"},{"X":"404.44","Y":"165.28"},{"X":"400.31","Y":"165.96"},{"X":"397.15","Y":"167.34"},{"X":"394.75","Y":"169.35"},{"X":"392.82","Y":"172.20"},{"X":"391.40","Y":"176.14"},{"X":"390.35","Y":"182.50"},{"X":"390.04","Y":"190.14"},{"X":"390.67","Y":"197.15"},{"X":"391.97","Y":"202.39"},{"X":"393.71","Y":"206.20"},{"X":"395.76","Y":"208.58"},{"X":"398.42","Y":"210.25"},{"X":"401.86","Y":"211.27"},{"X":"406.04","Y":"211.51"},{"X":"410.92","Y":"210.69"},{"X":"414.49","Y":"209.16"},{"X":"416.25","Y":"208.01"},{"X":"416.25","Y":"170.27"},{"X":"416.25","Y":"170.27"}]]'; return { "ss": deserialize_clipper_poly(text_polygon), "cc": deserialize_clipper_poly(text_clipping) }; } function get_rectangle_polys() { var rectangle1 = '[[{"X":155,"Y":61.67},{"X":155,"Y":212.7},{"X":288.98,"Y":212.7},{"X":288.98,"Y":61.67},{"X":173.01999999999998,"Y":61.67},{"X":155,"Y":61.67}],[{"X":274.37,"Y":190.77},{"X":171.24,"Y":190.77},{"X":171.24,"Y":81.16},{"X":274.37,"Y":81.16},{"X":274.37,"Y":81.16},{"X":274.37,"Y":190.77}]]'; var rectangle2 = '[[{"X":217.69,"Y":126.14},{"X":217.69,"Y":277.17},{"X":351.66999999999996,"Y":277.17},{"X":351.66999999999996,"Y":126.14},{"X":253.71,"Y":126.14},{"X":217.69,"Y":126.14}],[{"X":337.05,"Y":255.25},{"X":233.93,"Y":255.25},{"X":233.93,"Y":145.63},{"X":337.05,"Y":145.63},{"X":337.05,"Y":145.63},{"X":337.05,"Y":255.25}]]'; return { "ss": deserialize_clipper_poly(rectangle1), "cc": deserialize_clipper_poly(rectangle2) }; } function get_ZigZag_polys() { var rectangle1 = '[[{"X":370,"Y":99.5},{"X":330.5,"Y":99.5},{"X":284.5,"Y":99.5},{"X":238.5,"Y":99.5},{"X":207.7,"Y":99.5},{"X":198.4,"Y":140.7},{"X":194.7,"Y":157.5},{"X":177.7,"Y":232.5},{"X":166.9,"Y":192.4},{"X":152.8,"Y":139.5},{"X":145.8,"Y":163.6},{"X":139.4,"Y":186},{"X":132.4,"Y":210.5},{"X":127,"Y":194.5},{"X":117.8,"Y":167.3},{"X":117.8,"Y":188.5},{"X":117.8,"Y":208.5},{"X":127.3,"Y":173.5},{"X":131.5,"Y":158.3},{"X":142.1,"Y":195.6},{"X":150.7,"Y":225.5},{"X":162.5,"Y":184.8},{"X":167,"Y":169.2},{"X":172,"Y":152},{"X":181,"Y":121},{"X":199.8,"Y":250.5},{"X":203.5,"Y":181},{"X":204.6,"Y":159.5},{"X":207.7,"Y":99.5},{"X":213.9,"Y":147.1},{"X":217.9,"Y":177.5},{"X":221.4,"Y":204.1},{"X":227.4,"Y":250.5},{"X":235,"Y":199.6},{"X":239.2,"Y":171.5},{"X":250,"Y":99.5},{"X":257.8,"Y":148.5},{"X":263.9,"Y":186.7},{"X":266.5,"Y":203},{"X":274,"Y":250.5},{"X":285.9,"Y":164.8},{"X":289.6,"Y":138.4},{"X":295,"Y":99.5},{"X":305.1,"Y":163.1},{"X":319.1,"Y":250.5},{"X":321.3,"Y":234.5},{"X":328.3,"Y":184.5},{"X":332.3,"Y":155.6},{"X":340.2,"Y":99.5},{"X":346.1,"Y":136.6},{"X":348.5,"Y":151.9},{"X":357.2,"Y":206.6},{"X":364.1,"Y":250.5},{"X":372.3,"Y":182.4},{"X":376.3,"Y":149},{"X":379.5,"Y":122.1},{"X":382.2,"Y":99.5}]]'; var rectangle2 = '[]'; return { "ss": deserialize_clipper_poly(rectangle1), "cc": deserialize_clipper_poly(rectangle2) }; } function get_star_and_rect() { var star = '[[{"X":147.47,"Y":312.74},{"X":247.07,"Y":33.510000000000005},{"X":337.66,"Y":312.04},{"X":86.36,"Y":122.7},{"X":404.07,"Y":123.57},{"X":148.11,"Y":312.27},{"X":147.47,"Y":312.74}]]'; var rectangle1 = '[[{"X":336.36,"Y":261.38},{"X":155.25,"Y":260.49},{"X":155.25,"Y":84.06},{"X":336.36,"Y":84.06},{"X":336.36,"Y":261.38},{"X":336.36,"Y":261.38}]]'; return { "ss": deserialize_clipper_poly(star), "cc": deserialize_clipper_poly(rectangle1) }; } function get_spiral_and_rects() { var spiral = '[[{"X":222.02,"Y":294.08},{"X":202.56,"Y":292.96},{"X":183.69,"Y":289.52},{"X":165.670002,"Y":283.86},{"X":148.5,"Y":275.99},{"X":132.45999999999998,"Y":266.02},{"X":117.8,"Y":254.11},{"X":104.75,"Y":240.45},{"X":93.72,"Y":225.49},{"X":84.85,"Y":209.5},{"X":78.12,"Y":192.5},{"X":73.73,"Y":175.06},{"X":71.6,"Y":156.89},{"X":71.83,"Y":139.51},{"X":74.33,"Y":123.52},{"X":79.1,"Y":108.05},{"X":86.16,"Y":93.15},{"X":95.270001,"Y":79.41},{"X":106.41,"Y":66.85},{"X":119.19,"Y":55.97},{"X":133.6,"Y":46.79},{"X":149.15,"Y":39.7},{"X":165.51999999999998,"Y":34.82},{"X":182.41,"Y":32.2300004},{"X":199.5,"Y":31.97},{"X":214.94,"Y":34.03},{"X":229.61,"Y":38.33},{"X":243.45,"Y":44.81},{"X":256.13,"Y":53.36},{"X":267.330004,"Y":63.75},{"X":276.63,"Y":75.5},{"X":283.960004,"Y":88.57},{"X":289.03,"Y":102.35},{"X":291.840003,"Y":116.77},{"X":292.340003,"Y":131.44},{"X":290.53999999999996,"Y":144.5},{"X":286.49,"Y":157.05},{"X":280.16999999999996,"Y":168.96},{"X":271.9,"Y":179.61},{"X":261.710004,"Y":188.89},{"X":250.1,"Y":196.31},{"X":237.4,"Y":201.68},{"X":223.99,"Y":204.85},{"X":209.93,"Y":205.76},{"X":197.13,"Y":204.33},{"X":185.11,"Y":200.63},{"X":173.99,"Y":194.74},{"X":164.19,"Y":186.85},{"X":156.22,"Y":177.51},{"X":150.18,"Y":166.82},{"X":146.41,"Y":155.44},{"X":144.89,"Y":143.56},{"X":145.63,"Y":132.5},{"X":148.59,"Y":122.14},{"X":153.8,"Y":112.36},{"X":160.93,"Y":103.88},{"X":169.89,"Y":96.86},{"X":180.09,"Y":91.81},{"X":191.1,"Y":88.95},{"X":202.47,"Y":88.37},{"X":212.8,"Y":90.1},{"X":222.22,"Y":93.95},{"X":230.55,"Y":99.81},{"X":237.37,"Y":107.36},{"X":242.28,"Y":116.28},{"X":244.92,"Y":125.8},{"X":245.3,"Y":135.670002},{"X":243.42,"Y":144.44},{"X":239.27,"Y":152.74},{"X":233.18,"Y":159.73},{"X":225.31,"Y":165.19},{"X":216.34,"Y":168.54},{"X":206.82,"Y":169.6},{"X":198.23,"Y":168.4},{"X":190.26,"Y":164.97},{"X":183.5,"Y":159.55},{"X":178.57999999999998,"Y":152.77},{"X":175.66,"Y":144.92},{"X":175,"Y":136.87},{"X":176.64,"Y":132.74},{"X":180.14,"Y":130},{"X":184.55,"Y":129.420002},{"X":188.66,"Y":131.13},{"X":191.34,"Y":134.670002},{"X":192.98,"Y":143.46},{"X":196.15,"Y":148.15},{"X":201.12,"Y":151.43},{"X":206.97,"Y":152.6},{"X":214.06,"Y":151.54},{"X":220.43,"Y":148.24},{"X":225.15,"Y":143.26},{"X":227.84,"Y":137.26},{"X":228.34,"Y":130.41},{"X":226.58,"Y":122.84},{"X":222.68,"Y":116.12},{"X":216.8,"Y":110.59},{"X":209.61,"Y":106.92},{"X":201.39,"Y":105.35},{"X":191.84,"Y":106.08},{"X":182.76,"Y":109.12},{"X":174.94,"Y":114.11},{"X":168.57999999999998,"Y":120.86},{"X":164.26,"Y":128.730002},{"X":162.09,"Y":137.44},{"X":162.230002,"Y":147.31},{"X":164.64,"Y":157.2},{"X":169.35,"Y":166.56},{"X":176.03,"Y":174.64},{"X":184.51999999999998,"Y":181.28},{"X":194.25,"Y":185.91},{"X":204.75,"Y":188.36},{"X":216.73,"Y":188.57},{"X":228.83,"Y":186.5},{"X":240.34,"Y":182.2},{"X":250.83,"Y":175.81},{"X":259.9,"Y":167.54},{"X":267.03,"Y":157.91},{"X":272.02,"Y":147.35},{"X":274.830004,"Y":136.01},{"X":275.340003,"Y":123.74},{"X":273.580004,"Y":110.68},{"X":269.580004,"Y":98.12},{"X":263.3,"Y":86.19},{"X":255.05,"Y":75.52},{"X":244.91,"Y":66.18},{"X":233.35,"Y":58.67},{"X":220.7,"Y":53.21},{"X":207.02,"Y":49.86},{"X":192.67,"Y":48.8},{"X":176.82999999999998,"Y":50},{"X":161.34,"Y":53.51},{"X":146.540002,"Y":59.27},{"X":132.76,"Y":67.17},{"X":120.53999999999999,"Y":76.85},{"X":109.92,"Y":88.25},{"X":101.32,"Y":100.89},{"X":94.75999999999999,"Y":114.7},{"X":90.52,"Y":129.07},{"X":88.57,"Y":143.93},{"X":88.92,"Y":160.71},{"X":91.63,"Y":177.58},{"X":96.66,"Y":193.91},{"X":103.9,"Y":209.38},{"X":113.37,"Y":223.97},{"X":124.72,"Y":237.14},{"X":137.93,"Y":248.89},{"X":152.59,"Y":258.78999999999996},{"X":168.44,"Y":266.65},{"X":185.18,"Y":272.34},{"X":202.83,"Y":275.85},{"X":221.07,"Y":277.07},{"X":241.43,"Y":276},{"X":261.24,"Y":272.63},{"X":280.52,"Y":266.98},{"X":299,"Y":259.12},{"X":316.43,"Y":249.14},{"X":332.56,"Y":237.17},{"X":346.94,"Y":223.57},{"X":359.59,"Y":208.35},{"X":370.15,"Y":191.97},{"X":378.51,"Y":174.7},{"X":384.69,"Y":156.54},{"X":388.59,"Y":137.75},{"X":390.64,"Y":115.98},{"X":393.21,"Y":112.35},{"X":397.26,"Y":110.5},{"X":401.4,"Y":110.83},{"X":405.08,"Y":113.33},{"X":407,"Y":117.34},{"X":406.15,"Y":134.39},{"X":402.81,"Y":154.2},{"X":397.18,"Y":173.48},{"X":389.22,"Y":192.25},{"X":379.12,"Y":209.96},{"X":366.88,"Y":226.64},{"X":352.8,"Y":241.8},{"X":336.88,"Y":255.47},{"X":319.51,"Y":267.26},{"X":300.93,"Y":277.02},{"X":281.38,"Y":284.66},{"X":260.81,"Y":290.13},{"X":239.75,"Y":293.26},{"X":222.07,"Y":294.08},{"X":222.02,"Y":294.08}]]'; var rectangle1 = '[[{"X":210.91,"Y":210.89},{"X":107.65,"Y":210.65},{"X":107.65,"Y":27.58},{"X":210.91,"Y":27.75},{"X":210.91,"Y":36.45},{"X":210.91,"Y":210.89}],[{"X":304.24,"Y":323.13},{"X":210.91,"Y":322.86},{"X":210.91,"Y":70.9},{"X":304.24,"Y":70.91},{"X":304.24,"Y":148.61},{"X":304.24,"Y":323.13}],[{"X":407.5,"Y":254.59},{"X":304.24,"Y":254.35},{"X":304.24,"Y":71.28},{"X":407.5,"Y":71.28},{"X":407.5,"Y":71.28},{"X":407.5,"Y":254.59}]]'; return { "ss": deserialize_clipper_poly(spiral), "cc": deserialize_clipper_poly(rectangle1) }; } function get_rounded_grid_and_star() { var rounded_grid = '[[{"X":346.2,"Y":66.31},{"X":332.04,"Y":53.81},{"X":316.43,"Y":43.18},{"X":299.87,"Y":34.73995},{"X":282.39,"Y":28.44},{"X":263.95,"Y":24.33},{"X":245.15,"Y":22.56002},{"X":226.27,"Y":23.13},{"X":207.6,"Y":26.04},{"X":189.74,"Y":31.18},{"X":172.6702,"Y":38.53},{"X":156.65,"Y":47.95},{"X":141.69,"Y":59.49},{"X":128.2902,"Y":72.8},{"X":116.65,"Y":87.67},{"X":107.11,"Y":103.62},{"X":99.64,"Y":120.65},{"X":94.37,"Y":138.47},{"X":91.33,"Y":157.11},{"X":90.63,"Y":175.99},{"X":92.2599,"Y":194.8},{"X":96.2401,"Y":213.27},{"X":102.42,"Y":230.8},{"X":110.74,"Y":247.42},{"X":121.26,"Y":263.1},{"X":133.6702,"Y":277.35},{"X":147.74,"Y":289.95},{"X":163.2698,"Y":300.69},{"X":179.77,"Y":309.25},{"X":197.21,"Y":315.68},{"X":215.62,"Y":319.92},{"X":234.41,"Y":321.81},{"X":253.29,"Y":321.38},{"X":271.98,"Y":318.6},{"X":289.87,"Y":313.58},{"X":307,"Y":306.36},{"X":323.09,"Y":297.05},{"X":338.12,"Y":285.62},{"X":351.62,"Y":272.4},{"X":363.37,"Y":257.61},{"X":373.02,"Y":241.73},{"X":380.61,"Y":224.76},{"X":386,"Y":206.97},{"X":389.18,"Y":188.35},{"X":390.01,"Y":169.48},{"X":388.5,"Y":150.65},{"X":384.65,"Y":132.16},{"X":378.61,"Y":114.59},{"X":370.4,"Y":97.91},{"X":359.99,"Y":82.15},{"X":347.69,"Y":67.82},{"X":346.21,"Y":66.32},{"X":346.2,"Y":66.31}],[{"X":375.03,"Y":172.21},{"X":373.83,"Y":190.15},{"X":370.54,"Y":206.57},{"X":362.32,"Y":203.86},{"X":365.47,"Y":187.07},{"X":366.32,"Y":169.7},{"X":364.79,"Y":152.38},{"X":360.96,"Y":135.73},{"X":354.9,"Y":119.76},{"X":346.72,"Y":104.76},{"X":336.39,"Y":90.77},{"X":324.26,"Y":78.32},{"X":320.42,"Y":74.77},{"X":325.57,"Y":67.97},{"X":338.69,"Y":80.27},{"X":350.08,"Y":94.19},{"X":359.52,"Y":109.5},{"X":366.74,"Y":125.65},{"X":371.75,"Y":142.61},{"X":374.49,"Y":160.09},{"X":375.03,"Y":172.07},{"X":375.03,"Y":172.21}],[{"X":129.2698,"Y":172.21},{"X":130.44,"Y":156.06},{"X":133.9598,"Y":140.26},{"X":139.75,"Y":125.15},{"X":147.69,"Y":111.05},{"X":157.6,"Y":98.25},{"X":169.15,"Y":87.09},{"X":174.15,"Y":94.2},{"X":163.0798,"Y":105.17},{"X":153.78,"Y":117.67},{"X":146.4802,"Y":131.44},{"X":141.37,"Y":146.17},{"X":138.57,"Y":161.5},{"X":138.13,"Y":177.08},{"X":140.05,"Y":192.54},{"X":140.87,"Y":196.58},{"X":132.61,"Y":199.24},{"X":129.82,"Y":183.3},{"X":129.2698,"Y":172.22},{"X":129.2698,"Y":172.21}],[{"X":327.6,"Y":172.21},{"X":326.42,"Y":186.54},{"X":325.15,"Y":191.85},{"X":317.08,"Y":189.04},{"X":318.84,"Y":175.67},{"X":318.28,"Y":162.2},{"X":315.43,"Y":149.02},{"X":310.34,"Y":136.54},{"X":303.19,"Y":125.11},{"X":293.99,"Y":114.85},{"X":292.48,"Y":113.21},{"X":297.61,"Y":106.36},{"X":307.64,"Y":116.67},{"X":315.86,"Y":128.4802},{"X":322.02,"Y":141.48},{"X":325.96,"Y":155.31},{"X":327.56,"Y":169.6},{"X":327.6,"Y":172},{"X":327.6,"Y":172.21}],[{"X":153.0198,"Y":172.21},{"X":154.19,"Y":157.87},{"X":157.7098,"Y":143.92},{"X":163.49,"Y":130.75},{"X":171.35,"Y":118.7},{"X":181.07,"Y":108.1},{"X":183.26,"Y":106.49},{"X":188.11,"Y":113.5},{"X":178.65,"Y":123.52},{"X":171.2098,"Y":134.7698},{"X":165.8,"Y":147.12},{"X":162.61,"Y":160.22},{"X":161.7098,"Y":173.67},{"X":163.13,"Y":187.08},{"X":163.36,"Y":189.28},{"X":155.22,"Y":191.74},{"X":153.18,"Y":177.51},{"X":153.0198,"Y":172.41},{"X":153.0198,"Y":172.21}],[{"X":303.92,"Y":172.21},{"X":302.73,"Y":184.43},{"X":294.39,"Y":181.76},{"X":295.2104,"Y":170.41},{"X":293.6597,"Y":159.14},{"X":289.8,"Y":148.43},{"X":283.81,"Y":138.76},{"X":278.44,"Y":132.51},{"X":283.57,"Y":125.63},{"X":291.73,"Y":134.82},{"X":297.98,"Y":145.39},{"X":302.07,"Y":156.97},{"X":303.84,"Y":169.12},{"X":303.92,"Y":172.12},{"X":303.92,"Y":172.21}],[{"X":200.38,"Y":172.21},{"X":201.53,"Y":162.7},{"X":204.93,"Y":153.75},{"X":210.37,"Y":145.87},{"X":211.36,"Y":145.15},{"X":216.39,"Y":152.18},{"X":211.93,"Y":159.27},{"X":209.51,"Y":167.29},{"X":209.16,"Y":174.43},{"X":200.68,"Y":177.07},{"X":200.38,"Y":172.28},{"X":200.38,"Y":172.21}],[{"X":279.9196,"Y":177.17},{"X":271.4,"Y":174.36},{"X":270.87,"Y":166.01},{"X":268.12,"Y":158.1},{"X":264.19,"Y":152.1},{"X":269.5,"Y":145.05},{"X":275.1597,"Y":152.78},{"X":278.81,"Y":161.64},{"X":280.22,"Y":171.11},{"X":279.93,"Y":177.09},{"X":279.9196,"Y":177.17}],[{"X":251.65,"Y":183.77},{"X":247.81,"Y":186.59},{"X":247.94,"Y":182.57},{"X":251.37,"Y":183.68},{"X":251.65,"Y":183.77}],[{"X":252.45,"Y":168.26},{"X":254.89,"Y":165.21},{"X":256.24,"Y":169.49},{"X":252.54,"Y":168.29},{"X":252.45,"Y":168.26}],[{"X":240.31,"Y":159.45},{"X":238.03,"Y":156.14},{"X":242.64,"Y":156.24},{"X":240.35,"Y":159.39},{"X":240.31,"Y":159.45}],[{"X":228.17,"Y":168.26},{"X":224.41,"Y":169.28},{"X":225.81,"Y":165.03},{"X":228.11,"Y":168.18},{"X":228.17,"Y":168.26}],[{"X":232.81,"Y":182.52},{"X":232.69,"Y":186.53},{"X":229.1,"Y":183.73},{"X":232.52,"Y":182.62},{"X":232.81,"Y":182.52}],[{"X":247.81,"Y":202.54},{"X":255.59,"Y":199.43},{"X":262.26,"Y":194.37},{"X":266.99,"Y":188.75},{"X":275.13,"Y":191.69},{"X":269.4604,"Y":199.41},{"X":262.13,"Y":205.57},{"X":253.54,"Y":209.81},{"X":247.81,"Y":211.35},{"X":247.81,"Y":211.35},{"X":247.81,"Y":202.54}],[{"X":252.07,"Y":143.27},{"X":243.96,"Y":141.17},{"X":235.59,"Y":141.32},{"X":228.44,"Y":143.14},{"X":223.38,"Y":136.11},{"X":232.48,"Y":133.12},{"X":242.03,"Y":132.38},{"X":251.47,"Y":133.94},{"X":257.2,"Y":136.21},{"X":252.09,"Y":143.25},{"X":252.07,"Y":143.27}],[{"X":213.83,"Y":188.68},{"X":219.16,"Y":195.14},{"X":226,"Y":199.96},{"X":232.81,"Y":202.54},{"X":232.71,"Y":211.33},{"X":223.6,"Y":208.4},{"X":215.45,"Y":203.37},{"X":208.72,"Y":196.55},{"X":205.5,"Y":191.38},{"X":213.77,"Y":188.7},{"X":213.83,"Y":188.68}],[{"X":232.81,"Y":226.54},{"X":232.63,"Y":235.34},{"X":220.63,"Y":232.69},{"X":209.38,"Y":227.76},{"X":199.29,"Y":220.77},{"X":190.72,"Y":211.98},{"X":183.98,"Y":201.71},{"X":182.64,"Y":198.8},{"X":190.9,"Y":196.16},{"X":196.92,"Y":205.81},{"X":204.8,"Y":214.02},{"X":214.19,"Y":220.45},{"X":224.71,"Y":224.8},{"X":232.61,"Y":226.52},{"X":232.81,"Y":226.54}],[{"X":247.81,"Y":226.54},{"X":258.86,"Y":223.83},{"X":269.11,"Y":218.89},{"X":278.13,"Y":211.95},{"X":285.53,"Y":203.31},{"X":289.8,"Y":196.15},{"X":298.05,"Y":198.84},{"X":291.8403,"Y":209.44},{"X":283.7104,"Y":218.65},{"X":273.98,"Y":226.14},{"X":262.99,"Y":231.62},{"X":251.15,"Y":234.87},{"X":247.81,"Y":235.36},{"X":247.81,"Y":235.36},{"X":247.81,"Y":226.54}],[{"X":266.2,"Y":123.84},{"X":255.67,"Y":119.53},{"X":244.47,"Y":117.5},{"X":233.1,"Y":117.82},{"X":222.03,"Y":120.47},{"X":214.38,"Y":123.79},{"X":209.48,"Y":116.59},{"X":220.74,"Y":111.68},{"X":232.73,"Y":109.05},{"X":245.01,"Y":108.77},{"X":257.11,"Y":110.86},{"X":268.5804,"Y":115.25},{"X":271.2896,"Y":116.84},{"X":266.35,"Y":123.63},{"X":266.2,"Y":123.84}],[{"X":202.29,"Y":132.6702},{"X":194.93,"Y":141.35},{"X":189.51,"Y":151.35},{"X":186.28,"Y":162.26},{"X":185.4,"Y":173.61},{"X":186.15,"Y":181.89},{"X":177.9,"Y":184.53},{"X":176.7,"Y":172.31},{"X":177.86,"Y":160.08},{"X":181.36,"Y":148.31},{"X":187.07,"Y":137.44},{"X":194.76,"Y":127.86},{"X":197.29,"Y":125.8},{"X":202.24,"Y":132.6},{"X":202.29,"Y":132.6702}],[{"X":168.2,"Y":203.48},{"X":174.63,"Y":215.34},{"X":182.98,"Y":225.92},{"X":193.01,"Y":234.94},{"X":204.42,"Y":242.12},{"X":216.89,"Y":247.24},{"X":230.06,"Y":250.14},{"X":232.81,"Y":250.45},{"X":232.66,"Y":259.23},{"X":218.49,"Y":256.8},{"X":204.91,"Y":252.05},{"X":192.3,"Y":245.13},{"X":180.99,"Y":236.24},{"X":171.2902,"Y":225.63},{"X":163.44,"Y":213.57},{"X":160.07,"Y":206.12},{"X":168.06,"Y":203.53},{"X":168.2,"Y":203.48}],[{"X":247.81,"Y":250.45},{"X":261.07,"Y":248.02},{"X":273.72,"Y":243.35},{"X":285.37,"Y":236.57},{"X":295.7104,"Y":227.91},{"X":304.42,"Y":217.62},{"X":311.26,"Y":206},{"X":312.63,"Y":203.56},{"X":320.65,"Y":206.36},{"X":313.94,"Y":219.08},{"X":305.24,"Y":230.53},{"X":294.7896,"Y":240.41},{"X":282.86,"Y":248.46},{"X":269.78,"Y":254.44},{"X":255.89,"Y":258.1696},{"X":247.81,"Y":259.24},{"X":247.81,"Y":259.24},{"X":247.81,"Y":250.45}],[{"X":280.24,"Y":104.53},{"X":268.0903,"Y":98.68},{"X":255.12,"Y":95},{"X":241.71,"Y":93.61},{"X":228.26,"Y":94.52},{"X":215.16,"Y":97.73},{"X":202.81,"Y":103.15},{"X":200.26,"Y":104.37},{"X":195.31,"Y":97.37},{"X":208.19,"Y":90.97},{"X":221.96,"Y":86.79},{"X":236.22,"Y":84.94},{"X":250.6,"Y":85.45},{"X":264.69,"Y":88.31},{"X":278.12,"Y":93.47},{"X":285.3304,"Y":97.52},{"X":280.4,"Y":104.31},{"X":280.24,"Y":104.53}],[{"X":240.31,"Y":69.85},{"X":224.77,"Y":71.03},{"X":209.88,"Y":74.47},{"X":195.4,"Y":80.25},{"X":186.27,"Y":85.13},{"X":181.44,"Y":78.15},{"X":195.74,"Y":70.57},{"X":211,"Y":65.16},{"X":226.88,"Y":62.04},{"X":243.04,"Y":61.27},{"X":259.15,"Y":62.84},{"X":274.86,"Y":66.7401},{"X":289.8304,"Y":72.9},{"X":299.23,"Y":78.4},{"X":294.06,"Y":85.16},{"X":280.23,"Y":77.97},{"X":265.47,"Y":72.98},{"X":250.12,"Y":70.31},{"X":240.53,"Y":69.85},{"X":240.31,"Y":69.85}],[{"X":145.5798,"Y":210.82},{"X":152.56,"Y":224.76},{"X":161.57,"Y":237.47},{"X":172.4,"Y":248.69},{"X":184.79,"Y":258.14},{"X":198.47,"Y":265.6},{"X":213.13,"Y":270.89},{"X":228.42,"Y":273.88},{"X":232.81,"Y":274.29},{"X":232.64,"Y":282.91},{"X":216.62,"Y":280.63},{"X":201.1,"Y":276.03},{"X":186.42,"Y":269.2},{"X":172.89,"Y":260.32},{"X":160.7902,"Y":249.58},{"X":150.36,"Y":237.2},{"X":141.8298,"Y":223.44},{"X":137.4202,"Y":213.47},{"X":145.41,"Y":210.88},{"X":145.5798,"Y":210.82}],[{"X":247.81,"Y":274.29},{"X":263.22,"Y":271.97},{"X":277.81,"Y":267.44},{"X":291.82,"Y":260.61},{"X":304.63,"Y":251.73},{"X":315.96,"Y":241.02},{"X":325.54,"Y":228.73},{"X":333.15,"Y":215.13},{"X":335.12,"Y":210.85},{"X":343.34,"Y":213.56},{"X":336.21,"Y":228.09},{"X":327.03,"Y":241.42},{"X":316.03,"Y":253.29},{"X":303.43,"Y":263.45},{"X":289.49,"Y":271.68},{"X":274.5,"Y":277.79},{"X":258.78,"Y":281.63},{"X":247.81,"Y":282.92},{"X":247.81,"Y":282.92},{"X":247.81,"Y":274.29}],[{"X":339.67,"Y":196.56},{"X":342.21,"Y":181.18},{"X":342.39,"Y":165.6},{"X":340.21,"Y":150.16},{"X":335.7,"Y":135.25},{"X":328.96,"Y":121.19},{"X":320.17,"Y":108.32},{"X":309.54,"Y":96.93},{"X":306.51,"Y":93.91},{"X":311.67,"Y":87.25},{"X":323.27,"Y":98.54},{"X":333.13,"Y":111.37},{"X":341.03,"Y":125.5},{"X":346.77,"Y":140.63},{"X":350.23,"Y":156.45},{"X":351.35,"Y":172.59},{"X":350.12,"Y":188.73},{"X":347.95,"Y":199.24},{"X":339.68,"Y":196.56},{"X":339.67,"Y":196.56}],[{"X":313.32,"Y":59.03},{"X":307.96,"Y":65.9601},{"X":292.9604,"Y":57.76},{"X":277,"Y":51.68},{"X":260.35,"Y":47.83},{"X":243.33,"Y":46.27},{"X":225.96,"Y":47.04},{"X":209.16,"Y":50.13},{"X":192.93,"Y":55.47},{"X":177.58,"Y":62.97},{"X":172.2698,"Y":65.87},{"X":167.5,"Y":58.9},{"X":182.96,"Y":50.31},{"X":199.42,"Y":43.83},{"X":216.59,"Y":39.58},{"X":234.17,"Y":37.62005},{"X":252.15,"Y":38},{"X":269.63,"Y":40.7},{"X":286.6,"Y":45.68},{"X":302.76,"Y":52.86},{"X":313.12,"Y":58.91},{"X":313.32,"Y":59.03}],[{"X":155.18,"Y":67.87},{"X":160.1,"Y":75.1},{"X":147.49,"Y":87.07},{"X":136.63,"Y":100.65},{"X":127.73,"Y":115.58},{"X":121.08,"Y":131.32},{"X":116.64,"Y":147.82},{"X":114.48,"Y":164.77},{"X":114.66,"Y":182.16},{"X":117.15,"Y":199.06},{"X":118.19,"Y":203.94},{"X":110.01,"Y":206.46},{"X":106.64,"Y":189.1},{"X":105.59,"Y":171.14},{"X":106.92,"Y":153.21},{"X":110.56,"Y":135.9},{"X":116.45,"Y":119.22},{"X":124.48,"Y":103.46},{"X":134.7,"Y":88.66},{"X":146.78,"Y":75.33},{"X":155.07,"Y":67.9601},{"X":155.18,"Y":67.87}],[{"X":114.68,"Y":220.85},{"X":123.06,"Y":218.44},{"X":130.4202,"Y":233.86},{"X":139.99,"Y":248.38},{"X":151.45,"Y":261.4604},{"X":164.59,"Y":272.84},{"X":179.16,"Y":282.33},{"X":194.62,"Y":289.61},{"X":210.92,"Y":294.71},{"X":227.77,"Y":297.55},{"X":232.81,"Y":297.95},{"X":232.52,"Y":306.7},{"X":214.97,"Y":304.53},{"X":197.86,"Y":300.07},{"X":181.48,"Y":293.39},{"X":166.12,"Y":284.61},{"X":151.82,"Y":273.7},{"X":139.0798,"Y":261.01},{"X":128.14,"Y":246.73},{"X":119.31,"Y":231.41},{"X":114.72,"Y":220.97},{"X":114.68,"Y":220.85}],[{"X":247.81,"Y":306.71},{"X":248.04,"Y":297.93},{"X":264.99,"Y":295.74},{"X":281.48,"Y":291.27},{"X":297.2,"Y":284.59},{"X":311.88,"Y":275.84},{"X":325.47,"Y":264.99},{"X":337.44,"Y":252.39},{"X":347.59,"Y":238.27},{"X":355.57,"Y":223.16},{"X":357.93,"Y":218.25},{"X":365.83,"Y":221.11},{"X":358.32,"Y":237.13},{"X":348.6,"Y":252.26},{"X":336.95,"Y":265.97},{"X":323.6,"Y":278.02},{"X":308.77,"Y":288.19},{"X":292.99,"Y":296.19},{"X":276.3,"Y":302.04},{"X":258.98,"Y":305.63},{"X":247.94,"Y":306.71},{"X":247.81,"Y":306.71}]]'; var star = '[[{"X":240.31,"Y":12.26},{"X":292.45,"Y":117.59},{"X":408.23,"Y":134.69},{"X":324.43,"Y":216.63},{"X":344.16,"Y":332.1},{"X":240.06,"Y":277.63},{"X":136.4,"Y":332},{"X":155.99,"Y":216.19},{"X":72.33,"Y":134.4202},{"X":188.37,"Y":117.5},{"X":240.28,"Y":12.30999},{"X":240.31,"Y":12.26}]]'; return { "ss": deserialize_clipper_poly(rounded_grid), "cc": deserialize_clipper_poly(star) }; } function get_glyph_and_grid() { var glyph = '[[{"X":105.65,"Y":51.37},{"X":105.65,"Y":295.26},{"X":395.09,"Y":295.26},{"X":395.01,"Y":51.37},{"X":108.51,"Y":51.37},{"X":105.65,"Y":51.37}],[{"X":380.09,"Y":89.4799},{"X":349.33,"Y":89.4799},{"X":349.33,"Y":66.37},{"X":380.09,"Y":66.37},{"X":380.09,"Y":66.37},{"X":380.09,"Y":89.4799}],[{"X":257.87,"Y":127.7},{"X":257.87,"Y":104.48},{"X":288.63,"Y":104.48},{"X":288.44,"Y":127.7},{"X":283.0396,"Y":127.7},{"X":257.87,"Y":127.7}],[{"X":288.63,"Y":142.7},{"X":288.63,"Y":165.81},{"X":257.87,"Y":165.81},{"X":257.87,"Y":142.7},{"X":257.87,"Y":142.7},{"X":288.63,"Y":142.7}],[{"X":242.87,"Y":127.7},{"X":212.11,"Y":127.7},{"X":212.11,"Y":104.48},{"X":242.87,"Y":104.48},{"X":242.87,"Y":104.48},{"X":242.87,"Y":127.7}],[{"X":242.87,"Y":142.7},{"X":242.87,"Y":165.81},{"X":212.11,"Y":165.81},{"X":212.11,"Y":142.7},{"X":212.11,"Y":142.7},{"X":242.87,"Y":142.7}],[{"X":197.11,"Y":165.81},{"X":166.41,"Y":165.81},{"X":166.41,"Y":142.7},{"X":197.11,"Y":142.7},{"X":197.11,"Y":142.7},{"X":197.11,"Y":165.81}],[{"X":197.11,"Y":180.81},{"X":197.11,"Y":203.92},{"X":166.41,"Y":203.92},{"X":166.41,"Y":180.81},{"X":166.41,"Y":180.81},{"X":197.11,"Y":180.81}],[{"X":212.11,"Y":180.81},{"X":242.87,"Y":180.81},{"X":242.87,"Y":203.92},{"X":212.11,"Y":203.92},{"X":212.11,"Y":203.92},{"X":212.11,"Y":180.81}],[{"X":242.87,"Y":218.92},{"X":242.87,"Y":242.14},{"X":212.11,"Y":242.14},{"X":212.11,"Y":218.92},{"X":212.11,"Y":218.92},{"X":242.87,"Y":218.92}],[{"X":257.87,"Y":218.92},{"X":288.63,"Y":218.92},{"X":288.63,"Y":242.14},{"X":257.87,"Y":242.14},{"X":257.87,"Y":242.14},{"X":257.87,"Y":218.92}],[{"X":257.87,"Y":203.92},{"X":257.87,"Y":180.81},{"X":288.63,"Y":180.81},{"X":288.63,"Y":203.92},{"X":288.63,"Y":203.92},{"X":257.87,"Y":203.92}],[{"X":303.63,"Y":180.81},{"X":334.33004,"Y":180.81},{"X":334.33004,"Y":203.92},{"X":303.63,"Y":203.92},{"X":303.63,"Y":203.92},{"X":303.63,"Y":180.81}],[{"X":303.63,"Y":165.81},{"X":303.63,"Y":142.7},{"X":334.33004,"Y":142.7},{"X":334.33004,"Y":165.81},{"X":334.33004,"Y":165.81},{"X":303.63,"Y":165.81}],[{"X":303.63,"Y":127.7},{"X":303.63,"Y":104.48},{"X":334.33004,"Y":104.48},{"X":334.07,"Y":127.7},{"X":328.6696,"Y":127.7},{"X":303.63,"Y":127.7}],[{"X":303.63,"Y":89.4799},{"X":303.63,"Y":66.37},{"X":334.33004,"Y":66.37},{"X":334.15,"Y":89.4799},{"X":316.15,"Y":89.4799},{"X":303.63,"Y":89.4799}],[{"X":288.63,"Y":89.4799},{"X":257.87,"Y":89.4799},{"X":257.87,"Y":66.37},{"X":288.63,"Y":66.37},{"X":288.63,"Y":89.4799},{"X":288.63,"Y":89.4799}],[{"X":242.87,"Y":89.4799},{"X":212.11,"Y":89.4799},{"X":212.11,"Y":66.37},{"X":242.87,"Y":66.37},{"X":242.87,"Y":66.37},{"X":242.87,"Y":89.4799}],[{"X":197.11,"Y":89.4799},{"X":166.41,"Y":89.4799},{"X":166.41,"Y":66.37},{"X":197.11,"Y":66.37},{"X":197.11,"Y":66.37},{"X":197.11,"Y":89.4799}],[{"X":197.11,"Y":104.48},{"X":196.93,"Y":127.7},{"X":166.41,"Y":127.7},{"X":166.41,"Y":104.48},{"X":166.41,"Y":104.48},{"X":197.11,"Y":104.48}],[{"X":151.41,"Y":127.7},{"X":120.65,"Y":127.7},{"X":120.65,"Y":104.48},{"X":151.41,"Y":104.48},{"X":151.41,"Y":104.48},{"X":151.41,"Y":127.7}],[{"X":151.41,"Y":142.7},{"X":151.41,"Y":165.81},{"X":120.65,"Y":165.81},{"X":120.65,"Y":142.7},{"X":120.65,"Y":142.7},{"X":151.41,"Y":142.7}],[{"X":151.41,"Y":180.81},{"X":151.41,"Y":203.92},{"X":120.65,"Y":203.92},{"X":120.65,"Y":180.81},{"X":120.65,"Y":180.81},{"X":151.41,"Y":180.81}],[{"X":151.41,"Y":218.92},{"X":151.41,"Y":242.14},{"X":120.65,"Y":242.14},{"X":120.65,"Y":218.92},{"X":120.65,"Y":218.92},{"X":151.41,"Y":218.92}],[{"X":166.41,"Y":218.92},{"X":197.11,"Y":218.92},{"X":197.11,"Y":242.14},{"X":166.41,"Y":242.14},{"X":166.41,"Y":242.14},{"X":166.41,"Y":218.92}],[{"X":197.11,"Y":257.14},{"X":197.11,"Y":280.26},{"X":166.41,"Y":280.26},{"X":166.41,"Y":257.14},{"X":166.41,"Y":257.14},{"X":197.11,"Y":257.14}],[{"X":212.11,"Y":257.14},{"X":242.87,"Y":257.14},{"X":242.87,"Y":280.26},{"X":212.11,"Y":280.26},{"X":212.11,"Y":280.26},{"X":212.11,"Y":257.14}],[{"X":257.87,"Y":257.14},{"X":288.63,"Y":257.14},{"X":288.63,"Y":280.26},{"X":257.87,"Y":280.26},{"X":257.87,"Y":280.26},{"X":257.87,"Y":257.14}],[{"X":303.63,"Y":257.14},{"X":334.33004,"Y":257.14},{"X":334.33004,"Y":280.26},{"X":303.63,"Y":280.26},{"X":303.63,"Y":280.26},{"X":303.63,"Y":257.14}],[{"X":303.63,"Y":242.14},{"X":303.63,"Y":218.92},{"X":334.33004,"Y":218.92},{"X":334.33004,"Y":242.14},{"X":334.33004,"Y":242.14},{"X":303.63,"Y":242.14}],[{"X":349.33,"Y":218.92},{"X":380.09,"Y":218.92},{"X":380.09,"Y":242.14},{"X":349.33,"Y":242.14},{"X":349.33,"Y":242.14},{"X":349.33,"Y":218.92}],[{"X":349.33,"Y":203.92},{"X":349.33,"Y":180.81},{"X":380.09,"Y":180.81},{"X":380.09,"Y":203.92},{"X":380.09,"Y":203.92},{"X":349.33,"Y":203.92}],[{"X":349.33,"Y":165.81},{"X":349.33,"Y":142.7},{"X":380.09,"Y":142.7},{"X":380.09,"Y":165.81},{"X":380.09,"Y":165.81},{"X":349.33,"Y":165.81}],[{"X":349.33,"Y":127.7},{"X":349.33,"Y":104.48},{"X":380.09,"Y":104.48},{"X":379.9,"Y":127.7},{"X":374.5,"Y":127.7},{"X":349.33,"Y":127.7}],[{"X":151.41,"Y":66.37},{"X":151.12,"Y":89.4799},{"X":120.65,"Y":89.4799},{"X":120.65,"Y":66.37},{"X":120.65,"Y":66.37},{"X":151.41,"Y":66.37}],[{"X":120.65,"Y":257.14},{"X":151.41,"Y":257.14},{"X":151.41,"Y":280.26},{"X":120.65,"Y":280.26},{"X":120.65,"Y":280.26},{"X":120.65,"Y":257.14}],[{"X":349.33,"Y":280.26},{"X":349.33,"Y":257.14},{"X":380.09,"Y":257.14},{"X":380.09,"Y":280.26},{"X":380.09,"Y":280.26},{"X":349.33,"Y":280.26}]]'; var grid = '[[{"X":305.08004,"Y":241.97},{"X":306,"Y":251.51},{"X":308.18,"Y":256.4},{"X":311.72,"Y":259.09003},{"X":317.31,"Y":260.01},{"X":324.71004,"Y":259.01},{"X":332.45,"Y":255.86},{"X":335.57,"Y":257.5396},{"X":337.6,"Y":260.44},{"X":336.94,"Y":262.33004},{"X":328.27,"Y":268.74},{"X":317.9,"Y":273.4196},{"X":307.94,"Y":275.49},{"X":296.26,"Y":275.23},{"X":286.64,"Y":272.99},{"X":279.7896,"Y":269.31},{"X":274.14,"Y":263.55},{"X":271.6597,"Y":260.21004},{"X":269.2,"Y":261.06},{"X":254.83,"Y":268.51},{"X":242.11,"Y":272.97},{"X":227.59,"Y":275.23},{"X":209.91,"Y":275.48},{"X":197.47,"Y":273.63},{"X":187.91,"Y":270.13},{"X":180.48002,"Y":265.09003},{"X":175.32,"Y":258.88},{"X":172.2098,"Y":251.44},{"X":171.1,"Y":242.23},{"X":172.24,"Y":233.63},{"X":175.49,"Y":226.24},{"X":181,"Y":219.54},{"X":189.42002,"Y":213.3},{"X":201.36,"Y":207.73},{"X":217.23,"Y":203.25},{"X":238.28,"Y":200.1},{"X":265.24,"Y":198.78},{"X":269.37,"Y":198.47},{"X":269.98,"Y":182.93},{"X":268.74,"Y":171.32},{"X":266.05,"Y":163.7098},{"X":261.58004,"Y":157.72},{"X":255.24,"Y":153.24},{"X":247.06,"Y":150.3298},{"X":235.44,"Y":149.13},{"X":224.71,"Y":150.05},{"X":215.91,"Y":153},{"X":210.23002,"Y":156.86},{"X":207.64,"Y":160.85},{"X":207.19,"Y":165.28},{"X":209.34,"Y":169.86},{"X":212.0198,"Y":174.15},{"X":212.14,"Y":177.99},{"X":209.8,"Y":181.78},{"X":204.22,"Y":185.79},{"X":197.62,"Y":187.68},{"X":188.65,"Y":187.43},{"X":182.41,"Y":185.39},{"X":178.45,"Y":181.77},{"X":176.2098,"Y":176.9},{"X":176.03,"Y":170.64},{"X":178.2,"Y":164.13},{"X":183.09,"Y":157.7},{"X":191.04002,"Y":151.36},{"X":202.01,"Y":145.8298},{"X":216.09,"Y":141.57},{"X":232.08,"Y":139.24},{"X":250.07,"Y":139.18},{"X":266.13,"Y":141.23002},{"X":279.05,"Y":145.06},{"X":289.1597,"Y":150.3},{"X":295.9196,"Y":156.19},{"X":300.73,"Y":163.41},{"X":303.85,"Y":172.47},{"X":305.07,"Y":183.78},{"X":305.07,"Y":241.97},{"X":305.08004,"Y":241.97}],[{"X":243.99,"Y":64.95},{"X":255.92,"Y":66.07},{"X":266.21004,"Y":69.28},{"X":274.98,"Y":74.44},{"X":280.65,"Y":80.19},{"X":284.03,"Y":86.85},{"X":285.26,"Y":94.52001},{"X":284.28,"Y":102.84},{"X":281.24,"Y":109.66},{"X":276.0396,"Y":115.43},{"X":267.89,"Y":120.46},{"X":257.68,"Y":123.93},{"X":245.79,"Y":125.33},{"X":232.93,"Y":124.53},{"X":222.21,"Y":121.74},{"X":213.14,"Y":117.11},{"X":207.36,"Y":111.92},{"X":203.7,"Y":105.75},{"X":201.94,"Y":98.18},{"X":202.34,"Y":90.12},{"X":204.86,"Y":83.4},{"X":210.01,"Y":76.81},{"X":217.49,"Y":71.33},{"X":227.17,"Y":67.31},{"X":238.35,"Y":65.2},{"X":243.75,"Y":64.95},{"X":243.99,"Y":64.95}],[{"X":269.99,"Y":212.88},{"X":269.48,"Y":208.76},{"X":266.59003,"Y":208.36},{"X":245.76,"Y":210.86},{"X":230.95,"Y":214.67},{"X":220.9,"Y":219.34},{"X":213.82,"Y":224.85},{"X":209.69,"Y":230.71},{"X":207.92002,"Y":237.03},{"X":208.4,"Y":244.49},{"X":210.86,"Y":250.57},{"X":215.2,"Y":255.08},{"X":221.69,"Y":258.13},{"X":230.57,"Y":259.43},{"X":242.52,"Y":258.58004},{"X":255.27,"Y":255.23},{"X":266.07,"Y":250.04},{"X":269.34003,"Y":247.02},{"X":269.99,"Y":244.81},{"X":269.99,"Y":212.88},{"X":269.99,"Y":212.88}],[{"X":243.63,"Y":73.34},{"X":235.93,"Y":74.4},{"X":230.07,"Y":77.36},{"X":225.65,"Y":82.21001},{"X":223.05,"Y":88.57},{"X":222.41,"Y":96.92},{"X":223.94,"Y":104.53},{"X":227.23,"Y":110.22},{"X":231.99,"Y":114.29},{"X":238.44,"Y":116.65},{"X":246.81,"Y":116.94},{"X":253.73,"Y":115.1},{"X":258.87,"Y":111.5},{"X":262.63,"Y":106.12},{"X":264.65,"Y":98.93},{"X":264.59003,"Y":90.25},{"X":262.47,"Y":83.41},{"X":258.6597,"Y":78.43},{"X":253.37,"Y":75.08},{"X":246.08,"Y":73.43},{"X":243.68,"Y":73.34},{"X":243.63,"Y":73.34}]]'; return { "ss": deserialize_clipper_poly(glyph), "cc": deserialize_clipper_poly(grid) }; } function get_lines_and_star_and_donut() { var lines = '[[{"X":131.854,"Y":132.229},{"X":126.346,"Y":130.113},{"X":123.488,"Y":129.424},{"X":120.55,"Y":129.2},{"X":117.703,"Y":129.565},{"X":115.005,"Y":130.453},{"X":112.458,"Y":131.744},{"X":110.059,"Y":133.317},{"X":105.07,"Y":137.334},{"X":95.951,"Y":146.078},{"X":93.915,"Y":148.434},{"X":92.075,"Y":150.942},{"X":90.559,"Y":153.54},{"X":89.375,"Y":156.302},{"X":88.588,"Y":159.194},{"X":88.268,"Y":162.187},{"X":88.458,"Y":165.029},{"X":89.163,"Y":167.772},{"X":90.395,"Y":170.312},{"X":92.166,"Y":172.544},{"X":94.508,"Y":174.405},{"X":97.164,"Y":175.747},{"X":100.02,"Y":176.646},{"X":102.962,"Y":177.179},{"X":106.219,"Y":177.45},{"X":109.5,"Y":177.456},{"X":112.776,"Y":177.222},{"X":116.013,"Y":176.771},{"X":118.928,"Y":176.151},{"X":121.772,"Y":175.276},{"X":124.496,"Y":174.093},{"X":127.047,"Y":172.552},{"X":129.417,"Y":170.596},{"X":131.515,"Y":168.363},{"X":133.399,"Y":165.937},{"X":136.512,"Y":161.371},{"X":136.87,"Y":160.636}],[{"X":164.923,"Y":122.912},{"X":156.888,"Y":141.984},{"X":148.475,"Y":157.929},{"X":147.402,"Y":160.416},{"X":146.664,"Y":162.535},{"X":146.146,"Y":164.764},{"X":146.009,"Y":167.021},{"X":146.416,"Y":169.23},{"X":147.382,"Y":171.059},{"X":148.808,"Y":172.483},{"X":150.554,"Y":173.546},{"X":152.484,"Y":174.282},{"X":155.073,"Y":174.862},{"X":157.726,"Y":175.134},{"X":160.397,"Y":175.165},{"X":165.659,"Y":174.753},{"X":170.834,"Y":173.844},{"X":175.674,"Y":172.571},{"X":180.178,"Y":171.042},{"X":193.907,"Y":165.136}],[{"X":216.029,"Y":123.864},{"X":202.403,"Y":165.319},{"X":200.257,"Y":177.803}],[{"X":222.383,"Y":187.088},{"X":224.575,"Y":173.321},{"X":229.209,"Y":153.834},{"X":230.556,"Y":146.076},{"X":232.052,"Y":141.274},{"X":232.363,"Y":140.053},{"X":233.09,"Y":135.553}],[{"X":226.34,"Y":141.47},{"X":233.036,"Y":135.816},{"X":236.84,"Y":133.043},{"X":238.828,"Y":131.783},{"X":240.884,"Y":130.637},{"X":243.062,"Y":129.604},{"X":245.316,"Y":128.739},{"X":247.637,"Y":128.083},{"X":250.013,"Y":127.674},{"X":252.19,"Y":127.552},{"X":254.373,"Y":127.708},{"X":256.5,"Y":128.19},{"X":258.508,"Y":129.044},{"X":260.113,"Y":130.146},{"X":261.443,"Y":131.534},{"X":262.449,"Y":133.169},{"X":263.086,"Y":135.011},{"X":263.323,"Y":137.114},{"X":263.142,"Y":139.217},{"X":262.607,"Y":141.269},{"X":261.787,"Y":143.22},{"X":260.584,"Y":145.282},{"X":259.141,"Y":147.186},{"X":257.499,"Y":148.927},{"X":255.705,"Y":150.501},{"X":253.79,"Y":151.911},{"X":251.77,"Y":153.164},{"X":249.664,"Y":154.267},{"X":247.489,"Y":155.228},{"X":243.218,"Y":156.703},{"X":234.474,"Y":158.7},{"X":227.977,"Y":159.815}],[{"X":270.688,"Y":187.088},{"X":275.514,"Y":161.32},{"X":280.34,"Y":135.553}],[{"X":274.257,"Y":140.886},{"X":285.48,"Y":132.73},{"X":289.499,"Y":130.191},{"X":291.609,"Y":129.096},{"X":293.802,"Y":128.174},{"X":296.072,"Y":127.479},{"X":298.413,"Y":127.063},{"X":300.651,"Y":126.979},{"X":302.877,"Y":127.222},{"X":305.027,"Y":127.818},{"X":307.046,"Y":128.793},{"X":308.729,"Y":130.048},{"X":310.128,"Y":131.592},{"X":311.19,"Y":133.381},{"X":311.86,"Y":135.37},{"X":312.094,"Y":137.538},{"X":311.885,"Y":139.693},{"X":311.295,"Y":141.786},{"X":310.384,"Y":143.766},{"X":309.081,"Y":145.785},{"X":307.535,"Y":147.629},{"X":305.8,"Y":149.301},{"X":303.929,"Y":150.808},{"X":301.97,"Y":152.154},{"X":299.923,"Y":153.364},{"X":297.805,"Y":154.446},{"X":293.523,"Y":156.217},{"X":289.216,"Y":157.56},{"X":275.835,"Y":160.161}],[{"X":333.09,"Y":132.573},{"X":321.896,"Y":161.022},{"X":321.11,"Y":163.538},{"X":320.51,"Y":166.102},{"X":320.186,"Y":168.375},{"X":320.132,"Y":170.704},{"X":320.475,"Y":172.985},{"X":321.335,"Y":175.116},{"X":322.625,"Y":176.737},{"X":324.271,"Y":177.897},{"X":326.168,"Y":178.642},{"X":328.204,"Y":179.013},{"X":330.715,"Y":179.079},{"X":333.225,"Y":178.849},{"X":338.161,"Y":177.847},{"X":352.064,"Y":173.657},{"X":356.3,"Y":171.899},{"X":360.571,"Y":169.603},{"X":366.665,"Y":165.609}],[{"X":361.391,"Y":125.72},{"X":347.951,"Y":128.619},{"X":346.904,"Y":128.917},{"X":331.532,"Y":135.896}],[{"X":357.313,"Y":150.053},{"X":340.492,"Y":153.233},{"X":323.673,"Y":156.413}],[{"X":387.173,"Y":126.886},{"X":379.923,"Y":153.386},{"X":372.673,"Y":179.886}],[{"X":380.84,"Y":135.896},{"X":388.484,"Y":132.143},{"X":392.799,"Y":130.314},{"X":395.007,"Y":129.529},{"X":397.253,"Y":128.862},{"X":399.539,"Y":128.342},{"X":401.865,"Y":128.006},{"X":404.209,"Y":127.904},{"X":406.546,"Y":128.092},{"X":408.549,"Y":128.539},{"X":410.456,"Y":129.288},{"X":412.19,"Y":130.361},{"X":413.675,"Y":131.78},{"X":414.746,"Y":133.409},{"X":415.43,"Y":135.21},{"X":415.732,"Y":137.118},{"X":415.656,"Y":139.065},{"X":415.166,"Y":141.166},{"X":414.319,"Y":143.146},{"X":413.181,"Y":144.98},{"X":411.812,"Y":146.646},{"X":410.133,"Y":148.25},{"X":408.291,"Y":149.66},{"X":406.324,"Y":150.896},{"X":404.269,"Y":151.976},{"X":400.066,"Y":153.733},{"X":383.323,"Y":159.514},{"X":377.821,"Y":161.789},{"X":377.4,"Y":162.048},{"X":378.1,"Y":162.668},{"X":388.206,"Y":169.262},{"X":389.711,"Y":169.937},{"X":398.647,"Y":172.341},{"X":413.844,"Y":175.386}]]'; var star_and_donut = "[]"; var star_and_donut2 = '[[{"X":104.12,"Y":209.57},{"X":120.89,"Y":158.05},{"X":77,"Y":126.2},{"X":131.24,"Y":126.2},{"X":148,"Y":74.67},{"X":152.19,"Y":87.56},{"X":164.77,"Y":126.2},{"X":219,"Y":126.2},{"X":175.12,"Y":158.05},{"X":191.89,"Y":209.57},{"X":148,"Y":177.73}],[{"X":344.08,"Y":216.87},{"X":343.16,"Y":216.87},{"X":341.33,"Y":216.82},{"X":339.51,"Y":216.73},{"X":337.7,"Y":216.59},{"X":335.9,"Y":216.41},{"X":334.12,"Y":216.18},{"X":332.35,"Y":215.91},{"X":330.59,"Y":215.6},{"X":328.85,"Y":215.24},{"X":327.13,"Y":214.84},{"X":325.42,"Y":214.4},{"X":323.73,"Y":213.92},{"X":322.06,"Y":213.4},{"X":320.4,"Y":212.84},{"X":318.77,"Y":212.24},{"X":317.15,"Y":211.61},{"X":315.55,"Y":210.93},{"X":313.97,"Y":210.22},{"X":312.42,"Y":209.47},{"X":310.88,"Y":208.68},{"X":309.37,"Y":207.86},{"X":307.87,"Y":207},{"X":306.4,"Y":206.11},{"X":304.96,"Y":205.18},{"X":303.54,"Y":204.22},{"X":302.14,"Y":203.23},{"X":300.77,"Y":202.2},{"X":299.42,"Y":201.14},{"X":298.1,"Y":200.05},{"X":296.81,"Y":198.93},{"X":295.55,"Y":197.78},{"X":294.31,"Y":196.6},{"X":293.1,"Y":195.4},{"X":291.92,"Y":194.16},{"X":290.77,"Y":192.89},{"X":289.65,"Y":191.6},{"X":288.56,"Y":190.28},{"X":287.5,"Y":188.93},{"X":286.48,"Y":187.56},{"X":285.48,"Y":186.17},{"X":284.52,"Y":184.74},{"X":283.6,"Y":183.3},{"X":282.7,"Y":181.83},{"X":281.85,"Y":180.34},{"X":281.02,"Y":178.82},{"X":280.24,"Y":177.29},{"X":279.49,"Y":175.73},{"X":278.77,"Y":174.15},{"X":278.1,"Y":172.55},{"X":277.46,"Y":170.94},{"X":276.86,"Y":169.3},{"X":276.3,"Y":167.64},{"X":275.78,"Y":165.97},{"X":275.3,"Y":164.28},{"X":274.86,"Y":162.57},{"X":274.46,"Y":160.85},{"X":274.1,"Y":159.11},{"X":273.79,"Y":157.35},{"X":273.52,"Y":155.59},{"X":273.29,"Y":153.8},{"X":273.11,"Y":152.01},{"X":272.97,"Y":150.2},{"X":272.88,"Y":148.38},{"X":272.83,"Y":146.54},{"X":272.83,"Y":145.62},{"X":272.83,"Y":144.7},{"X":272.88,"Y":142.87},{"X":272.97,"Y":141.04},{"X":273.11,"Y":139.24},{"X":273.29,"Y":137.44},{"X":273.52,"Y":135.66},{"X":273.79,"Y":133.89},{"X":274.1,"Y":132.13},{"X":274.46,"Y":130.39},{"X":274.86,"Y":128.67},{"X":275.3,"Y":126.96},{"X":275.78,"Y":125.27},{"X":276.3,"Y":123.6},{"X":276.86,"Y":121.94},{"X":277.46,"Y":120.31},{"X":278.1,"Y":118.69},{"X":278.77,"Y":117.09},{"X":279.49,"Y":115.51},{"X":280.24,"Y":113.95},{"X":281.02,"Y":112.42},{"X":281.85,"Y":110.9},{"X":282.7,"Y":109.41},{"X":283.6,"Y":107.94},{"X":284.52,"Y":106.5},{"X":285.48,"Y":105.08},{"X":286.48,"Y":103.68},{"X":287.5,"Y":102.31},{"X":288.56,"Y":100.96},{"X":289.65,"Y":99.64},{"X":290.77,"Y":98.35},{"X":291.92,"Y":97.08},{"X":293.1,"Y":95.85},{"X":294.31,"Y":94.64},{"X":295.55,"Y":93.46},{"X":296.81,"Y":92.31},{"X":298.1,"Y":91.19},{"X":299.42,"Y":90.1},{"X":300.77,"Y":89.04},{"X":302.14,"Y":88.02},{"X":303.54,"Y":87.02},{"X":304.96,"Y":86.06},{"X":306.4,"Y":85.14},{"X":307.87,"Y":84.24},{"X":309.37,"Y":83.39},{"X":310.88,"Y":82.56},{"X":312.42,"Y":81.78},{"X":313.97,"Y":81.03},{"X":315.55,"Y":80.31},{"X":317.15,"Y":79.64},{"X":318.77,"Y":79},{"X":320.4,"Y":78.4},{"X":322.06,"Y":77.84},{"X":323.73,"Y":77.32},{"X":325.42,"Y":76.84},{"X":327.13,"Y":76.4},{"X":328.85,"Y":76},{"X":330.59,"Y":75.64},{"X":332.35,"Y":75.33},{"X":334.12,"Y":75.06},{"X":335.9,"Y":74.83},{"X":337.7,"Y":74.65},{"X":339.51,"Y":74.51},{"X":341.33,"Y":74.42},{"X":343.16,"Y":74.38},{"X":344.08,"Y":74.37},{"X":344.97,"Y":74.38},{"X":346.73,"Y":74.42},{"X":348.5,"Y":74.51},{"X":350.25,"Y":74.64},{"X":352,"Y":74.81},{"X":353.74,"Y":75.03},{"X":355.47,"Y":75.29},{"X":357.19,"Y":75.58},{"X":358.9,"Y":75.93},{"X":360.6,"Y":76.31},{"X":362.29,"Y":76.74},{"X":363.97,"Y":77.2},{"X":365.64,"Y":77.71},{"X":367.29,"Y":78.25},{"X":368.92,"Y":78.84},{"X":370.54,"Y":79.47},{"X":372.15,"Y":80.13},{"X":373.74,"Y":80.83},{"X":375.31,"Y":81.58},{"X":376.86,"Y":82.36},{"X":378.4,"Y":83.18},{"X":379.91,"Y":84.04},{"X":381.41,"Y":84.93},{"X":382.88,"Y":85.86},{"X":384.34,"Y":86.83},{"X":385.77,"Y":87.84},{"X":387.17,"Y":88.88},{"X":388.56,"Y":89.95},{"X":389.92,"Y":91.07},{"X":391.25,"Y":92.22},{"X":392.56,"Y":93.4},{"X":393.84,"Y":94.62},{"X":394.47,"Y":95.24},{"X":395.09,"Y":95.87},{"X":396.31,"Y":97.15},{"X":397.49,"Y":98.46},{"X":398.64,"Y":99.79},{"X":399.75,"Y":101.15},{"X":400.83,"Y":102.53},{"X":401.87,"Y":103.94},{"X":402.88,"Y":105.37},{"X":403.84,"Y":106.82},{"X":404.78,"Y":108.29},{"X":405.67,"Y":109.79},{"X":406.53,"Y":111.3},{"X":407.35,"Y":112.84},{"X":408.13,"Y":114.39},{"X":408.87,"Y":115.96},{"X":409.57,"Y":117.55},{"X":410.24,"Y":119.16},{"X":410.86,"Y":120.78},{"X":411.45,"Y":122.42},{"X":412,"Y":124.07},{"X":412.5,"Y":125.73},{"X":412.97,"Y":127.41},{"X":413.39,"Y":129.1},{"X":413.78,"Y":130.8},{"X":414.12,"Y":132.51},{"X":414.42,"Y":134.23},{"X":414.68,"Y":135.97},{"X":414.89,"Y":137.71},{"X":415.07,"Y":139.45},{"X":415.2,"Y":141.21},{"X":415.28,"Y":142.97},{"X":415.33,"Y":144.74},{"X":415.33,"Y":145.62},{"X":415.33,"Y":146.54},{"X":415.28,"Y":148.38},{"X":415.19,"Y":150.2},{"X":415.05,"Y":152.01},{"X":414.87,"Y":153.8},{"X":414.64,"Y":155.59},{"X":414.37,"Y":157.35},{"X":414.06,"Y":159.11},{"X":413.7,"Y":160.85},{"X":413.3,"Y":162.57},{"X":412.87,"Y":164.28},{"X":412.38,"Y":165.97},{"X":411.86,"Y":167.64},{"X":411.3,"Y":169.3},{"X":410.7,"Y":170.94},{"X":410.07,"Y":172.55},{"X":409.39,"Y":174.15},{"X":408.68,"Y":175.73},{"X":407.93,"Y":177.29},{"X":407.14,"Y":178.82},{"X":406.32,"Y":180.34},{"X":405.46,"Y":181.83},{"X":404.57,"Y":183.3},{"X":403.64,"Y":184.74},{"X":402.68,"Y":186.17},{"X":401.69,"Y":187.56},{"X":400.66,"Y":188.93},{"X":399.6,"Y":190.28},{"X":398.51,"Y":191.6},{"X":397.39,"Y":192.89},{"X":396.24,"Y":194.16},{"X":395.06,"Y":195.4},{"X":393.86,"Y":196.6},{"X":392.62,"Y":197.78},{"X":391.35,"Y":198.93},{"X":390.06,"Y":200.05},{"X":388.74,"Y":201.14},{"X":387.39,"Y":202.2},{"X":386.02,"Y":203.23},{"X":384.63,"Y":204.22},{"X":383.2,"Y":205.18},{"X":381.76,"Y":206.11},{"X":380.29,"Y":207},{"X":378.8,"Y":207.86},{"X":377.28,"Y":208.68},{"X":375.75,"Y":209.47},{"X":374.19,"Y":210.22},{"X":372.61,"Y":210.93},{"X":371.01,"Y":211.61},{"X":369.4,"Y":212.24},{"X":367.76,"Y":212.84},{"X":366.1,"Y":213.4},{"X":364.43,"Y":213.92},{"X":362.74,"Y":214.4},{"X":361.03,"Y":214.84},{"X":359.31,"Y":215.24},{"X":357.57,"Y":215.6},{"X":355.81,"Y":215.91},{"X":354.05,"Y":216.18},{"X":352.26,"Y":216.41},{"X":350.47,"Y":216.59},{"X":348.66,"Y":216.73},{"X":346.84,"Y":216.82},{"X":345,"Y":216.87}],[{"X":344.08,"Y":181.25},{"X":345,"Y":181.24},{"X":346.82,"Y":181.15},{"X":348.62,"Y":180.96},{"X":350.39,"Y":180.69},{"X":352.13,"Y":180.34},{"X":353.84,"Y":179.9},{"X":355.51,"Y":179.38},{"X":357.15,"Y":178.78},{"X":358.74,"Y":178.1},{"X":360.3,"Y":177.35},{"X":361.82,"Y":176.53},{"X":363.28,"Y":175.64},{"X":364.71,"Y":174.68},{"X":366.08,"Y":173.65},{"X":367.4,"Y":172.56},{"X":368.66,"Y":171.41},{"X":369.87,"Y":170.2},{"X":371.02,"Y":168.94},{"X":372.11,"Y":167.62},{"X":373.14,"Y":166.25},{"X":374.1,"Y":164.82},{"X":374.99,"Y":163.35},{"X":375.81,"Y":161.84},{"X":376.56,"Y":160.28},{"X":377.24,"Y":158.69},{"X":377.84,"Y":157.05},{"X":378.36,"Y":155.38},{"X":378.8,"Y":153.67},{"X":379.15,"Y":151.93},{"X":379.42,"Y":150.16},{"X":379.61,"Y":148.36},{"X":379.7,"Y":146.54},{"X":379.71,"Y":145.62},{"X":379.7,"Y":144.7},{"X":379.61,"Y":142.88},{"X":379.42,"Y":141.08},{"X":379.15,"Y":139.31},{"X":378.8,"Y":137.57},{"X":378.36,"Y":135.87},{"X":377.84,"Y":134.19},{"X":377.24,"Y":132.56},{"X":376.56,"Y":130.96},{"X":375.81,"Y":129.4},{"X":374.99,"Y":127.89},{"X":374.1,"Y":126.42},{"X":373.14,"Y":125},{"X":372.11,"Y":123.62},{"X":371.02,"Y":122.3},{"X":369.87,"Y":121.04},{"X":368.66,"Y":119.83},{"X":367.4,"Y":118.68},{"X":366.08,"Y":117.59},{"X":364.71,"Y":116.57},{"X":363.28,"Y":115.61},{"X":361.82,"Y":114.71},{"X":360.3,"Y":113.89},{"X":358.74,"Y":113.14},{"X":357.15,"Y":112.46},{"X":355.51,"Y":111.86},{"X":353.84,"Y":111.34},{"X":352.13,"Y":110.91},{"X":350.39,"Y":110.55},{"X":348.62,"Y":110.28},{"X":346.82,"Y":110.1},{"X":345,"Y":110},{"X":344.08,"Y":110},{"X":343.16,"Y":110},{"X":341.34,"Y":110.1},{"X":339.54,"Y":110.28},{"X":337.77,"Y":110.55},{"X":336.04,"Y":110.91},{"X":334.33,"Y":111.34},{"X":332.65,"Y":111.86},{"X":331.02,"Y":112.46},{"X":329.42,"Y":113.14},{"X":327.86,"Y":113.89},{"X":326.35,"Y":114.71},{"X":324.88,"Y":115.61},{"X":323.46,"Y":116.57},{"X":322.08,"Y":117.59},{"X":320.77,"Y":118.68},{"X":319.5,"Y":119.83},{"X":318.29,"Y":121.04},{"X":317.14,"Y":122.3},{"X":316.05,"Y":123.62},{"X":315.03,"Y":125},{"X":314.07,"Y":126.42},{"X":313.17,"Y":127.89},{"X":312.35,"Y":129.4},{"X":311.6,"Y":130.96},{"X":310.92,"Y":132.56},{"X":310.33,"Y":134.19},{"X":309.8,"Y":135.87},{"X":309.37,"Y":137.57},{"X":309.01,"Y":139.31},{"X":308.74,"Y":141.08},{"X":308.56,"Y":142.88},{"X":308.46,"Y":144.7},{"X":308.46,"Y":145.62},{"X":308.46,"Y":146.54},{"X":308.56,"Y":148.36},{"X":308.74,"Y":150.16},{"X":309.01,"Y":151.93},{"X":309.37,"Y":153.67},{"X":309.8,"Y":155.38},{"X":310.33,"Y":157.05},{"X":310.92,"Y":158.69},{"X":311.6,"Y":160.28},{"X":312.35,"Y":161.84},{"X":313.17,"Y":163.35},{"X":314.07,"Y":164.82},{"X":315.03,"Y":166.25},{"X":316.05,"Y":167.62},{"X":317.14,"Y":168.94},{"X":318.29,"Y":170.2},{"X":319.5,"Y":171.41},{"X":320.77,"Y":172.56},{"X":322.08,"Y":173.65},{"X":323.46,"Y":174.68},{"X":324.88,"Y":175.64},{"X":326.35,"Y":176.53},{"X":327.86,"Y":177.35},{"X":329.42,"Y":178.1},{"X":331.02,"Y":178.78},{"X":332.65,"Y":179.38},{"X":334.33,"Y":179.9},{"X":336.04,"Y":180.34},{"X":337.77,"Y":180.69},{"X":339.54,"Y":180.96},{"X":341.34,"Y":181.15},{"X":343.16,"Y":181.24}]]'; return { "ss": deserialize_clipper_poly(lines), "cc": deserialize_clipper_poly(star_and_donut) }; } function get_collinear_test() { console.log("collinear"); var collinear = '[[{"X":22.304,"Y":66.96},{"X":26.104,"Y":55.44},{"X":29.902,"Y":43.921},{"X":33.701,"Y":32.401},{"X":37.5,"Y":20.882},{"X":50,"Y":22.598},{"X":62.5,"Y":24.313},{"X":75,"Y":26.029},{"X":87.5,"Y":27.745},{"X":81.373,"Y":54.828},{"X":75.246,"Y":81.911},{"X":69.118,"Y":108.995},{"X":62.991,"Y":136.078},{"X":54.78,"Y":137.181},{"X":46.569,"Y":138.284},{"X":38.358,"Y":139.387},{"X":30.147,"Y":140.49},{"X":29.412,"Y":150.416},{"X":28.677,"Y":160.343},{"X":27.941,"Y":170.269},{"X":27.207,"Y":180.195},{"X":47.305,"Y":193.186},{"X":67.402,"Y":206.176},{"X":87.5,"Y":219.166},{"X":107.599,"Y":232.157},{"X":109.314,"Y":194.167},{"X":111.03,"Y":156.177},{"X":112.746,"Y":118.187},{"X":114.461,"Y":80.196},{"X":103.922,"Y":72.966},{"X":93.383,"Y":65.735},{"X":82.844,"Y":58.505},{"X":72.305,"Y":51.274},{"X":84.314,"Y":52.99},{"X":96.324,"Y":54.706},{"X":108.334,"Y":56.421},{"X":120.344,"Y":58.137},{"X":128.064,"Y":58.75},{"X":135.785,"Y":59.362},{"X":143.506,"Y":59.975},{"X":151.226,"Y":60.588},{"X":157.354,"Y":78.848},{"X":163.481,"Y":97.107},{"X":169.608,"Y":115.367},{"X":175.736,"Y":133.627},{"X":146.691,"Y":129.46},{"X":117.647,"Y":125.294},{"X":88.604,"Y":121.127},{"X":59.559,"Y":116.96},{"X":79.804,"Y":123.165},{"X":100.048,"Y":129.369},{"X":120.293,"Y":135.573},{"X":140.538,"Y":141.777},{"X":146.641,"Y":153.71},{"X":152.745,"Y":165.643},{"X":158.848,"Y":177.576},{"X":164.952,"Y":189.509},{"X":166.055,"Y":211.813},{"X":167.157,"Y":234.117},{"X":168.26,"Y":256.422},{"X":169.363,"Y":278.726},{"X":154.78,"Y":281.299},{"X":140.196,"Y":283.872},{"X":125.613,"Y":286.445},{"X":111.03,"Y":289.019},{"X":96.324,"Y":285.22},{"X":81.618,"Y":281.421},{"X":66.912,"Y":277.622},{"X":52.206,"Y":273.823},{"X":67.28,"Y":266.838},{"X":82.354,"Y":259.853},{"X":97.427,"Y":252.867},{"X":112.5,"Y":245.882},{"X":142.893,"Y":240.367},{"X":173.285,"Y":234.853},{"X":203.677,"Y":229.338},{"X":234.069,"Y":223.823},{"X":258.456,"Y":213.039},{"X":282.843,"Y":202.254},{"X":307.23,"Y":191.47},{"X":331.617,"Y":180.686},{"X":324.143,"Y":168.676},{"X":316.667,"Y":156.666},{"X":309.191,"Y":144.656},{"X":301.717,"Y":132.646},{"X":286.521,"Y":123.088},{"X":271.324,"Y":113.529},{"X":256.128,"Y":103.971},{"X":240.932,"Y":94.412},{"X":234.559,"Y":83.015},{"X":228.187,"Y":71.617},{"X":221.814,"Y":60.22},{"X":215.441,"Y":48.823},{"X":216.177,"Y":43.186},{"X":216.912,"Y":37.549},{"X":217.647,"Y":31.912},{"X":218.383,"Y":26.274},{"X":228.922,"Y":26.152},{"X":239.461,"Y":26.029},{"X":250,"Y":25.907},{"X":260.539,"Y":25.784},{"X":274.51,"Y":25.784},{"X":288.48,"Y":25.784},{"X":302.451,"Y":25.784},{"X":316.422,"Y":25.784},{"X":316.422,"Y":28.235},{"X":316.422,"Y":30.686},{"X":316.422,"Y":33.137},{"X":316.422,"Y":35.588},{"X":311.152,"Y":42.083},{"X":305.883,"Y":48.578},{"X":300.613,"Y":55.073},{"X":295.344,"Y":61.568},{"X":292.77,"Y":74.191},{"X":290.196,"Y":86.813},{"X":287.623,"Y":99.436},{"X":285.049,"Y":112.059},{"X":269.73,"Y":115.49},{"X":254.412,"Y":118.921},{"X":239.094,"Y":122.353},{"X":223.775,"Y":125.784},{"X":215.81,"Y":138.578},{"X":207.844,"Y":151.373},{"X":199.878,"Y":164.167},{"X":191.912,"Y":176.961},{"X":191.667,"Y":188.063},{"X":191.422,"Y":199.166},{"X":191.177,"Y":210.27},{"X":190.932,"Y":221.372},{"X":190.564,"Y":236.936},{"X":190.196,"Y":252.5},{"X":189.829,"Y":268.064},{"X":189.461,"Y":283.628},{"X":194.608,"Y":286.201},{"X":199.755,"Y":288.774},{"X":204.902,"Y":291.348},{"X":210.049,"Y":293.921},{"X":225.49,"Y":295.023},{"X":240.932,"Y":296.127},{"X":256.373,"Y":297.23},{"X":271.814,"Y":298.333},{"X":281.74,"Y":290.244},{"X":291.667,"Y":282.156},{"X":301.594,"Y":274.068},{"X":311.52,"Y":265.979},{"X":317.524,"Y":253.602},{"X":323.529,"Y":241.225},{"X":329.534,"Y":228.848},{"X":335.539,"Y":216.47},{"X":344.527,"Y":208.627},{"X":353.515,"Y":200.783},{"X":362.502,"Y":192.94},{"X":371.49,"Y":185.098},{"X":382.601,"Y":201.029},{"X":393.711,"Y":216.961},{"X":404.821,"Y":232.893},{"X":415.932,"Y":248.823},{"X":413.848,"Y":257.893},{"X":411.765,"Y":266.961},{"X":409.682,"Y":276.029},{"X":407.598,"Y":285.099},{"X":399.919,"Y":284.854},{"X":392.24,"Y":284.607},{"X":384.562,"Y":284.362},{"X":376.883,"Y":284.117},{"X":360.297,"Y":273.7},{"X":343.711,"Y":263.283},{"X":327.125,"Y":252.867},{"X":310.539,"Y":242.45},{"X":313.848,"Y":230.809},{"X":317.157,"Y":219.166},{"X":320.467,"Y":207.523},{"X":323.775,"Y":195.882},{"X":341.668,"Y":166.715},{"X":359.56,"Y":137.549},{"X":377.451,"Y":108.382},{"X":395.344,"Y":79.215},{"X":403.064,"Y":72.353},{"X":410.785,"Y":65.49},{"X":418.506,"Y":58.627},{"X":426.227,"Y":51.764},{"X":432.967,"Y":50.294},{"X":439.707,"Y":48.823},{"X":446.447,"Y":47.353},{"X":453.188,"Y":45.882},{"X":456.496,"Y":53.725},{"X":459.805,"Y":61.568},{"X":463.113,"Y":69.411},{"X":466.422,"Y":77.254},{"X":466.422,"Y":85.955},{"X":466.422,"Y":94.656},{"X":466.422,"Y":103.357},{"X":466.422,"Y":112.059},{"X":454.657,"Y":123.333},{"X":442.893,"Y":134.607},{"X":431.128,"Y":145.882},{"X":419.363,"Y":157.157},{"X":413.971,"Y":165.49},{"X":408.579,"Y":173.823},{"X":403.188,"Y":182.156},{"X":397.795,"Y":190.489},{"X":390.197,"Y":194.901},{"X":382.599,"Y":199.313},{"X":375,"Y":203.726},{"X":367.402,"Y":208.138},{"X":358.701,"Y":225.907},{"X":350,"Y":243.677},{"X":341.299,"Y":261.446},{"X":332.598,"Y":279.216},{"X":338.48,"Y":287.794},{"X":344.362,"Y":296.372},{"X":350.244,"Y":304.95},{"X":356.127,"Y":313.528},{"X":363.603,"Y":313.528},{"X":371.078,"Y":313.528},{"X":378.554,"Y":313.528},{"X":386.029,"Y":313.528},{"X":394.607,"Y":312.671},{"X":403.187,"Y":311.813},{"X":411.766,"Y":310.956},{"X":420.344,"Y":310.099},{"X":423.775,"Y":300.785},{"X":427.206,"Y":291.471},{"X":430.637,"Y":282.156},{"X":434.068,"Y":272.843},{"X":434.804,"Y":259.362},{"X":435.539,"Y":245.882},{"X":436.274,"Y":232.401},{"X":437.01,"Y":218.921},{"X":436.643,"Y":211.445},{"X":436.274,"Y":203.97},{"X":435.906,"Y":196.494},{"X":435.539,"Y":189.019},{"X":424.143,"Y":178.848},{"X":412.745,"Y":168.676},{"X":401.348,"Y":158.504},{"X":389.951,"Y":148.333},{"X":372.917,"Y":138.896},{"X":355.883,"Y":129.46},{"X":338.849,"Y":120.024},{"X":321.814,"Y":110.588},{"X":313.604,"Y":103.97},{"X":305.393,"Y":97.353},{"X":297.182,"Y":90.735},{"X":288.971,"Y":84.117},{"X":281.985,"Y":77.867},{"X":275,"Y":71.617},{"X":268.015,"Y":65.367},{"X":261.029,"Y":59.117},{"X":285.662,"Y":55.809},{"X":310.294,"Y":52.5},{"X":334.926,"Y":49.19},{"X":359.559,"Y":45.882},{"X":371.201,"Y":45.882},{"X":382.843,"Y":45.882},{"X":394.484,"Y":45.882},{"X":406.127,"Y":45.882},{"X":411.152,"Y":59.24},{"X":416.177,"Y":72.598},{"X":421.201,"Y":85.956},{"X":426.227,"Y":99.313},{"X":431.741,"Y":110.588},{"X":437.256,"Y":121.862},{"X":442.771,"Y":133.137},{"X":448.285,"Y":144.412},{"X":446.324,"Y":152.549},{"X":444.363,"Y":160.687},{"X":442.402,"Y":168.824},{"X":440.441,"Y":176.961},{"X":421.568,"Y":190.147},{"X":402.696,"Y":203.334},{"X":383.824,"Y":216.52},{"X":364.951,"Y":229.706},{"X":352.328,"Y":240.857},{"X":339.706,"Y":252.01},{"X":327.084,"Y":263.162},{"X":314.461,"Y":274.313},{"X":304.167,"Y":285.465},{"X":293.873,"Y":296.617},{"X":283.579,"Y":307.77},{"X":273.285,"Y":318.921},{"X":258.947,"Y":318.431},{"X":244.608,"Y":317.94},{"X":230.27,"Y":317.45},{"X":215.932,"Y":316.96},{"X":225.878,"Y":296.127},{"X":235.824,"Y":275.294},{"X":245.771,"Y":254.461},{"X":255.717,"Y":233.628},{"X":256.064,"Y":210.834},{"X":256.412,"Y":188.039},{"X":256.76,"Y":165.245},{"X":257.107,"Y":142.451},{"X":245.956,"Y":150.049},{"X":234.804,"Y":157.646},{"X":223.652,"Y":165.245},{"X":212.5,"Y":172.843},{"X":187.868,"Y":176.887},{"X":163.235,"Y":180.931},{"X":138.603,"Y":184.975},{"X":113.971,"Y":189.019},{"X":124.265,"Y":178.602},{"X":134.559,"Y":168.186},{"X":144.854,"Y":157.769},{"X":155.147,"Y":147.353},{"X":162.746,"Y":144.166},{"X":170.344,"Y":140.98},{"X":177.942,"Y":137.794},{"X":185.54,"Y":134.607},{"X":167.771,"Y":156.176},{"X":150,"Y":177.744},{"X":132.23,"Y":199.313},{"X":114.461,"Y":220.882},{"X":100.368,"Y":222.965},{"X":86.274,"Y":225.049},{"X":72.182,"Y":227.133},{"X":58.088,"Y":229.216},{"X":54.534,"Y":243.432},{"X":50.98,"Y":257.646},{"X":47.427,"Y":271.861},{"X":43.873,"Y":286.077},{"X":43.873,"Y":291.348},{"X":43.873,"Y":296.617},{"X":43.873,"Y":301.887},{"X":43.873,"Y":307.157},{"X":48.285,"Y":307.77},{"X":52.696,"Y":308.383},{"X":57.108,"Y":308.996},{"X":61.52,"Y":309.608},{"X":69.976,"Y":309.976},{"X":78.432,"Y":310.343},{"X":86.888,"Y":310.71},{"X":95.343,"Y":311.077},{"X":101.716,"Y":310.955},{"X":108.088,"Y":310.833},{"X":114.461,"Y":310.711},{"X":120.833,"Y":310.589},{"X":123.652,"Y":308.138},{"X":126.471,"Y":305.687},{"X":129.29,"Y":303.235},{"X":132.108,"Y":300.784},{"X":131.863,"Y":280.809},{"X":131.618,"Y":260.833},{"X":131.373,"Y":240.857},{"X":131.128,"Y":220.882},{"X":120.466,"Y":202.5},{"X":109.805,"Y":184.117},{"X":99.143,"Y":165.735},{"X":88.481,"Y":147.353},{"X":70.221,"Y":165.857},{"X":51.961,"Y":184.362},{"X":33.701,"Y":202.867},{"X":15.441,"Y":221.372},{"X":17.893,"Y":231.666},{"X":20.344,"Y":241.96},{"X":22.795,"Y":252.254},{"X":25.246,"Y":262.548},{"X":129.535,"Y":268.186},{"X":233.824,"Y":273.823},{"X":338.113,"Y":279.461},{"X":442.402,"Y":285.099},{"X":336.888,"Y":264.633},{"X":231.373,"Y":244.167},{"X":125.858,"Y":223.701},{"X":20.344,"Y":203.235},{"X":131.363,"Y":203.569},{"X":242.382,"Y":203.903},{"X":353.4,"Y":204.237},{"X":464.42,"Y":204.571},{"X":352.788,"Y":190.635},{"X":241.156,"Y":176.697},{"X":129.524,"Y":162.76},{"X":17.893,"Y":148.823},{"X":127.819,"Y":150.662},{"X":237.745,"Y":152.5},{"X":347.672,"Y":154.338},{"X":457.598,"Y":156.176},{"X":349.387,"Y":143.186},{"X":241.177,"Y":130.196},{"X":132.966,"Y":117.206},{"X":24.755,"Y":104.215},{"X":137.133,"Y":106.299},{"X":249.511,"Y":108.382},{"X":361.889,"Y":110.465},{"X":474.266,"Y":112.549},{"X":362.868,"Y":103.848},{"X":251.471,"Y":95.146},{"X":140.074,"Y":86.445},{"X":28.677,"Y":77.745},{"X":66.422,"Y":65.49},{"X":104.167,"Y":53.235},{"X":141.912,"Y":40.98},{"X":179.658,"Y":28.725},{"X":230.638,"Y":39.387},{"X":281.618,"Y":50.049},{"X":332.598,"Y":60.71},{"X":383.578,"Y":71.372},{"X":408.823,"Y":71.372},{"X":434.068,"Y":71.372},{"X":459.313,"Y":71.372},{"X":484.559,"Y":71.372},{"X":464.461,"Y":58.75},{"X":444.363,"Y":46.127},{"X":424.266,"Y":33.504},{"X":404.168,"Y":20.882},{"X":307.967,"Y":37.426},{"X":211.766,"Y":53.97},{"X":115.564,"Y":70.515},{"X":19.363,"Y":87.059},{"X":38.849,"Y":145.882},{"X":58.334,"Y":204.705},{"X":77.819,"Y":263.529},{"X":97.304,"Y":322.353},{"X":100.368,"Y":247.107},{"X":103.432,"Y":171.862},{"X":106.496,"Y":96.617},{"X":109.56,"Y":21.372},{"X":121.202,"Y":92.573},{"X":132.844,"Y":163.774},{"X":144.486,"Y":234.976},{"X":156.128,"Y":306.177},{"X":158.456,"Y":235.956},{"X":160.785,"Y":165.735},{"X":163.113,"Y":95.515},{"X":165.441,"Y":25.294},{"X":184.314,"Y":100.171},{"X":203.187,"Y":175.049},{"X":222.059,"Y":249.926},{"X":240.932,"Y":324.804},{"X":244.628,"Y":246.74},{"X":248.324,"Y":168.676},{"X":252.021,"Y":90.612},{"X":255.717,"Y":12.549}]]'; return { "ss": deserialize_clipper_poly(collinear), "cc": [] }; } function get_custom_poly() { var selected_value = $("#custom_polygons_select").val(); if (benchmark_running) { return { "ss": deserialize_clipper_poly(default_custom_subject_polygon), "cc": deserialize_clipper_poly(default_custom_clip_polygon) }; } var arr = $.totalStorage('custom_polygons'); if (selected_value !== "") { //selected_value = parseInt(selected_value,10); return { "ss": deserialize_clipper_poly(arr[selected_value].subj), "cc": deserialize_clipper_poly(arr[selected_value].clip) }; } //else return { "ss": '[[{"X":0,"Y":0},{"X":1,"Y":1}]]', "cc": '[[{"X":0,"Y":0},{"X":1,"Y":1}]]' }; else return { "ss": deserialize_clipper_poly(default_custom_subject_polygon), "cc": deserialize_clipper_poly(default_custom_clip_polygon) }; } function get_random_polys(which, polygon) { var point_count, polygon_count; if (which == "subj") { point_count = rnd_sett.subj_point_count; polygon_count = rnd_sett.subj_polygon_count; } else if (which == "clip") { point_count = rnd_sett.clip_point_count; polygon_count = rnd_sett.clip_polygon_count; } if (arguments.length === 1) polygon = parseInt($('input[type="radio"][name="polygons"]:checked').val(), 10); if (polygon != 4 && polygon != 5) return new ClipperLib.Paths(); var svg = $("#p"); var margin = 10; rnd_sett.rand_min_x = 0 + margin; rnd_sett.rand_max_x = parseFloat(svg.attr("width"), 10) - margin; rnd_sett.rand_min_y = 0 + margin; rnd_sett.rand_max_y = parseFloat(svg.attr("height"), 10) - margin; var i, j, pp, np = new ClipperLib.Paths(), prev_x = null, prev_y = null, horiz_or_vertic = null, prev_horiz_or_vertic = null; for (i = 0; i < polygon_count; i++) { np[i] = new ClipperLib.Path(); for (j = 0; j < point_count; j++) { pp = { X: 0, Y: 0 }; // new ClipperLib.FPoint() or new ClipperLib.IntPoint(); if (polygon == 4) { horiz_or_vertic = rnd("int", 0, 1); // 0 = horiz, 1 = vertic if (prev_horiz_or_vertic === horiz_or_vertic) { if (horiz_or_vertic === 0) horiz_or_vertic = 1; else if (horiz_or_vertic === 1) horiz_or_vertic = 0; else horiz_or_vertic = 0; } if (horiz_or_vertic === 0) // horiz => y remains same { pp.X = +round(rnd("float", rnd_sett.rand_min_x, rnd_sett.rand_max_x)); if (prev_y == null) pp.Y = +round(rnd("float", rnd_sett.rand_min_y, rnd_sett.rand_max_y)); else pp.Y = +prev_y; prev_x = pp.X; prev_y = pp.Y; prev_horiz_or_vertic = horiz_or_vertic; } else // vertic => x remains same { pp.Y = +round(rnd("float", rnd_sett.rand_min_y, rnd_sett.rand_max_y)); if (prev_x == null) pp.X = +round(rnd("float", rnd_sett.rand_min_x, rnd_sett.rand_max_x)); else pp.X = +prev_x; prev_x = pp.X; prev_y = pp.Y; prev_horiz_or_vertic = horiz_or_vertic; } // last point fix if (j == point_count - 1 && point_count !== 1) { if (horiz_or_vertic === 0) // horiz => y remains same { pp.X = +np[i][0].X; } else // vertic => x remains same { pp.Y = +np[i][0].Y; } np[i].push(pp); } else np[i].push(pp); } else if (polygon == 5) { pp.X = +round(rnd("float", rnd_sett.rand_min_x, rnd_sett.rand_max_x)); pp.Y = +round(rnd("float", rnd_sett.rand_min_y, rnd_sett.rand_max_y)); np[i].push(pp); } } prev_x = null; prev_y = null; horiz_or_vertic = null; prev_horiz_or_vertic = null; } rnd_sett.scale = scale; return np; } function scale_again_random_poly(poly) { if (is_float_clipper) return poly; var i, j; for (i = 0; i < poly.length; i++) { for (j = 0; j < poly[i].length; j++) { poly[i][j].X = round(poly[i][j].X / rnd_sett.scale); poly[i][j].Y = round(poly[i][j].Y / rnd_sett.scale); } } return poly; } function scale_again_random_grid_poly(poly) { if (is_float_clipper) return; var i, j; for (i = 0; i < poly.length; i++) { for (j = 0; j < poly[i].length; j++) { poly[i][j].X = round(poly[i][j].X / rnd_grid_sett.scale); poly[i][j].Y = round(poly[i][j].Y / rnd_grid_sett.scale); } } } function rnd(intfloat, Amin, Amax) { var num; if (intfloat == "float") num = (Amin + (Amax - Amin) * Math.random()).toFixed(2); else if (intfloat == "int") num = Math.floor(Amin + (1 + Amax - Amin) * Math.random()); return num; } function Odd(i) { return (i % 2 != 0); } function rand(from, to) { return Math.floor(Math.random() * (to - from + 1) + from); } function del(subj) { //randomly delete roughly 1/8 of them ... for (var i = 0; i < 100; i++) delete subj[rand(0, 800)]; var subj2 = []; for (var i = 0; i < 800; i++) { if (subj[i] != null) subj2.push(subj[i]); } return subj2; } function get_random_grids(subj_or_clip, grid_type) { gsize = 20 * scale; var hor_amount = 21 - 1; var ver_amount = 17 - 1; hor_amount = 12 - 1; ver_amount = 12 - 1; var amount = hor_amount * ver_amount * 2; var hor_offset = ((500 - (gsize / scale * hor_amount)) * scale) / 2; var ver_offset = ((350 - (gsize / scale * ver_amount)) * scale) / 2; if (1 == 1) { if (grid_type == 1) { //make a grid of triangles ... var subj = new Array(amount); for (var i = 0; i < ver_amount; i++) for (var j = 0; j < hor_amount; j++) { subj[i * 40 + j * 2] = [ { X: j * gsize + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + gsize + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + hor_offset, Y: i * gsize + gsize + ver_offset }]; subj[i * 40 + j * 2 + 1] = [ { X: j * gsize + gsize + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + gsize + hor_offset, Y: i * gsize + gsize + ver_offset }, { X: j * gsize + hor_offset, Y: i * gsize + gsize + ver_offset }]; } //randomly delete roughly 1/8 of them ... subj = del(subj); } else if (grid_type == 2) { //alternative shapes 1 ... var subj = new Array(amount / 2); for (var i = 0; i < ver_amount; i++) for (var j = 0; j < hor_amount; j++) { if (Odd(i)) var k = 4; else k = -4; subj[i * 20 + j] = [ { X: j * gsize + k + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + gsize + k + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + gsize + k + hor_offset, Y: i * gsize + gsize + ver_offset }, { X: j * gsize + k + hor_offset, Y: i * gsize + gsize + ver_offset }]; } //randomly delete roughly 1/8 of them ... subj = del(subj); } else { //alternative shapes 2 ... var subj = new Array(amount / 2); for (var i = 0; i < ver_amount; i++) for (var j = 0; j < hor_amount; j++) { subj[i * 20 + j] = [ { X: j * gsize + gsize / 2 + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + gsize + gsize / 2 + hor_offset, Y: i * gsize + ver_offset }, { X: j * gsize + gsize - gsize / 2 + hor_offset, Y: i * gsize + gsize + ver_offset }, { X: j * gsize - gsize / 2 + hor_offset, Y: i * gsize + gsize + ver_offset }]; } //randomly delete roughly 1/8 of them ... subj = del(subj); } //random_grid_subj = subj; } else subj = random_grid_subj; rnd_grid_sett.scale = scale; return subj; } function get_rect_poly() { var rect_poly = '[[{"X":100,"Y":100},{"X":200,"Y":100},{"X":200,"Y":200},{"X":100,"Y":200},{"X":100,"Y":100}]]'; rect_poly = '[[{"X":100,"Y":100},{"X":100,"Y":100},{"X":200,"Y":100},{"X":200,"Y":200},{"X":100,"Y":200},{"X":100,"Y":100}]]'; return deserialize_clipper_poly(rect_poly); } function round(a) { if (is_float_clipper) return a; if (global_do_not_round_and_scale) return a; else return Math.floor(a * scale); } function Math_round(a) { if (is_float_clipper) return a; return Math.round(a); } window.lsk = 0; function deserialize_clipper_poly(polystr) { window.lsk++; var poly = JSON.parse(polystr); var i, j, pp, n = [ [] ], m, pm; var np = new ClipperLib.Paths(); for (i = 0, m = poly.length; i < m; i++) { np[i] = new ClipperLib.Path(); for (j = 0, pm = poly[i].length; j < pm; j++) { pp = { X: 0, Y: 0 }; // new ClipperLib.FPoint() or new ClipperLib.IntPoint(); if (!isNaN(Number(poly[i][j].X)) && !isNaN(Number(poly[i][j].Y))) { pp.X = round(Number(poly[i][j].X)); pp.Y = round(Number(poly[i][j].Y)); if (benchmark_running) { if (pp.X > bench.max_point_x) bench.max_point_x = pp.X; if (pp.Y > bench.max_point_y) bench.max_point_y = pp.Y; if (pp.X < bench.min_point_x) bench.min_point_x = pp.X; if (pp.Y < bench.min_point_y) bench.min_point_y = pp.Y; if (typeof (bench.points["L" + pp.X]) == "undefined") bench.points["L" + pp.X] = scale + ":" + pp.X + ":" + poly[i][j].X; if (typeof (bench.points["L" + pp.Y]) == "undefined") bench.points["L" + pp.Y] = scale + ":" + pp.Y + ":" + poly[i][j].Y; } np[i].push(pp); } else return n; } } return np; } (function () { "use strict"; SVG.create = function () { p = Raphael("svgcontainer", 500, 350); p.canvas.setAttribute("id", "p"); var str = "<filter id='innerbewel' x0='-50%' y0='-50%' width='200%' height='200%' >"; str += "<feGaussianBlur in='SourceAlpha' stdDeviation='2' result='blur'/>"; str += "<feOffset dy='3' dx='3'/>"; str += "<feComposite in2='SourceAlpha' operator='arithmetic'"; str += " k2='-1' k3='1' result='hlDiff'/>"; str += "<feFlood flood-color='white' flood-opacity='0.8'/>"; // changed to 1.0 for speed str += "<feComposite in2='hlDiff' operator='in'/>"; str += "<feComposite in2='SourceGraphic' operator='over' result='withGlow'/>"; str += "<feOffset in='blur' dy='-3' dx='-3'/>"; str += "<feComposite in2='SourceAlpha' operator='arithmetic'"; str += " k2='-1' k3='1' result='shadowDiff'/>"; str += "<feFlood flood-color='black' flood-opacity='0.5'/>"; // changed to 1.0 for speed str += "<feComposite in2='shadowDiff' operator='in'/>"; str += "<feComposite in2='withGlow' operator='over'/>"; str += "</filter>"; var markers = ''; // Markers to show start, mid and end points of path markers += '<marker id="StartMarker" viewBox="0 0 10 10" refX="0" refY="5" markerUnits="strokeWidth" markerWidth="10" markerHeight="10" stroke="red" stroke-width="1" fill="none" orient="auto">'; markers += '<path d="M0,5L10,5M5,0L10,5M5,10L10,5">'; markers += '</marker>'; markers += '<marker id="MidMarker" stroke-opacity="1.0" viewBox="-1 -1 12 12" refX="5" refY="5" markerWidth="4" markerHeight="4" stroke="red" stroke-width="1" fill="yellow" stroke-opacity="0.5" fill-opacity="0.5" orient="0" markerUnits="strokeWidth">'; markers += '<circle cx="5" cy="5" r="5"></circle>'; markers += '</marker>'; markers += '<marker id="EndMarker" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="8" stroke="blue" stroke-width="1" fill="none" orient="auto">'; markers += '<rect x="0" y="0" width="10" height="10"></rect>'; markers += '</marker>'; // This second invisible marker is needed to avoid noisy after images in Chrome: markers += '<marker id="StartMarker2" viewBox="0 0 10 10" refX="0" refY="5" markerUnits="strokeWidth" markerWidth="10" markerHeight="10" stroke="none" fill="none" orient="auto">'; markers += '<path d="M0,5L10,5M5,0L10,5M5,10L10,5">'; markers += '</marker>'; markers += '<marker id="MidMarker2" stroke-opacity="1.0" viewBox="-1 -1 12 12" refX="5" refY="5" markerWidth="4" markerHeight="4" stroke="none" fill="none" orient="0" markerUnits="strokeWidth">'; markers += '<circle cx="5" cy="5" r="5"></circle>'; markers += '</marker>'; markers += '<marker id="EndMarker2" viewBox="0 0 10 10" refX="5" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="8" stroke="none" fill="none" orient="auto">'; markers += '<rect x="0" y="0" width="10" height="10"></rect>'; markers += '</marker>'; $("body").append("<svg id='dummy' style='display:none'><defs>" + str + markers + "</defs></svg>"); $("#p defs").append($("#innerbewel")); $("#p defs").append($("#dummy marker")); $("#dummy").remove(); var svg_p = $('#p'); /* svg_p.on('mousedown', function(){ $('.svg_mypath').css('pointer-events', 'initial'); }); */ svg_p.on('mouseout', function() { if(!sub_poly_links_update) return; hide_path(); }) svg_p.on('click', function(){ if(!sub_poly_links_update) return; //console.log(document.querySelectorAll( "#p :hover" )); if(global_i !== null && global_fr !== null && SVG.clipper_paths[global_fr-1].length) popup_path(global_i, global_fr, SVG.clipper_paths[global_fr-1].length); }); /* $(document).on('mouseup', function(){ //$('.svg_mypath').css('pointer-events', ''); }); */ var pt = svg_p[0].createSVGPoint(); var pt2 = {X:0,Y:0}; svg_p.on('mousemove', function(e){ if(!sub_poly_links_update) return; var id = null; pt.x = e.clientX; pt.y = e.clientY; var elem = document.elementFromPoint(pt.x, pt.y); if(elem !== null) { var id = elem.getAttribute('id'); if(id !== null) { id = id.replace('p', ''); if(id === '') id = null; } } pt = pt.matrixTransform(svg_p[0].getScreenCTM().inverse()); pt2.X = pt.x; pt2.Y = pt.y; var fr = null; var selected_i = null; var hide = 1; for(var i = 0; i < SVG.clipper_paths.length; i++) { if(typeof SVG.clipper_paths[i] !== 'undefined') { for(var j = 0; j < SVG.clipper_paths[i].length; j++) { if(ClipperLib.Clipper.PointInPolygon(pt2, SVG.clipper_paths[i][j])) { fr = i + 1; selected_i = j; } } } } if(window.global_fr !== fr || window.global_i !== selected_i || window.global_id !== id) { hide_path(); if(fr!==null && selected_i !== null) { show_path(selected_i, fr, SVG.clipper_paths[fr-1].length); hide = 0; } } window.global_fr = fr; window.global_i = selected_i; window.global_id = id; }); return p; }; SVG.addpaths = function (a, b, c, a1, b1) { if (a) { subj_subpolygons = a.length; a = this.polys2path(a, "1"); if (sub_poly_links_update) { if (typeof (subj_subpolygons) == "undefined") subj_subpolygons = 0; $("#subj_subpolygons").html(subj_subpolygons); $("#subj_points_in_subpolygons").html(this.sub_poly_links); $("#subj_points_total").html(this.total.toString()); subj_points_total = this.total; } } if (b) { clip_subpolygons = b.length; b = this.polys2path(b, "2"); if (sub_poly_links_update) { if (typeof (clip_subpolygons) == "undefined") clip_subpolygons = 0; $("#clip_subpolygons").html(clip_subpolygons); $("#clip_points_in_subpolygons").html(this.sub_poly_links); $("#clip_points_total").html(this.total.toString()); clip_points_total = this.total; } } if (typeof (c) != "undefined" && typeof (c.length) != "undefined") solution_subpolygons = c.length; else solution_subpolygons = 0; if (c) { c = this.polys2path(c, "3"); if (sub_poly_links_update) { $("#solution_subpolygons").html(solution_subpolygons); $("#solution_points_in_subpolygons").html(this.sub_poly_links); $("#solution_points_total").html(this.total.toString()); solution_points_total = this.total; } } if (sub_poly_links_update) { $("#points_total").html((subj_points_total + clip_points_total + solution_points_total).toString()); if (isNaN(subj_subpolygons)) subj_subpolygons = 0; else if (isNaN(clip_subpolygons)) clip_subpolygons = 0; else if (isNaN(solution_subpolygons)) solution_subpolygons = 0; $("#all_subpolygons").html(subj_subpolygons + clip_subpolygons + solution_subpolygons); } if (a) p1 = p.path(a); if (b) p2 = p.path(b); if (c) p3 = p.path(c); if (a) p1.node.setAttribute("id", "p1"); if (b) p2.node.setAttribute("id", "p2"); if (c) p3.node.setAttribute("id", "p3"); if (c && bevel) $("#p3").attr("filter", "url(#innerbewel)"); else if (c && !bevel) $("#p3").removeAttr("filter"); if (!subj_is_closed && a) p1.node.setAttribute("class", "openpath"); else if (subj_is_closed && a) $("#p1").removeAttr("class"); if (a) $("#p1").removeAttr("fill stroke"); if (b) $("#p2").removeAttr("fill stroke"); if (c) $("#p3").removeAttr("fill stroke"); var PolyFillType = { pftEvenOdd: 0, pftNonZero: 1, pftPositive: 2, pftNegative: 3 }; if (a) { if (a1 == PolyFillType.pftEvenOdd) $("#p1").attr("fill-rule", "evenodd"); else $("#p1").attr("fill-rule", "nonzero"); } if (b) { if (b1 == PolyFillType.pftEvenOdd) $("#p2").attr("fill-rule", "evenodd"); else $("#p2").attr("fill-rule", "nonzero"); } // p.setViewBox(bbox.x, bbox.y, bbox.width, bbox.height, true); // p.setSize(bbox.width, bbox.height); }; SVG.sub_poly_counts = null; SVG.sub_poly_links = null; SVG.total = null; SVG.clipper_paths = []; SVG.polys2path = function (a, fr) { //if(typeof fr === 'undefined') return; //console.log('polys2path', a, fr); scaled_paths[fr] = []; SVG.clipper_paths[fr-1] = a; var path = "", i, j, link, d; this.sub_poly_counts = []; this.sub_poly_links = ""; this.total = 0; if (!scale) scale = 1; var a_length = a.length; var a_i_length; var classi = "subpolylinks"; for (i = 0; i < a_length; i++) { this.sub_poly_counts.push(a[i].length); d = ""; a_i_length = a[i].length; SVG.clipper_paths[fr-1][i].fr = fr; SVG.clipper_paths[fr-1][i].i = i; SVG.clipper_paths[fr-1][i].a_i_length = a_i_length; if (a_i_length) { for (j = 0; j < a_i_length; j++) { this.total++; if (j == 0) { d += "M"; } else { d += "L"; } d += (a[i][j].X / scale) + ", " + (a[i][j].Y / scale); } if (!(!subj_is_closed && fr == 1)) d += "Z"; //Z only for closed subj paths } path += d; if (sub_poly_links_update) { if (d.trim() == "Z") d = ""; scaled_paths[fr].push(d); if (benchmark_running) classi = "subpolylinks_disabled"; link = '<span id="subpolylinks_'+fr+'_'+i+'" class="' + classi + '" onclick="popup_path(' + i + ',' + fr + ',' + a_i_length + ')" onmouseover="show_path(' + i + ',' + fr + ',' + a_i_length + ')" onmouseout="hide_path()" >' + a_i_length + '</span>, '; this.sub_poly_links += link; } } if (sub_poly_links_update) this.sub_poly_links = this.sub_poly_links.substring(0, this.sub_poly_links.length - 2); if (path.trim() == "Z") path = ""; if (benchmark_running) $(".subpolylinks").removeClass("subpolylinks subpolylinks_disabled").addClass("subpolylinks_disabled"); else $(".subpolylinks_disabled").removeClass("subpolylinks subpolylinks_disabled").addClass("subpolylinks"); return path; } window.SVG = SVG; })() function toint(a) { a = parseInt(a, 10); return a; } // Englarges mypath ( = black partially transparent path) // when clicked function popup_path(i, fr, point_count) { if (point_count == 0) return; if (benchmark_running) return false; if (typeof (i) == "undefined") d = scaled_paths[fr].join(" "); else d = scaled_paths[fr][i]; var points_string = normalize_clipper_poly(d, true); // quiet var area; SolutionPolygonClicked = false; SolutionPolygonString = ""; if (points_string !== false) { if (typeof (i) == "undefined") // which means that "Points" column is clicked { if (fr == 3) { $("#polygon_explorer_string_inp").val(format_output(points_string, "ExPolygons")); SolutionPolygonClicked = true; SolutionPolygonString = points_string; } else { $("#polygon_explorer_string_inp").val(format_output(points_string)); } var scaled_paths_length = scaled_paths.length; var points_str; area = 0; for (var j = 0; j < scaled_paths_length; j++) { points_str = normalize_clipper_poly(scaled_paths[fr][j], true); if (points_str !== false) { var polygon = JSON.parse(points_str.replace(/^\[\[/, "[").replace(/\]\]$/, "]")); area += ClipperLib.Clipper.Area(polygon); } } var points_scaled = JSON.parse(points_string); var polygonal_perimeter = ClipperLib.JS.PerimeterOfPaths(points_scaled, true, 1); var line_perimeter = ClipperLib.JS.PerimeterOfPaths(points_scaled, false, 1); var bounds = ClipperLib.JS.BoundsOfPaths(points_scaled, 1); $("#area").html("Area: " + area + "<br>Polygonal perimeter: " + polygonal_perimeter + "<br>Line perimeter: " + line_perimeter + "<br>Height: " + (bounds.bottom - bounds.top) + "<br>Width: " + (bounds.right - bounds.left)); } else { $("#polygon_explorer_string_inp").val(format_output(points_string).replace(/^\[\[/, "[").replace(/\]\]$/, "]")); area = ClipperLib.Clipper.Area(JSON.parse(points_string.replace(/^\[\[/, "[").replace(/\]\]$/, "]"))); var points_scaled = JSON.parse(points_string); var polygonal_perimeter = ClipperLib.JS.PerimeterOfPaths(points_scaled, true, 1); var line_perimeter = ClipperLib.JS.PerimeterOfPaths(points_scaled, false, 1); var bounds = ClipperLib.JS.BoundsOfPaths(points_scaled, 1); $("#area").html("Area: " + area + "<br>Polygonal perimeter: " + polygonal_perimeter + "<br>Line perimeter: " + line_perimeter + "<br>Height: " + (bounds.bottom - bounds.top) + "<br>Width: " + (bounds.right - bounds.left)); } $('#subj_points_total,#clip_points_total,#solution_points_total') .removeClass('subpolylinks_selected'); $('[id^="subpolylinks_"]').removeClass('subpolylinks_selected'); $('#subpolylinks_'+fr+'_'+i).addClass('subpolylinks_selected'); if (typeof (i) == "undefined") { if(fr == 3) $('#solution_points_total').addClass('subpolylinks_selected'); else if(fr == 2) $('#clip_points_total').addClass('subpolylinks_selected'); else if(fr == 1) $('#subj_points_total').addClass('subpolylinks_selected'); } } else { $("#polygon_explorer_string_inp").val("Some error occurred when parsing polygon points!"); } $(mypath.node).removeAttr('fill stroke').attr('class', 'svg_mypath'); $(mypath.node).attr('fill-rule', $('#p' + fr).attr('fill-rule')); $(mypath.node).attr('vector-effect', 'non-scaling-stroke'); // This is not supported in IE 9 and IE10 pre! if(typeof mypath.node === 'undefined' || mypath.node === null) { return; } var bb = mypath.node.getBBox(); var svg_w = toint($('#p').attr('width')); var svg_h = toint($('#p').attr('height')); var x_scale = (svg_w - 20) / bb.width; var y_scale = (svg_h - 20) / bb.height; var scal = Math.min(x_scale, y_scale); var x_trans = -(bb.x + bb.width / 2) + svg_w / 2; var y_trans = -(bb.y + bb.height / 2) + svg_h / 2; $('#StartMarker')[0].setAttribute('markerWidth', 10 / scal * 2); $('#StartMarker')[0].setAttribute('markerHeight', 10 / scal * 2); $('#MidMarker')[0].setAttribute('markerWidth', 4 / scal * 2); $('#MidMarker')[0].setAttribute('markerHeight', 4 / scal * 2); $('#EndMarker')[0].setAttribute('markerWidth', 4 / scal * 2); $('#EndMarker')[0].setAttribute('markerHeight', 4 / scal * 2); mypath.animate( { 'transform': 't' + x_trans + ' ' + y_trans + 's' + scal + ' ' + scal }, 500, function () { $(mypath.node).attr( { 'marker-start': 'url(#StartMarker)', 'marker-mid': 'url(#MidMarker)', 'marker-end': 'url(#EndMarker)' }); }); } // Shows mypath ( = black partially transparent path) // when hovered function show_path(i, fr, point_count) { if (point_count == 0) return; if (benchmark_running) return false; var d; if (typeof (i) == "undefined") d = scaled_paths[fr].join(" "); else d = scaled_paths[fr][i]; mypath = p.path(d); $(mypath.node).removeAttr('fill stroke').attr('class', 'svg_mypath'); $(mypath.node).attr('fill-rule', $('#p' + fr).attr('fill-rule')); $(mypath.node).attr('vector-effect', 'non-scaling-stroke'); //$('#p .svg_mypath').attr('onclick', "popup_path("+i+","+fr+","+point_count+")"); } // Hides mypath ( = black partially transparent path) function hide_path() { if (mypath == null) return; $(mypath.node).attr( { 'marker-start': 'url(#StartMarker2)', 'marker-mid': 'url(#MidMarker2)', 'marker-end': 'url(#EndMarker2)' }); if ($(mypath.node).attr('transform')) mypath.animate( { 'transform': 's1 1' }, 500, function () { this.animate( { 'opacity': '0' }, 500, function () { this.remove(); }); }); else mypath.animate( { 'opacity': '0' }, 300, function () { this.remove(); }); } function set_default_custom_polygon() { var subj = default_custom_subject_polygon; var clip = default_custom_clip_polygon; var def_obj = { "subj": subj, "clip": clip }; var arr = $.totalStorage('custom_polygons'); if (typeof (arr) == "undefined" || arr === null || !isArray(arr) || arr.length == 0) arr = []; arr[0] = def_obj; $.totalStorage('custom_polygons', arr); } function update_custom_polygons_select() { var arr = $.totalStorage('custom_polygons'); var selected_value = $("#custom_polygons_select").val(); if (!selected_value && selected_value + "" !== "0") selected_value = 0; $("#custom_polygons_select option").remove(); var arr_length = 0; if (isArray(arr)) arr_length = arr.length; var selected_txt, i; if (arr_length > 0) for (i = 0; i < arr_length; i++) { selected_txt = ""; if (i == selected_value) selected_txt = "selected"; if (arr[i] !== null) $("#custom_polygons_select").append('<option ' + selected_txt + ' value="' + i + '">Poly ' + i + '</option>'); } else set_default_custom_polygon(); if ($("#custom_polygons_select option").length === 0) set_default_custom_polygon(); // If previously selected value is removed, select the next one if (arr_length > 0) if (arr[selected_value] === null) { for (i = parseInt(selected_value, 10); i < arr_length; i++) { if (arr[i] !== null) { $('#custom_polygons_select').val(i); break; } } } $('#custom_polygons_select').change(); } function show_alert(e, obj, txt) { var x = e.pageX - obj.offsetLeft + $(obj).width() / 2; var y = e.pageY - obj.offsetTop; $("#custom_poly_message_box_green") .stop() .css( { height: '0px', opacity: '0', left: x + 1, top: y - 1, width: '0px', display: 'block' }) .html("") .animate( { left: (x + 200), top: (y - 40), height: '40px', width: '200px', opacity: '0.9' }, 300, function () { $(this).html(txt).animate( { opacity: '0.9' }, 1200, function () { $(this).animate( { opacity: 0 }, 600, function () { $(this).css("display", "none"); }) }) }); } function update_fieldset_heights() { $("#misc_fieldset").css("min-height", "").css("height", ""); $("#polygon_explorer_fieldset").css("min-height", "").css("height", ""); $("#benchmark_fieldset_f").css("min-height", "").css("height", ""); var td_heights = []; td_heights.push($("#td0").innerHeight()); td_heights.push($("#td1").innerHeight()); td_heights.push($("#td2").innerHeight()); td_heights.push($("#td3").innerHeight()); var max_td_height = Array_max(td_heights); var max_index; var children_heights; var children_heights_arr = []; for (var i = 0; i < td_heights.length; i++) { children_heights = 0; if (td_heights != max_td_height || 1 == 1) { $("#td" + i).find("fieldset, #svgcontainer, #filltype_cliptype_table").not("[id='']").each(function () { if ($(this).css("display") != "none") { children_heights += $(this).outerHeight(true); //console.log(this.type + ":" + $(this).attr("id") + ":" + $(this).outerHeight(true) + ":" + $(this).outerWidth(true)); } else { //console.log("----- NOT COUNTED:"+this.type + ":" + $(this).attr("id") + ":" + $(this).outerHeight(true) + ":" + $(this).outerWidth(true)); } }); } children_heights_arr.push(children_heights); //console.log("-------------"); } var misc_fieldset_height = $("#misc_fieldset").height(); var polygon_explorer_fieldset_height = $("#polygon_explorer_fieldset").height(); var benchmark_fieldset_f_height = $("#benchmark_fieldset_f").height(); misc_fieldset_height += (max_td_height - children_heights_arr[0]) + $("#misc_fieldset").outerHeight(true); polygon_explorer_fieldset_height += (max_td_height - children_heights_arr[1]); benchmark_fieldset_f_height += (max_td_height - children_heights_arr[2]); $("#misc_fieldset").css("min-height", misc_fieldset_height + "px"); $("#polygon_explorer_fieldset").css("min-height", polygon_explorer_fieldset_height + "px"); $("#benchmark_fieldset_f").css("min-height", benchmark_fieldset_f_height + "px"); } function resize() { myresize(); } function myresize() { var freeheight = $(window).height(); var polygon_explorer_div_max_height = freeheight - 360; if (polygon_explorer_div_max_height < 170) polygon_explorer_div_max_height = 170; // This causes problems when resizing polygon explorer textarea, so have to comment: //$("#polygon_explorer_div").css("max-height", polygon_explorer_div_max_height +"px"); } // ADDITIONAL SVG WINDOW STARTS window.update_enlarged_SVG = false; window.update_enlarged_SVG_source = false; window.svg_source_place = "svg_source_container"; function svg_source_enlarge() { var window_height = $(document).height() * 0.9; var window_width = $(document).width() * 0.9; var source = $("#svg_source_textarea").val().replace(/ id=\"/g, ' id="_'); $("#enlarged_svg").html(source); var original_height = $("#_p").attr("height"); var original_width = $("#_p").attr("width"); // get bbox of all children of svg $("body").append('<div id="dummy" style="display:block;visibility:hidden"><svg><g id="g123"></g></svg></div>'); $("#g123").append($("#_p").children().clone()); $("#dummy").html($("#dummy").html()); var bb = $("#g123")[0].getBBox(); var g_width = bb.width + 10; var g_height = bb.height + 10; var g_x = bb.x - 5; var g_y = bb.y - 5; $("#dummy").remove(); /* $("body").append('<img id="width_img" width="100%" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">'); var window_width = parseInt(window.getComputedStyle($("#width_img")[0],null).getPropertyValue("width")); $("#width_img").remove(); */ $("#_p").attr("viewBox", g_x + " " + g_y + " " + g_width + " " + g_height); $("#enlarged_svg").html($("#enlarged_svg").html()); $("#enlarged_svg").css("display", "block"); if (svg_source_place == "svg_source_container") // at the bottom { $("#_p").attr("width", window_width); $("#_p").attr("height", parseInt((window_width / original_width) * original_height)); $("#_p1,#_p2,#_p3").css("stroke-width", 0.8 * (original_width / window_width)); } else // at the right { $("#_p").attr("height", window_height); $("#_p").attr("width", parseInt((window_height / original_height) * original_width)); $("#_p1,#_p2,#_p3").css("stroke-width", 0.8 * (original_height / window_height)); } $("#svg_source_textarea").css("display", "none"); if (benchmark_running) var disabled = "disabled"; else disabled = ""; $("#svg_source_enlarge_button").html('<button ' + disabled + ' class="textarea_hide_buttons" onClick="show_svg_source_f()" title="Show SVG source">Show SVG source</button>'); update_enlarged_SVG_source = true; update_enlarged_SVG = true; } function show_svg_source_f() { $("#svg_source_textarea").css("display", "block"); show_svg_source_click("non_click"); $("#enlarged_svg").html(""); if (benchmark_running) var disabled = "disabled"; else disabled = ""; $("#svg_source_enlarge_button").html('<button ' + disabled + ' class="textarea_hide_buttons" onClick="svg_source_enlarge()" title="Show SVG">Show SVG</button>'); update_enlarged_SVG_source = true; update_enlarged_SVG = false; } function show_svg_source_click(non_click) { update_enlarged_SVG_source = true; if (!update_enlarged_SVG) update_enlarged_SVG = false; if (non_click !== "non_click") { if ($("#show_svg_source").html() == "Show SVG, Bottom") { $("#show_svg_source").html("Show SVG, Right"); $("#show_svg_source").attr("title", "Show current SVG and it's source at the right side of the page"); svg_source_place = "svg_source_container"; $("#svg_source_container2").html(""); } else { $("#show_svg_source").html("Show SVG, Bottom"); $("#show_svg_source").attr("title", "Show current SVG and it's source at the bottom of the page"); svg_source_place = "svg_source_container2"; $("#svg_source_container").html(""); } var textarea_str = '<div id="svg_source_textarea_div">'; textarea_str += '<button class="textarea_hide_buttons" onClick="$(\'#svg_source_textarea_div\').remove();update_enlarged_SVG_source=false;update_enlarged_SVG=false" title="Hide SVG source">Hide</button>'; if (benchmark_running) var disabled = "disabled"; else disabled = ""; textarea_str += '<span id="svg_source_enlarge_button"><button ' + disabled + ' class="textarea_hide_buttons" onClick="svg_source_enlarge()" title="Show SVG">Show SVG</button></span><br>'; textarea_str += '<div style="display:none" id="enlarged_svg"></div>'; textarea_str += '<textarea id="svg_source_textarea"></textarea>'; textarea_str += '</div>'; $("#" + svg_source_place).append(textarea_str); } var svg_source = $("#svgcontainer").html().replace(/\>/g, ">\n"); $("#svg_source_textarea").val(svg_source); //svg_source_enlarge(); } // ADDITIONAL SVG WINDOW ENDS // BENCHMARKING STARTS function benchmark3(i) { var start_time = new Date().getTime(); var obj = bench_glob[i]; clean = obj.clean; lighten = obj.lighten; if (clean) { cleandelta = obj.cleandelta; $('#cleandelta').val(cleandelta); $('#clean').attr('checked', 'checked'); } else $('#clean').removeAttr('checked'); if (lighten) { lighten_distance = obj.lighten_distance; $('#lighten_distance').val(lighten_distance); $('#lighten').attr('checked', 'checked'); } else $('#lighten').removeAttr('checked'); joinType = obj.joinType; $('input[type="radio"][name="joinType"][value="' + joinType + '"]').attr('checked', 'checked'); endType = obj.endType; $('input[type="radio"][name="endType"][value="' + endType + '"]').attr('checked', 'checked'); offsettable_poly = obj.offsettable_poly; $('input[type="radio"][name="offsettable_poly"][value="' + offsettable_poly + '"]').attr('checked', 'checked'); delta = obj.delta; $('#delta').val(delta); miterLimit = obj.miterLimit; $('#miterLimit').val(miterLimit); arcTolerance = obj.arcTolerance; $('#arcTolerance').val(arcTolerance); AutoFix = obj.AutoFix; if (AutoFix) $('#AutoFix').attr('checked', 'checked'); else $('#AutoFix').removeAttr('checked'); ExPolygons = obj.ExPolygons; if (ExPolygons) $('#ExPolygons').attr('checked', 'checked'); else $('#ExPolygons').removeAttr('checked'); Simplify = obj.Simplify; if (Simplify) $('#Simplify').attr('checked', 'checked'); else $('#Simplify').removeAttr('checked'); PreserveCollinear = obj.PreserveCollinear; if (PreserveCollinear) $('#PreserveCollinear').attr('checked', 'checked'); else $('#PreserveCollinear').removeAttr('checked'); ReverseSolution = obj.ReverseSolution; if (ReverseSolution) $('#ReverseSolution').attr('checked', 'checked'); else $('#ReverseSolution').removeAttr('checked'); StrictlySimple = obj.StrictlySimple; if (StrictlySimple) $('#StrictlySimple').attr('checked', 'checked'); else $('#StrictlySimple').removeAttr('checked'); off_poly_closed = obj.off_poly_closed; if (off_poly_closed) $('#off_poly_closed').attr('checked', 'checked'); else $('#off_poly_closed').removeAttr('checked'); subject_fillType = obj.subject_fillType; $("input[name='subject_fillType'][value='" + subject_fillType + "']").attr("checked", "checked"); clip_fillType = obj.clip_fillType; $("input[name='clip_fillType'][value='" + clip_fillType + "']").attr("checked", "checked"); clipType = obj.clipType; //console.log('*'+obj.clipType+'*'); //$("input[name='clipType'][value='" + clipType + "']").attr("checked", "checked").trigger("change"); $("input[name='clipType']").val([clipType + '']); scale = obj.scale; $('#scale').val(scale); var polygon_id; if (obj.polygon_id == 4 || obj.polygon_id == 5) { rnd_sett = obj.rnd_sett; if (polygon_id_global !== obj.polygon_id || clicked_benchmark_button_id === 'benchmark3') { random_subj = get_random_polys("subj", obj.polygon_id); random_clip = get_random_polys("clip", obj.polygon_id); polygon_id_global = obj.polygon_id; } } if (typeof obj.polygon_id === 'number') polygon_id = obj.polygon_id; else if (typeof obj.polygon_id === 'string') { var polygon_id_arr = obj.polygon_id.split('_'); polygon_id = +polygon_id_arr[0]; //console.log('polygon_id', polygon_id); if (polygon_id === 11) { var grid_type = +polygon_id_arr[1]; if (grid_type_global !== grid_type) { random_grid_subj = get_random_grids("subj", grid_type); scale_again_random_grid_poly(random_grid_subj); grid_type_global = grid_type; } $('input[type="radio"][name="polygons"][value="' + polygon_id + '"]').attr('checked', 'checked').trigger("change"); $('#random_grid_type').val(grid_type); } } if (polygon_id === 10) { $("#clean").attr('checked', 'checked'); clean = true; } if (polygon_id !== 11) { $('input[type="radio"][name="polygons"][value="' + polygon_id + '"]').attr('checked', 'checked').trigger("change"); } make_clip(); obj = null; window.last_completed_bench = i; var end_time = new Date().getTime(); var time = end_time - start_time; bench_glob[i].measured_time = time; bench_elapsed_time += time; bench_glob[i].elapsed_time = bench_elapsed_time; // update next timeouts for (var lsk = i + 1; lsk < bench_glob.length; lsk++) { clearTimeout(bench_glob[lsk].setTimeout); } if (i < bench_glob.length - 1) { bench_glob[i + 1].setTimeout = setTimeout("benchmark3(" + (i + 1) + ")", timeout_time_addition); } if (1 === 0) for (var lsk = i + 1; lsk < bench_glob.length; lsk++) { clearTimeout(bench_glob[lsk].setTimeout); bench_glob[lsk].setTimeout = setTimeout("benchmark3(" + (lsk) + ")", timeout_time_addition + lsk * time); //bench_glob[lsk-1].elapsed_time + lsk * bench_glob[lsk-1].measured_time); //console.log(lsk, bench_glob[lsk-1].elapsed_time, bench_glob[lsk-1].measured_time, bench_glob[lsk-1].elapsed_time + lsk * bench_glob[lsk-1].measured_time); } var results = ''; if (typeof bench.list[0] !== 'undefined') { var elapsed_time = end_time - bench.list[0].start; } else var elapsed_time = 0; results += Math.floor((i + 1) / bench_glob.length * 100) + " % ("; results += (elapsed_time / 1000).toFixed(1) + " s) of "; results += "benchmark " + (repeat + 1) + " / " + repeat_times + ". "; results += "Remaining: "; results += Math.floor((((elapsed_time / (i + 1)) * (bench_glob.length - i + 1)) / 1000)) + " s."; $("#benchmark_multiple_status").html(results); $("#benchmark_multiple_status").css("display", "table-cell"); if (i == 0) { var multiple_runs_table = bench.print_multiple_runs(); if ($("#benchmark_multiple_table").length) $("#benchmark_multiple_table").remove(); $("#benchmark_multiple_table_cont").append(multiple_runs_table); } else if (i == bench_glob.length - 1) { if (!$("#benchmark_exports_textarea").length) { var textarea_str = '<div id="benchmark_exports_textarea_div">'; textarea_str += '<button class="textarea_hide_buttons" onClick="$(\'#benchmark_exports_textarea_div\').remove()" title="Hide Benchmark exports">Hide</button><br>'; textarea_str += '<textarea id="benchmark_exports_textarea"></textarea>'; textarea_str += '</div>'; $("#benchmark_exports_container").append(textarea_str); } if (benchmark_exports.indexOf("max_point_x") == -1) { benchmark_exports += "bench.max_point_x:" + bench.max_point_x + "\n"; benchmark_exports += "bench.max_point_y:" + bench.max_point_y + "\n"; benchmark_exports += "bench.min_point_x:" + bench.min_point_x + "\n"; benchmark_exports += "bench.min_point_y:" + bench.min_point_y + "\n"; } benchmark_exports += bench.totals + ";" + browserg.browser + ";" + browserg.version + "\n"; $("#benchmark_exports_textarea").val(benchmark_exports); bench.totals_arr_multiple.push(bench.totals_arr[0]); var multiple_runs_table = bench.print_multiple_runs(); if ($("#benchmark_multiple_table").length) $("#benchmark_multiple_table").remove(); $("#benchmark_multiple_table_cont").append(multiple_runs_table); repeat++; if (repeat < repeat_times) { benchmark_automatic_click = 1; $("#" + clicked_benchmark_button_id).trigger("click"); } else { bench_glob.length = 0; repeat = 0; benchmark_running = 0; ClipperLib.MaxSteps = ClipperLib_MaxSteps_original; $("#" + clicked_benchmark_button_id).html($("#" + clicked_benchmark_button_id).html().replace("Stop", "Run")); $("#" + clicked_benchmark_button_id).attr("title", $("#" + clicked_benchmark_button_id).attr("title").replace("Stop", "Execute")); $("button,input,select").removeAttr('disabled'); $('#sub_poly_links_update').trigger("change"); } } } (function (window) { var benchmark = function (varname) { if (typeof (varname) == "string") this.varname = varname; else this.varname = ""; this.list = []; this.cats = []; this.cats.arr = []; this.type = "benchmark"; this.includeSVG = true; this.totals = ""; this.totals_arr = []; this.totals_arr_multiple = []; this.max_point_x = Number.NEGATIVE_INFINITY; this.min_point_x = Number.POSITIVE_INFINITY; this.max_point_y = Number.NEGATIVE_INFINITY; this.min_point_y = Number.POSITIVE_INFINITY; this.points = []; }; // returns index // cat = category, which name belongs to // name = code region name or function, which is measured benchmark.prototype.start = function (cat, name) { if (cat == "") return; if (name == "") return; var b = {}; b.start = new Date().getTime(); b.name = name; b.cat = cat; this.list.push(b); return this.list.length - 1; } benchmark.prototype.end = function (index) { this.list[index].end = new Date().getTime(); this.list[index].time = this.list[index].end - this.list[index].start; var this_list_cat = this.list[index].cat; var this_list_cat_counts = this_list_cat + "_counts"; var this_list_cat_time_sum = this_list_cat + "_time_sum" if (typeof (this.cats[this_list_cat_counts]) == "undefined") this.cats.arr.push(this_list_cat); if (typeof (this.cats[this_list_cat_time_sum]) == "undefined") this.cats[this_list_cat_time_sum] = 0; if (typeof (this.cats[this_list_cat_counts]) == "undefined") this.cats[this_list_cat_counts] = 0; this.cats[this_list_cat_time_sum] += this.list[index].time; this.cats[this_list_cat_counts]++; if (typeof (bench_glob) != "undefined" && bench_glob.length > 0) { this.list[index].bench_glob_index = window.last_completed_bench; } } benchmark.prototype.clear = function () { this.list = []; this.cats = []; this.cats.arr = []; this.includeSVG = true; return true; } benchmark.prototype.print = function (all) { var tbl = '<style>'; tbl += '.bench {width:317px;border-collapse:collapse;white-space:nowrap;}'; tbl += '.bench td, .bench th{font-size:12px;text-align:left;border:1px solid #444444; padding:2px}'; tbl += '.bench th{background-color:#DDDDDD;}'; tbl += '.bench tfoot td{background-color:#DDDDDD;}'; tbl += '.bench_foot{font-weight:bold;}'; tbl += '</style>'; tbl += '<table class="bench"><thead><tr>'; tbl += '<th>Num</th>'; tbl += '<th>Name</th>'; tbl += '<th>Category</th>'; tbl += '<th>Time</th>'; tbl += '</tr></thead>'; tbl += '<tbody>'; var time, totaltime = 0, i, m; if (this.list && this.list.length) { m = this.list.length; // print all var start_index = 0; if (!all) { if (bench_glob.length) start_index = m - 3; else start_index = m - 16; if (start_index < 0) start_index = 0; } for (i = start_index; i < m; i++) { time = (this.list[i].time); tbl += '<tr><td>'; tbl += (i + 1); tbl += '</td><td>'; tbl += this.list[i].name; tbl += '</td><td>'; tbl += this.list[i].cat; tbl += '</td><td>'; tbl += time; tbl += '</td></tr>'; } } tbl += '</tbody>'; tbl += '</table>'; var tbl2 = ""; tbl2 += '<table style="margin-top:10px;margin-bottom:10px" class="bench"><thead><tr>'; tbl2 += '<th>Num</th>'; tbl2 += '<th>Category</th>'; tbl2 += '<th>Calls</th>'; tbl2 += '<th>Sum</th>'; tbl2 += '<th>Avg</th>'; tbl2 += '</tr></thead>'; tbl2 += '<tbody>'; m = this.cats.arr.length; var item; this.totals = ""; this.totals_arr = []; var totals_arr_item = []; var counts_sum = 0, cat_time_sum = 0, cat_time_avg = 0, this_list_i_cat, this_list_i_cat_time_sum, this_list_i_cat_counts; if (m > 0) for (i = 0; i < m; i++) { tbl2 += '<tr><td>'; item = (i + 1); tbl2 += item; tbl2 += '</td><td>'; this_list_i_cat = this.cats.arr[i]; item = this_list_i_cat; tbl2 += item; tbl2 += '</td><td>'; this_list_i_cat_counts = this.cats[this_list_i_cat + "_counts"]; item = this_list_i_cat_counts; tbl2 += item; counts_sum += this_list_i_cat_counts; tbl2 += '</td><td>'; this_list_i_cat_time_sum = this.cats[this_list_i_cat + "_time_sum"]; item = this_list_i_cat_time_sum; tbl2 += item; cat_time_sum += this_list_i_cat_time_sum; tbl2 += '</td><td>'; item = (this_list_i_cat_time_sum / this_list_i_cat_counts).toFixed(4); tbl2 += item; tbl2 += '</td></tr>'; } tbl2 += '</tbody>'; if (m > 0) { tbl2 += '<tfoot><tr><td class="bench_foot" colspan="2">Total</td>'; item = (counts_sum); totals_arr_item.push(item); this.totals += item + ";"; tbl2 += '<td>' + item + '</td>'; item = (cat_time_sum); totals_arr_item.push(item); this.totals += item + ";"; tbl2 += '<td>' + item + '</td>'; item = (cat_time_sum / counts_sum).toFixed(4); totals_arr_item.push(item); this.totals += item; tbl2 += '<td style="padding: 4px; background-color: hsl(125, 73%, 80%); border: 3px solid black; font-weight: bold; font-size: 16px;">' + item + '</td>'; tbl2 += '</tr>'; tbl2 += '</tfoot>'; } tbl2 += '</table>'; this.totals_arr.push(totals_arr_item); tbl += tbl2; if (benchmark_running) var disabled = "disabled"; else disabled = ""; tbl += '<button ' + disabled + ' onClick="try { ' + this.varname + '.clear();$(\'#benchmark_div\').html(' + this.varname + '.print()); return true; } catch (e) {return false}">Clear Benchmarks</button>'; tbl += '<button ' + disabled + ' onClick="try { $(\'#benchmark_div\').html(' + this.varname + '.print(1)); } catch (e) {return false}">Show all</button>'; return tbl; } benchmark.prototype.print_multiple_runs = function (str) { var tbl2 = ""; tbl2 += '<table id="benchmark_multiple_table" style="margin-top:10px;margin-bottom:10px" class="bench"><thead><tr>'; tbl2 += '<th>Num</th>'; tbl2 += '<th>Calls</th>'; tbl2 += '<th>Sum</th>'; tbl2 += '<th>Avg</th>'; tbl2 += '</tr></thead>'; tbl2 += '<tbody>'; var item, counts_sum = 0, time_sum = 0; var times_array = []; for (var i = 0, m = this.totals_arr_multiple.length; i < m; i++) { times_array.push(this.totals_arr_multiple[i][1]); } var max = Array_max(times_array); var min = Array_min(times_array); var range = max - min; var average = getAverageFromNumArr(times_array, 4); var stdev = getStandardDeviation(times_array, 4); var minus_range = min - average; var plus_range = max - average; for (var i = 0, m = this.totals_arr_multiple.length; i < m; i++) { tbl2 += '<tr><td>'; item = (i + 1); tbl2 += item; tbl2 += '</td><td>'; item = this.totals_arr_multiple[i][0]; tbl2 += item; tbl2 += '</td><td>'; item = this.totals_arr_multiple[i][1]; tbl2 += item; time_sum += item; tbl2 += '</td><td>'; item = this.totals_arr_multiple[i][2]; tbl2 += item; tbl2 += '</td></tr>'; } tbl2 += '<tr><td colspan="4" id="benchmark_multiple_status" style="display:none"></td></tr>'; if (!isNaN(average)) { tbl2 += '<tr><td colspan="4">'; tbl2 += '<b>Average:</b> ' + average + " ms<br>"; tbl2 += '<b>Min:</b> ' + min + " ms<br>"; tbl2 += '<b>Max:</b> ' + max + " ms<br>"; tbl2 += '<b>Range:</b> ' + range.toFixed(4) + " ms<br>"; tbl2 += '<b>Minus-Range:</b> ' + minus_range.toFixed(4) + " ms<br>"; tbl2 += '<b>Plus-Range:</b> ' + plus_range.toFixed(4) + " ms<br>"; tbl2 += '<b>Stdev:</b> ' + stdev + " ms<br>"; tbl2 += '<b>Range/Average %:</b> ' + (range / average * 100).toFixed(4) + "<br>"; tbl2 += '<b>Minus-Range/Average %:</b> ' + (minus_range / average * 100).toFixed(4) + "<br>"; tbl2 += '<b>Plus-Range/Average %:</b> ' + (plus_range / average * 100).toFixed(4) + "<br>"; tbl2 += '<b>Stdev/Average %:</b> ' + (stdev / average * 100).toFixed(4) + "<br>"; tbl2 += '</td></tr>'; } tbl2 += '</tbody>'; return tbl2; } window.benchmark = benchmark; })(window); // Programmer: Larry Battle // Date: Mar 06, 2011 // Purpose: Calculate standard deviation, variance, and average among an array of numbers. function isArray(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; }; function getNumWithSetDec(num, numOfDec) { var pow10s = Math.pow(10, numOfDec || 0); return (numOfDec) ? Math.round(pow10s * num) / pow10s : num; }; function getAverageFromNumArr(numArr, numOfDec) { if (!isArray(numArr)) { return false; } var i = numArr.length, sum = 0; if (i) while (i--) { sum += numArr[i]; } return getNumWithSetDec((sum / numArr.length), numOfDec); }; function getVariance(numArr, numOfDec) { if (!isArray(numArr)) { return false; } var avg = getAverageFromNumArr(numArr, numOfDec), i = numArr.length, v = 0; if (i) while (i--) { v += Math.pow((numArr[i] - avg), 2); } v /= numArr.length; return getNumWithSetDec(v, numOfDec); }; function getStandardDeviation(numArr, numOfDec) { if (!isArray(numArr)) { return false; } var stdDev = Math.sqrt(getVariance(numArr, numOfDec)); return getNumWithSetDec(stdDev, numOfDec); }; function Array_max(array) { return Math.max.apply(Math, array); }; function Array_min(array) { return Math.min.apply(Math, array); }; // BENCHMARKING ENDS function colorize_boxes_like_in_svg() { var bg_color = $("#p").css("background-color"); bg_color = new RGBColor(bg_color); var fill_color, stroke_color, fill_opacity, stroke_opacity, box; for (var i = 1; i <= 3; i++) { fill_color = $("#p" + i).css("fill"); fill_color = new RGBColor(fill_color); fill_opacity = $("#p" + i).css("fill-opacity"); fill_color = fill_color.flattenRGBA(fill_opacity, bg_color); stroke_color = $("#p" + i).css("stroke"); stroke_color = new RGBColor(stroke_color); stroke_opacity = $("#p" + i).css("stroke-opacity"); stroke_color = stroke_color.flattenRGBA(stroke_opacity, bg_color); if (i == 1) box = "#subject_box"; else if (i == 2) box = "#clip_box"; else if (i == 3) box = "#solution_box"; $(box).css("background-color", fill_color); } } // The following class exists only for transferring color values from SVG to html table // It could be got without this, but wanted to try this. // May be I remove this and make precalculated values /** * A class to parse color values * @author Stoyan Stefanov <sstoo@gmail.com> * @link http://www.phpied.com/rgb-color-parser-in-javascript/ * @license Use it if you like it */ function RGBColor(color_string) { if (typeof (color_string) == "undefined") color_string = ""; this.ok = false; // strip any leading # if (color_string.charAt(0) == '#') { // remove # if any color_string = color_string.substr(1, 6); } color_string = color_string.replace(/ /g, ''); color_string = color_string.toLowerCase(); // before getting into regexps, try simple matches // and overwrite the input var simple_colors = { aliceblue: 'f0f8ff', antiquewhite: 'faebd7', aqua: '00ffff', aquamarine: '7fffd4', azure: 'f0ffff', beige: 'f5f5dc', bisque: 'ffe4c4', black: '000000', blanchedalmond: 'ffebcd', blue: '0000ff', blueviolet: '8a2be2', brown: 'a52a2a', burlywood: 'deb887', cadetblue: '5f9ea0', chartreuse: '7fff00', chocolate: 'd2691e', coral: 'ff7f50', cornflowerblue: '6495ed', cornsilk: 'fff8dc', crimson: 'dc143c', cyan: '00ffff', darkblue: '00008b', darkcyan: '008b8b', darkgoldenrod: 'b8860b', darkgray: 'a9a9a9', darkgreen: '006400', darkkhaki: 'bdb76b', darkmagenta: '8b008b', darkolivegreen: '556b2f', darkorange: 'ff8c00', darkorchid: '9932cc', darkred: '8b0000', darksalmon: 'e9967a', darkseagreen: '8fbc8f', darkslateblue: '483d8b', darkslategray: '2f4f4f', darkturquoise: '00ced1', darkviolet: '9400d3', deeppink: 'ff1493', deepskyblue: '00bfff', dimgray: '696969', dodgerblue: '1e90ff', feldspar: 'd19275', firebrick: 'b22222', floralwhite: 'fffaf0', forestgreen: '228b22', fuchsia: 'ff00ff', gainsboro: 'dcdcdc', ghostwhite: 'f8f8ff', gold: 'ffd700', goldenrod: 'daa520', gray: '808080', green: '008000', greenyellow: 'adff2f', honeydew: 'f0fff0', hotpink: 'ff69b4', indianred: 'cd5c5c', indigo: '4b0082', ivory: 'fffff0', khaki: 'f0e68c', lavender: 'e6e6fa', lavenderblush: 'fff0f5', lawngreen: '7cfc00', lemonchiffon: 'fffacd', lightblue: 'add8e6', lightcoral: 'f08080', lightcyan: 'e0ffff', lightgoldenrodyellow: 'fafad2', lightgrey: 'd3d3d3', lightgreen: '90ee90', lightpink: 'ffb6c1', lightsalmon: 'ffa07a', lightseagreen: '20b2aa', lightskyblue: '87cefa', lightslateblue: '8470ff', lightslategray: '778899', lightsteelblue: 'b0c4de', lightyellow: 'ffffe0', lime: '00ff00', limegreen: '32cd32', linen: 'faf0e6', magenta: 'ff00ff', maroon: '800000', mediumaquamarine: '66cdaa', mediumblue: '0000cd', mediumorchid: 'ba55d3', mediumpurple: '9370d8', mediumseagreen: '3cb371', mediumslateblue: '7b68ee', mediumspringgreen: '00fa9a', mediumturquoise: '48d1cc', mediumvioletred: 'c71585', midnightblue: '191970', mintcream: 'f5fffa', mistyrose: 'ffe4e1', moccasin: 'ffe4b5', navajowhite: 'ffdead', navy: '000080', oldlace: 'fdf5e6', olive: '808000', olivedrab: '6b8e23', orange: 'ffa500', orangered: 'ff4500', orchid: 'da70d6', palegoldenrod: 'eee8aa', palegreen: '98fb98', paleturquoise: 'afeeee', palevioletred: 'd87093', papayawhip: 'ffefd5', peachpuff: 'ffdab9', peru: 'cd853f', pink: 'ffc0cb', plum: 'dda0dd', powderblue: 'b0e0e6', purple: '800080', red: 'ff0000', rosybrown: 'bc8f8f', royalblue: '4169e1', saddlebrown: '8b4513', salmon: 'fa8072', sandybrown: 'f4a460', seagreen: '2e8b57', seashell: 'fff5ee', sienna: 'a0522d', silver: 'c0c0c0', skyblue: '87ceeb', slateblue: '6a5acd', slategray: '708090', snow: 'fffafa', springgreen: '00ff7f', steelblue: '4682b4', tan: 'd2b48c', teal: '008080', thistle: 'd8bfd8', tomato: 'ff6347', turquoise: '40e0d0', violet: 'ee82ee', violetred: 'd02090', wheat: 'f5deb3', white: 'ffffff', whitesmoke: 'f5f5f5', yellow: 'ffff00', yellowgreen: '9acd32' }; for (var key in simple_colors) { if (color_string == key) { color_string = simple_colors[key]; } } // emd of simple type-in colors // array of color definition objects var color_defs = [ { re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'], process: function (bits) { return [ parseInt(bits[1], 10), parseInt(bits[2], 10), parseInt(bits[3], 10) ]; } }, { re: /^(\w{2})(\w{2})(\w{2})$/, example: ['#00ff00', '336699'], process: function (bits) { return [ parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16) ]; } }, { re: /^(\w{1})(\w{1})(\w{1})$/, example: ['#fb0', 'f0f'], process: function (bits) { return [ parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16) ]; } }]; // search through the definitions to find a match for (var i = 0; i < color_defs.length; i++) { var re = color_defs[i].re; var processor = color_defs[i].process; var bits = re.exec(color_string); if (bits) { var channels = processor(bits); this.r = channels[0]; this.g = channels[1]; this.b = channels[2]; this.ok = true; } } // validate/cleanup values this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r); this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g); this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b); // some getters this.toRGB = function () { return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')'; }; this.toHex = function () { var r = this.r.toString(16); var g = this.g.toString(16); var b = this.b.toString(16); if (r.length == 1) r = '0' + r; if (g.length == 1) g = '0' + g; if (b.length == 1) b = '0' + b; return '#' + r + g + b; }; this.flattenRGBA = function (a, bg) { var alpha = 1 - parseFloat(a); this.r = Math.round((a * (this.r / 255) + (alpha * (bg.r / 255))) * 255); this.g = Math.round((a * (this.g / 255) + (alpha * (bg.g / 255))) * 255); this.b = Math.round((a * (this.b / 255) + (alpha * (bg.b / 255))) * 255); return this.toHex(); }; } /* // Not used, because using mouse and repeated events is better function offset_key(e) { if (e.which == 38) { make_offset(1); } else if (e.which == 40) { make_offset(-1); } e.stopPropagation(); e.preventDefault(); } */ function round_to(num, dec) { if (typeof (num) == "undefined" || typeof (dec) == "undefined" || isNaN(dec)) { alert("Cannot round other than number"); return false; } else return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); } function update_enlarged_SVG_if_needed() { if (update_enlarged_SVG) { show_svg_source_click("non_click"); svg_source_enlarge(); } else if (update_enlarged_SVG_source && !update_enlarged_SVG) { show_svg_source_click("non_click"); } } function to_printable(a) { return a.toFixed(3); } function get_polys(scale_again) { var polygon = parseInt($('input[type="radio"][name="polygons"]:checked').val(), 10); var polys; if (polygon === 0) { polys = get_gb_and_arrow(); ss = polys.ss; cc = polys.cc; } else if (polygon === 1) { polys = get_text_polys(); ss = polys.ss; cc = polys.cc; } else if (polygon == 2) { polys = get_rectangle_polys(); ss = polys.ss; cc = polys.cc; } else if (polygon == 3) { polys = get_ZigZag_polys(); ss = polys.ss; cc = polys.cc; } else if (polygon == 6) { polys = get_star_and_rect(); ss = polys.ss; cc = polys.cc; } else if (polygon == 7) { polys = get_spiral_and_rects(); ss = polys.ss; cc = polys.cc; } else if (polygon == 8) { polys = get_rounded_grid_and_star(); ss = polys.ss; cc = polys.cc; } else if (polygon == 9) { polys = get_glyph_and_grid(); ss = polys.ss; cc = polys.cc; } else if (polygon == 10) { polys = get_custom_poly(); ss = polys.ss; cc = polys.cc; } else if (polygon == 4 || polygon == 5) { if (!random_subj) random_subj = get_random_polys("subj"); if (!random_clip) random_clip = get_random_polys("clip"); if (scale_again) { random_subj = scale_again_random_poly(random_subj); random_clip = scale_again_random_poly(random_clip); ss = random_subj; cc = random_clip; rnd_sett.scale = scale; } else { ss = random_subj; cc = random_clip; } } else if (polygon == 11) { if (!random_grid_subj) random_grid_subj = get_random_grids("subj", rnd_grid_sett.random_grid_type); if (scale_again) { scale_again_random_grid_poly(random_grid_subj); ss = random_grid_subj; cc = []; rnd_grid_sett.scale = scale; } else { ss = random_grid_subj; cc = []; } } sss = [ [] ]; } // Main function which setups defaults // and attach events // and finally draw the default svg image function main() { // formats internal representation of polygons to // specified output format and prints them on input fields $("#output_format").change(function () { var selected_val = parseInt($(this).val(), 10); output_format = selected_val; if ($("#custom_polygons_fieldset").css("display") != "none") { var subj = $("#custom_polygon_subj").val(); var clip = $("#custom_polygon_clip").val(); subj = normalize_clipper_poly(subj, true); // quiet clip = normalize_clipper_poly(clip, true); // quiet if (subj !== false && clip !== false) { $("#custom_polygon_subj").val(format_output(subj)); $("#custom_polygon_clip").val(format_output(clip)); } } var polygon_explorer_string = $("#polygon_explorer_string_inp").val(); polygon_explorer_string = normalize_clipper_poly(polygon_explorer_string, true); // quiet if (polygon_explorer_string !== false) { $("#polygon_explorer_string_inp").val(format_output(polygon_explorer_string)); } }); $("#sample_custom_polygon").change(function () { var polygon = parseInt($(this).val(), 10); var polys; global_do_not_round_and_scale = true; var subj = "", clip = ""; if (polygon === "") { subj = ""; clip = ""; } else if (polygon === 0) { polys = get_gb_and_arrow(); subj = polys.ss; clip = polys.cc; } else if (polygon == 1) { polys = get_text_polys(); subj = polys.ss; clip = polys.cc; } else if (polygon == 2) { polys = get_rectangle_polys(); subj = polys.ss; clip = polys.cc; } else if (polygon == 3) { polys = get_ZigZag_polys(); subj = polys.ss; clip = polys.cc; } else if (polygon == 4 || polygon == 5) { subj = get_random_polys("subj", polygon); clip = get_random_polys("clip", polygon); } else if (polygon == 6) { polys = get_star_and_rect(); subj = polys.ss; clip = polys.cc; } else if (polygon == 7) { polys = get_spiral_and_rects(); subj = polys.ss; clip = polys.cc; } else if (polygon == 8) { polys = get_rounded_grid_and_star(); subj = polys.ss; clip = polys.cc; } else if (polygon == 9) { polys = get_glyph_and_grid(); subj = polys.ss; clip = polys.cc; } else if (polygon == 10) { polys = get_custom_poly(); subj = polys.ss; clip = polys.cc; } else if (polygon == 12) { polys = get_collinear_test(); subj = polys.ss; clip = polys.cc; } global_do_not_round_and_scale = false; if (subj != "") subj = JSON.stringify(subj); if (clip != "") clip = JSON.stringify(clip); $("#custom_polygon_subj").val(format_output(subj)); $("#custom_polygon_clip").val(format_output(clip)); }); $("#help_custom_polygon").click(function () { var txt = ""; txt += 'A) You can add your own custom polygons in several formats:\n\n'; txt += '1) The program uses as an inner default the following format: JSON-stringified array of arrays of point objects eg. [[{"X":100,"Y":100},{"X":200,"Y":100},{"X":200,"Y":200},{"X":100,"Y":200}],[{"X":110,"Y":110},{"X":210,"Y":110},{"X":210,"Y":210},{"X":110,"Y":210}]]. This format allows to input sub polygons. Each sub polygon is an array of point objects. This format makes it easy to transfer polygons to other programs that use Clipper library and is suitable for storing polygons in database.\n\n'; txt += '2) JSON-stringified array of point objects eg. [{"X":100,"Y":100},{"X":200,"Y":100},{"X":200,"Y":200},{"X":100,"Y":200}]. This format doesn\'t allow to input sub polygons.\n\n'; txt += '3) JSON-stringified array of arrays of coordinates without "X" and "Y" eg. [[100,100,200,100,200,200,100,200],[110,110,210,110,210,210,110,210]]. This format allows to input sub polygons. Each sub polygon is an array of coordinates so that each x coordinate is followed by an y coordinate. This format makes it easy to transfer polygons to other programs that use Clipper library and is suitable for storing polygons in database.\n\n'; txt += '4) JSON-stringified array of x and y coordinates eg. [100,100,200,100,200,200,100,200] or [100 100 200 100 200 200 100 200] or [100 100,200 100,200 200,100 200] or the same without []:s. This format doesn\'t allow to input sub polygons.\n\n'; txt += '5) SVG path strings with commands MLVHZ or mlvhz eg. M100,100 L200,100 L200,200 L100,200Z M110,110 L210,110 L210,210 L110,210Z. This format allows to input sub polygons. Each subpolygon starts with M (moveto) command.\n\n'; txt += '\n'; txt += 'B) Custom polygons are saved in browser\'s Local Storage, so they should be tolerant for page reload and browser crashes.\n'; txt += '\n'; alert(txt); }); $("#help_builtin_polygon_sets").click(function () { var txt = ''; txt += 'Builtin polygon sets\n\n'; txt += 'You can add builtin polygon sets into Subj and Clip input fields to edit copies of them.\n\n'; txt += 'Note! Before saving, nothing happens. After saving, the SVG window is also updated.'; alert(txt); }); $("#help_output_format").click(function () { var txt = ''; txt += 'Output format\n\n'; txt += 'To change the polygon coordinate output format please use the above dropdown. The available formats are:\n\n'; txt += '- Clipper: [[{"X":100,"Y":100},{"X":200,"Y":200}]]\n\n'; txt += '- Plain: [[100,100,200,200]]\n\n'; txt += '- SVG: M100,100L200,200Z\n\n'; txt += 'There are two places where this has effect: 1) the above text box 2) the Subj and Clip text boxes in Custom Polygon fieldset.'; alert(txt); }); $("#remove_custom_polygon").click(function () { var selected_value = $("#custom_polygons_select").val(); if (selected_value + "" === "0") { alert("Cannot remove the default polygon."); } else if (selected_value) { if (confirm("Remove custom polygon " + selected_value + "?")) { var arr = $.totalStorage('custom_polygons'); arr[selected_value] = null; $.totalStorage('custom_polygons', arr); update_custom_polygons_select(); } } else alert("Nothing removable."); }); $("#removeall_custom_polygon").click(function () { var count = $("#custom_polygons_select option").length; if (count > 1) { if (confirm("Remove all " + (count - 1) + " custom polygons?")) { $.totalStorage('custom_polygons', []); set_default_custom_polygon(); update_custom_polygons_select(); } } else alert("Nothing removable."); }); $("#save_custom_polygon").click(function (e) { var subj = $("#custom_polygon_subj").val(); var clip = $("#custom_polygon_clip").val(); subj = normalize_clipper_poly(subj); clip = normalize_clipper_poly(clip); if (subj === false || clip === false) return false; if (typeof ($.totalStorage('custom_polygons')) == "undefined" || $.totalStorage('custom_polygons') === null) { set_default_custom_polygon(); } var polygon_set = {}; polygon_set.subj = subj; polygon_set.clip = clip; var arr2 = $.totalStorage('custom_polygons'); var selected_value = $("#custom_polygons_select").val(); if (selected_value + "" !== "0" && selected_value) { arr2[selected_value] = polygon_set; $.totalStorage('custom_polygons', arr2); update_custom_polygons_select(); show_alert(e, this, "Polygon " + (selected_value) + " updated!"); } else if (selected_value + "" === "0") { alert("The default custom polygon cannot be overwrited. If you want to modify it, save it first as a new."); } else alert("Polygon update failed!"); }); $("#add_as_new_custom_polygon").click(function (e) { var subj = $("#custom_polygon_subj").val(); var clip = $("#custom_polygon_clip").val(); subj = normalize_clipper_poly(subj); clip = normalize_clipper_poly(clip); if (subj === false || clip === false) return false; if (typeof ($.totalStorage('custom_polygons')) == "undefined" || $.totalStorage('custom_polygons') === null) { set_default_custom_polygon(); } var polygon_set = {}; polygon_set.subj = subj; polygon_set.clip = clip; var arr2 = $.totalStorage('custom_polygons'); arr2.push(polygon_set); $.totalStorage('custom_polygons', arr2); update_custom_polygons_select(); $('#custom_polygons_select').val(arr2.length - 1).change(); show_alert(e, this, "New polygon " + (arr2.length - 1) + " added!"); }); $("#custom_polygons_select").change(function () { var selected_value = $("#custom_polygons_select").val(); if (!selected_value && selected_value + "" !== "0") selected_value = 0; var arr = $.totalStorage('custom_polygons'); if (isArray(arr) && arr.length && typeof (arr[selected_value]) != "undefined") { $("#custom_polygon_subj").val(format_output(arr[selected_value].subj)); $("#custom_polygon_clip").val(format_output(arr[selected_value].clip)); make_clip(); } }); $("input[type='radio'][name='polygons']").change(function (e) { if (!benchmark_running) clipType = clipType_default; $('input[type="radio"][name="clipType"][value="' + clipType + '"]').attr('checked', 'checked'); var val = parseInt($(this).val(), 10); selected_polygon_set = val; if (val == 10) { $("#random_polygons_fieldset").css("display", "none"); $("#random_grids_fieldset").css("display", "none"); $("#custom_polygons_fieldset").css("display", "block"); set_default_custom_polygon(); update_custom_polygons_select(); update_fieldset_heights(); $("#custom_polygons_select").change(); if (!benchmark_running) make_clip(); return; } else $("#custom_polygons_fieldset").css("display", "none"); if (val == 11) { clipType = 1; $('input[type="radio"][name="clipType"][value="' + clipType + '"]').attr('checked', 'checked'); $("#random_polygons_fieldset").css("display", "none"); $("#custom_polygons_fieldset").css("display", "none"); $("#random_grids_fieldset").css("display", "block"); if (!benchmark_running) { random_grid_subj = get_random_grids("subj", rnd_grid_sett.random_grid_type); scale_again_random_grid_poly(random_grid_subj); } update_fieldset_heights(); if (!benchmark_running) make_clip(); return; } else { $("#custom_polygons_fieldset").css("display", "none"); $("#random_grids_fieldset").css("display", "none"); } if (val == 3) { clipType = 1; $('input[type="radio"][name="clipType"][value="' + clipType + '"]').attr('checked', 'checked'); } else if (val == 4 || val == 5) { $("#random_polygons_fieldset").css("display", "block"); if (val == 4) rnd_sett_defaults.current = "rect"; else rnd_sett_defaults.current = "norm"; // Test for ranges if (rnd_sett.clip_point_count < rnd_sett_defaults[rnd_sett_defaults.current].min.clip_point_count) rnd_sett.clip_point_count = rnd_sett_defaults[rnd_sett_defaults.current].min.clip_point_count; if (rnd_sett.clip_point_count > rnd_sett_defaults[rnd_sett_defaults.current].max.clip_point_count) rnd_sett.clip_point_count = rnd_sett_defaults[rnd_sett_defaults.current].max.clip_point_count; $('#clip_point_count').val(rnd_sett.clip_point_count); if (rnd_sett.clip_polygon_count < rnd_sett_defaults[rnd_sett_defaults.current].min.clip_polygon_count) rnd_sett.clip_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].min.clip_polygon_count; if (rnd_sett.clip_polygon_count > rnd_sett_defaults[rnd_sett_defaults.current].max.clip_polygon_count) rnd_sett.clip_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].max.clip_polygon_count; $('#clip_polygon_count').val(rnd_sett.clip_polygon_count); if (rnd_sett.subj_point_count < rnd_sett_defaults[rnd_sett_defaults.current].min.subj_point_count) rnd_sett.subj_point_count = rnd_sett_defaults[rnd_sett_defaults.current].min.subj_point_count; if (rnd_sett.subj_point_count > rnd_sett_defaults[rnd_sett_defaults.current].max.subj_point_count) rnd_sett.subj_point_count = rnd_sett_defaults[rnd_sett_defaults.current].max.subj_point_count; $('#subj_point_count').val(rnd_sett.subj_point_count); if (rnd_sett.subj_polygon_count < rnd_sett_defaults[rnd_sett_defaults.current].min.subj_polygon_count) rnd_sett.subj_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].min.subj_polygon_count; if (rnd_sett.subj_polygon_count > rnd_sett_defaults[rnd_sett_defaults.current].max.subj_polygon_count) rnd_sett.subj_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].max.subj_polygon_count; $('#subj_polygon_count').val(rnd_sett.subj_polygon_count); if (!benchmark_running) { random_subj = get_random_polys("subj", val); random_clip = get_random_polys("clip", val); } } else $("#random_polygons_fieldset").css("display", "none"); if (!benchmark_running) make_clip(); update_fieldset_heights(); }); $('#generate_random_polygons').hold(function (e) { random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $("input[name='clipType']").change(function () { if (benchmark_running) { console.log(benchmark_running); return; } if ($('input[type="radio"][name="clipType"][value=""]').is(":checked")) { $('input[type="radio"][name="offsettable_poly"][value="1"]').attr('checked', 'checked'); offsettable_poly = 1; } else { $("#offsettable_poly3").attr('checked', 'checked'); offsettable_poly = 3; } clipType = $('input[type="radio"][name="clipType"]:checked').val(); if (clipType !== "") clipType = parseInt(clipType, 10); make_clip(); }); $("input[name='subject_fillType']").change(function () { subject_fillType = parseInt(this.value, 10); make_clip(); }); $("input[name='clip_fillType']").change(function () { clip_fillType = parseInt(this.value, 10); make_clip(); }); $("input[name='offsettable_poly']").change(function () { if (benchmark_running) { console.log(benchmark_running); return; } offsettable_poly = parseInt(this.value, 10); // When offsettable poly is set to Subject or Clip, then boolean operations are not done. // To show this to user, set clipType to "No" if (offsettable_poly == 1 || offsettable_poly == 2) { $('input[type="radio"][name="clipType"][value=""]').attr('checked', 'checked'); clipType = ""; } make_clip(); }); $('#scale_minus').hold(function () { var scale_orig = $('#scale').val(); if (scale_orig && !isNaN(scale_orig) && parseInt(scale_orig, 10).toString() !== "0") scale = parseFloat(scale_orig); scale = scale - scale_addition; scale = Math.round(scale / scale_addition) * scale_addition; if (scale <= 0) scale = 1.0; $('#scale').val(to_printable(scale)); $('#scale').trigger('change'); }, { duration: 300, speed: 0, min: 150 }); $('#scale').change(function () { if (this.value && !isNaN(this.value) && parseInt(this.value, 10).toString() !== "0") { scale = parseFloat(this.value); get_polys(true); sss = cc; make_clip(); } else alert("Scale has to be a number"); }); $('#scale_plus').hold(function () { var scale_orig = $('#scale').val(); if (scale_orig && !isNaN(scale_orig) && parseInt(scale_orig, 10).toString() !== "0") scale = parseFloat(scale_orig); scale = scale + scale_addition; scale = Math.round(scale / scale_addition) * scale_addition; $('#scale').val(to_printable(scale)); $('#scale').trigger('change'); }, { duration: 300, speed: 0, min: 150 }); $('#delta_minus').hold(function () { var delta_orig = $('#delta').val(); if (!isNaN(delta_orig)) delta = parseFloat(delta_orig); delta = delta - 1; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#delta').change(function (e) { var delta_orig = $('#delta').val(); if (!isNaN(delta_orig)) delta = parseFloat(delta_orig); make_clip(); }); $('#delta_plus').hold(function () { var delta_orig = $('#delta').val(); if (!isNaN(delta_orig)) delta = parseFloat(delta_orig); delta = delta + 1; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $("input[name='joinType']").change(function () { joinType = parseInt(this.value, 10); //make_offset(); make_clip(); }); $("input[name='endType']").change(function () { endType = parseInt(this.value, 10); //make_offset(); make_clip(); }); $('#miterLimit_minus').hold(function () { var miterLimit_orig = $('#miterLimit').val(); if (!isNaN(miterLimit_orig)) miterLimit = parseFloat(miterLimit_orig); miterLimit = miterLimit - 0.1; if (miterLimit < 1.0) miterLimit = 1.0; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $("#miterLimit").change(function () { miterLimit = parseFloat(this.value); make_clip(); }); $('#miterLimit_plus').hold(function () { var miterLimit_orig = $('#miterLimit').val(); if (!isNaN(miterLimit_orig)) miterLimit = parseFloat(miterLimit_orig); miterLimit = miterLimit + 0.1; if (miterLimit < 1.0) miterLimit = 1.0; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#arcTolerance_minus').hold(function () { var arcTolerance_orig = $('#arcTolerance').val(); if (!isNaN(arcTolerance_orig)) arcTolerance = parseFloat(arcTolerance_orig); arcTolerance = arcTolerance - 0.1; if (arcTolerance < 0.001) arcTolerance = 0.001; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $("#arcTolerance").change(function () { arcTolerance = parseFloat(this.value); if (arcTolerance < 0.001) arcTolerance = 0.001; make_clip(); }); $('#arcTolerance_plus').hold(function () { var arcTolerance_orig = $('#arcTolerance').val(); if (!isNaN(arcTolerance_orig)) arcTolerance = parseFloat(arcTolerance_orig); arcTolerance = arcTolerance + 0.1; if (arcTolerance < 0.001) arcTolerance = 0.001; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $("#cleandelta").change(function () { var cleandelta_orig = $(this).val(); var this_value = parseFloat(this.value); if (!isNaN(this_value)) cleandelta = this_value; //else cleandelta = cleandelta_orig; make_clip(); }); $("#lighten_distance").change(function () { var lighten_distance_orig = $(this).val(); var this_value = parseFloat(this.value); if (!isNaN(this_value)) lighten_distance = this_value; //else lighten_distance = lighten_distance_orig; make_clip(); }); $("#AutoFix").change(function () { if ($(this).attr('checked')) AutoFix = true; else AutoFix = false; make_clip(); }); $("#ExPolygons").change(function () { if ($(this).attr('checked')) ExPolygons = true; else ExPolygons = false; if (SolutionPolygonClicked) $("#polygon_explorer_string_inp").val(format_output(SolutionPolygonString, "ExPolygons")); //make_clip(); }); $("#Simplify").change(function () { if ($(this).attr('checked')) Simplify = true; else Simplify = false; make_clip(); }); $("#clean").change(function () { if ($(this).attr('checked')) { if ($("#cleandelta").val() + "".trim() == "") { cleandelta = cleandelta_default; $("#cleandelta").val(cleandelta); } clean = true; } else { clean = false; } make_clip(); }); $("#lighten").change(function () { if ($(this).attr('checked')) lighten = true; else lighten = false; make_clip(); }); $("#lighten").change(function () { if ($(this).attr('checked')) { if ($("#lighten_distance").val() + "".trim() == "") { lighten_distance = lighten_distance_default; $("#lighten_distance").val(lighten_distance); } lighten = true; } else { lighten = false; } make_clip(); }); $("#PreserveCollinear").change(function () { if ($(this).attr('checked')) PreserveCollinear = true; else PreserveCollinear = false; make_clip(); }); $("#ReverseSolution").change(function () { if ($(this).attr('checked')) ReverseSolution = true; else ReverseSolution = false; make_clip(); }); $("#StrictlySimple").change(function () { if ($(this).attr('checked')) StrictlySimple = true; else StrictlySimple = false; make_clip(); }); $("#off_poly_closed").change(function () { if ($(this).attr('checked')) off_poly_closed = true; else off_poly_closed = false; make_clip(); }); $('#subj_polygon_count_minus').hold(function () { var subj_polygon_count_orig = $('#subj_polygon_count').val(); if (!isNaN(subj_polygon_count_orig)) rnd_sett.subj_polygon_count = parseFloat(subj_polygon_count_orig); rnd_sett.subj_polygon_count = rnd_sett.subj_polygon_count - 1; if (rnd_sett.subj_polygon_count < rnd_sett_defaults[rnd_sett_defaults.current].min.subj_polygon_count) rnd_sett.subj_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].min.subj_polygon_count; $('#subj_polygon_count').val(rnd_sett.subj_polygon_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#subj_polygon_count').change(function (e) { var subj_polygon_count_orig = $('#subj_polygon_count').val(); if (!isNaN(subj_polygon_count_orig)) rnd_sett.subj_polygon_count = parseFloat(subj_polygon_count_orig); if (rnd_sett.subj_polygon_count < rnd_sett_defaults[rnd_sett_defaults.current].min.subj_polygon_count) rnd_sett.subj_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].min.subj_polygon_count; if (rnd_sett.subj_polygon_count > rnd_sett_defaults[rnd_sett_defaults.current].max.subj_polygon_count) rnd_sett.subj_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].max.subj_polygon_count; $('#subj_polygon_count').val(rnd_sett.subj_polygon_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }); $('#subj_polygon_count_plus').hold(function () { var subj_polygon_count_orig = $('#subj_polygon_count').val(); if (!isNaN(subj_polygon_count_orig)) rnd_sett.subj_polygon_count = parseFloat(subj_polygon_count_orig); rnd_sett.subj_polygon_count = rnd_sett.subj_polygon_count + 1; if (rnd_sett.subj_polygon_count > rnd_sett_defaults[rnd_sett_defaults.current].max.subj_polygon_count) rnd_sett.subj_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].max.subj_polygon_count; $('#subj_polygon_count').val(rnd_sett.subj_polygon_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#subj_point_count_minus').hold(function () { var subj_point_count_orig = $('#subj_point_count').val(); if (!isNaN(subj_point_count_orig)) rnd_sett.subj_point_count = parseFloat(subj_point_count_orig); rnd_sett.subj_point_count = rnd_sett.subj_point_count - 1; if (rnd_sett.subj_point_count < rnd_sett_defaults[rnd_sett_defaults.current].min.subj_point_count) rnd_sett.subj_point_count = rnd_sett_defaults[rnd_sett_defaults.current].min.subj_point_count; $('#subj_point_count').val(rnd_sett.subj_point_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#subj_point_count').change(function (e) { var subj_point_count_orig = $('#subj_point_count').val(); if (!isNaN(subj_point_count_orig)) rnd_sett.subj_point_count = parseFloat(subj_point_count_orig); if (rnd_sett.subj_point_count < rnd_sett_defaults[rnd_sett_defaults.current].min.subj_point_count) rnd_sett.subj_point_count = rnd_sett_defaults[rnd_sett_defaults.current].min.subj_point_count; if (rnd_sett.subj_point_count > rnd_sett_defaults[rnd_sett_defaults.current].max.subj_point_count) rnd_sett.subj_point_count = rnd_sett_defaults[rnd_sett_defaults.current].max.subj_point_count; $('#subj_point_count').val(rnd_sett.subj_point_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }); $('#subj_point_count_plus').hold(function () { var subj_point_count_orig = $('#subj_point_count').val(); if (!isNaN(subj_point_count_orig)) rnd_sett.subj_point_count = parseFloat(subj_point_count_orig); rnd_sett.subj_point_count = rnd_sett.subj_point_count + 1; if (rnd_sett.subj_point_count > rnd_sett_defaults[rnd_sett_defaults.current].max.subj_point_count) rnd_sett.subj_point_count = rnd_sett_defaults[rnd_sett_defaults.current].max.subj_point_count; $('#subj_point_count').val(rnd_sett.subj_point_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#clip_polygon_count_minus').hold(function () { var clip_polygon_count_orig = $('#clip_polygon_count').val(); if (!isNaN(clip_polygon_count_orig)) rnd_sett.clip_polygon_count = parseFloat(clip_polygon_count_orig); rnd_sett.clip_polygon_count = rnd_sett.clip_polygon_count - 1; if (rnd_sett.clip_polygon_count < rnd_sett_defaults[rnd_sett_defaults.current].min.clip_polygon_count) rnd_sett.clip_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].min.clip_polygon_count; $('#clip_polygon_count').val(rnd_sett.clip_polygon_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#clip_polygon_count').change(function (e) { var clip_polygon_count_orig = $('#clip_polygon_count').val(); if (!isNaN(clip_polygon_count_orig)) rnd_sett.clip_polygon_count = parseFloat(clip_polygon_count_orig); if (rnd_sett.clip_polygon_count < rnd_sett_defaults[rnd_sett_defaults.current].min.clip_polygon_count) rnd_sett.clip_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].min.clip_polygon_count; if (rnd_sett.clip_polygon_count > rnd_sett_defaults[rnd_sett_defaults.current].max.clip_polygon_count) rnd_sett.clip_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].max.clip_polygon_count; $('#clip_polygon_count').val(rnd_sett.clip_polygon_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }); $('#clip_polygon_count_plus').hold(function () { var clip_polygon_count_orig = $('#clip_polygon_count').val(); if (!isNaN(clip_polygon_count_orig)) rnd_sett.clip_polygon_count = parseFloat(clip_polygon_count_orig); rnd_sett.clip_polygon_count = rnd_sett.clip_polygon_count + 1; if (rnd_sett.clip_polygon_count > rnd_sett_defaults[rnd_sett_defaults.current].max.clip_polygon_count) rnd_sett.clip_polygon_count = rnd_sett_defaults[rnd_sett_defaults.current].max.clip_polygon_count; $('#clip_polygon_count').val(rnd_sett.clip_polygon_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#clip_point_count_minus').hold(function () { var clip_point_count_orig = $('#clip_point_count').val(); if (!isNaN(clip_point_count_orig)) rnd_sett.clip_point_count = parseFloat(clip_point_count_orig); rnd_sett.clip_point_count = rnd_sett.clip_point_count - 1; if (rnd_sett.clip_point_count < rnd_sett_defaults[rnd_sett_defaults.current].min.clip_point_count) rnd_sett.clip_point_count = rnd_sett_defaults[rnd_sett_defaults.current].min.clip_point_count; $('#clip_point_count').val(rnd_sett.clip_point_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#clip_point_count').change(function (e) { var clip_point_count_orig = $('#clip_point_count').val(); if (!isNaN(clip_point_count_orig)) rnd_sett.clip_point_count = parseFloat(clip_point_count_orig); if (rnd_sett.clip_point_count < rnd_sett_defaults[rnd_sett_defaults.current].min.clip_point_count) rnd_sett.clip_point_count = rnd_sett_defaults[rnd_sett_defaults.current].min.clip_point_count; if (rnd_sett.clip_point_count > rnd_sett_defaults[rnd_sett_defaults.current].max.clip_point_count) rnd_sett.clip_point_count = rnd_sett_defaults[rnd_sett_defaults.current].max.clip_point_count; $('#clip_point_count').val(rnd_sett.clip_point_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }); $('#clip_point_count_plus').hold(function () { var clip_point_count_orig = $('#clip_point_count').val(); if (!isNaN(clip_point_count_orig)) rnd_sett.clip_point_count = parseFloat(clip_point_count_orig); rnd_sett.clip_point_count = rnd_sett.clip_point_count + 1; if (rnd_sett.clip_point_count > rnd_sett_defaults[rnd_sett_defaults.current].max.clip_point_count) rnd_sett.clip_point_count = rnd_sett_defaults[rnd_sett_defaults.current].max.clip_point_count; $('#clip_point_count').val(rnd_sett.clip_point_count); random_subj = get_random_polys("subj"); random_clip = get_random_polys("clip"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); /* random_grid_type_minus random_grid_type random_grid_type_plus random_grid_size_minus random_grid_size random_grid_size_plus var rnd_grid_sett = { random_grid_type: 1, random_grid_size: 32 }; */ // ------------------------------------------- // eyup $('#generate_random_grids').hold(function (e) { random_grid_subj = get_random_grids("subj", rnd_grid_sett.random_grid_type); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#random_grid_type_minus').hold(function () { var random_grid_type_orig = $('#random_grid_type').val(); rnd_grid_sett.random_grid_type--; if (rnd_grid_sett.random_grid_type < 1) rnd_grid_sett.random_grid_type = 3; $('#random_grid_type').val(rnd_grid_sett.random_grid_type); random_grid_subj = get_random_grids("subj", rnd_grid_sett.random_grid_type); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#random_grid_type').change(function (e) { var random_grid_type_orig = parseInt($('#random_grid_type').val(), 10); if (rnd_grid_sett.random_grid_type > 3) rnd_grid_sett.random_grid_type = 3; if (rnd_grid_sett.random_grid_type < 1) rnd_grid_sett.random_grid_type = 1; if (!isNaN(rnd_grid_sett.random_grid_type)) rnd_grid_sett.random_grid_type = parseFloat(rnd_grid_sett.random_grid_type); //$('#random_grid_type').val(rnd_grid_sett.random_grid_type); random_grid_subj = get_random_grids("subj", rnd_grid_sett.random_grid_type); make_clip(); }); $('#random_grid_type_plus').hold(function () { var random_grid_type_orig = $('#random_grid_type').val(); rnd_grid_sett.random_grid_type++; if (rnd_grid_sett.random_grid_type > 3) rnd_grid_sett.random_grid_type = 1; $('#random_grid_type').val(rnd_grid_sett.random_grid_type); random_grid_subj = get_random_grids("subj", rnd_grid_sett.random_grid_type); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#transform_rotation_minus').hold(function () { var transform_rotation_orig = parseInt($('#transform_rotation').val(), 10); transform.rotation = transform.rotation - 1; if (transform.rotation < -360) transform.rotation = 360; $('#transform_rotation').val(transform.rotation); transform.distort = null; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#transform_rotation').change(function (e) { var transform_rotation_orig = $('#transform_rotation').val(); if (!isNaN(transform.rotation)) transform.rotation = parseFloat(transform_rotation_orig); if (transform.rotation < -360) transform.rotation = -360; if (transform.rotation > 360) transform.rotation = 360; $('#transform_rotation').val(transform.rotation); transform.distort = null; make_clip(); }); $('#transform_rotation_plus').hold(function () { var transform_rotation_orig = parseInt($('#transform_rotation').val(), 10); transform.rotation = transform.rotation + 1; if (transform.rotation > 360) transform.rotation = -360; $('#transform_rotation').val(transform.rotation); transform.distort = null; make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#transform_distort').hold(function (e) { transform.distort = "generate_new"; transform.rotation = 0; transform.distort_destination = null; $("#transform_rotation").val("0"); make_clip(); }, { duration: 300, speed: 0, min: 150 }); $('#transform_distort_sample1').click(function (e) { transform.distort = "generate_new"; transform.distort_destination = transform.destination1; transform.rotation = 0; $("#transform_rotation").val("0"); make_clip(); }); $('#transform_distort_sample2').click(function (e) { transform.distort = "generate_new"; transform.distort_destination = transform.destination2; transform.rotation = 0; $("#transform_rotation").val("0"); make_clip(); }); $('#transform_reset').click(function (e) { transform.distort = null; transform.rotation = 0; $('#transform_rotation').val(transform.rotation); make_clip(); }); // ------------------------------------------- $("#bevel").change(function () { if ($(this).attr('checked')) { bevel = true; $("#p3").attr("filter", "url(#innerbewel)"); } else { bevel = false; $("#p3").removeAttr("filter"); } update_enlarged_SVG_if_needed(); }); function show_svg_source_click_2() { show_svg_source_click(); svg_source_enlarge(); } $("#show_svg_source").click(show_svg_source_click_2); $('#sub_poly_links_update').change(function () { if ($(this).is(':checked')) { sub_poly_links_update = 1; if (!p) p = SVG.create(); if (p1) p1.remove(); if (p2) p2.remove(); if (p3) p3.remove(); SVG.addpaths(ss, cc, off_result, subject_fillType, clip_fillType); } else { sub_poly_links_update = 0; $("#subj_subpolygons, #subj_points_in_subpolygons, #subj_points_total, #clip_subpolygons, #clip_points_in_subpolygons, #clip_points_total, #solution_subpolygons, #solution_points_in_subpolygons, #solution_points_total, #points_total, #all_subpolygons, #area").html(""); } }); $("#output_format").val(output_format); myresize(); $("document").mousedown(function () { ismousedown = true; }); $("document").mouseup(function () { ismousedown = false; }); $("#benchmark1,#benchmark1b,#benchmark2,#benchmark2b,#benchmark3").click(function () { clicked_benchmark_button_id = $(this).attr("id"); if (benchmark_running && !benchmark_automatic_click) { for (var lsk = 0; lsk < bench_glob.length; lsk++) { clearTimeout(bench_glob[lsk].setTimeout); } bench_glob.length = 0; repeat = 0; benchmark_running = 0; ClipperLib.MaxSteps = ClipperLib_MaxSteps_original; $("#" + clicked_benchmark_button_id).html($("#" + clicked_benchmark_button_id).html().replace("Stop", "Run")); $("#" + clicked_benchmark_button_id).attr("title", $("#" + clicked_benchmark_button_id).attr("title").replace("Stop", "Execute")); $("button,input,select").removeAttr('disabled'); $('#sub_poly_links_update').trigger("change"); return; } else { // disable buttons that are not allowed to click when running $("button,input,select").attr('disabled', 'disabled'); $("#benchmark1,#benchmark1b,#benchmark2,#benchmark2b,#benchmark3").each(function () { var $this = $(this); if ($this.attr("id") != clicked_benchmark_button_id) $this.attr('disabled', 'disabled'); else $this.removeAttr('disabled'); }); $('.transforms_table button, .transforms_table input, .transforms_table select').removeAttr('disabled'); } benchmark_automatic_click = 0; benchmark_running = 1; ClipperLib.MaxSteps = 10; $("#" + clicked_benchmark_button_id).html($("#" + clicked_benchmark_button_id).html().replace("Run", "Stop")); $("#" + clicked_benchmark_button_id).attr("title", $("#" + clicked_benchmark_button_id).attr("title").replace("Execute", "Stop")); bench.clear(); bench.includeSVG = false; var scaleLocal; var simplifyLocal; var polygon_id; var deltaLocal, clipTypeLocal, offsettable_polyLocal_start, offsettable_polyLocal_end; var offsettable_polyLocal, joinTypeLocal, endTypeLocal, miterLimitLocal, miterLimitLocal_start, miterLimitLocal_end; var arcTolerancesLocal, arcToleranceLocal, arcToleranceLocal_start, arcToleranceLocal_end; var fillTypeLocal, fillTypeLocal_start, fillTypeLocal_end; var endTypeLocal_start = 0, endTypeLocal_end = 4; var timeout_time = 0; window.last_completed_bench = ""; bench_glob.length = 0; timeout_time = 0; window.last_completed_bench = ""; var count; var deltaLocals = [-5, 5, 0]; var deltaLocal_i, m; var this_id = $(this).attr("id"); var polygon_ids; if (this_id === "benchmark3") polygon_ids = ["11_1", "11_2", "11_3", 4, 5]; else polygon_ids = [0, 1, 2, 3, /*4, 5, "11_1", "11_2", "11_3",*/ 6, 7, 8, 9, 10]; //polygon_ids = ["11_1","11_2", "11_3"]; //polygon_ids = [4,5]; //polygon_ids = [9,10]; var arcTolerances = [0.05, 0.25, 2]; //arcTolerances = [0.05,0.06,0.07,0.08,0.09,0.1,0.11,0.12,0.25,2]; var arcTolerances_default = [0.25]; var pid; var aid; var rnd_sett_local; var ExPolygons_local; var Simplify_local = simplifyLocal; var PreserveCollinear_local; var ReverseSolution_local; var StrictlySimple_local; var off_poly_closed_local; var clean_local; var cleandelta_local; var lighten_local; var lighten_distance_local; if (this_id == "benchmark1b" || this_id == "benchmark2b") repeat_times = 5; else repeat_times = 1; if (this_id === 'benchmark3') repeat_times = 400; for (count = 0; count < 2; count++) { if (this_id == "benchmark1" || this_id == "benchmark1b") { if (is_float_clipper) scaleLocal = 1; else scaleLocal = 100; if (count === 1) continue; } else if (this_id == "benchmark2" || this_id == "benchmark2b") { if (is_float_clipper) scaleLocal = 1; else scaleLocal = 100000000; if (count === 1) continue; } else if (this_id == "benchmark3") { if (is_float_clipper) { $('#scale').val(1); scale = 1; scaleLocal = 1; } else scaleLocal = 100; if (count === 1) continue; } //for (polygon_id = 4; polygon_id < 6; polygon_id++) { for (pid = 0; pid < polygon_ids.length; pid++) { polygon_id = polygon_ids[pid]; //if (!(polygon_id == 0 || polygon_id == 1 || polygon_id == 7 || polygon_id == 8 || polygon_id == 9)) continue; if (polygon_id == 4 || polygon_id == 5) { fillTypeLocal_start = 0; fillTypeLocal_end = 1; } else { fillTypeLocal_start = 1; fillTypeLocal_end = 1 } for (fillTypeLocal = fillTypeLocal_start; fillTypeLocal < fillTypeLocal_end + 1; fillTypeLocal++) { for (clipTypeLocal = 0; clipTypeLocal < 5; clipTypeLocal++) { if (clipTypeLocal === 0) { offsettable_polyLocal_start = 1; offsettable_polyLocal_end = 2; } else { offsettable_polyLocal_start = 3; offsettable_polyLocal_end = 3; } for (offsettable_polyLocal = offsettable_polyLocal_start; offsettable_polyLocal < offsettable_polyLocal_end + 1; offsettable_polyLocal++) { //if (polygon_id === 0 && offsettable_polyLocal == 2) continue; for (endTypeLocal = endTypeLocal_start; endTypeLocal < endTypeLocal_end + 1; endTypeLocal += 1) { for (joinTypeLocal = 0; joinTypeLocal < 3; joinTypeLocal++) { for (deltaLocal_i = 0, m = deltaLocals.length; deltaLocal_i < m; deltaLocal_i++) { deltaLocal = deltaLocals[deltaLocal_i]; if (deltaLocal && offsettable_polyLocal !== 3) { simplifyLocal = true; } else simplifyLocal = false; if (joinTypeLocal == 2 && deltaLocal !== 0) { miterLimitLocal_start = 1; miterLimitLocal_end = 6; arcTolerancesLocal = arcTolerances_default; } else { if (joinTypeLocal === 1 && deltaLocal !== 0) { arcTolerancesLocal = arcTolerances; } else if (this_id == "benchmark2" || this_id == "benchmark2b") { // big integers miterLimitLocal_start = 2; miterLimitLocal_end = 2; arcTolerancesLocal = arcTolerances_default; } else { // normal miterLimitLocal_start = 2; miterLimitLocal_end = 2; arcTolerancesLocal = arcTolerances_default; } } for (aid = 0; aid < arcTolerancesLocal.length; aid++) { arcToleranceLocal = arcTolerancesLocal[aid]; for (miterLimitLocal = miterLimitLocal_start; miterLimitLocal < miterLimitLocal_end + 1; miterLimitLocal += 2) { if (this_id === 'benchmark3') rnd_sett_local = { clip_polygon_count: rnd('int', 1, 4), clip_point_count: rnd('int', 1, 15), subj_polygon_count: rnd('int', 1, 4), subj_point_count: rnd('int', 1, 15) }; else rnd_sett_local = { clip_polygon_count: 4, clip_point_count: 8, subj_polygon_count: 4, subj_point_count: 8 }; if (this_id === 'benchmark3') { ExPolygons_local = +rnd('int', 0, 1); Simplify_local = +rnd('int', 0, 1); PreserveCollinear_local = +rnd('int', 0, 1); ReverseSolution_local = +rnd('int', 0, 1); StrictlySimple_local = +rnd('int', 0, 1); off_poly_closed_local = +rnd('int', 0, 1); clean_local = +rnd('int', 0, 1); cleandelta_local = +rnd('float', 0, 2); lighten_local = +rnd('int', 0, 2); lighten_distance_local = +rnd('float', 0, 2); deltaLocal = +rnd('float', -100, 100); miterLimitLocal = +rnd('float', 0, 100); arcToleranceLocal = +rnd('float', 0.01, 10); } else { ExPolygons_local = false; Simplify_local = simplifyLocal; PreserveCollinear_local = false; ReverseSolution_local = false; StrictlySimple_local = false; off_poly_closed_local = true; clean_local = false; cleandelta_local = 0.1; lighten_local = false; lighten_distance_local = 0.1; } bench_glob[bench_glob.length] = { //clicked_benchmark_button_id: this_id, polygon_id: polygon_id, joinType: joinTypeLocal, // 0,1 endType: endTypeLocal, // 0,1 offsettable_poly: offsettable_polyLocal, // 1,2,3 delta: deltaLocal, // -10 - 10 miterLimit: miterLimitLocal, // 1 - 5 arcTolerance: arcToleranceLocal, // 0.25 AutoFix: true, // false, true ExPolygons: ExPolygons_local, // false, true Simplify: Simplify_local, // false, true PreserveCollinear: PreserveCollinear_local, // false, true ReverseSolution: ReverseSolution_local, // false, true StrictlySimple: StrictlySimple_local, // false, true off_poly_closed: off_poly_closed_local, // false, true subject_fillType: fillTypeLocal, // 0,1 clip_fillType: fillTypeLocal, //0, 1 clipType: (clipTypeLocal === 0) ? "" : clipTypeLocal - 1, // "",0,1,2,3 scale: scaleLocal, // 100, 100 000, 1000 000 000 rnd_sett: rnd_sett_local, clean: clean_local, cleandelta: cleandelta_local, lighten: lighten_local, lighten_distance: lighten_distance_local }; timeout_time += timeout_time_addition; bench_glob[bench_glob.length - 1].setTimeout = setTimeout("benchmark3(" + (bench_glob.length - 1) + ")", timeout_time); bench_glob[bench_glob.length - 1].timeout_time = timeout_time; } } } } } } } } } } //setTimeout(function(){console.log(bench_glob);},1000); }); $('#scale').val(to_printable(scale)); $('#delta').val(to_printable(delta)); $('#miterLimit').val(to_printable(miterLimit)); $('#arcTolerance').val(to_printable(arcTolerance)); if (AutoFix) $('#AutoFix').attr('checked', 'checked'); else $('#AutoFix').removeAttr('checked'); if (ExPolygons) $('#ExPolygons').attr('checked', 'checked'); else $('#ExPolygons').removeAttr('checked'); if (Simplify) $('#Simplify').attr('checked', 'checked'); else $('#Simplify').removeAttr('checked'); if (clean) $('#clean').attr('checked', 'checked'); else $('#clean').removeAttr('checked'); $("#cleandelta").val(cleandelta_default); if (lighten) $('#lighten').attr('checked', 'checked'); else $('#lighten').removeAttr('checked'); $('#lighten_distance').val(lighten_distance_default); if (PreserveCollinear) $('#PreserveCollinear').attr('checked', 'checked'); else $('#PreserveCollinear').removeAttr('checked'); if (ReverseSolution) $('#ReverseSolution').attr('checked', 'checked'); else $('#ReverseSolution').removeAttr('checked'); if (StrictlySimple) $('#StrictlySimple').attr('checked', 'checked'); else $('#StrictlySimple').removeAttr('checked'); if (off_poly_closed) $('#off_poly_closed').attr('checked', 'checked'); else $('#off_poly_closed').removeAttr('checked'); $('input[type="radio"][name="clipType"][value="' + clipType + '"]').attr('checked', 'checked'); $('input[type="radio"][name="subject_fillType"][value="' + subject_fillType + '"]').attr('checked', 'checked'); $('input[type="radio"][name="clip_fillType"][value="' + clip_fillType + '"]').attr('checked', 'checked'); $('input[type="radio"][name="polygons"][value="' + polygons_default + '"]').attr('checked', 'checked').change(); var polygon = parseInt(polygons_default, 10); if (polygon == 4) rnd_sett = rnd_sett_defaults.rects. default; else rnd_sett = rnd_sett_defaults.norm. default; $('input[type="radio"][name="offsettable_poly"][value="' + offsettable_poly + '"]').attr('checked', 'checked'); $('#subj_polygon_count').val(rnd_sett.subj_polygon_count); $('#subj_point_count').val(rnd_sett.subj_point_count); $('#clip_polygon_count').val(rnd_sett.clip_polygon_count); $('#clip_point_count').val(rnd_sett.clip_point_count); $('#random_grid_type').val(rnd_grid_sett.random_grid_type); //$('#random_grid_rotation').val(rnd_grid_sett.random_grid_rotation); if (bevel) $('#bevel').attr('checked', 'checked'); else $('#bevel').removeAttr('checked'); if (sub_poly_links_update) $('#sub_poly_links_update').attr('checked', 'checked'); else $('#sub_poly_links_update').removeAttr('checked'); $('input[type="radio"][name="joinType"][value="' + joinType + '"]').attr('checked', 'checked').change(); $('input[type="radio"][name="endType"][value="' + endType + '"]').attr('checked', 'checked').change(); make_clip(); colorize_boxes_like_in_svg(); } // main() function make_offset() { // -------------------------------- // SELECT OFSETTABLE POLYGON STARTS // -------------------------------- //console.log("make_offset()"); var off_poly, off_poly1, off_poly2, off_poly3; offsettable_poly = parseInt($('input[type="radio"][name="offsettable_poly"]:checked').val(), 10); if (offsettable_poly == 1) { if (transform.rotation == 0 && transform.distort == null) off_poly = ClipperLib.JS.Clone(ss); else off_poly = ClipperLib.JS.Clone(ss_transformed); } else if (offsettable_poly == 2) { if (transform.rotation === 0 && transform.distort == null) off_poly = ClipperLib.JS.Clone(cc); else off_poly = ClipperLib.JS.Clone(cc_transformed); } else if (offsettable_poly == 3) { off_poly = sss; } if (typeof (off_poly) == "undefined" || !(sss instanceof Array)) off_poly = [ [] ]; // ------------------------------ // SELECT OFSETTABLE POLYGON ENDS // ------------------------------ if (ClipperLib.biginteger_used === null) ClipperLib.biginteger_used = 0; // ------------- // CLEAN STARTS // ------------- if (clean) { //off_poly = ClipperLib.Clean(off_poly, cleandelta * scale); off_poly = ClipperLib.Clipper.CleanPolygons(off_poly, cleandelta * scale); } //if (isArray(off_poly) && off_poly.length) //console.log(JSON.stringify(off_poly[0])); // ------------- // CLEAN ENDS // ------------- // --------------- // SIMPLIFY STARTS // --------------- // Must simplify before offsetting, to get offsetting right in certain cases. // Other operations (boolean ones) doesn't need this. // This is needed when offsetting polygons that has selfintersecting parts ( eg. 5-point star needs this ) if (Simplify) { // Simplifying is only needed when offsetting original polys, because // results of boolean operations are already simplified. // Note! if clip polygon is the same as subject polygon // then it seems that simplifying is needed also for result of boolean operation (ie. solution). if (offsettable_poly == 1) // subj { off_poly = ClipperLib.Clipper.SimplifyPolygons(off_poly, subject_fillType); } if (offsettable_poly == 2) // clip { off_poly = ClipperLib.Clipper.SimplifyPolygons(off_poly, clip_fillType); } if (offsettable_poly == 3) // solution { off_poly = ClipperLib.Clipper.SimplifyPolygons(off_poly, clip_fillType); if (subject_fillType !== clip_fillType) { console.log("Subject filltype and Clip filltype are different. We used Clip filltype in SimplifyPolygons()."); } } } // ------------- // SIMPLIFY ENDS // ------------- // ------------------------------ // ACTUAL OFFSET OPERATION STARTS // ------------------------------ if (delta) { cpr.Clear(); var param_delta = round_to(delta * scale, 3); var param_miterLimit = round_to(miterLimit, 3); var param_arcTolerance = round_to(arcTolerance * scale, 3); //console.log(param_delta, param_miterLimit, param_arcTolerance); if (param_arcTolerance < 0.0009 * scale) { alert("To prevent browser hanging, we don't accept too low arcTolerances."); } else { off_result = new ClipperLib.Paths(); var B0 = bench.start("Offset", "Offset(" + param_delta + ", " + joinType + ", " + endType + ", " + param_miterLimit + "," + param_arcTolerance + ")"); var co = new ClipperLib.ClipperOffset(param_miterLimit, param_arcTolerance); co.AddPaths(off_poly, joinType, endType); co.Execute(off_result, param_delta); bench.end(B0); // off_poly_closed } } else { off_result = off_poly; } // ---------------------------- // ACTUAL OFFSET OPERATION ENDS // ------------------------------ // ---------------------------- // LIGHTENING STARTS // ------------------------------ if (lighten) { off_result = ClipperLib.JS.Lighten(off_result, lighten_distance * scale); if (!(off_result[0] instanceof Array)) off_result = [off_result]; // Because lighten may produce self-intersections, // must Simplify to be sure that result is free of them, // but only if user wants if (Simplify) { off_result = ClipperLib.Clipper.SimplifyPolygons(off_result, subject_fillType); } } // ---------------------------- // LIGHTENING ENDS // ------------------------------ // -------------------------------- // SVG UPDATE STARTS // -------------------------------- if (!p) p = SVG.create(); if (p1) p1.remove(); if (p2) p2.remove(); if (p3) p3.remove(); if (transform.rotation !== 0 || transform.distort !== null) { ss = ss_transformed; cc = cc_transformed; } if (bench.includeSVG) var B3 = bench.start("SVG", "addpaths(ss, cc, off_result, " + subject_fillType + ", " + clip_fillType + ")"); SVG.addpaths(ss, cc, off_result, subject_fillType, clip_fillType); if (bench.includeSVG) bench.end(B3); if (transform.rotation !== 0 || transform.distort !== null) { ss = ss_copy; cc = cc_copy; } // -------------------------------- // SVG UPDATE ENDS // -------------------------------- // -------------------------------- // UPDATE BIGINTEGERS TOGGLE STARTS // -------------------------------- if (ClipperLib.biginteger_used !== null) { if (ClipperLib.biginteger_used) $("#biginteger_used").html("true"); else $("#biginteger_used").html("false"); } else $("#biginteger_used").html("unknown"); ClipperLib.biginteger_used = null; // ------------------------------ // UPDATE BIGINTEGERS TOGGLE ENDS // ------------------------------ // UPDATE DELTA TO FORM $('#delta').val(to_printable(delta)); // UPDATE MITERLIMIT TO FORM $('#miterLimit').val(to_printable(miterLimit)); $('#arcTolerance').val(to_printable(arcTolerance)); // PRINT BENCHMARKS $("#benchmark_div").html(bench.print()); update_enlarged_SVG_if_needed(); update_fieldset_heights(); } function transferPoint(p, source, destination) { var ADDING = 0.001; // to avoid dividing by zero var xI = p.X; var yI = p.Y; var xA = source[0].X; var yA = source[0].Y; var xC = source[2].X; var yC = source[2].Y; var xAu = destination[0].X; var yAu = destination[0].Y; var xBu = destination[1].X; var yBu = destination[1].Y; var xCu = destination[2].X; var yCu = destination[2].Y; var xDu = destination[3].X; var yDu = destination[3].Y; // Calculations // if points are the same, have to add a ADDING to avoid dividing by zero if (xBu == xCu) xCu += ADDING; if (xAu == xDu) xDu += ADDING; if (xAu == xBu) xBu += ADDING; if (xDu == xCu) xCu += ADDING; var kBC = (yBu - yCu) / (xBu - xCu); var kAD = (yAu - yDu) / (xAu - xDu); var kAB = (yAu - yBu) / (xAu - xBu); var kDC = (yDu - yCu) / (xDu - xCu); if (kBC == kAD) kAD += ADDING; var xE = (kBC * xBu - kAD * xAu + yAu - yBu) / (kBC - kAD); var yE = kBC * (xE - xBu) + yBu; if (kAB == kDC) kDC += ADDING; var xF = (kAB * xBu - kDC * xCu + yCu - yBu) / (kAB - kDC); var yF = kAB * (xF - xBu) + yBu; if (xE == xF) xF += ADDING; var kEF = (yE - yF) / (xE - xF); if (kEF == kAB) kAB += ADDING; var xG = (kEF * xDu - kAB * xAu + yAu - yDu) / (kEF - kAB); var yG = kEF * (xG - xDu) + yDu; if (kEF == kBC) kBC += ADDING; var xH = (kEF * xDu - kBC * xBu + yBu - yDu) / (kEF - kBC); var yH = kEF * (xH - xDu) + yDu; var rG = (yC - yI) / (yC - yA); var rH = (xI - xA) / (xC - xA); var xJ = (xG - xDu) * rG + xDu; var yJ = (yG - yDu) * rG + yDu; var xK = (xH - xDu) * rH + xDu; var yK = (yH - yDu) * rH + yDu; if (xF == xJ) xJ += ADDING; if (xE == xK) xK += ADDING; var kJF = (yF - yJ) / (xF - xJ); //23 var kKE = (yE - yK) / (xE - xK); //12 var xKE; if (kJF == kKE) kKE += ADDING; var xIu = (kJF * xF - kKE * xE + yE - yF) / (kJF - kKE); var yIu = kJF * (xIu - xJ) + yJ; p.X = Math_round(xIu); p.Y = Math_round(yIu); } function angle(c, b, a) { var ab = { X: b.X - a.X, Y: b.Y - a.Y }; var cb = { X: b.X - c.X, Y: b.Y - c.Y }; var dot = (ab.X * cb.X + ab.Y * cb.Y); var cross = (ab.X * cb.Y - ab.Y * cb.X); var alpha = Math.atan2(cross, dot); return alpha * 180 / Math.PI; } function isPermissible(p) { var p0 = p[0]; var p1 = p[1]; var p2 = p[2]; var p3 = p[3]; var a0 = angle(p3, p0, p1); var a1 = angle(p0, p1, p2); var a2 = angle(p1, p2, p3); var a3 = angle(p2, p3, p0); if (!(a0 > 1 && a0 < 179) || !(a1 > 1 && a1 < 179) || !(a2 > 1 && a2 < 179) || !(a3 > 1 && a3 < 179)) return false; else return true; } function rotatePoint(pt, center, cosAngle, sinAngle) { var dx = (pt.X - center.X); var dy = (pt.Y - center.Y); pt.X = center.X + Math_round(dx * cosAngle - dy * sinAngle); pt.Y = center.Y + Math_round(dx * sinAngle + dy * cosAngle); return pt; } function make_clip() { ClipperLib.biginteger_used = null; if (!cpr) { cpr = new ClipperLib.Clipper(); } else cpr.Clear(); get_polys(); //if (clipType !== "" && offsettable_poly == 3) if (1 == 1) { if (PreserveCollinear) cpr.PreserveCollinear = true; else cpr.PreserveCollinear = false; if (ReverseSolution) cpr.ReverseSolution = true; else cpr.ReverseSolution = false; if (StrictlySimple) cpr.StrictlySimple = true; else cpr.StrictlySimple = false; cpr.AddPaths(ss, ClipperLib.PolyType.ptSubject, subj_is_closed); cpr.AddPaths(cc, ClipperLib.PolyType.ptClip, true); var bounds, center; if (transform.rotation === 0) { ss_copy = ClipperLib.JS.Clone(ss); cc_copy = ClipperLib.JS.Clone(cc); } else { ss_transformed = ClipperLib.JS.Clone(ss); cc_transformed = ClipperLib.JS.Clone(cc); bounds = ClipperLib.Clipper.GetBounds(ss.concat(cc)); center = { X: Math_round(bounds.left + (bounds.right - bounds.left) / 2), Y: Math_round(bounds.top + (bounds.bottom - bounds.top) / 2) }; cpr.Clear(); var angleRad = (transform.rotation / 180) * Math.PI; var cosAngle = Math.cos(angleRad); var sinAngle = Math.sin(angleRad); for (var i = 0, ilen = ss_transformed.length; i < ilen; i++) for (var j = 0, jlen = ss_transformed[i].length; j < jlen; j++) rotatePoint(ss_transformed[i][j], center, cosAngle, sinAngle) for (var i = 0, ilen = cc_transformed.length; i < ilen; i++) for (var j = 0, jlen = cc_transformed[i].length; j < jlen; j++) rotatePoint(cc_transformed[i][j], center, cosAngle, sinAngle) cpr.Clear(); cpr.AddPaths(ss_transformed, ClipperLib.PolyType.ptSubject, subj_is_closed); cpr.AddPaths(cc_transformed, ClipperLib.PolyType.ptClip, true); } if (transform.distort === null) { ss_copy = ClipperLib.JS.Clone(ss); cc_copy = ClipperLib.JS.Clone(cc); } else { ss_transformed = ClipperLib.JS.Clone(ss); cc_transformed = ClipperLib.JS.Clone(cc); if (typeof (bounds) == "undefined") { bounds = ClipperLib.Clipper.GetBounds(ss_transformed.concat(cc_transformed)); center = { X: bounds.left + (bounds.right - bounds.left) / 2, Y: bounds.top + (bounds.bottom - bounds.top) / 2 }; } //console.log("transform.distort:" + transform.distort); var source = [ { X: bounds.left, Y: bounds.top }, { X: bounds.right, Y: bounds.top }, { X: bounds.right, Y: bounds.bottom }, { X: bounds.left, Y: bounds.bottom }]; if (transform.distort == "generate_new") { var centerOffset = 1 * scale; var marg = 100 * scale; do { var destination = [ { X: rand(bounds.left - marg, center.X - centerOffset), Y: rand(bounds.top - marg, center.Y - centerOffset) }, { X: rand(center.X + centerOffset, bounds.right + marg), Y: rand(bounds.top - marg, center.Y - centerOffset) }, { X: rand(center.X + centerOffset, bounds.right + marg), Y: rand(center.Y + centerOffset, bounds.bottom + marg) }, { X: rand(bounds.left - marg, center.X - centerOffset), Y: rand(center.Y + centerOffset, bounds.bottom + marg) }]; } while (!isPermissible(destination)); if (transform.distort_destination) destination = transform.distort_destination; transform.distort = destination; } else destination = transform.distort; for (var i = 0, ilen = ss_transformed.length; i < ilen; i++) for (var j = 0, jlen = ss_transformed[i].length; j < jlen; j++) transferPoint(ss_transformed[i][j], source, destination) for (var i = 0, ilen = cc_transformed.length; i < ilen; i++) for (var j = 0, jlen = cc_transformed[i].length; j < jlen; j++) transferPoint(cc_transformed[i][j], source, destination) //console.log(ss_transformed); cpr.Clear(); cpr.AddPaths(ss_transformed, ClipperLib.PolyType.ptSubject, subj_is_closed); cpr.AddPaths(cc_transformed, ClipperLib.PolyType.ptClip, true); // center and scale to fit window var padding = 10; var bb = ClipperLib.Clipper.GetBounds(ss_transformed.concat(cc_transformed)); var window_width = 500; var window_height = 350; var bb_min_x = padding * scale; var bb_max_x = window_width * scale - padding; var bb_min_y = padding * scale; var bb_max_y = window_height * scale - padding; var max_width = bb_max_x - bb_min_x; var max_height = bb_max_y - bb_min_y; var fit_scale_x = (max_width - bb_min_x) / (bb.right - bb.left); var fit_scale_y = (max_height - bb_min_x) / (bb.bottom - bb.top); var fit_translate_x = (-bb.left + bb_min_x / fit_scale_x); var fit_translate_y = (-bb.top + bb_min_y / fit_scale_y); for (var i = 0, ilen = ss_transformed.length; i < ilen; i++) for (var j = 0, jlen = ss_transformed[i].length; j < jlen; j++) { ss_transformed[i][j].X = Math_round((ss_transformed[i][j].X + fit_translate_x) * fit_scale_x); ss_transformed[i][j].Y = Math_round((ss_transformed[i][j].Y + fit_translate_y) * fit_scale_y); } for (var i = 0, ilen = cc_transformed.length; i < ilen; i++) for (var j = 0, jlen = cc_transformed[i].length; j < jlen; j++) { cc_transformed[i][j].X = Math_round((cc_transformed[i][j].X + fit_translate_x) * fit_scale_x); cc_transformed[i][j].Y = Math_round((cc_transformed[i][j].Y + fit_translate_y) * fit_scale_y); } cpr.Clear(); cpr.AddPaths(ss_transformed, ClipperLib.PolyType.ptSubject, subj_is_closed); cpr.AddPaths(cc_transformed, ClipperLib.PolyType.ptClip, true); } if (clipType !== "" && offsettable_poly == 3) { sss = new ClipperLib.Paths(); /* cpr.PreserveCollinear = false; cpr.StrictlySimple = false; cpr.ReverseSolution = true; //console.log(cpr.PreserveCollinear); */ /* cpr.ZFillFunction = function (FPoint_bot1, FPoint_top1, FPoint_bot2, FPoint_top2, FPoint_intersectPt) { FPoint_intersectPt.Z = 100; } */ if (!subj_is_closed) sss = new ClipperLib.PolyTree(); var B1 = bench.start("Boolean", "Execute(" + clipType + ", sss, " + subject_fillType + ", " + clip_fillType + ")"); cpr.Execute(clipType, sss, subject_fillType, clip_fillType); bench.end(B1); if (!subj_is_closed) sss = ClipperLib.Clipper.PolyTreeToPaths(sss); //console.log(JSON.stringify(sss)); } } make_offset(); } </script> <div style="padding-top:3px;padding-left:12px;"><a target="_blank" href="https://sourceforge.net/p/jsclipper/wiki/Donations/" target="_blank">Donate Javascript Clipper Project</a> </div> <div style="padding-top:3px;padding-left:12px;"><a target="_blank" href="https://sourceforge.net/p/jsclipper/wiki/Main_Demo%206/">Wiki page of this demo</a> More <a target="_blank" href="http://jsclipper.sourceforge.net/6.4.2.2/index.html?p=starter_boolean.html">examples</a>.</div> </div> </body> </html>