{"ScriptPreparationCode":"var max = Math.max.bind(Math);\r\nvar min = Math.min.bind(Math);\r\n\r\nfunction between(a, x, b) {\r\n return a \u003C= x \u0026\u0026 x \u003C= b;\r\n}\r\n\r\nfunction intersect_1d(start1, end1, start2, end2) {\r\n var c1 = between(start1, start2, end1) ? 1 : 0;\r\n var c2 = between(start1, end2, end1) ? 2 : 0;\r\n var c3 = between(start2, start1, end2) ? 4 : 0;\r\n var c4 = between(start2, end1, end2) ? 8 : 0;\r\n var _case = c1 | c2 | c3 | c4;\r\n switch (_case) {\r\n case 0: return [NaN, NaN];\r\n case 1: return [start2, start2];\r\n case 2: return [end2, end2];\r\n case 3: return [start2, end2];\r\n case 4: return [start1, start1];\r\n case 5: return [min(start1, start2), max(start1, start2)];\r\n case 6: return [min(start1, end2), max(start1, end2)];\r\n case 7: return [min(start1, start2), max(start1, end2)];\r\n case 8: return [end1, end1];\r\n case 9: return [min(end1, start2), max(end1, start2)];\r\n case 10: return [min(end1, end2), max(end1, end2)];\r\n case 11: return [min(end1, start2), max(end1, end2)];\r\n case 12: return [start1, end1];\r\n case 13: return [min(start1, start2), max(end1, start2)];\r\n case 14: return [min(start1, end2), max(end1, end2)];\r\n case 15: return [start1, end2];\r\n default: return [NaN, NaN];\r\n }\r\n}\r\n\r\nfunction intersect_2d(A, B) {\r\n var _a = intersect_1d(A.top, A.bottom, B.top, B.bottom), top = _a[0], bottom = _a[1];\r\n var _b = intersect_1d(A.left, A.right, B.left, B.right), left = _b[0], right = _b[1];\r\n if (isNaN(top) || isNaN(bottom) || isNaN(left) || isNaN(right) || (top === bottom) || (left === right)) {\r\n return null;\r\n }\r\n return { left: left, top: top, right: right, bottom: bottom };\r\n}\r\n\r\nfunction clip(A, B) {\r\n var rectangles = [];\r\n if (A.top \u003C B.top) {\r\n rectangles.push({ left: A.left, top: A.top, right: A.right, bottom: B.top });\r\n }\r\n if (A.left \u003C B.left) {\r\n rectangles.push({ left: A.left, top: max(A.top, B.top), right: B.left, bottom: min(A.bottom, B.bottom) });\r\n }\r\n if (A.right \u003E B.right) {\r\n rectangles.push({ left: B.right, top: max(A.top, B.top), right: A.right, bottom: min(A.bottom, B.bottom) });\r\n }\r\n if (A.bottom \u003E B.bottom) {\r\n rectangles.push({ left: A.left, top: B.bottom, right: A.right, bottom: A.bottom });\r\n }\r\n return rectangles;\r\n}\r\n\r\nfunction sign(owner) {\r\n return function (rect) { return ({ rect: rect, owner: owner }); };\r\n}\r\nvar sign1 = sign(1);\r\nvar sign2 = sign(2);\r\nvar sign3 = sign(3);\r\nfunction overlap(A, B) {\r\n var AB = intersect_2d(A, B);\r\n if (AB === null) {\r\n return [];\r\n }\r\n var rA = clip(A, AB).map(sign1);\r\n var rB = clip(B, AB).map(sign2);\r\n var rAB = sign3(AB);\r\n return rA.concat(rB).concat(rAB);\r\n}\r\n\r\nfunction randomRect() {\r\n var top = Math.random();\r\n var left = Math.random();\r\n var bottom = top \u002B Math.random();\r\n var right = left \u002B Math.random();\r\n return rect(top, left, bottom, right);\r\n}\r\n\r\nfunction rect(top, left, bottom, right) {\r\n return { left: left, top: top, right: right, bottom: bottom };\r\n}","TestCases":[{"Name":"overlap","Code":"overlap(randomRect(), randomRect())","IsDeferred":false},{"Name":"clip","Code":"clip(randomRect(), randomRect())","IsDeferred":false},{"Name":"intersect_2d","Code":"intersect_2d(randomRect(), randomRect())","IsDeferred":false}]}