var _matrix=window._matrix=window.$m=function(A){return new _matrix.classref.assert(A)},_vector=window._vector=window.$v=function(A){return new _vector.classref.assert(A)},_polygon=window._polygon=window.$p=function(A){return new _polygon.classref.assert(A)},_latlng=window._latlng=window.$ll=function(A){return new _latlng.classref.assert(A)};_matrix.classref=_matrix.prototype={assert:function(B){var A;if(B==undefined||B==null){this.data=[];this.rows=0;this.columns=0;this.square=false}else{if(typeof (B.matrix)=="function"&&(A=B.matrix())){this.data=A.data;this.square=A.square;this.rows=A.rows;this.columns=A.columns}else{if(B.length){this.data=B;this.rows=this.data.length;this.columns=this.data[0].length;if(this.rows>0){this.square=this.columns==this.rows}else{this.square=false}}}}return this},matrix:function(){return this},equalDimensions:function(A){var B=_matrix(A);return this.rows==B.rows&&this.columns==B.columns},elm:function(B,A){return this.data[B][A]},add:function(A){var C=false,B=null;if(typeof (A)=="number"){C=true}else{B=_matrix(A)}if(C||this.equalDimensions(B)){var F=[];for(var E=0;E<this.rows;E++){var G=[];for(var D=0;D<this.columns;D++){if(C){G.push(this.elm(E,D)+A)}else{G.push(this.elm(E,D)+B.elm(E,D))}}F.push(G)}return _matrix(F)}else{throw new Error("Matrix dimensions must be equal")}},subtract:function(A){var C=false,B=null;if(typeof (A)=="number"){C=true}else{B=_matrix(A)}if(C||this.equalDimensions(B)){var F=[];for(var E=0;E<this.rows;E++){var G=[];for(var D=0;D<this.columns;D++){if(C){rows.push(this.elm(E,D)-A)}else{G.push(this.elm(E,D)-B.elm(E,D))}}F.push(G)}return _matrix(F)}else{throw new Error("Matrix dimensions must be equal")}},multiply:function(F){var C=false,B=null,H=0;if(typeof (F)=="number"){C=true;H=this.columns}else{B=_matrix(F);H=B.columns}if(C||this.columns==B.rows){var G=[];for(var E=0;E<this.rows;E++){var J=[];for(var D=0;D<H;D++){var I=0;if(C){I=this.elm(E,D)*F}else{for(var A=0;A<this.columns;A++){I+=this.elm(E,A)*B.elm(A,D)}}J.push(I)}G.push(J)}return _matrix(G)}else{throw new Error("Multiplication invalid with given matrix")}},divide:function(A){return this.multiply(_matrix(A).inverse())},transpose:function(){var C=[];for(var B=0;B<this.columns;B++){var D=[];for(var A=0;A<this.rows;A++){D.push(this.elm(A,B))}C.push(D)}return _matrix(C)},inverse:function(){if(!this.square){throw new Error("Inversion is only valid for a square matrix")}var A=function(B){var C=1/(B.elm(0,0)*B.elm(1,1)-B.elm(0,1)*B.elm(1,0));return _matrix([[B.elm(1,1),-1*B.elm(0,1)],[-1*B.elm(1,0),B.elm(0,0)]]).multiply(C)};if(this.rows==2){return A(this)}throw new Error("TODO: General case inversion for n-sized matrix")},determinant:function(){if(!this.square){throw new Error("Determinant is only valid for a square matrix")}var B=function(C){return C.el(0,0)*C.el(1,1)-C.el(0,1)*C.el(1,0)};var A=function(C){return(C.el(0,0)*C.el(1,1)*C.el(2,2)+C.el(0,1)*C.el(1,2)*C.el(2,0)+C.el(0,2)*C.el(1,0)*C.el(2,1))-(C.el(2,0)*C.el(1,1)*C.el(0,2)+C.el(2,1)*C.el(1,2)*C.el(0,0)+C.el(2,2)*C.el(1,0)*C.el(0,1))};if(this.rows==2){return B(this)}if(this.rows==3){return A(this)}throw new Error("TODO: Gaussian elimination for n-size matrix");return null},rotate:function(){throw new Error("TODO: Not implemented")},identity:function(){var C=[];for(var B=0;B<this.rows;B++){var D=[];for(var A=0;A<this.columns;A++){D.push((B==A)?1:0)}C.push(D)}return _matrix(C)},normalize:function(){throw new Error("TODO: Not implemented")}},_vector.classref=_vector.prototype={assert:function(B){this.data=[0,0,0];if(B==undefined||B==null){this.dims=0;this.data=[]}else{if(B.vector&&typeof (B.vector)=="function"){var A=B.vector();this.data=A.data;this.dims=A.dims}else{if(B.x||B.y||B.z){this.data[0]=B.x||0;this.data[1]=B.y||0;this.data[2]=B.z||0}else{if(B.length){this.data=B;this.dims=B.length}}}}return this},vector:function(){return this},matrix:function(){return _matrix([this.data])},latlng:function(){var I=this.data[0],H=this.data[1],F=this.data[2]||0;var A=Math.atan2(H,I);var B=Math.sqrt(Math.pow(I,2)+Math.pow(H,2));var C=Math.atan((F*_latlng.WGS84_RADIUS_MAJOR)/(B*_latlng.WGS84_RADIUS_MINOR));var J=F+_latlng.WGS84_SECOND_ECCENTRICITY_SQUARED*_latlng.WGS84_RADIUS_MINOR*Math.pow(Math.sin(C),3);var K=B-_latlng.WGS84_FIRST_ECCENTRICITY_SQUARED*_latlng.WGS84_RADIUS_MAJOR*Math.pow(Math.cos(C),3);var E=Math.atan(J/K);var D=_latlng.WGS84_RADIUS_MAJOR/Math.sqrt(1-(_latlng.WGS84_FIRST_ECCENTRICITY_SQUARED*Math.pow(Math.sin(E),2)));var G=(B/Math.cos(E))-D;return _latlng([_vector.numberToDegrees(E),_vector.numberToDegrees(A),G])},x:function(){return this.data[0]},y:function(){return this.data[1]},z:function(){return this.data[2]},add:function(A){var B=false,E=null;if(typeof (A)=="number"){B=true}else{E=_vector(A)}if(B||this.dims==E.dims){var D=[];for(var C=0;C<this.dims;C++){if(B){D.push(this.elm(C)+A)}else{D.push(this.elm(C)+E.elm(C))}}return _vector(D)}else{throw new Error("Vector dimensions must be equal")}},subtract:function(A){var B=false,E=null;if(typeof (A)=="number"){B=true}else{E=_vector(A)}if(B||this.dims==E.dims){var D=[];for(var C=0;C<this.dims;C++){if(B){D.push(this.elm(C)-A)}else{D.push(this.elm(C)-E.elm(C))}}return _vector(D)}else{throw new Error("Vector dimensions must be equal")}},multiply:function(A){if(!typeof (A)=="number"){throw new Error("You must pass a scalar value")}var C=[];for(var B=0;B<this.dims;B++){C.push(this.elm(B)*A)}return _vector(C)},dot_product:function(A){var D=0;var B=_vector(A);if(B.dims!=this.dims){throw new Error("Vector dimensions must be equal")}for(var C=0;C<this.dims;C++){D+=this.elm(C)*B.elm(C)}return D},cross_product:function(A){var B=_vector(A);if(B.dims!=this.dims){throw new Error("Vector dimensions must be equal")}if(B.dims!=2&&B.dims!=3){throw new Error("Cross product is only valid for 2 or 3 dimensional vectors")}if(B.dims==2){return(this.elm(0)*B.elm(1)-this.elm(1)*B.elm(0))}else{var C=[this.elm(1)*B.elm(2)-this.elm(2)*B.elm(1),this.elm(2)*B.elm(0)-this.elm(0)*B.elm(2),this.elm(0)*B.elm(1)-this.elm(1)*B.elm(0)];return _vector(C)}},distance:function(A){var B=_vector(A);if(B.dims!=this.dims){throw new Error("Vector dimensions must be equal")}return Math.sqrt(this.dot_product(B))},midpoint:function(B){var C=_vector(B);var A=[];if(C.dims!=this.dims){throw new Error("Vector dimensions must be equal")}for(var D=0;D<C.dims;D++){A.push((this.elm(D)+C.elm(D))/2)}return _vector(A)},midpoint_2d:function(A){return this.midpoint(A)},distance_2d_fast:function(A){var D=_vector(A);if(D.dims!=this.dims){throw new Error("Vector dimensions must be equal")}if(D.dims<2){throw new Error("Vector must be 2 dimensional")}var C=Math.abs(D.elm(0)-this.elm(0));var B=Math.abs(D.elm(1)-this.elm(1));if(B>=C){return(0.41*C)+(0.941246*B)}else{return(0.41*B)+(0.941246*C)}},magnitude:function(){return Math.sqrt(this.dot_product(this))},norm:function(C){if(C==undefined||C==null){C=2}var B=0;for(var A=0;A<this.dims;A++){B+=Math.pow(this.elm(A),C)}B=Math.pow(B,1/C);return B},angle_between:function(A){var C=_vector(A);if(C.dims!=this.dims){throw new Error("Vector dimensions must be equal")}var D=this.dot_product(C);var B=this.magnitude()*C.magnitude();return Math.acos(D/B)},project_onto:function(A){var C=_vector(A);if(C.dims!=this.dims){throw new Error("Vector dimensions must be equal")}var D=this.dot_product(A);var B=Math.pow(A.magnitude(),2);return A.multiply(D/B)},elm:function(A){return this.data[A]}},_polygon.classref=_polygon.prototype={assert:function(C){if(C==undefined||C==null){this.head=null;this.tail=null;this.count=0}else{if(C.polygon&&typeof (C.polygon)=="function"){var B=C.polygon();this.head=B.head;this.tail=B.tail;this.count=B.count}else{if(C.length){this.count=0;for(var A=0;A<C.length;A++){this.add_point(C[A])}}}}return this},polygon:function(){return this},matrix:function(){return _matrix(this.to_point_array())},vtx:function(B,C){this.x=(B[0])||0;this.y=(B[1])||0;this.z=(B[2])||0;this.next=null;this.prev=null;this.nextPoly=null;this.intersect=false;this.neighbor=null;this.couple=null;this.alpha=0;this.entry_exit=0;this.copy=function(){return new _polygon.classref.vtx([this.x,this.y],{alpha:this.alpha,entry_exit:this.entry_exit})};this.filtered_prev=function(D){var E=this.prev;while(E!=this){if(D(E)){return E}E=E.prev}return null};this.filtered_next=function(D){var E=this.next;while(E!=this){if(D(E)){return E}E=E.next}return null};this.next_non_intersecting=function(){return this.filtered_next(function(D){return !D.intersect})};if(C!=null&&C!=undefined){for(var A in C){this[A]=C[A]}}return this},add_point:function(A,C){var B=new _polygon.classref.vtx(A,C);this.add_vtx(B);return this},add_vtx:function(A){if(this.head==null){this.head=A;this.tail=A;this.head.prev=this.head;this.head.next=this.head;this.count++}else{this.insert_vertex_after(A,this.tail)}return this},to_point_array:function(){var A=[];this.foreach(function(B){A.push([B.x,B.y,B.z])});return A},foreach:function(A){var B=this.head;do{A.apply(this,[B]);B=B.next}while(B!=this.head);return this},insert_sort_between:function(A,B,C){var D=B;while(D!=C&&D.alpha<A.alpha){D=D.next}this.insert_vertex_before(A,D);return this},insert_vertex_before:function(B,C){var A=C.prev;C.prev=B;A.next=B;B.next=C;B.prev=A;if(C==this.head){this.tail=B}this.count++;return this},insert_vertex_after:function(B,C){var A=C.next;C.next=B;A.prev=B;B.prev=C;B.next=A;if(this.tail==C){this.tail=B}this.count++;return this},remove_vertex:function(C){var B=C.prev,A=C.next;if(B==A&&B==C){this.head=null;this.tail=null;this.count=0;return }else{B.next=A;A.prev=B;if(C==this.head){this.head=A}if(C==this.tail){this.tail=B}this.count--}},_clean:function(){var B=this.head;do{var A=B.next;if(B.intersect){this.remove_vertex(B)}B=A}while(B!=null&&B!=this.head)},contains_2d:function(B){var C=_polygon(B);var A=0;this.foreach(function(D){if(C.point_inside_2d(D)){A++}});return(A==this.count)},intersects_2d:function(A){var C=_polygon(A);var B=[];this.foreach(function(D){C.foreach(function(F){var E=D.next_non_intersecting(),G=F.next_non_intersecting();if(E==null||G==null){throw new Error("Polygon list integrity broken")}var H=_vector.pointOfIntersectionForLineSegments([[D.x,D.y],[E.x,E.y]],[[F.x,F.y],[G.x,G.y]]);if(H!=null){B.push(_vector(H[0],H[1]))}})});if(B.length==0){return null}else{return B}},point_inside_2d:function(C){var A=0,B=_vector(C),D=[-10000000,B.y()];this.foreach(function(H){if(!H.intersect){var G=H.next_non_intersecting();var F=[D,[B.x(),B.y()]],E=[[H.x,H.y],[G.x,G.y]],I=_vector.pointOfIntersectionForLineSegments(F,E);if(I!=null){A++}}});return((A%2)!=0)},point_inside_fast_2d:function(C){var B=_vector(C);var E=false;var A=B.x(),D=B.y();this.foreach(function(G){var H=G,F=G.prev;if((((H.y<=D)&&(D<F.y))||((F.y<=D)&&(D<H.y)))&&(A<(F.x-H.x)*(D-H.y)/(F.y-H.y)+H.x)){E=!E}});return E},convex_hull_2d:function(){var E=this.to_point_array();var B=null;var A=[];for(var C=0;C<E.length;C++){if(B==null){B=E[C]}else{if(E[C][1]<=B[1]){if(B[1]==E[C][1]){if(E[C][0]<B[0]){B=E[C]}}else{B=E[C]}}}}B=_vector(B);var D=B.magnitude();E.sort(function(I,G){var L=Math.acos(B.dot_product(I)/(_vector(I).magnitude()*D));var K=Math.acos(B.dot_product(G)/(_vector(G).magnitude()*D));if(L==K){var J=B.distance_2d_fast(I);var H=B.distance_2d_fast(G);if(J==H){return 0}else{if(J<H){return -1}else{return 1}}}else{if(L<K){return -1}else{return 1}}});A.push(E[0]);var F=function(G,I,H){return(I[0]-G[0])*(H[1]-G[1])-(H[0]-G[0])*(I[1]-G[1])};for(var C=1;C<E.length;C++){while((A.length>=2)?F(A[A.length-2],A[A.length-1],E[C])<=0:A[A.length-1]==E[C]){A.pop()}A.push(E[C])}return _polygon(A)},clip_2d:function(A){return this._boolean_2d(A)},union_2d:function(A){return this._boolean_2d(A,"|")},subtract_2d:function(A){return this._boolean_2d(A,"-")},area_2d:function(){var C=this.head;var B=0;do{var A=C.next;B+=C.x*A.y-A.x*C.y;C=A}while(C!=this.tail);return B*0.5},centroid_2d:function(){var C=this.area_2d();var F=1/(6*C);var A=0,G=0;var E=this.head;do{var B=E.next;var D=(E.x*B.y-B.x*E.y);A+=(E.x+B.x)*D;G+=(E.y+B.y)*D;E=B}while(E!=this.tail);A*=F;G*=F;return _vector([A,G])},centroid_3d:function(){var C=Math.floor(this.count/3);var D=[0,0,0],E=0;var F=this.head;for(var A=0;A<C;A++){var I=F,H=F.next,G=F.next.next;var K=[H.x-I.x,H.y-I.y,H.z-I.z],J=[G.x-I.x,G.y-I.y,G.z-I.z];var B=_vector(K).cross_product(J).magnitude();E+=B;D[0]+=B*((I.x+H.x+G.x)/3);D[1]+=B*((I.y+H.y+G.y)/3);D[2]+=B*((I.z+H.z+G.z)/3);F=G.next}D[0]/=E;D[1]/=E;D[2]/=E;return _vector(D)},_boolean_2d:function(F,L){var M=1,O=-1;var X=_polygon(F),U=this;var E=0.999999;if(L==null||L==undefined){L=null}var C=function(a,Z){if(Z==null||Z==undefined){Z=5}return parseFloat(a.toFixed(Z))};U.foreach(function(Z){if(!Z.intersect){X.foreach(function(i){if(!i.intersect){var g=Z.next_non_intersecting(),h=i.next_non_intersecting();if(g==null||h==null){throw new Error("Polygon list integrity broken")}var j=_vector.pointOfIntersectionForLineSegments([[Z.x,Z.y],[g.x,g.y]],[[i.x,i.y],[h.x,h.y]]);if(j!=null){var e=C(j[0]),d=C(j[1]),b=C(j[2],3),a=C(j[3],3);if(b==0||b==1||a==0||a==1){if(b==0){Z.x=Z.x+C((1-E)*(g.x-Z.x));Z.y=Z.y+C((1-E)*(g.y-Z.y))}else{if(b==1){g.x=Z.x+C(E*(g.x-Z.x));g.y=Z.y+C(E*(g.y-Z.y))}else{if(a==0){i.x=i.x+C((1-E)*(h.x-i.x));i.y=i.y+C((1-E)*(h.y-i.y))}else{if(a==1){h.x=i.x+C(E*(h.x-i.x));h.y=i.y+C(E*(h.y-i.y))}}}}}else{var f=new _polygon.classref.vtx([e,d],{alpha:b,intersect:true}),c=new _polygon.classref.vtx([e,d],{alpha:a,intersect:true});f.neighbor=c;c.neighbor=f;U.insert_sort_between(f,Z,g);X.insert_sort_between(c,i,h)}}}})}});var Y,V;switch(L){case"|":Y=true;V=true;break;case"-":Y=true;V=false;break;default:Y=false;V=false;break}var B=[U,X],H=[Y,V];for(var T=0,S=B.length-1;T<B.length;S=T++){var N=B[T],D=B[S];var G=D.point_inside_2d(N.head);var A;if(G){A=!H[T]}else{A=H[T]}var R=(A)?M:O;N.foreach(function(Z){if(Z.intersect){Z.entry_exit=R;R=(R==O)?M:O}})}var K=null,W=[];U.foreach(function(Z){if(Z.intersect&&!Z.processed){W.push(Z)}});for(var T=0;T<W.length;T++){var Q=W[T];if(Q.processed){continue}var J=_polygon();do{for(;!Q.processed;Q=Q.neighbor){for(var I=Q.entry_exit;;){Q.processed=true;var P=Q.copy();J.add_vtx(P);Q=(I==O)?Q.next:Q.prev;if(Q.intersect){Q.processed=true;break}}}}while(!Q.processed);if(K!=null){J.head.nextPoly=K}K=J}U._clean();X._clean();return K}},_latlng.classref=_latlng.prototype={assert:function(B){if(B==undefined||B==null){this.data=[0,0,0]}else{if(B.latlng&&typeof (B.latlng)=="function"){var A=B.latlng();this.data=A.data}else{if(B.length){if(B.length>3||B.length<2){throw new Error("You must provide at least 2 coordinates (latitude, longitude) and at most 3 coordinates (latitude, longitude, altitude)")}this.data=B;if(this.data.length==2){this.data.push(0)}}}}return this},_toCartesian:function(){var G=_vector.numberToRadians(this.data[0]),A=_vector.numberToRadians(this.data[1]),D=this.data[2]||0;var K=_latlng.WGS84_RADIUS_MAJOR;var I=_latlng.WGS84_RADIUS_MINOR;var L=_latlng.WGS84_FIRST_ECCENTRICITY_SQUARED;var B=Math.sin(G);var C=Math.cos(G);var E=K/Math.sqrt(1-(L*Math.pow(B,2)));var J=(E+D)*C*Math.cos(A);var H=(E+D)*C*Math.sin(A);var F=(_latlng.WGS84_CURVE_MULTIPLICAND*E+D)*B;return[J,H,F]},vector:function(){return _vector(this._toCartesian())},matrix:function(){return _matrix(this._toCartesian())},latlng:function(){return this},lat:function(){return this.data[0]},lng:function(){return this.data[1]},alt:function(){return this.data[2]},distance_to:function(I){var g=_latlng(I);var H=this.lat(),j=this.lng(),G=g.lat(),h=g.lng();var m=6378137,l=6356752.3142,e=1/298.257223563;var N=_vector.numberToRadians(h-j);var k=Math.atan((1-e)*Math.tan(_vector.numberToRadians(H)));var i=Math.atan((1-e)*Math.tan(_vector.numberToRadians(G)));var K=Math.sin(k),F=Math.cos(k);var J=Math.sin(i),E=Math.cos(i);var Q=N,M,P=20;do{var Y=Math.sin(Q),D=Math.cos(Q);var n=Math.sqrt((E*Y)*(E*Y)+(F*J-K*E*D)*(F*J-K*E*D));if(n==0){return 0}var c=K*J+F*E*D;var X=Math.atan2(n,c);var W=F*E*Y/n;var d=1-W*W;var O=c-2*K*J/d;if(isNaN(O)){O=0}var T=e/16*d*(4+e*(4-3*d));M=Q;Q=N+(1-T)*e*W*(X+T*n*(O+T*c*(-1+2*O*O)))}while(Math.abs(Q-M)>1e-12&&--P>0);if(P==0){return NaN}var S=d*(m*m-l*l)/(l*l);var V=1+S/16384*(4096+S*(-768+S*(320-175*S)));var U=S/1024*(256+S*(-128+S*(74-47*S)));var Z=U*n*(O+U/4*(c*(-1+2*O*O)-U/6*O*(-3+4*n*n)*(-3+4*O*O)));var R=l*V*(X-Z);R=parseFloat(R.toFixed(3));return R},distance_to_miles:function(A){var B=this.distance_to(A);return B/_latlng.METERS_PER_MILE},bearing_between:function(F){var I=_latlng(F);var C=_vector.numberToRadians(this.lat()),B=_vector.numberToRadians(I.lat()),E=this.lng(),D=I.lng();var A=_vector.numberToRadians(D-E);var G=Math.sin(A)*Math.cos(B);var H=Math.cos(C)*Math.sin(B)-Math.sin(C)*Math.cos(B)*Math.cos(A);return _latlng.numberToBearing(Math.atan2(G,H))},destination_given_distance_and_bearing:function(H,J){var I=this.lat(),A=this.lng();var D=_latlng.EARTH_RADIUS_KM;var C=_vector.numberToRadians(I),G=_vector.numberToRadians(A);var E=_latlng.numberToBearing(J);var B=Math.asin(Math.sin(C)*Math.cos(H/D)+Math.cos(C)*Math.sin(H/D)*Math.cos(E));var F=G+Math.atan2(Math.sin(E)*Math.sin(H/D)*Math.cos(C),Math.cos(H/D)-Math.sin(C)*Math.sin(B));F=(F+Math.PI)%(2*Math.PI)-Math.PI;if(isNaN(B)||isNaN(F)){return null}return _latlng([B.toDeg(),F.toDeg()])}};_vector.numberToRadians=function(A){return A*Math.PI/180};_vector.numberToDegrees=function(A){return A*180/Math.PI};_vector.numberInRange=function(C,B,A){return(C>=B&&C<=A)};_vector.pointOfIntersectionForLineSegments=function(G,F){var I=G[0],K=G[1],H=F[0],J=F[1];var E=(J[1]-H[1])*(K[0]-I[0])-(J[0]-H[0])*(K[1]-I[1]);if(E==0){return null}var D=(J[0]-H[0])*(I[1]-H[1])-(J[1]-H[1])*(I[0]-H[0]);var C=(K[0]-I[0])*(I[1]-H[1])-(K[1]-I[1])*(I[0]-H[0]);if(D==0&&E==0&&D==C){return null}var B=D/E,A=C/E;if(_vector.numberInRange(B,0,1)&&_vector.numberInRange(A,0,1)){return[I[0]+B*(K[0]-I[0]),I[1]+B*(K[1]-I[1]),B,A]}return null};_latlng.numberToBearing=function(A){return(_vector.numberToDegrees(A)+360)%360};_latlng.EARTH_RADIUS_KM=6371;_latlng.WGS84_RADIUS_MAJOR=6378137;_latlng.WGS84_RADIUS_MINOR=6356752.314245;_latlng.WGS84_FIRST_ECCENTRICITY_SQUARED=0.00669437999014;_latlng.WGS84_SECOND_ECCENTRICITY_SQUARED=0.00673949674228;_latlng.WGS84_CURVE_MULTIPLICAND=0.9933056200098024;_latlng.METERS_PER_MILE=1609.344;_matrix.classref.assert.prototype=_matrix.classref,_vector.classref.assert.prototype=_vector.classref,_polygon.classref.assert.prototype=_polygon.classref,_latlng.classref.assert.prototype=_latlng.classref;