Author: Adam <git@apiote.xyz>
Merge branch 'develop' for version 3.0
%!v(PANIC=String method: strings: negative Repeat count)
diff --git a/3imba.svg b/3imba.svg new file mode 100644 index 0000000000000000000000000000000000000000..55d9af1cd0196dbde99fbb5c3272c388fdf9c2c1 --- /dev/null +++ b/3imba.svg @@ -0,0 +1,173 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + viewBox="0 0 290.54199 108" + id="vector" + version="1.1" + sodipodi:docname="ic_launcher_foreground.svg" + width="290.54199" + height="108" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> + <metadata + id="metadata176"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs174" /> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1017" + id="namedview172" + showgrid="false" + fit-margin-top="8" + fit-margin-left="8" + fit-margin-bottom="8" + fit-margin-right="8" + inkscape:zoom="3.0903185" + inkscape:cx="135.99551" + inkscape:cy="2.2347546" + inkscape:window-x="0" + inkscape:window-y="27" + inkscape:window-maximized="1" + inkscape:current-layer="vector" /> + <rect + id="rect178" + width="274.54199" + height="92" + x="8" + y="8" + style="display:inline;fill:#3a3a3b;fill-opacity:1;stroke-width:0.7538203" + ry="16" /> + <g + id="group_1" + transform="scale(0.16904335)" + style="display:inline"> + <g + id="group" + transform="translate(173.03255,173.03255)"> + <path + id="path" + d="m 62.962,292.5 v 0 c -3.7,-0.9 -5.7,-3.8 -4.3,-6.5 l 32.3,-62.9 c 1.3,-2.6 5.5,-4 9.2,-3 v 0 c 3.7,0.9 5.7,3.8 4.3,6.5 l -32.3,62.9 c -1.3,2.6 -5.4,4 -9.2,3 z" + inkscape:connector-curvature="0" + style="fill:#54af39" /> + <path + id="path_1" + d="m 229.662,292.5 v 0 c 3.7,-0.9 5.7,-3.8 4.3,-6.5 l -32.3,-62.9 c -1.3,-2.6 -5.5,-4 -9.2,-3 v 0 c -3.7,0.9 -5.7,3.8 -4.3,6.5 l 32.3,62.9 c 1.3,2.6 5.5,4 9.2,3 z" + inkscape:connector-curvature="0" + style="fill:#54af39" /> + <path + id="path_2" + d="m 151.362,36.9 -0.6,0.2 c -1.8,0.7 -3.8,-0.3 -4.5,-2.1 l -9.6,-26.7 c -0.7,-1.8 0.3,-3.8 2.1,-4.5 l 0.6,-0.2 c 1.8,-0.7 3.8,0.3 4.5,2.1 l 9.6,26.7 c 0.7,1.9 -0.3,3.9 -2.1,4.5 z" + inkscape:connector-curvature="0" + style="fill:#54af39" /> + <path + id="path_3" + d="m 180.662,3.8 v 0 c 0,2.1 -1.7,3.8 -3.8,3.8 h -61 c -2.1,0 -3.8,-1.7 -3.8,-3.8 v 0 c 0,-2.1 1.7,-3.8 3.8,-3.8 h 61 c 2.1,0 3.8,1.7 3.8,3.8 z" + inkscape:connector-curvature="0" + style="fill:#54af39" /> + <path + id="path_4" + d="m 218.762,236.7 h -144.9 c -13.3,0 -24,-10.8 -24,-24 v -108 c 0,-41.3 33.5,-74.9 74.9,-74.9 h 43.3 c 41.3,0 74.9,33.5 74.9,74.9 v 108 c -0.1,13.2 -10.9,24 -24.2,24 z" + inkscape:connector-curvature="0" + style="fill:#54af39" /> + <path + id="path_5" + d="m 212.562,146.2 h -132.5 c -5.6,0 -10.2,-4.5 -10.2,-10.2 v -34.9 c 0,-16.9 13.7,-30.6 30.6,-30.6 h 91.7 c 16.9,0 30.6,13.7 30.6,30.6 V 136 c -0.1,5.7 -4.6,10.2 -10.2,10.2 z" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <path + id="path_6" + d="m 161.462,55.5 h -30.3 c -3.2,0 -5.7,-2.6 -5.7,-5.7 v 0 c 0,-3.2 2.6,-5.7 5.7,-5.7 h 30.3 c 3.2,0 5.7,2.6 5.7,5.7 v 0 c 0,3.1 -2.6,5.7 -5.7,5.7 z" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <path + id="path_7" + d="m 87.062,191.9 m -14.8,0 c 0,-3.924 1.56,-7.691 4.335,-10.465 2.774,-2.775 6.541,-4.335 10.465,-4.335 3.924,0 7.691,1.56 10.465,4.335 2.775,2.774 4.335,6.541 4.335,10.465 0,3.924 -1.56,7.691 -4.335,10.465 -2.774,2.775 -6.541,4.335 -10.465,4.335 -3.924,0 -7.691,-1.56 -10.465,-4.335 -2.775,-2.774 -4.335,-6.541 -4.335,-10.465" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <path + id="path_8" + d="m 205.662,191.9 m -14.8,0 c 0,-3.924 1.56,-7.691 4.335,-10.465 2.774,-2.775 6.541,-4.335 10.465,-4.335 3.924,0 7.691,1.56 10.465,4.335 2.775,2.774 4.335,6.541 4.335,10.465 0,3.924 -1.56,7.691 -4.335,10.465 -2.774,2.775 -6.541,4.335 -10.465,4.335 -3.924,0 -7.691,-1.56 -10.465,-4.335 -2.775,-2.774 -4.335,-6.541 -4.335,-10.465" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + </g> + </g> + <g + aria-label="Bimba" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:64px;line-height:1.25;font-family:Railway;-inkscape-font-specification:Railway;letter-spacing:0px;word-spacing:0px;display:inline;fill:#ffffff;fill-opacity:1;stroke:none" + id="text987" + transform="translate(1.2584746)"> + <path + d="m 115.02928,62.896002 c 0,0.896 -0.256,1.792 -0.704,2.624 -0.448,0.832 -1.024,1.536 -1.792,2.176 -0.768,0.64 -1.6,1.088 -2.624,1.472 -1.024,0.384 -2.048,0.512 -3.2,0.512 h -7.935998 v -14.848 h 3.391998 4.416 c 1.152,0 2.24,0.256 3.264,0.64 1.024,0.448 1.92,1.024 2.688,1.728 0.768,0.768 1.344,1.6 1.792,2.56 0.448,1.024 0.704,2.048 0.704,3.136 z m -4.672,-19.968 c 0,0.768 -0.192,1.536 -0.512,2.176 -0.384,0.64 -0.832,1.216 -1.408,1.728 -0.576,0.512 -1.216,0.896 -1.984,1.152 -0.768,0.32 -1.536,0.448 -2.368,0.448 h -5.311998 v -10.752 h 5.119998 c 0.832,0 1.664,0.192 2.432,0.448 0.768,0.256 1.472,0.64 2.112,1.088 0.576,0.512 1.024,1.024 1.408,1.664 0.32,0.64 0.512,1.344 0.512,2.048 z m 11.584,19.904 c 0,-2.688 -0.768,-5.184 -2.24,-7.424 -1.536,-2.24 -3.456,-3.968 -5.824,-5.248 0.96,-0.96 1.728,-2.048 2.304,-3.328 0.512,-1.216 0.832,-2.496 0.832,-3.904 0,-1.6 -0.384,-3.136 -1.024,-4.544 -0.704,-1.408 -1.664,-2.624 -2.816,-3.712 -1.216,-1.024 -2.624,-1.856 -4.224,-2.496 -1.6,-0.576 -3.264,-0.896 -5.056,-0.896 H 98.773 v 44.8 h 7.87228 c 2.048,0 4.032,-0.32 5.888,-1.024 1.856,-0.704 3.456,-1.664 4.864,-2.88 1.408,-1.152 2.496,-2.56 3.328,-4.224 0.768,-1.6 1.216,-3.328 1.216,-5.12 z" + id="path989" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ssssscccscccsscscsccssccsscccscccsccssccs" /> + <path + d="m 133.07727,76.080002 v -30.336 h -6.336 v 30.336 z m 1.344,-38.272 -4.48,-4.544 -4.48,4.544 4.48,4.48 z" + id="path991" + inkscape:connector-curvature="0" /> + <path + d="m 187.2212,76.080002 v -18.048 c 0,-1.664 -0.384,-3.328 -1.024,-4.864 -0.704,-1.536 -1.6,-2.88 -2.752,-4.032 -1.152,-1.152 -2.496,-2.048 -4.032,-2.752 -1.536,-0.64 -3.072,-1.024 -4.736,-1.024 -2.048,0 -4.032,0.448 -5.888,1.216 -1.92,0.832 -3.712,1.984 -5.376,3.392 -1.216,-1.344 -2.624,-2.432 -4.224,-3.328 -1.664,-0.832 -3.392,-1.28 -5.184,-1.28 -1.472,0 -2.88,0.192 -4.16,0.576 -1.344,0.384 -2.56,0.96 -3.712,1.6 v -1.856 h -6.592 v 30.4 h 6.528 v -21.504 c 0.768,-0.768 1.792,-1.408 3.008,-1.92 1.216,-0.448 2.56,-0.704 4.032,-0.704 0.96,0 1.856,0.192 2.752,0.512 0.832,0.32 1.6,0.768 2.24,1.28 0.64,0.576 1.088,1.216 1.472,1.984 0.384,0.768 0.576,1.536 0.576,2.304 v 18.048 h 6.4 v -20.096 c 0.96,-1.216 2.048,-2.176 3.328,-2.944 1.216,-0.704 2.496,-1.088 3.904,-1.088 0.96,0 1.856,0.192 2.752,0.512 0.832,0.32 1.6,0.768 2.24,1.28 0.64,0.576 1.088,1.216 1.472,1.984 0.384,0.768 0.576,1.536 0.576,2.304 v 18.048 z" + id="path993" + inkscape:connector-curvature="0" /> + <path + d="m 216.53314,60.912002 c 0,1.28 -0.256,2.496 -0.768,3.648 -0.512,1.152 -1.152,2.176 -1.984,3.008 -0.896,0.896 -1.856,1.536 -2.944,2.048 -1.152,0.512 -2.304,0.704 -3.584,0.704 -1.536,0 -3.008,-0.256 -4.352,-0.768 -1.408,-0.512 -2.56,-1.216 -3.52,-2.112 v -12.736 c 0.96,-0.896 2.112,-1.6 3.456,-2.112 1.344,-0.512 2.816,-0.832 4.416,-0.832 1.28,0 2.432,0.256 3.584,0.768 1.088,0.512 2.048,1.152 2.944,1.984 0.832,0.832 1.472,1.792 1.984,2.88 0.512,1.152 0.768,2.304 0.768,3.52 z m 6.4,0 c 0,-2.112 -0.448,-4.096 -1.28,-6.016 -0.832,-1.856 -1.92,-3.52 -3.328,-4.928 -1.408,-1.408 -3.072,-2.496 -4.992,-3.328 -1.92,-0.832 -3.904,-1.28 -6.016,-1.28 -1.472,0 -2.88,0.192 -4.224,0.576 -1.344,0.384 -2.56,0.96 -3.712,1.6 v -16.256 h -6.4 v 44.8 h 6.4 v -1.472 c 1.152,0.704 2.368,1.216 3.712,1.6 1.28,0.384 2.688,0.512 4.16,0.512 2.112,0 4.096,-0.384 6.016,-1.216 1.92,-0.832 3.584,-1.984 4.992,-3.392 1.408,-1.408 2.56,-3.136 3.392,-5.056 0.832,-1.92 1.28,-3.968 1.28,-6.144 z" + id="path995" + inkscape:connector-curvature="0" /> + <path + d="m 245.20509,69.296002 c -0.896,0.512 -1.856,0.96 -2.88,1.28 -1.024,0.32 -2.048,0.448 -2.944,0.448 -1.664,0 -3.136,-0.192 -4.288,-0.576 -1.152,-0.384 -1.728,-1.216 -1.728,-2.624 0,-0.896 0.256,-1.664 0.896,-2.304 0.64,-0.576 1.472,-1.024 2.56,-1.344 1.024,-0.32 2.304,-0.576 3.776,-0.704 1.408,-0.128 2.944,-0.192 4.608,-0.192 z m 6.4,6.784 v -18.88 c 0,-2.816 -0.448,-5.12 -1.344,-6.848 -0.896,-1.728 -1.92,-3.072 -3.2,-3.968 -1.28,-0.896 -2.624,-1.472 -4.032,-1.728 -1.408,-0.256 -2.688,-0.448 -3.776,-0.448 -1.536,0 -3.072,0.256 -4.672,0.768 -1.664,0.512 -3.072,1.088 -4.224,1.856 l -2.432,8.064 h 0.64 c 1.792,-1.6 3.52,-2.688 5.184,-3.328 1.664,-0.64 3.392,-0.96 5.248,-0.96 1.216,0 2.24,0.192 3.072,0.448 0.768,0.32 1.408,0.768 1.92,1.344 0.448,0.576 0.768,1.28 0.96,2.176 0.128,0.896 0.256,1.856 0.256,2.944 -3.328,0 -6.144,0.32 -8.448,0.832 -2.304,0.576 -4.16,1.344 -5.568,2.24 -1.408,0.96 -2.432,2.048 -3.072,3.328 -0.64,1.28 -0.896,2.624 -0.896,4.032 0,1.28 0.256,2.432 0.832,3.456 0.512,1.024 1.28,1.984 2.24,2.752 0.896,0.832 1.984,1.472 3.264,1.92 1.28,0.448 2.624,0.64 4.096,0.64 1.152,0 2.368,-0.192 3.776,-0.576 1.408,-0.384 2.624,-0.896 3.776,-1.664 v 1.6 z" + id="path997" + inkscape:connector-curvature="0" /> + </g> + <g + aria-label="Bimba" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:56px;line-height:1.25;font-family:Railway;-inkscape-font-specification:Railway;letter-spacing:0px;word-spacing:0px;display:none;fill:#ffffff;fill-opacity:1;stroke:none" + id="text1004" + transform="translate(-0.114,-6.8644098)"> + <path + d="m 116.40217,69.760412 c 0,0.896 -0.256,1.792 -0.704,2.624 -0.448,0.832 -1.024,1.536 -1.792,2.176 -0.768,0.64 -1.6,1.088 -2.624,1.472 -1.024,0.384 -2.048,0.512 -3.2,0.512 h -7.936 v -14.848 h 3.392 4.416 c 1.152,0 2.24,0.256 3.264,0.64 1.024,0.448 1.92,1.024 2.688,1.728 0.768,0.768 1.344,1.6 1.792,2.56 0.448,1.024 0.704,2.048 0.704,3.136 z m -4.672,-19.968 c 0,0.768 -0.192,1.536 -0.512,2.176 -0.384,0.64 -0.832,1.216 -1.408,1.728 -0.576,0.512 -1.216,0.896 -1.984,1.152 -0.768,0.32 -1.536,0.448 -2.368,0.448 h -5.312 v -10.752 h 5.12 c 0.832,0 1.664,0.192 2.432,0.448 0.768,0.256 1.472,0.64 2.112,1.088 0.576,0.512 1.024,1.024 1.408,1.664 0.32,0.64 0.512,1.344 0.512,2.048 z m 11.584,19.904 c 0,-2.688 -0.768,-5.184 -2.24,-7.424 -1.536,-2.24 -3.456,-3.968 -5.824,-5.248 0.96,-0.96 1.728,-2.048 2.304,-3.328 0.512,-1.216 0.832,-2.496 0.832,-3.904 0,-1.6 -0.384,-3.136 -1.024,-4.544 -0.704,-1.408 -1.664,-2.624 -2.816,-3.712 -1.216,-1.024 -2.624,-1.856 -4.224,-2.496 -1.6,-0.576 -3.264,-0.896 -5.056,-0.896 H 93.746168 v 44.8 h 14.272002 c 2.048,0 4.032,-0.32 5.888,-1.024 1.856,-0.704 3.456,-1.664 4.864,-2.88 1.408,-1.152 2.496,-2.56 3.328,-4.224 0.768,-1.6 1.216,-3.328 1.216,-5.12 z" + style="font-size:64px" + id="path4709" + inkscape:connector-curvature="0" /> + <path + d="m 134.45016,82.944412 v -30.336 h -6.336 v 30.336 z m 1.344,-38.272 -4.48,-4.544 -4.48,4.544 4.48,4.48 z" + style="font-size:64px" + id="path4711" + inkscape:connector-curvature="0" /> + <path + d="m 188.59409,82.944412 v -18.048 c 0,-1.664 -0.384,-3.328 -1.024,-4.864 -0.704,-1.536 -1.6,-2.88 -2.752,-4.032 -1.152,-1.152 -2.496,-2.048 -4.032,-2.752 -1.536,-0.64 -3.072,-1.024 -4.736,-1.024 -2.048,0 -4.032,0.448 -5.888,1.216 -1.92,0.832 -3.712,1.984 -5.376,3.392 -1.216,-1.344 -2.624,-2.432 -4.224,-3.328 -1.664,-0.832 -3.392,-1.28 -5.184,-1.28 -1.472,0 -2.88,0.192 -4.16,0.576 -1.344,0.384 -2.56,0.96 -3.712,1.6 v -1.856 h -6.592 v 30.4 h 6.528 v -21.504 c 0.768,-0.768 1.792,-1.408 3.008,-1.92 1.216,-0.448 2.56,-0.704 4.032,-0.704 0.96,0 1.856,0.192 2.752,0.512 0.832,0.32 1.6,0.768 2.24,1.28 0.64,0.576 1.088,1.216 1.472,1.984 0.384,0.768 0.576,1.536 0.576,2.304 v 18.048 h 6.4 v -20.096 c 0.96,-1.216 2.048,-2.176 3.328,-2.944 1.216,-0.704 2.496,-1.088 3.904,-1.088 0.96,0 1.856,0.192 2.752,0.512 0.832,0.32 1.6,0.768 2.24,1.28 0.64,0.576 1.088,1.216 1.472,1.984 0.384,0.768 0.576,1.536 0.576,2.304 v 18.048 z" + style="font-size:64px" + id="path4713" + inkscape:connector-curvature="0" /> + <path + d="m 217.90603,67.776412 c 0,1.28 -0.256,2.496 -0.768,3.648 -0.512,1.152 -1.152,2.176 -1.984,3.008 -0.896,0.896 -1.856,1.536 -2.944,2.048 -1.152,0.512 -2.304,0.704 -3.584,0.704 -1.536,0 -3.008,-0.256 -4.352,-0.768 -1.408,-0.512 -2.56,-1.216 -3.52,-2.112 v -12.736 c 0.96,-0.896 2.112,-1.6 3.456,-2.112 1.344,-0.512 2.816,-0.832 4.416,-0.832 1.28,0 2.432,0.256 3.584,0.768 1.088,0.512 2.048,1.152 2.944,1.984 0.832,0.832 1.472,1.792 1.984,2.88 0.512,1.152 0.768,2.304 0.768,3.52 z m 6.4,0 c 0,-2.112 -0.448,-4.096 -1.28,-6.016 -0.832,-1.856 -1.92,-3.52 -3.328,-4.928 -1.408,-1.408 -3.072,-2.496 -4.992,-3.328 -1.92,-0.832 -3.904,-1.28 -6.016,-1.28 -1.472,0 -2.88,0.192 -4.224,0.576 -1.344,0.384 -2.56,0.96 -3.712,1.6 v -16.256 h -6.4 v 44.8 h 6.4 v -1.472 c 1.152,0.704 2.368,1.216 3.712,1.6 1.28,0.384 2.688,0.512 4.16,0.512 2.112,0 4.096,-0.384 6.016,-1.216 1.92,-0.832 3.584,-1.984 4.992,-3.392 1.408,-1.408 2.56,-3.136 3.392,-5.056 0.832,-1.92 1.28,-3.968 1.28,-6.144 z" + style="font-size:64px" + id="path4715" + inkscape:connector-curvature="0" /> + <path + d="m 246.57798,76.160412 c -0.896,0.512 -1.856,0.96 -2.88,1.28 -1.024,0.32 -2.048,0.448 -2.944,0.448 -1.664,0 -3.136,-0.192 -4.288,-0.576 -1.152,-0.384 -1.728,-1.216 -1.728,-2.624 0,-0.896 0.256,-1.664 0.896,-2.304 0.64,-0.576 1.472,-1.024 2.56,-1.344 1.024,-0.32 2.304,-0.576 3.776,-0.704 1.408,-0.128 2.944,-0.192 4.608,-0.192 z m 6.4,6.784 v -18.88 c 0,-2.816 -0.448,-5.12 -1.344,-6.848 -0.896,-1.728 -1.92,-3.072 -3.2,-3.968 -1.28,-0.896 -2.624,-1.472 -4.032,-1.728 -1.408,-0.256 -2.688,-0.448 -3.776,-0.448 -1.536,0 -3.072,0.256 -4.672,0.768 -1.664,0.512 -3.072,1.088 -4.224,1.856 l -2.432,8.064 h 0.64 c 1.792,-1.6 3.52,-2.688 5.184,-3.328 1.664,-0.64 3.392,-0.96 5.248,-0.96 1.216,0 2.24,0.192 3.072,0.448 0.768,0.32 1.408,0.768 1.92,1.344 0.448,0.576 0.768,1.28 0.96,2.176 0.128,0.896 0.256,1.856 0.256,2.944 -3.328,0 -6.144,0.32 -8.448,0.832 -2.304,0.576 -4.16,1.344 -5.568,2.24 -1.408,0.96 -2.432,2.048 -3.072,3.328 -0.64,1.28 -0.896,2.624 -0.896,4.032 0,1.28 0.256,2.432 0.832,3.456 0.512,1.024 1.28,1.984 2.24,2.752 0.896,0.832 1.984,1.472 3.264,1.92 1.28,0.448 2.624,0.64 4.096,0.64 1.152,0 2.368,-0.192 3.776,-0.576 1.408,-0.384 2.624,-0.896 3.776,-1.664 v 1.6 z" + style="font-size:64px" + id="path4717" + inkscape:connector-curvature="0" /> + </g> +</svg> diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc new file mode 100644 index 0000000000000000000000000000000000000000..82b6b91898a92c69afe84a1c981f27ee2f58c133 --- /dev/null +++ b/CHANGELOG.adoc @@ -0,0 +1,76 @@ += Changelog + +All notable changes to this project will be documented in this file. + +The format is based on https://keepachangelog.com/en/1.0.0/[Keep a Changelog], but uses AsciiDoc instead of Markdown, +and this project adheres to https://semver.org/spec/v2.0.0.html[Semantic Versioning]. + +== Unreleased + +* Searching lines +* Travel planning +* Offline timetable +* Alerts + +== [3.0] – 2023-04-11 + +=== Changed + +* completely new architecture + +== [2.2.2] – 2019-03-11 + +=== Changed + +* drop HTML formatting in PEKA messages + +== [2.2.1] – 2019-03-04 + +=== Changed + +* white icons (low floor, tickets) in night mode + +== [2.2.0] – 2019-02-26 + +=== Added + +* showing low floor and ticket checkouts in VM departures + +=== Changed + +* departures empty state is semi-transparent + +== [2.1] – 2019-02-04 + +=== Added + +* showing empty search result +* loading in shed selection and stop screen +* VM messages + +=== Changed + +* search bar +* empty departures state +* ‘now’ departure is ‘in a moment’ if the vehicle is not on-stop +* sorting departures: on-stop at the top +* sorting search results by similarity + +== [2.0] – 2018-09-21 + +=== Added + +* official timetable from ZTM + +=== Changed + +* VM can be used without offline timetable +* offline timetable uses exact dates (instead of workdays/saturdays/holidays) +* VM is quicker and is more reliable (as it’s computed in the same way as offline departures) +* favourites rewritten from scratch +* app is movable to external storage +* new colours—grey and green—fitting new Poznań style + +=== Fixed + +* multiple bug fixes diff --git a/CHANGELOG.rst b/CHANGELOG.rst deleted file mode 100644 index 7e205e91cb1687496ebb21e320a553a0466f0788..0000000000000000000000000000000000000000 --- a/CHANGELOG.rst +++ /dev/null @@ -1,102 +0,0 @@ -Changelog -######### - -All notable changes to this project will be documented in this file. - -The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_`, using ReStructuredText instead of Markdown, and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_. - -[Unreleased] -============ - -Added ------ - -+ logging and reporting crashes -+ history of frequently searched stops -+ retry buttons -+ caching favourite -+ update info in APK releases -+ day/night setting – auto, always day, always night -+ trip planning -+ full timetable online -+ free train departures -+ searching by lines -+ city bike stations - -Changed -------- - -* reduce flickering of search results -* VM messages appear also in favourites (if it contains 1 stop only) -* ‘no connectivity’ warning only when offline timetable is not present - -[2.2.2] – 2019-03-11 -==================== - -Changed -------- - -* drop HTML formatting in PEKA messages - -[2.2.1] – 2019-03-04 -==================== - -Changed -------- - -* white icons (low floor, tickets) in night mode - -[2.2.0] – 2019-02-26 -==================== - -Added ------ - -+ showing low floor and ticket checkouts in VM departures - -Changed -------- - -* departures empty state is semi-transparent - -[2.1] – 2019-02-04 -================== - -Added ------ - -+ showing empty search result -+ loading in shed selection and stop screen -+ VM messages - -Changed -------- - -* search bar -* empty departures state -* ‘now’ departure is ‘in a moment’ if the vehicle is not on-stop -* sorting departures: on-stop at the top -* sorting search results by similarity - -[2.0] – 2018-09-21 -================== - -Added ------ - -+ official timetable from ZTM - -Changed -------- - -* VM can be used without offline timetable -* offline timetable uses exact dates (instead of workdays/saturdays/holidays) -* VM is quicker and is more reliable (as it’s computed in the same way as offline departures) -* favourites rewritten from scratch -* app is movable to external storage -* new colours—grey and green—fitting new Poznań style - -Fixed ------ - -* multiple bug fixes diff --git a/CODE_OF_CONDUCT b/CODE_OF_CONDUCT new file mode 100644 index 0000000000000000000000000000000000000000..22572bcbc92d27dd11f2f1aacd9de9f9917837a6 --- /dev/null +++ b/CODE_OF_CONDUCT @@ -0,0 +1,53 @@ +Code of Merit + +1. The project creators, lead developers, core team, constitute +the managing members of the project and have final say in every decision +of the project, technical or otherwise, including overruling previous decisions. +There are no limitations to this decisional power. + +2. Contributions are an expected result of your membership on the project. +Don't expect others to do your work or help you with your work forever. + +3. All members have the same opportunities to seek any challenge they want +within the project. + +4. Authority or position in the project will be proportional +to the accrued contribution. Seniority must be earned. + +5. Software is evolutive: the better implementations must supersede lesser +implementations. Technical advantage is the primary evaluation metric. + +6. This is a space for technical prowess; topics outside of the project +will not be tolerated. + +7. Non technical conflicts will be discussed in a separate space. Disruption +of the project will not be allowed. + +8. Individual characteristics, including but not limited to, +body, sex, sexual preference, race, language, religion, nationality, +or political preferences are irrelevant in the scope of the project and +will not be taken into account concerning your value or that of your contribution +to the project. + +9. Discuss or debate the idea, not the person. + +10. There is no room for ambiguity: Ambiguity will be met with questioning; +further ambiguity will be met with silence. It is the responsibility +of the originator to provide requested context. + +11. If something is illegal outside the scope of the project, it is illegal +in the scope of the project. This Code of Merit does not take precedence over +governing law. + +12. This Code of Merit governs the technical procedures of the project not the +activities outside of it. + +13. Participation on the project equates to agreement of this Code of Merit. + +14. No objectives beyond the stated objectives of this project are relevant +to the project. Any intent to deviate the project from its original purpose +of existence will constitute grounds for remedial action which may include +expulsion from the project. + +This document is adapted from the Code of Merit, version 1.0. +See: https://codeofmerit.org/. diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000000000000000000000000000000000000..afbd4fa417b2548febc28e4c00e9ba7e4970c5bb --- /dev/null +++ b/README.adoc @@ -0,0 +1,60 @@ += Bimba +apiote <me@apiote.xyz> +v3.0 2023-04-11 +:toc: + +Bimba is a FLOSS public transport passenger companion; a timetable in your pocket. + +Bimba can be found on https://floss.social/@bimba[Mastodon] + +== Name + +Bimba is pronounced BEEM-bah [ˈbimba]. +The name is Poznań subdialect for ‘tram’. + +== Installing + +Preffered method is to download Bimba from F-Droid: + +[link=https://f-droid.org/packages/xyz.apiote.bimba.czwek] +image::https://f-droid.org/badge/get-it-on.png[Get it on F-Droid,207,80] + +== Contribute + +This project uses The Code of Merit, which is available as CODE_OF_CONDUCT file. + +The roadmap is available in `CHANGELOG.adoc` file and—although it’s not set in stone—feature requests are highly discouraged. Contributions, however, are welcome as patches; please send them to `bimba@git.apiote.xyz` using `git send-email`. Patches must include a sign-off to certify agreement to https://developercertificate.org/[Developer Certificate of Origin]. + +All communication—questions, bugs, etc.—should go through the mailing list available at `bimba@git.apiote.xyz`. Note that all communication will be made public at https://asgard.apiote.xyz/. + +== Mirrors + +The canonical repository for this project is https://git.apiote.xyz/Bimba.git it’s mirrored at https://notabug.org/apiote/Bimba + +Mirrors exist solely for the sake of the code and any additional functions provided by third-party services (including but not limited to issues and pull requests) will not be used and will be ignored. + +== License + +---- +Bimba Copyright (c) apiote + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <https://www.gnu.org/licenses/>. +---- + +=== Thanks to… + +* https://github.com/tebriz159 for new logo + +* https://fonts.google.com/icons[Material Icons], © Google Apache 2.0 +* https://github.com/mancj/MaterialSearchBar[Search bar], © mancj MIT diff --git a/README.md b/README.md deleted file mode 100644 index 793b6c5f6d49f36560e2646de2bb3029315b807d..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# Bimba [![Build Status](https://travis-ci.org/apiote/Bimba.svg?branch=master)](https://travis-ci.org/apiote/Bimba) -Bimba (pronounced BEEM-bah [ˈbiːmbʌ], Poznań subdialect for ‘tram’) is the first Free-Software Poznań wandering guide - -With Bimba You can check the public transport timetable in Poznań agglomeration (run by ZTM Poznań), and thanks to the Virtual Monitor You can see when exactly a bus or tram will arrive. - -<a href="https://f-droid.org/packages/ml.adamsprogs.bimba/" target="_blank"> -<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="80"/></a> - -Bimba can be found at [Mastodon](https://floss.social/@bimba) - -## Mirror - -If You’re reading this on Github, You’re seeing a mirror. Changes are pushed to the mirror only when there’s a push to `master`. The original repo is available on [NotABug](https://notabug.org/apiote/Bimba). - -Tags (releases) are published in both services but binary builds after version 2.0 are available only on NotABug. - -Issues will be tracked in both services. Pull requests on Github will be asked to be sent via e-mail as `diff`s. - -## Roadmap - -*more important higher* - -* [x] incremental timetable generator -* [x] favourite stops - * [x] offline timetable - * [x] Virtual Monitor - * [x] peek all departures in a favourite -* [x] less non-intuitive timetable refresh gesture -* [ ] nearest stop(s) by GPS -* [ ] ‘through mid-stop’ on lines with only 1 direction -* [ ] city bike stations on map -* [ ] searching by line number -* [ ] stops on map -* [ ] refreshing on wakeup -* [x] VM times immediately if online, not through offline timetable -* [x] detecting holiday -* [ ] ticket machines on map -* [ ] ever-present searchbar -* [ ] other things on map - -## If You want to help… - -### …be sure to… - -* check the issues, both closed and open; -* check the most recent commit. Master contains published snapshots; The most recent commit will be on other branch—most likely `develop`, but there may be a release, feature or hotfix branches. For full description of workflow model head to [Nvie’s model](https://nvie.com/posts/a-successful-git-branching-model/). - -### …then You can… - -* add a new translation. Just translate `strings.xml` and make a pull request or an issue; -* set up Your own converter instance. For more info head to the [converter readme](converter/README.md) -* help me move my own converter to some PaaS (like Heroku or other I-don’t-know-because-I-cannot-into-cloud) -* think about any other way -* <small> donate. More info [there](http://apiote.tk/donate/)</small> - -## Thanks to… - -* [tebriz159@github](https://github.com/tebriz159) for new logo ([#4](https://github.com/apiote/Bimba/issues/4)) -* [Vistaus@github](https://github.com/Vistaus) for Dutch translation ([#5](https://github.com/apiote/Bimba/pull/5)) - ---- - - Bimba - Copyright (C) 2017–2018 Adam Pioterek - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. - -- Ticket machine icon [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Ticket_machine_icon.svg), © [Therud](https://commons.wikimedia.org/wiki/User:Therud) CC-BY-SA 4.0 -- Icons [Material](https://material.io/icons), © Google Apache 2.0 -- Feature image [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Poznan._Kaponiera_finally_opened_(44).jpg), © MOs810 CC BY-SA 4.0 -- [Search View](https://github.com/arimorty/floatingsearchview), © arimorty Apache 2.0 -- JSON [gson](https://github.com/google/gson), © Google Apache 2.0 -- HTTP [okhttp](https://github.com/square/okhttp), © square Apache 2.0 -- [SQLite](https://github.com/requery/sqlite-android), © requery Apache 2.0 diff --git a/app/.gitignore b/app/.gitignore index 796b96d1c402326528b4ba3c12ee9d92d0e212e9..42afabfd2abebf31384ca7797186a27a4b7dbee8 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1 @@ -/build +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 053942d2c3516a112b36037739800223883f06f1..4a826718a3be350286e3dbe39465842db656594b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,48 +1,61 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id "org.jetbrains.kotlin.plugin.parcelize" +} android { - compileSdkVersion 28 - buildToolsVersion '28.0.3' + compileSdk 33 + defaultConfig { - applicationId "ml.adamsprogs.bimba" - minSdkVersion 19 - targetSdkVersion 28 - versionCode 19 - versionName "2.2.2" + applicationId "xyz.apiote.bimba.czwek" + minSdk 21 + targetSdk 33 + versionCode 20 + versionName "3.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables.useSupportLibrary = true } + buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + coreLibraryDesugaringEnabled true + } + kotlinOptions { + jvmTarget = '1.8' + } + buildFeatures { + viewBinding true + } + namespace 'xyz.apiote.bimba.czwek' + buildToolsVersion '33.0.1' } dependencies { - implementation fileTree(include: ['*.jar'], dir: 'libs') - androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { - exclude group: 'com.android.support', module: 'support-annotations' - }) - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.cardview:cardview:1.0.0' - implementation 'androidx.vectordrawable:vectordrawable:1.0.1' - implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3' - implementation 'com.google.android.material:material:1.1.0-alpha04' - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.27.0-eap13' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.27.0-eap13' - testImplementation 'junit:junit:4.12' - implementation 'io.requery:sqlite-android:3.22.0' - implementation 'com.google.code.gson:gson:2.8.2' - implementation 'com.squareup.okhttp3:okhttp:3.12.0' - implementation 'com.github.mancj:MaterialSearchBar:0.8.1' -} -repositories { - maven { url "https://maven.google.com" } - maven { url 'https://jitpack.io' } - mavenCentral() + implementation 'androidx.core:core-ktx:1.9.0' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.8.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' + implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' + implementation 'androidx.navigation:navigation-ui-ktx:2.5.3' + implementation 'com.github.mancj:MaterialSearchBar:0.8.5' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.core:core-splashscreen:1.0.0' + implementation 'com.google.openlocationcode:openlocationcode:1.0.4' + implementation 'org.osmdroid:osmdroid-android:6.1.14' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3' + implementation 'org.yaml:snakeyaml:2.0' + implementation project(path: ':fruchtfleisch') + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 386a7fa4d2a2ac482e92cea4d3f0b5bff83424f2..481bb434814107eb79d7a30b676d344b0df2f8ce 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,13 +1,9 @@ # Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/adam/.android-sdk/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface @@ -15,3 +11,11 @@ # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 25e36bf5433aefd3a374503d0e5d22067650e1ad..ba54cbb104e4c1c2a15a22f4172846243d9d6206 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,69 +1,69 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" - package="ml.adamsprogs.bimba" - android:installLocation="auto"> - - <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> - <uses-permission android:name="android.permission.INTERNET" /> - - <application - android:icon="@mipmap/ic_launcher" - android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher_round" - android:supportsRtl="true" - android:theme="@style/AppTheme" - tools:ignore="GoogleAppIndexingWarning"> - <activity android:name=".activities.DashActivity" /> + xmlns:tool="http://schemas.android.com/tools"> - <service - android:name=".datasources.TimetableDownloader" - android:exported="false" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - <activity - android:name=".activities.SplashActivity" - android:theme="@style/SplashTheme"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> + <application + android:name="xyz.apiote.bimba.czwek.Bimba" + android:allowBackup="true" + android:dataExtractionRules="@xml/data_extraction_rules" + android:fullBackupContent="@xml/backup_rules" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/Theme.Bimba.Style" + tool:targetApi="31"> + <activity + android:name="xyz.apiote.bimba.czwek.settings.ServerChooserActivity" + android:exported="false"> + <meta-data + android:name="android.app.lib_name" + android:value="" /> + </activity> + <activity + android:name="xyz.apiote.bimba.czwek.onboarding.OnboardingActivity"> + </activity> + <activity + android:name="xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity" + android:exported="false" /> + <activity + android:name="xyz.apiote.bimba.czwek.onboarding.FirstRunActivity" + android:exported="true" + android:theme="@style/Theme.Bimba.Splash"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - </activity> - <activity android:name=".activities.EditFavouriteActivity" /> - <activity - android:name=".activities.SettingsActivity" - android:label="@string/title_activity_settings" - android:parentActivityName=".activities.DashActivity" - android:theme="@style/AppTheme"> - <meta-data - android:name="android.support.PARENT_ACTIVITY" - android:value="ml.adamsprogs.bimba.activities.DashActivity" /> - </activity> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity + android:name="xyz.apiote.bimba.czwek.departures.DeparturesActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.VIEW" /> - <service - android:name=".datasources.VmService" - android:enabled="true" - android:exported="false" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> - <activity android:name=".activities.StopSpecifyActivity" /> - <activity - android:name=".activities.StopActivity" - android:label="@string/title_activity_stop" - android:parentActivityName=".activities.StopSpecifyActivity" - android:theme="@style/AppTheme"> - <meta-data - android:name="android.support.PARENT_ACTIVITY" - android:value="ml.adamsprogs.bimba.activities.StopSpecifyActivity" /> - </activity> - <activity - android:name=".activities.LineSpecifyActivity" - android:label="@string/title_activity_main" - android:parentActivityName=".activities.DashActivity" - android:theme="@style/AppTheme"> - <meta-data - android:name="android.support.PARENT_ACTIVITY" - android:value="ml.adamsprogs.bimba.activities.DashActivity" /> - </activity> - </application> + <data android:scheme="http" /> + <data android:scheme="https" /> + <data android:host="www.peka.poznan.pl" /> + <data android:pathPrefix="/vm" /> + </intent-filter> + </activity> + <activity + android:name="xyz.apiote.bimba.czwek.search.ResultsActivity" + android:exported="false" + android:label="@string/title_activity_results" /> + <activity + android:name="xyz.apiote.bimba.czwek.dashboard.MainActivity" + android:exported="false" + android:windowSoftInputMode="adjustPan" /> + </application> </manifest> \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..51de732e44c246bac252b581c3bb1b3c9aa345c6 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png deleted file mode 100644 index 7a9bd078b1aed42188fe767423683c64a468312e..0000000000000000000000000000000000000000 Binary files a/app/src/main/ic_launcher-web.png and /dev/null differ diff --git a/app/src/main/java/ml/adamsprogs/bimba/Declinator.kt b/app/src/main/java/ml/adamsprogs/bimba/Declinator.kt deleted file mode 100644 index 9f456f1352381e2bdf0b57333094c665dffea751..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/Declinator.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ml.adamsprogs.bimba - -class Declinator { - companion object { - fun decline(number: Int): Int { - return when { - number == 0 -> R.string.now - number % 10 == 0 -> R.string.departure_in__plural_genitive - number == 1 -> R.string.departure_in__singular_genitive - number in listOf(12,13,14) -> R.string.departure_in__plural_genitive - number % 10 in listOf(2, 3, 4) -> R.string.departure_in__plural_nominative - number % 10 in listOf(1,5,6,7,8,9) -> R.string.departure_in__plural_genitive - else -> -1 - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt b/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt deleted file mode 100644 index faedcc757de71be595d9cd42158d306e3d44964d..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/MessageReceiver.kt +++ /dev/null @@ -1,65 +0,0 @@ -package ml.adamsprogs.bimba - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import ml.adamsprogs.bimba.datasources.TimetableDownloader -import ml.adamsprogs.bimba.datasources.VmService -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Plate - -class MessageReceiver private constructor() : BroadcastReceiver() { - companion object { - private var receiver:MessageReceiver? = null - fun getMessageReceiver(): MessageReceiver { - if (receiver == null) - receiver = MessageReceiver() - return receiver as MessageReceiver - } - } - - private val onTimetableDownloadListeners: HashSet<OnTimetableDownloadListener> = HashSet() - private val onVmListeners: HashSet<OnVmListener> = HashSet() - - override fun onReceive(context: Context?, intent: Intent?) { - if (intent?.action == TimetableDownloader.ACTION_DOWNLOADED) { - val result = intent.getStringExtra(TimetableDownloader.EXTRA_RESULT) - for (listener in onTimetableDownloadListeners) { - listener.onTimetableDownload(result) - } - } - if (intent?.action == VmService.ACTION_READY) { - val departures = intent.getStringArrayListExtra(VmService.EXTRA_DEPARTURES)?.map { Departure.fromString(it) }?.toSet() - val plateId = intent.getSerializableExtra(VmService.EXTRA_PLATE_ID) as Plate.ID? - val stopCode = intent.getSerializableExtra(VmService.EXTRA_STOP_CODE) as String - val code = intent.getIntExtra(VmService.EXTRA_CODE, 0) - for (listener in onVmListeners) { - listener.onVm(departures, plateId, stopCode, code) - } - } - } - - fun addOnTimetableDownloadListener(listener: OnTimetableDownloadListener) { - onTimetableDownloadListeners.add(listener) - } - - fun removeOnTimetableDownloadListener(listener: OnTimetableDownloadListener) { - onTimetableDownloadListeners.remove(listener) - } - - fun addOnVmListener(listener: OnVmListener) { - onVmListeners.add(listener) - } - - fun removeOnVmListener(listener: OnVmListener) { - onVmListeners.remove(listener) - } - - interface OnTimetableDownloadListener { - fun onTimetableDownload(result: String?) - } - - interface OnVmListener { - fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID?, stopCode: String, code: Int) - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/NetworkStateReceiver.kt b/app/src/main/java/ml/adamsprogs/bimba/NetworkStateReceiver.kt deleted file mode 100644 index 770ba13101e61f4ccd213248bb2af9aadc0f4874..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/NetworkStateReceiver.kt +++ /dev/null @@ -1,43 +0,0 @@ -package ml.adamsprogs.bimba - -import android.net.ConnectivityManager -import android.content.Intent -import android.content.BroadcastReceiver -import android.content.Context - -class NetworkStateReceiver : BroadcastReceiver() { - - private val onConnectivityChangeListeners = HashSet<OnConnectivityChangeListener>() - - override fun onReceive(context: Context, intent: Intent) { - if (intent.extras != null) { - val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - val ni = connectivityManager.activeNetworkInfo - - if (ni != null && ni.isConnectedOrConnecting) { - for (listener in onConnectivityChangeListeners) - listener.onConnectivityChange(true) - } else if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, java.lang.Boolean.FALSE)) { - for (listener in onConnectivityChangeListeners) - listener.onConnectivityChange(false) - } - } - } - - interface OnConnectivityChangeListener { - fun onConnectivityChange(connected: Boolean) - } - - companion object { - lateinit var manager: ConnectivityManager - - fun init(context: Context) { - manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager - } - - fun isNetworkAvailable(): Boolean { - val activeNetworkInfo = manager.activeNetworkInfo - return activeNetworkInfo != null && activeNetworkInfo.isConnected - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/NotificationChannels.kt b/app/src/main/java/ml/adamsprogs/bimba/NotificationChannels.kt deleted file mode 100644 index 738003153a01f7d7753f888009f26268299a5f78..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/NotificationChannels.kt +++ /dev/null @@ -1,26 +0,0 @@ -package ml.adamsprogs.bimba - -import android.app.NotificationChannel -import android.app.NotificationManager -import android.os.Build -import androidx.annotation.RequiresApi - - -class NotificationChannels { - companion object { - const val CHANNEL_UPDATES = "updates" - - @RequiresApi(Build.VERSION_CODES.O) - fun makeChannel(id: String, name: String, manager: NotificationManager) { - try { - manager.getNotificationChannel(id) - } catch (e: RuntimeException) { - val channel = NotificationChannel(id, name, NotificationManager.IMPORTANCE_MIN) - channel.enableLights(false) - channel.enableVibration(false) - channel.setShowBadge(false) - manager.createNotificationChannel(channel) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt b/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt deleted file mode 100644 index 99225e0e49c57da0143579fe0ecda2b31459456e..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/ProviderProxy.kt +++ /dev/null @@ -1,269 +0,0 @@ -package ml.adamsprogs.bimba - -import android.content.Context -import android.content.Intent -import kotlinx.coroutines.* -import kotlinx.coroutines.android.Main -import ml.adamsprogs.bimba.datasources.VmClient -import ml.adamsprogs.bimba.datasources.VmService -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Plate -import ml.adamsprogs.bimba.models.StopSegment -import ml.adamsprogs.bimba.models.Timetable -import ml.adamsprogs.bimba.models.suggestions.GtfsSuggestion -import ml.adamsprogs.bimba.models.suggestions.StopSuggestion -import java.util.* -import kotlin.collections.HashMap - -class ProviderProxy(context: Context? = null) { - private val vmClient = VmClient.getVmClient() - private var timetable: Timetable = Timetable.getTimetable(context) - private var suggestions = emptyList<GtfsSuggestion>() - private val requests = HashMap<String, Request>() - - var mode = if (timetable.isEmpty()) MODE_VM else MODE_FULL - - companion object { - const val MODE_FULL = "mode_full" - const val MODE_VM = "mode_vm" - } - - fun getSuggestions(query: String = "", callback: (List<GtfsSuggestion>) -> Unit) { - GlobalScope.launch { - suggestions = getStopSuggestions(query) //+ getLineSuggestions(query) //todo<p:v+1> + bike stations, train stations, &c - val filtered = filterSuggestions(query) - launch(Dispatchers.Main) { - callback(filtered) - } - } - } - - private suspend fun getStopSuggestions(query: String): List<StopSuggestion> { - val vmSuggestions = withContext(Dispatchers.Default) { - vmClient.getStops(query) - } - - return if (vmSuggestions.isEmpty() and !timetable.isEmpty()) { - timetable.getStopSuggestions() - } else { - vmSuggestions - } - } - - private fun filterSuggestions(query: String): List<GtfsSuggestion> { - return suggestions.filter { - deAccent(it.name).contains(deAccent(query), true) - } - } - - private fun deAccent(str: String): String { - var result = str.replace('ę', 'e', true) - result = result.replace('ó', 'o', true) - result = result.replace('ą', 'a', true) - result = result.replace('ś', 's', true) - result = result.replace('ł', 'l', true) - result = result.replace('ż', 'z', true) - result = result.replace('ź', 'z', true) - result = result.replace('ć', 'c', true) - result = result.replace('ń', 'n', true) - return result - } - - fun getSheds(name: String, callback: (Map<String, Set<String>>) -> Unit) { - GlobalScope.launch { - val vmSheds = vmClient.getSheds(name) - - val sheds = if (vmSheds.isEmpty() and !timetable.isEmpty()) { - timetable.getHeadlinesForStop(name) - } else { - vmSheds - } - - launch(Dispatchers.Main) { - callback(sheds) - } - } - } - - fun getVmMessage(shed: String, callback: (String?) -> Unit) { - GlobalScope.launch { - val message = vmClient.getMessage(shed) - launch(Dispatchers.Main) { - callback(message) - } - } - } - - fun subscribeForDepartures(stopSegments: Set<StopSegment>, listener: OnDeparturesReadyListener, context: Context): String { - stopSegments.forEach { - val intent = Intent(context, VmService::class.java) - intent.putExtra("stop", it.stop) - intent.action = "request" - context.startService(intent) - } - val uuid = UUID.randomUUID().toString() - requests[uuid] = Request(listener, stopSegments) - return uuid - } - - fun subscribeForDepartures(stopCode: String, listener: OnDeparturesReadyListener, context: Context): String { - val intent = Intent(context, VmService::class.java) - intent.putExtra("stop", stopCode) - intent.action = "request" - context.startService(intent) - - val uuid = UUID.randomUUID().toString() - requests[uuid] = Request(listener, setOf(StopSegment(stopCode, null))) - return uuid - } - - private fun constructSegmentDepartures(stopSegments: Set<StopSegment>): Deferred<Map<String, List<Departure>>> { - return GlobalScope.async { - if (timetable.isEmpty()) - emptyMap() - else { - timetable.getStopDeparturesBySegments(stopSegments) - } - } - } - - private fun filterDepartures(departures: Map<String, List<Departure>>): List<Departure> { - val now = Calendar.getInstance().secondsAfterMidnight() - val lines = HashMap<String, Int>() - val twoDayDepartures = (timetable.getServiceForToday()?.let { - departures[it] - } ?: emptyList()) + - (timetable.getServiceForTomorrow()?.let { service -> - departures[service]!!.map { it.copy().apply { tomorrow = true } } - } ?: emptyList()) - - return twoDayDepartures - .filter { it.timeTill(now) >= 0 } - .filter { - val existed = lines[it.line] ?: 0 - if (existed < 3) { - lines[it.line] = existed + 1 - true - } else false - } - } - - fun unsubscribeFromDepartures(uuid: String, context: Context) { - requests[uuid]?.unsubscribe(context) - requests.remove(uuid) - } - - fun refreshTimetable(context: Context) { - timetable = Timetable.getTimetable(context, true) - mode = MODE_FULL - } - - fun getFullTimetable(stopCode: String): Map<String, List<Departure>> { - return if (timetable.isEmpty()) - emptyMap() - else - timetable.getStopDepartures(stopCode) - - } - - fun getFullTimetable(stopSegments: Set<StopSegment>): Map<String, List<Departure>> { - return if (timetable.isEmpty()) - emptyMap() - else - timetable.getStopDeparturesBySegments(stopSegments) - - } - - fun fillStopSegment(stopSegment: StopSegment, callback: (StopSegment?) -> Unit) { - GlobalScope.launch { - callback(fillStopSegment(stopSegment)) - } - } - - suspend fun fillStopSegment(stopSegment: StopSegment): StopSegment? { - if (stopSegment.plates != null) - return stopSegment - - return if (timetable.isEmpty()) - vmClient.getDirections(stopSegment.stop) - else - timetable.getHeadlinesForStopCode(stopSegment.stop) - } - - fun getStopName(stopCode: String, callback: (String?) -> Unit) { - GlobalScope.launch { - callback(getStopName(stopCode)) - } - } - - suspend fun getStopName(stopCode: String): String? { - return if (timetable.isEmpty()) - vmClient.getName(stopCode) - else - timetable.getStopName(stopCode) - } - - fun describeService(service: String, context: Context): String? { - return if (timetable.isEmpty()) - null - else - timetable.getServiceDescription(service, context) - } - - fun getServiceFirstDay(service: String): Int { - return timetable.getServiceFirstDay(service) - } - - interface OnDeparturesReadyListener { - fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) - } - - inner class Request(private val listener: OnDeparturesReadyListener, private val segments: Set<StopSegment>) : MessageReceiver.OnVmListener { - private val receiver = MessageReceiver.getMessageReceiver() - private val receivedPlates = HashSet<Plate.ID>() - - private var cache: Deferred<Map<String, List<Departure>>>? = null - - init { - receiver.addOnVmListener(this@Request) - GlobalScope.launch { - cache = constructSegmentDepartures(segments) - } - } - - override fun onVm(vmDepartures: Set<Departure>?, plateId: Plate.ID?, stopCode: String, code: Int) { - GlobalScope.launch(Dispatchers.Main) { - if ((plateId == null || vmDepartures == null) and (timetable.isEmpty())) { - listener.onDeparturesReady(emptyList(), null, code) - return@launch - } - if (plateId == null) { - listener.onDeparturesReady(filterDepartures(cache!!.await()), null, code) - } else { - if (segments.any { plateId in it }) { - if (vmDepartures != null) { - listener.onDeparturesReady(vmDepartures.toList(), plateId, code) - if (plateId !in receivedPlates) - receivedPlates.add(plateId) - } else { - receivedPlates.remove(plateId) - if (receivedPlates.isEmpty()) { - listener.onDeparturesReady(filterDepartures(cache!!.await()), null, code) - } - } - } - } - } - } - - fun unsubscribe(context: Context) { - segments.forEach { - val intent = Intent(context, VmService::class.java) - intent.putExtra("stop", it.stop) - intent.action = "remove" - context.startService(intent) - } - receiver.removeOnVmListener(this) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/AppCompatPreferenceActivity.java b/app/src/main/java/ml/adamsprogs/bimba/activities/AppCompatPreferenceActivity.java deleted file mode 100644 index d276164afc8be57b1d2a6d4c629670704dd536cf..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/AppCompatPreferenceActivity.java +++ /dev/null @@ -1,110 +0,0 @@ -package ml.adamsprogs.bimba.activities; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.preference.PreferenceActivity; -import android.view.MenuInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.LayoutRes; -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.widget.Toolbar; - -/** - * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls - * to be used with AppCompat. - */ -public abstract class AppCompatPreferenceActivity extends PreferenceActivity { - - private AppCompatDelegate mDelegate; - - @Override - protected void onCreate(Bundle savedInstanceState) { - getDelegate().installViewFactory(); - getDelegate().onCreate(savedInstanceState); - super.onCreate(savedInstanceState); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - getDelegate().onPostCreate(savedInstanceState); - } - - public ActionBar getSupportActionBar() { - return getDelegate().getSupportActionBar(); - } - - public void setSupportActionBar(@Nullable Toolbar toolbar) { - getDelegate().setSupportActionBar(toolbar); - } - - @Override - public MenuInflater getMenuInflater() { - return getDelegate().getMenuInflater(); - } - - @Override - public void setContentView(@LayoutRes int layoutResID) { - getDelegate().setContentView(layoutResID); - } - - @Override - public void setContentView(View view) { - getDelegate().setContentView(view); - } - - @Override - public void setContentView(View view, ViewGroup.LayoutParams params) { - getDelegate().setContentView(view, params); - } - - @Override - public void addContentView(View view, ViewGroup.LayoutParams params) { - getDelegate().addContentView(view, params); - } - - @Override - protected void onPostResume() { - super.onPostResume(); - getDelegate().onPostResume(); - } - - @Override - protected void onTitleChanged(CharSequence title, int color) { - super.onTitleChanged(title, color); - getDelegate().setTitle(title); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - getDelegate().onConfigurationChanged(newConfig); - } - - @Override - protected void onStop() { - super.onStop(); - getDelegate().onStop(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - getDelegate().onDestroy(); - } - - public void invalidateOptionsMenu() { - getDelegate().invalidateOptionsMenu(); - } - - private AppCompatDelegate getDelegate() { - if (mDelegate == null) { - mDelegate = AppCompatDelegate.create(this, null); - } - return mDelegate; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt deleted file mode 100644 index cd714bbfd3e7e604ffb1d83c2e9ee486a2eb482a..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt +++ /dev/null @@ -1,460 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Context -import android.content.DialogInterface -import android.content.Intent -import android.content.IntentFilter -import android.os.Bundle -import android.preference.PreferenceManager.getDefaultSharedPreferences -import android.text.Editable -import android.text.TextWatcher -import android.view.ActionMode -import android.view.Menu -import android.view.MenuItem -import android.view.View -import android.view.inputmethod.InputMethodManager -import androidx.appcompat.app.AlertDialog -import androidx.appcompat.app.AppCompatActivity -import com.google.android.material.navigation.NavigationView -import com.google.android.material.snackbar.Snackbar -import com.mancj.materialsearchbar.MaterialSearchBar -import com.mancj.materialsearchbar.MaterialSearchBar.BUTTON_BACK -import com.mancj.materialsearchbar.MaterialSearchBar.BUTTON_NAVIGATION -import kotlinx.android.synthetic.main.activity_dash.* -import ml.adamsprogs.bimba.* -import ml.adamsprogs.bimba.collections.FavouriteStorage -import ml.adamsprogs.bimba.datasources.TimetableDownloader -import ml.adamsprogs.bimba.datasources.VmService -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Plate -import ml.adamsprogs.bimba.models.Timetable -import ml.adamsprogs.bimba.models.adapters.FavouritesAdapter -import ml.adamsprogs.bimba.models.adapters.SuggestionsAdapter -import ml.adamsprogs.bimba.models.suggestions.EmptySuggestion -import ml.adamsprogs.bimba.models.suggestions.GtfsSuggestion -import ml.adamsprogs.bimba.models.suggestions.LineSuggestion -import ml.adamsprogs.bimba.models.suggestions.StopSuggestion -import java.text.DateFormat -import java.util.* -import kotlin.collections.ArrayList - -class DashActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener, - FavouritesAdapter.OnMenuItemClickListener, FavouritesAdapter.ViewHolder.OnClickListener, ProviderProxy.OnDeparturesReadyListener, SuggestionsAdapter.OnSuggestionClickListener { - - val context: Context = this - private val receiver = MessageReceiver.getMessageReceiver() - private lateinit var timetable: Timetable - private var suggestions: List<GtfsSuggestion>? = null - private lateinit var drawerLayout: androidx.drawerlayout.widget.DrawerLayout - private lateinit var drawerView: NavigationView - lateinit var favouritesList: androidx.recyclerview.widget.RecyclerView - lateinit var searchView: MaterialSearchBar - private lateinit var favourites: FavouriteStorage - private lateinit var adapter: FavouritesAdapter - private val actionModeCallback = ActionModeCallback() - private var actionMode: ActionMode? = null - private var isWarned = false - private lateinit var providerProxy: ProviderProxy - private lateinit var suggestionsAdapter: SuggestionsAdapter - - companion object { - const val REQUEST_EDIT_FAVOURITE = 1 - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_dash) - - setSupportActionBar(toolbar) - - providerProxy = ProviderProxy(this) - timetable = Timetable.getTimetable() - NetworkStateReceiver.init(this) - - prepareFavourites() - - prepareListeners() - startDownloaderService() - - drawerLayout = drawer_layout - drawerView = drawer - //drawer.setCheckedItem(R.id.drawer_home) - drawerView.setNavigationItemSelectedListener { item -> - when (item.itemId) { - R.id.drawer_refresh -> { - startDownloaderService(true) - } - R.id.drawer_settings -> { - startActivity(Intent(context, SettingsActivity::class.java)) - } - else -> { - } - } - drawerLayout.closeDrawer(drawerView) - super.onOptionsItemSelected(item) - } - - warnTimetableValidity() - - showValidityInDrawer() - - searchView = search_view - suggestionsAdapter = SuggestionsAdapter(layoutInflater, this, this) - searchView.setCustomSuggestionAdapter(suggestionsAdapter) - - searchView.addTextChangeListener(object : TextWatcher { - override fun afterTextChanged(s: Editable?) { - if (searchView.isSearchEnabled) { - getSuggestions(s.toString()) - } - } - - override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { - } - - override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - } - - }) - - searchView.setOnSearchActionListener(object : MaterialSearchBar.OnSearchActionListener { - override fun onButtonClicked(buttonCode: Int) { - when (buttonCode) { - BUTTON_NAVIGATION -> { - if (drawerLayout.isDrawerOpen(drawerView)) - drawerLayout.closeDrawer(drawerView) - else - drawerLayout.openDrawer(drawerView) - } - BUTTON_BACK -> { - searchView.disableSearch() - } - } - } - - override fun onSearchStateChanged(enabled: Boolean) { - } - - override fun onSearchConfirmed(text: CharSequence?) { - getSuggestions(text.toString()) - } - }) - } - - private fun getSuggestions(query: String = "") { - providerProxy.getSuggestions(query) { suggestions -> - if (!suggestionsAdapter.equals(suggestions)) { - if (suggestions.isEmpty()) { - suggestionsAdapter.clearSuggestions() - suggestionsAdapter.addSuggestion(EmptySuggestion()) - } else { - suggestionsAdapter.updateSuggestions(suggestions, query) - } - searchView.showSuggestionsList() - } - } - } - - override fun onSuggestionClickListener(suggestion: GtfsSuggestion) { - val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager - var view = (context as DashActivity).currentFocus - if (view == null) { - view = View(context) - } - imm.hideSoftInputFromWindow(view.windowToken, 0) - if (suggestion is StopSuggestion) { - val intent = Intent(context, StopSpecifyActivity::class.java) - intent.putExtra(StopSpecifyActivity.EXTRA_STOP_NAME, suggestion.name) - startActivity(intent) - } else if (suggestion is LineSuggestion) { - val intent = Intent(context, LineSpecifyActivity::class.java) - intent.putExtra(LineSpecifyActivity.EXTRA_LINE_ID, suggestion.name) - startActivity(intent) - } - } - - override fun onRestart() { - super.onRestart() - favourites = FavouriteStorage.getFavouriteStorage(context) - favourites.forEach { - it.subscribeForDepartures(this, this) - } - } - - override fun onStop() { - super.onStop() - favourites.forEach { - it.unsubscribeFromDepartures(this) - } - } - - private fun showValidityInDrawer() { - if (timetable.isEmpty()) { - drawerView.menu.findItem(R.id.drawer_validity_since).title = getString(R.string.validity_offline_unavailable) - } else { - val formatter = DateFormat.getDateInstance(DateFormat.SHORT) - var calendar = calendarFromIsoD(timetable.getValidSince()) - formatter.timeZone = calendar.timeZone - drawerView.menu.findItem(R.id.drawer_validity_since).title = getString(R.string.valid_since, formatter.format(calendar.time)) - calendar = calendarFromIsoD(timetable.getValidTill()) - formatter.timeZone = calendar.timeZone - drawerView.menu.findItem(R.id.drawer_validity_till).title = getString(R.string.valid_till, formatter.format(calendar.time)) - } - } - - private fun warnTimetableValidity() { - if (isWarned) - return - isWarned = true - if (timetable.isEmpty()) - return - val validTill = timetable.getValidTill() - val today = Calendar.getInstance().toIsoDate() - val tomorrow = Calendar.getInstance().apply { - this.add(Calendar.DAY_OF_MONTH, 1) - }.toIsoDate() - - try { - timetable.getServiceForToday() - if (today > validTill) { - notifyTimetableValidity(-1) - suggestions = ArrayList() - return - } - if (today == validTill) { - notifyTimetableValidity(0) - return - } - } catch (e: IllegalArgumentException) { - notifyTimetableValidity(-1) - suggestions = ArrayList() - return - } - - try { - timetable.getServiceForTomorrow() - if (tomorrow == validTill) { - notifyTimetableValidity(1) - return - } - } catch (e: IllegalArgumentException) { - notifyTimetableValidity(1) - return - } - } - - private fun notifyTimetableValidity(daysTillInvalid: Int) { - val message = when (daysTillInvalid) { - -1 -> getString(R.string.timetable_validity_finished) - 0 -> getString(R.string.timetable_validity_today) - 1 -> getString(R.string.timetable_validity_tomorrow) - else -> return - } - AlertDialog.Builder(context) - .setPositiveButton(context.getText(android.R.string.ok) - ) { dialog: DialogInterface, _: Int -> dialog.cancel() } - .setCancelable(true) - .setMessage(message) - .create().show() - - if (daysTillInvalid == -1) { - Timetable.delete(this) - } - } - - private fun prepareFavourites() { - favourites = FavouriteStorage.getFavouriteStorage(context) - favourites.forEach { - it.subscribeForDepartures(this, this) - } - val layoutManager = androidx.recyclerview.widget.LinearLayoutManager(context) - favouritesList = favourites_list - adapter = FavouritesAdapter(context, favourites, this, this) - favouritesList.adapter = adapter - favouritesList.itemAnimator = androidx.recyclerview.widget.DefaultItemAnimator() - favouritesList.layoutManager = layoutManager - } - - override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) { - favouritesList.adapter!!.notifyDataSetChanged() - showError(drawer_layout, code, this) - } - - private fun prepareListeners() { - val filter = IntentFilter(TimetableDownloader.ACTION_DOWNLOADED) - filter.addAction(VmService.ACTION_READY) - filter.addCategory(Intent.CATEGORY_DEFAULT) - registerReceiver(receiver, filter) - receiver.addOnTimetableDownloadListener(context as MessageReceiver.OnTimetableDownloadListener) - } - - private fun startDownloaderService(force: Boolean = false) { - if (getDefaultSharedPreferences(this).getBoolean(getString(R.string.key_timetable_automatic_update), false) or force) - startService(Intent(context, TimetableDownloader::class.java)) - } - - override fun onBackPressed() { - if (drawerLayout.isDrawerOpen(drawerView)) { - drawerLayout.closeDrawer(drawerView) - return - } - if (searchView.isSearchEnabled) { - searchView.disableSearch() - } else { - super.onBackPressed() - } - } - - override fun onResume() { - super.onResume() - adapter.favourites = favourites - favouritesList.adapter!!.notifyDataSetChanged() - } - - override fun onDestroy() { - super.onDestroy() - receiver.removeOnTimetableDownloadListener(context as MessageReceiver.OnTimetableDownloadListener) - unregisterReceiver(receiver) - } - - override fun onTimetableDownload(result: String?) { - val message: String = when (result) { - TimetableDownloader.RESULT_NO_CONNECTIVITY -> getString(R.string.no_connectivity_cant_update) - TimetableDownloader.RESULT_UP_TO_DATE -> getString(R.string.timetable_up_to_date) - TimetableDownloader.RESULT_FINISHED -> getString(R.string.timetable_downloaded) - else -> getString(R.string.error_try_later) - } - Snackbar.make(findViewById(R.id.drawer_layout), message, Snackbar.LENGTH_LONG).show() - if (result == TimetableDownloader.RESULT_FINISHED) { - timetable = Timetable.getTimetable(this, true) - getSuggestions(searchView.text) - showValidityInDrawer() - } - } - - override fun edit(name: String): Boolean { - val positionBefore = favourites.indexOf(name) - val intent = Intent(this, EditFavouriteActivity::class.java) - intent.putExtra(EditFavouriteActivity.EXTRA_FAVOURITE, favourites[name]) - intent.putExtra(EditFavouriteActivity.EXTRA_POSITION_BEFORE, positionBefore) - startActivityForResult(intent, REQUEST_EDIT_FAVOURITE) - return true - } - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == REQUEST_EDIT_FAVOURITE) { - if (resultCode == Activity.RESULT_OK) { - val name = data!!.getStringExtra(EditFavouriteActivity.EXTRA_NEW_NAME) - val positionBefore = data.getIntExtra(EditFavouriteActivity.EXTRA_POSITION_BEFORE, -1) - //adapter.favourites = favourites.favouritesList - if (positionBefore == -1) - favouritesList.adapter!!.notifyDataSetChanged() - else { - val positionAfter = favourites.indexOf(name) - favouritesList.adapter!!.notifyItemChanged(positionBefore) - favouritesList.adapter!!.notifyItemMoved(positionBefore, positionAfter) - } - adapter[name]?.let { - it.unsubscribeFromDepartures(context) - it.subscribeForDepartures(this, context) - } - } - } - } - - override fun delete(name: String): Boolean { - favourites.delete(name) - //adapter.favourites = favourites.favouritesList - favouritesList.adapter!!.notifyItemRemoved(favourites.indexOf(name)) - return true - } - - @SuppressLint("MissingSuperCall") - override fun onSaveInstanceState(outState: Bundle) { - //hack below line to be commented to prevent crash on nougat. - //super.onSaveInstanceState(outState); - } - - override fun onItemClicked(position: Int) { - if (actionMode != null) { - toggleSelection(position) - } else { - val intent = Intent(context, StopActivity::class.java) - intent.putExtra(StopActivity.SOURCE_TYPE, StopActivity.SOURCE_TYPE_FAV) - intent.putExtra(StopActivity.EXTRA_FAVOURITE, favourites[position]) - startActivity(intent) - } - } - - override fun onItemLongClicked(position: Int): Boolean { - if (actionMode == null) { - actionMode = startActionMode(actionModeCallback) - } - - toggleSelection(position) - - return true - } - - private fun toggleSelection(position: Int) { - adapter.toggleSelection(position) - val count = adapter.getSelectedItemCount() - - if (count == 0) { - actionMode?.finish() - } else { - actionMode?.title = getString(R.string.merge_favourites) - actionMode?.invalidate() - } - } - - private fun clearSelection() { - adapter.clearSelection() - actionMode?.finish() - } - - private inner class ActionModeCallback : ActionMode.Callback { - override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { - menuInflater.inflate(R.menu.menu_favourite_merge, menu) - return true - } - - override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { - return false - } - - override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { - return when (item.itemId) { - R.id.action_merge -> { - val selectedPositions = adapter.getSelectedItems() - val selectedNames = selectedPositions.map { favourites[it]?.name }.filter { it != null }.map { it!! } - - (1 until selectedNames.size).forEach { - selectedNames[it].let { name -> - adapter.notifyItemRemoved(adapter.indexOf(name)) - adapter[name]?.unsubscribeFromDepartures(context) - } - } - favourites.merge(selectedNames, context) - adapter[selectedNames[0]]?.let { - it.unsubscribeFromDepartures(context) - it.subscribeForDepartures(this@DashActivity, context) - } - adapter.notifyItemChanged(adapter.indexOf(selectedNames[0])) - - clearSelection() - true - } - - else -> false - } - } - - override fun onDestroyActionMode(mode: ActionMode) { - (favouritesList.adapter as FavouritesAdapter).clearSelection() - actionMode = null - } - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/EditFavouriteActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/EditFavouriteActivity.kt deleted file mode 100644 index c372b185980e24b33d0c621529557d547276aa91..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/EditFavouriteActivity.kt +++ /dev/null @@ -1,57 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import android.widget.EditText -import androidx.appcompat.app.AppCompatActivity -import kotlinx.android.synthetic.main.activity_edit_favourite.* -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.collections.FavouriteStorage -import ml.adamsprogs.bimba.models.Favourite -import ml.adamsprogs.bimba.models.adapters.FavouriteEditRowAdapter - - -class EditFavouriteActivity : AppCompatActivity() { - companion object { - const val EXTRA_FAVOURITE = "favourite" - const val EXTRA_POSITION_BEFORE = "position_before" - const val EXTRA_NEW_NAME = "new_name" - } - - private lateinit var favourites: FavouriteStorage - private lateinit var nameEdit: EditText - private var favourite: Favourite? = null - private var positionBefore: Int? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_edit_favourite) - - favourite = intent.getParcelableExtra(EXTRA_FAVOURITE) - positionBefore = intent.getIntExtra(EXTRA_POSITION_BEFORE, -1) - if (favourite == null) - finish() - favourites = FavouriteStorage.getFavouriteStorage(this) - - val recyclerView = favourite_edit_list - val layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this) - recyclerView!!.layoutManager = layoutManager - val dividerItemDecoration = androidx.recyclerview.widget.DividerItemDecoration(this, layoutManager.orientation) - recyclerView.addItemDecoration(dividerItemDecoration) - recyclerView.adapter = FavouriteEditRowAdapter(favourite!!, favourite_edit_loading, favourite_edit_list) - setSupportActionBar(toolbar) - supportActionBar?.title = getString(R.string.edit_favourite_title, favourite!!.name) - nameEdit = favourite_name_edit - nameEdit.setText(favourite!!.name) - } - - override fun onBackPressed() { - favourites.rename(favourite?.name!!, nameEdit.text.toString()) - val returnIntent = Intent() - returnIntent.putExtra(EXTRA_POSITION_BEFORE, positionBefore) - returnIntent.putExtra(EXTRA_NEW_NAME, nameEdit.text.toString()) - setResult(Activity.RESULT_OK, returnIntent) - super.onBackPressed() - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/LineSpecifyActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/LineSpecifyActivity.kt deleted file mode 100644 index 79f7b0e63feb2b36c529c64ba63418a83a215ff6..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/LineSpecifyActivity.kt +++ /dev/null @@ -1,79 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.appcompat.app.AppCompatActivity -import com.google.android.material.tabs.TabLayout -import kotlinx.android.synthetic.main.activity_line_specify.* -import kotlinx.android.synthetic.main.fragment_line_specify.view.* -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.models.Timetable - -class LineSpecifyActivity : AppCompatActivity() { - companion object { - const val EXTRA_LINE_ID = "line_id" - } - - private var sectionsPagerAdapter: SectionsPagerAdapter? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_line_specify) - - setSupportActionBar(toolbar) - supportActionBar?.setDisplayHomeAsUpEnabled(true) - - val line = intent.getStringExtra(EXTRA_LINE_ID) - - val timetable = Timetable.getTimetable() - val graphs = timetable.getTripGraphs(line) - - sectionsPagerAdapter = SectionsPagerAdapter(supportFragmentManager, graphs) - - container.adapter = sectionsPagerAdapter - - for (i in 0 until tabs.tabCount) { - tabs.getTabAt(i)?.text = graphs[i].headsign - } - - container.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tabs)) - tabs.addOnTabSelectedListener(TabLayout.ViewPagerOnTabSelectedListener(container)) - } - - inner class SectionsPagerAdapter(fm: androidx.fragment.app.FragmentManager, private val graphs: Array<Timetable.TripGraph>) : androidx.fragment.app.FragmentPagerAdapter(fm) { - - override fun getItem(position: Int): androidx.fragment.app.Fragment { - return PlaceholderFragment.newInstance(position + 1, graphs[position]) - } - - override fun getCount() = 2 - } - - class PlaceholderFragment : androidx.fragment.app.Fragment() { - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { - val rootView = inflater.inflate(R.layout.fragment_line_specify, container, false) - rootView.section_label.text = arguments?.getString("graph") //todo draw it + clickable - return rootView - } - - companion object { - private const val ARG_SECTION_NUMBER = "section_number" - - fun newInstance(sectionNumber: Int, graph: Timetable.TripGraph): PlaceholderFragment { - val fragment = PlaceholderFragment() - val args = Bundle() - args.putInt(ARG_SECTION_NUMBER, sectionNumber) - - //todo serialise graph // or draw and pass image - //args.putString("graph", graph.first.map { "${it.key}: ${it.value.joinToString(", ")}" }.joinToString("\n")) - - fragment.arguments = args - return fragment - } - } - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/SettingsActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/SettingsActivity.kt deleted file mode 100644 index a05be9afc33eba5fe1030e4538f9330b44ff01c7..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/SettingsActivity.kt +++ /dev/null @@ -1,59 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.preference.* -import android.os.Bundle -import androidx.core.app.NavUtils -import android.view.MenuItem -import kotlinx.android.synthetic.main.activity_settings.* - -import ml.adamsprogs.bimba.* - -class SettingsActivity: AppCompatPreferenceActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_settings) - setSupportActionBar(toolbar) - supportActionBar.setDisplayHomeAsUpEnabled(true) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - android.R.id.home -> { - NavUtils.navigateUpFromSameTask(this) - return true - } - } - return super.onOptionsItemSelected(item) - } - - class MainPreferenceFragment : PreferenceFragment() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - addPreferencesFromResource(R.xml.pref_main) - - bindPreferenceSummaryToValue(findPreference(getString(R.string.key_timetable_source_url))) - } - - private fun bindPreferenceSummaryToValue(preference: Preference) { - preference.onPreferenceChangeListener = bindPreferenceSummaryToValueListener - - bindPreferenceSummaryToValueListener.onPreferenceChange(preference, - PreferenceManager - .getDefaultSharedPreferences(preference.context) - .getString(preference.key, "")) - } - - private val bindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, newValue -> - val stringValue = newValue.toString() - if (preference is EditTextPreference) { - if (preference.getKey() == getString(R.string.key_timetable_source_url)) { - preference.summary = stringValue - } - } else { - preference.summary = stringValue - } - true - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/SplashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/SplashActivity.kt deleted file mode 100644 index ff18b865168fce18b51c8abb639f0b194051a12d..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/SplashActivity.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.content.Intent -import android.os.Bundle -import androidx.appcompat.app.AppCompatActivity -import androidx.appcompat.app.AppCompatDelegate - - -class SplashActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO) - startActivity(Intent(this, DashActivity::class.java)) - finish() - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt deleted file mode 100644 index 425c9d04d2798f49ec0fd81ec4b72cb41e13554a..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt +++ /dev/null @@ -1,285 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.content.DialogInterface -import android.content.Intent -import android.content.IntentFilter -import android.os.Build -import android.os.Bundle -import android.text.Html -import android.view.Menu -import android.view.MenuItem -import android.view.View -import android.widget.AdapterView -import androidx.appcompat.app.AlertDialog -import androidx.appcompat.app.AppCompatActivity -import androidx.core.content.res.ResourcesCompat -import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.activity_stop.* -import kotlinx.android.synthetic.main.banner.* -import ml.adamsprogs.bimba.* -import ml.adamsprogs.bimba.collections.FavouriteStorage -import ml.adamsprogs.bimba.datasources.TimetableDownloader -import ml.adamsprogs.bimba.datasources.VmService -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Favourite -import ml.adamsprogs.bimba.models.Plate -import ml.adamsprogs.bimba.models.StopSegment -import ml.adamsprogs.bimba.models.adapters.DeparturesAdapter -import ml.adamsprogs.bimba.models.adapters.ServiceAdapter -import java.util.Calendar -import kotlin.collections.HashMap -import kotlin.collections.HashSet -import kotlin.collections.set - -class StopActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener, ProviderProxy.OnDeparturesReadyListener { - companion object { - const val EXTRA_STOP_CODE = "stopCode" - const val EXTRA_STOP_NAME = "stopName" - const val EXTRA_FAVOURITE = "favourite" - const val SOURCE_TYPE = "sourceType" - const val SOURCE_TYPE_STOP = "stop" - const val SOURCE_TYPE_FAV = "favourite" - - const val TIMETABLE_TYPE_DEPARTURE = "timetable_type_departure" - const val TIMETABLE_TYPE_FULL = "timetable_type_full" - } - - private var stopCode = "" - private var favourite: Favourite? = null - private var timetableType = TIMETABLE_TYPE_DEPARTURE - private val context = this - private val receiver = MessageReceiver.getMessageReceiver() - private lateinit var providerProxy: ProviderProxy - private val departures = HashMap<Plate.ID, List<Departure>>() - private val fullDepartures = HashMap<String, List<Departure>>() - private lateinit var subscriptionId: String - private lateinit var adapter: DeparturesAdapter - - - private lateinit var sourceType: String - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_stop) - - providerProxy = ProviderProxy(this) - - sourceType = intent.getStringExtra(SOURCE_TYPE) - - setSupportActionBar(toolbar) - - when (sourceType) { - SOURCE_TYPE_STOP -> { - stopCode = intent.getSerializableExtra(EXTRA_STOP_CODE) as String - supportActionBar?.title = intent.getSerializableExtra(EXTRA_STOP_NAME) as String - } - SOURCE_TYPE_FAV -> { - favourite = intent.getParcelableExtra(EXTRA_FAVOURITE) - supportActionBar?.title = favourite!!.name - } - } - - showFab() - - val layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this) - departuresList.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(departuresList.context, layoutManager.orientation)) - departuresList.adapter = DeparturesAdapter(this, null, true) - adapter = departuresList.adapter as DeparturesAdapter - departuresList.layoutManager = layoutManager - - departuresList.addOnScrollListener(object : androidx.recyclerview.widget.RecyclerView.OnScrollListener() { - override fun onScrollStateChanged(recyclerView: androidx.recyclerview.widget.RecyclerView, newState: Int) {} - override fun onScrolled(recyclerView: androidx.recyclerview.widget.RecyclerView, dx: Int, dy: Int) { - updateFabVisibility(dy) - super.onScrolled(recyclerView, dx, dy) - } - }) - - if (stopCode != "") - providerProxy.getVmMessage(stopCode) { message -> - if (message != null) { - val rendered = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY).toString() - } else { - @Suppress("DEPRECATION") - Html.fromHtml(message).toString() - } - - banner.visibility = View.VISIBLE - banner_text.text = rendered - banner_more.setOnClickListener { - AlertDialog.Builder(context) - .setPositiveButton(context.getText(android.R.string.ok)) - { dialog: DialogInterface, _: Int -> dialog.cancel() } - .setCancelable(true) - .setMessage(rendered) - .create().show() - } - } - } - - prepareOnDownloadListener() - subscribeForDepartures() - } - - private fun showFab() { - if (sourceType == SOURCE_TYPE_FAV) - return - - val favourites = FavouriteStorage.getFavouriteStorage(context) - if (!favourites.has(stopCode)) { - fab.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_favourite_empty, this.theme)) - } - - fab.setOnClickListener { - if (!favourites.has(stopCode)) { - val items = HashSet<StopSegment>() - items.add(StopSegment(stopCode, null)) - favourites.add(stopCode, items, this@StopActivity) - fab.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_favourite, this.theme)) - } else { - Snackbar.make(it, getString(R.string.stop_already_fav), Snackbar.LENGTH_LONG) - .setAction("Action", null).show() - } - } - } - - //fixme<p:5> maybe better effects - private fun updateFabVisibility(dy: Int) { - if (fab == null) - return - if (dy > 0) { - fab.hide() - } else { - fab.show() - } - } - - private fun prepareOnDownloadListener() { - val filter = IntentFilter(TimetableDownloader.ACTION_DOWNLOADED) - filter.addAction(VmService.ACTION_READY) - filter.addCategory(Intent.CATEGORY_DEFAULT) - registerReceiver(receiver, filter) - receiver.addOnTimetableDownloadListener(context) - } - - private fun subscribeForDepartures() { - subscriptionId = if (sourceType == SOURCE_TYPE_STOP) { - providerProxy.subscribeForDepartures(stopCode, this, this) - } else - favourite!!.subscribeForDepartures(this, context) - } - - override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) { - progressBar.visibility = View.GONE - showError(stop_layout, code, this) - if (plateId == null) { - this.departures.clear() - this.departures[Plate.ID.dummy] = departures - } else { - this.departures.remove(Plate.ID.dummy) - this.departures[plateId] = departures - } - if (timetableType == TIMETABLE_TYPE_FULL) - return - refreshAdapter() - if (adapter.departures?.isEmpty() != false) { - emptyStateIcon.visibility = View.VISIBLE - emptyStateText.visibility = View.VISIBLE - departuresList.visibility = View.GONE - } else { - emptyStateIcon.visibility = View.GONE - emptyStateText.visibility = View.GONE - departuresList.visibility = View.VISIBLE - } - } - - private fun refreshAdapter() { - if (timetableType == TIMETABLE_TYPE_FULL) { - @Suppress("UNCHECKED_CAST") - adapter.departures = fullDepartures[(dateSpinner.selectedItem as ServiceAdapter.RowItem).service] - } else { - val now = Calendar.getInstance() - val seconds = now.secondsAfterMidnight() - adapter.departures = this.departures.flatMap { it.value }.sortedBy { (if (it.onStop) 0 else 1) * 172800 + it.timeTill(seconds) } // todo sorted by also onStop - } - adapter.notifyDataSetChanged() - } - - override fun onTimetableDownload(result: String?) { - val message: String = when (result) { - TimetableDownloader.RESULT_NO_CONNECTIVITY -> getString(R.string.no_connectivity_cant_update) - TimetableDownloader.RESULT_UP_TO_DATE -> getString(R.string.timetable_up_to_date) - TimetableDownloader.RESULT_FINISHED -> getString(R.string.timetable_downloaded) - else -> getString(R.string.error_try_later) - } - try { - Snackbar.make(findViewById(R.id.stop_layout), message, Snackbar.LENGTH_LONG).show() - } catch (e: IllegalArgumentException) { - } - providerProxy.refreshTimetable(this) - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - if (providerProxy.mode == ProviderProxy.MODE_FULL) - menuInflater.inflate(R.menu.menu_stop, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - val id = item.itemId - - if (id == R.id.action_change_type) { - if (timetableType == TIMETABLE_TYPE_DEPARTURE) { - timetableType = TIMETABLE_TYPE_FULL - - item.icon = (ResourcesCompat.getDrawable(resources, R.drawable.ic_timetable_departure, this.theme)) - adapter.relativeTime = false - if (fullDepartures.isEmpty()) - if (sourceType == SOURCE_TYPE_STOP) - fullDepartures.putAll(providerProxy.getFullTimetable(stopCode)) - else - fullDepartures.putAll(favourite!!.fullTimetable()) - - dateSpinner.let { spinner -> - spinner.adapter = ServiceAdapter(this, R.layout.toolbar_spinner_item, fullDepartures.keys.map { - ServiceAdapter.RowItem(it, providerProxy.describeService(it, this)!!) - }.sorted()).apply { - setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - } - spinner.visibility = View.VISIBLE - spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - refreshAdapter() - } - - override fun onNothingSelected(parent: AdapterView<*>?) { - } - - } - } - - refreshAdapter() - } else { - dateSpinner.visibility = View.GONE - timetableType = TIMETABLE_TYPE_DEPARTURE - item.icon = (ResourcesCompat.getDrawable(resources, R.drawable.ic_timetable_full, this.theme)) - adapter.relativeTime = true - refreshAdapter() - } - return true - } - - return super.onOptionsItemSelected(item) - } - - override fun onDestroy() { - super.onDestroy() - receiver.removeOnTimetableDownloadListener(context) - if (sourceType == SOURCE_TYPE_STOP) - providerProxy.unsubscribeFromDepartures(subscriptionId, this) - else - favourite!!.unsubscribeFromDepartures(this) - unregisterReceiver(receiver) - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt deleted file mode 100644 index e2db35f26607e62e800fa323755b65b7bab5d34e..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt +++ /dev/null @@ -1,76 +0,0 @@ -package ml.adamsprogs.bimba.activities - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.appcompat.app.AppCompatActivity -import kotlinx.android.synthetic.main.activity_stop_specify.* -import ml.adamsprogs.bimba.ProviderProxy -import ml.adamsprogs.bimba.R - -class StopSpecifyActivity : AppCompatActivity() { - - companion object { - const val EXTRA_STOP_NAME = "stopName" - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_stop_specify) - - val name = intent.getStringExtra(EXTRA_STOP_NAME) - val providerProxy = ProviderProxy(this) - providerProxy.getSheds(name) { - progressBar.visibility = View.GONE - val layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this) - val departuresList: androidx.recyclerview.widget.RecyclerView = list_view - - departuresList.adapter = ShedAdapter(this, it, name) - departuresList.layoutManager = layoutManager - } - /*val timetable = Timetable.getTimetable(this) - val headlines = timetable.getHeadlinesForStop(name)*/ - - - setSupportActionBar(toolbar) - supportActionBar?.title = name - } - - class ShedAdapter(val context: Context, private val values: Map<String, Set<String>>, private val stopName: String) : - androidx.recyclerview.widget.RecyclerView.Adapter<ShedAdapter.ViewHolder>() { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val context = parent.context - val inflater = LayoutInflater.from(context) - - val rowView = inflater.inflate(R.layout.row_shed, parent, false) - return ViewHolder(rowView) - } - - override fun getItemCount(): Int = values.size - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.root.setOnClickListener { - val code = values.keys.sorted()[position] - val intent = Intent(context, StopActivity::class.java) - intent.putExtra(StopActivity.SOURCE_TYPE, StopActivity.SOURCE_TYPE_STOP) - intent.putExtra(StopActivity.EXTRA_STOP_CODE, code) - intent.putExtra(StopActivity.EXTRA_STOP_NAME, stopName) - context.startActivity(intent) - } - holder.stopCode.text = values.keys.sorted()[position] - holder.stopHeadlines.text = values.entries.sortedBy { it.key }[position].value - .sortedBy { it.split(" → ")[0].padStart(4, '0') } - .joinToString() - } - - inner class ViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) { - val root = itemView.findViewById<View>(R.id.shed_row)!! - val stopCode: TextView = itemView.findViewById(R.id.stop_code) - val stopHeadlines: TextView = itemView.findViewById(R.id.stop_headlines) - } - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/collections/FavouriteStorage.kt b/app/src/main/java/ml/adamsprogs/bimba/collections/FavouriteStorage.kt deleted file mode 100644 index 38292650494637faefb6a23f1b8b6b6050752dbb..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/collections/FavouriteStorage.kt +++ /dev/null @@ -1,188 +0,0 @@ -package ml.adamsprogs.bimba.collections - -import android.content.Context -import android.content.SharedPreferences -import com.google.gson.* -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Favourite -import ml.adamsprogs.bimba.models.Plate -import ml.adamsprogs.bimba.models.StopSegment -import ml.adamsprogs.bimba.secondsAfterMidnight -import java.util.Calendar -import kotlin.collections.ArrayList -import kotlin.collections.HashMap -import kotlin.collections.HashSet -import kotlin.collections.component1 -import kotlin.collections.component2 -import kotlin.collections.set - - -class FavouriteStorage private constructor(context: Context) : Iterable<Favourite> { - companion object { - private var favouriteStorage: FavouriteStorage? = null - fun getFavouriteStorage(context: Context? = null): FavouriteStorage { - return if (favouriteStorage == null) { - if (context == null) - throw IllegalArgumentException("requested new storage appContext not given") - else { - favouriteStorage = FavouriteStorage(context) - favouriteStorage as FavouriteStorage - } - } else - favouriteStorage as FavouriteStorage - } - } - - val favourites = HashMap<String, Favourite>() - private val positionIndex = IndexableTreeSet<String>() - private val preferences: SharedPreferences = context.getSharedPreferences("ml.adamsprogs.bimba.prefs", Context.MODE_PRIVATE) - - init { - val favouritesString = preferences.getString("favourites", "{}") - JsonParser().parse(favouritesString).asJsonObject.entrySet().forEach { (name, timetables) -> - timetables.asJsonArray.map { - val plates = it.asJsonObject["plates"].let { element -> - if (element == null || element.isJsonNull) - null - else { - element.asJsonArray.map { it -> - it.asJsonObject.let { id -> - Plate.ID(id["line"].asString, id["stop"].asString, id["headsign"].asString) - } - }.toHashSet() - } - } - StopSegment(it.asJsonObject["stop"].asString, plates) - }.toHashSet().let { - favourites[name] = Favourite(name, it, context) - } - positionIndex.add(name) - } - } - - override fun iterator(): Iterator<Favourite> = favourites.values.iterator() - - fun has(name: String): Boolean = favourites.contains(name) - - fun add(name: String, timetables: HashSet<StopSegment>, context: Context) { - if (favourites[name] == null) { - favourites[name] = Favourite(name, timetables, context) - addIndex(name) - serialize() - } - } - - fun add(name: String, favourite: Favourite) { - if (favourites[name] == null) { - favourites[name] = favourite - addIndex(name) - serialize() - } - } - - private fun addIndex(name: String) { - positionIndex.add(name) - } - - fun delete(name: String) { - favourites.remove(name) - positionIndex.remove(name) - serialize() - } - - fun delete(name: String, plate: Plate.ID): Boolean { - return favourites[name]?.delete(plate).let { - serialize() - it - } ?: false - } - - private fun serialize() { - val rootObject = JsonObject() - for ((name, favourite) in favourites) { - val timetables = JsonArray() - for (timetable in favourite.segments) { - val segment = JsonObject() - segment.addProperty("stop", timetable.stop) - val plates = - if (timetable.plates == null) - JsonNull.INSTANCE - else - JsonArray().apply { - for (plate in timetable.plates ?: HashSet()) { - val element = JsonObject() - element.addProperty("stop", plate.stop) - element.addProperty("line", plate.line) - element.addProperty("headsign", plate.headsign) - add(element) - } - } - segment.add("plates", plates) - timetables.add(segment) - } - rootObject.add(name, timetables) - } - val favouritesString = Gson().toJson(rootObject) - val editor = preferences.edit() - editor.putString("favourites", favouritesString) - editor.apply() - } - - fun merge(names: List<String>, context: Context) { - if (names.size < 2) - return - - val newCache = HashMap<String, ArrayList<Departure>>() - names.forEach { name -> - favourites[name]!!.fullTimetable().forEach { - if (newCache[it.key] == null) - newCache[it.key] = ArrayList() - newCache[it.key]!!.addAll(it.value) - } - } - val now = Calendar.getInstance().secondsAfterMidnight() - newCache.forEach { entry -> - entry.value.sortBy { it.timeTill(now) } - } - val newFavourite = Favourite(names[0], HashSet(), newCache, context) - for (name in names) { - newFavourite.segments.addAll(favourites[name]!!.segments) - favourites.remove(name) - positionIndex.remove(name) - } - favourites[names[0]] = newFavourite - addIndex(names[0]) - - serialize() - } - - fun rename(oldName: String, newName: String) { - val favourite = favourites[oldName] ?: return - favourite.rename(newName) - favourites.remove(oldName) - positionIndex.remove(oldName) - favourites[newName] = favourite - addIndex(newName) - serialize() - } - - operator fun get(name: String): Favourite? { - return favourites[name] - } - - operator fun get(position: Int): Favourite? { - return favourites[positionIndex[position]] - } - - operator fun set(name: String, value: Favourite) { - favourites[name] = value - serialize() - } - - fun indexOf(name: String): Int { - return positionIndex.indexOf(name) - } - - val size - get() = favourites.size -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/collections/IndexableTreeSet.kt b/app/src/main/java/ml/adamsprogs/bimba/collections/IndexableTreeSet.kt deleted file mode 100644 index 19719f1a61a394bd4cf61dcd35e09ac21a0dc08a..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/collections/IndexableTreeSet.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ml.adamsprogs.bimba.collections - -import java.util.TreeSet - -class IndexableTreeSet<T>: TreeSet<T>() { - operator fun get(position: Int): T { - @Suppress("UNCHECKED_CAST") - return this.toArray()[position] as T - } - -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt deleted file mode 100644 index 8eb2b34377ea9f1abf1093d2c3928a5cff204f9d..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/datasources/TimetableDownloader.kt +++ /dev/null @@ -1,165 +0,0 @@ -package ml.adamsprogs.bimba.datasources - -import android.annotation.TargetApi -import android.app.IntentService -import android.app.Notification -import android.app.NotificationManager -import android.content.Context -import android.content.Intent -import android.os.Build -import android.preference.PreferenceManager.getDefaultSharedPreferences -import androidx.core.app.NotificationCompat -import ml.adamsprogs.bimba.* -import java.io.EOFException -import java.io.File -import java.io.FileOutputStream -import java.io.IOException -import java.net.ConnectException -import java.net.HttpURLConnection -import java.net.URL -import java.util.zip.GZIPInputStream -import javax.net.ssl.HttpsURLConnection -import javax.net.ssl.SSLException - -class TimetableDownloader : IntentService("TimetableDownloader") { - companion object { - const val ACTION_DOWNLOADED = "ml.adamsprogs.bimba.timetableDownloaded" - const val EXTRA_RESULT = "result" - const val RESULT_NO_CONNECTIVITY = "no connectivity" - const val RESULT_UP_TO_DATE = "up-to-date" - const val RESULT_FINISHED = "finished" - } - - private lateinit var notificationManager: NotificationManager - private var sizeCompressed: Int = 0 - private var sizeUncompressed: Int = 0 - - override fun onHandleIntent(intent: Intent?) { - - if (intent != null) { - notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - val prefs = this.getSharedPreferences("ml.adamsprogs.bimba.prefs", Context.MODE_PRIVATE)!! - if (!NetworkStateReceiver.isNetworkAvailable()) { - sendResult(RESULT_NO_CONNECTIVITY) - return - } - - val localETag = prefs.getString("etag", "") - - val httpCon: HttpURLConnection - try { - var sourceUrl = getDefaultSharedPreferences(this).getString(getString(R.string.key_timetable_source_url), getString(R.string.timetable_source_url))!! - sourceUrl = sourceUrl.replace(Regex("^.*://", RegexOption.IGNORE_CASE), "") - sourceUrl = "https://$sourceUrl" - val url = URL(sourceUrl) - try { - httpCon = url.openConnection() as HttpsURLConnection - httpCon.addRequestProperty("If-None-Match", localETag) - httpCon.connect() - } catch (e: SSLException) { - sendResult(RESULT_NO_CONNECTIVITY) - return - } - if (httpCon.responseCode == HttpsURLConnection.HTTP_NOT_MODIFIED) { - sendResult(RESULT_UP_TO_DATE) - return - } - if (httpCon.responseCode != HttpsURLConnection.HTTP_OK) { - sendResult(RESULT_NO_CONNECTIVITY) - return - } - } catch (e: IOException) { - sendResult(RESULT_NO_CONNECTIVITY) - return - } catch (e: EOFException) { - sendResult(RESULT_NO_CONNECTIVITY) - return - } catch (e: ConnectException) { - sendResult(RESULT_NO_CONNECTIVITY) - return - } - - val newETag = httpCon.getHeaderField("ETag") - sizeCompressed = httpCon.getHeaderField("Content-Length").toInt() / 1024 - sizeUncompressed = httpCon.getHeaderField("X-Uncompressed-Content-Length").toInt() / 1024 - - notify(0, R.string.timetable_downloading, R.string.timetable_downloading_progress, R.string.timetable_decompressing, sizeCompressed, sizeUncompressed) - - - val gtfsDb = File(getSecondaryExternalFilesDir(), "timetable_new.db") - - val inputStream = httpCon.inputStream - val gzipInputStream = GZIPInputStream(inputStream) - val outputStream = FileOutputStream(gtfsDb) - - gzipInputStream.listenableCopyTo(outputStream) { - notify((it / 1024).toInt(), R.string.timetable_downloading, R.string.timetable_downloading_progress, R.string.timetable_decompressing, sizeCompressed, sizeUncompressed) - } - - val prefsEditor = prefs.edit() - prefsEditor.putString("etag", newETag) - prefsEditor.apply() - - val oldDb = File(getSecondaryExternalFilesDir(), "timetable.db") - gtfsDb.renameTo(oldDb) // todo<p:1> delete old before downloading (may require stopping VmService), and mutex with VmService - - cancelNotification() - - sendResult(RESULT_FINISHED) - } - } - - private fun sendResult(result: String) { - val broadcastIntent = Intent() - broadcastIntent.action = ACTION_DOWNLOADED - broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT) - broadcastIntent.putExtra(EXTRA_RESULT, result) - sendBroadcast(broadcastIntent) - } - - private fun notify(downloadedKBytes: Int, titleId: Int, dwdMessageId: Int, dcmMessageId: Int, sizeCompressed: Int, sizeUncompressed: Int) { - val progress = Math.min(downloadedKBytes, sizeCompressed) - val message = if (progress < sizeCompressed) - getString(dwdMessageId, - progress / 1024F, sizeCompressed / 1024F) - else - "" - val title = if (progress < sizeCompressed) - getString(titleId) - else - getString(dcmMessageId) - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) - notifyCompat(downloadedKBytes, title, message, sizeUncompressed) - else - notifyStandard(downloadedKBytes, title, message, sizeUncompressed) - } - - @Suppress("DEPRECATION") - private fun notifyCompat(progress: Int, title: String, message: String, max: Int) { - val builder = NotificationCompat.Builder(this) - .setSmallIcon(R.drawable.ic_download) - .setContentTitle(title) - .setContentText(message) - .setCategory(NotificationCompat.CATEGORY_PROGRESS) - .setOngoing(true) - .setProgress(max, progress, false) - notificationManager.notify(42, builder.build()) - } - - @TargetApi(Build.VERSION_CODES.O) - private fun notifyStandard(progress: Int, title: String, message: String, max: Int) { - NotificationChannels.makeChannel(NotificationChannels.CHANNEL_UPDATES, "Updates", notificationManager) - val builder = Notification.Builder(this, NotificationChannels.CHANNEL_UPDATES) - .setSmallIcon(R.drawable.ic_download) - .setContentTitle(title) - .setContentText(message) - .setCategory(Notification.CATEGORY_PROGRESS) - .setOngoing(true) - .setProgress(max, progress, false) - notificationManager.notify(42, builder.build()) - } - - private fun cancelNotification() { - notificationManager.cancel(42) - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt deleted file mode 100644 index 69fac3a1226caa3f5f664310cbb3e9fd5601b0c7..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt +++ /dev/null @@ -1,156 +0,0 @@ -package ml.adamsprogs.bimba.datasources - -import com.google.gson.Gson -import com.google.gson.JsonObject -import com.google.gson.JsonSyntaxException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import ml.adamsprogs.bimba.NetworkStateReceiver -import ml.adamsprogs.bimba.models.Plate -import ml.adamsprogs.bimba.models.StopSegment -import ml.adamsprogs.bimba.models.suggestions.StopSuggestion -import okhttp3.MediaType -import okhttp3.OkHttpClient -import okhttp3.RequestBody -import java.io.IOException -import java.util.* -import kotlin.collections.HashMap -import kotlin.collections.HashSet - -class VmClient { - companion object { - private var vmClient: VmClient? = null - - fun getVmClient(): VmClient { - if (vmClient == null) - vmClient = VmClient() - return vmClient!! - } - } - - suspend fun getSheds(name: String): Map<String, Set<String>> { - val (_, response) = makeRequest("getBollardsByStopPoint", """{"name": "$name"}""") - if (!response.has("success")) - return emptyMap() - val rootObject = response["success"].asJsonObject["bollards"].asJsonArray - val result = HashMap<String, Set<String>>() - rootObject.forEach { element -> - val code = element.asJsonObject["bollard"].asJsonObject["tag"].asString - result[code] = element.asJsonObject["directions"].asJsonArray.map { - """${it.asJsonObject["lineName"].asString} → ${it.asJsonObject["direction"].asString}""" - }.toSet() - } - return result - } - - /* - suspend fun getPlatesByStopPoint(code: String): Set<Plate.ID>? { - val getTimesResponse = makeRequest("getTimes", """{"symbol": "$code"}""") - val name = getTimesResponse["success"].asJsonObject["bollard"].asJsonObject["name"].asString - - val bollards = getBollardsByStopPoint(name) - return bollards.filter { - it.key == code - }.values.flatMap { - it.map { - val (line, headsign) = it.split(" → ") - Plate.ID(AgencyAndId(line), AgencyAndId(code), headsign) - } - }.toSet() - }*/ - - suspend fun getStops(pattern: String): List<StopSuggestion> { - val (_, response) = withContext(Dispatchers.Default) { - makeRequest("getStopPoints", """{"pattern": "$pattern"}""") - } - - if (!response.has("success")) - return emptyList() - - val points = response["success"].asJsonArray.map { it.asJsonObject } - - val names = HashSet<String>() - - points.forEach { - val name = it["name"].asString - names.add(name) - } - - return names.map { StopSuggestion(it, "") } - } - - suspend fun makeRequest(method: String, data: String): Pair<Int, JsonObject> { - if (!NetworkStateReceiver.isNetworkAvailable()) - return Pair(0, JsonObject()) - - val client = OkHttpClient() - val url = "http://www.peka.poznan.pl/vm/method.vm?ts=${Calendar.getInstance().timeInMillis}" - val body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded; charset=UTF-8"), - "method=$method&p0=$data") - val request = okhttp3.Request.Builder() - .url(url) - .post(body) - .build() - - - var responseBody: String? = null - var responseCode = 0 - try { - withContext(Dispatchers.Default) { - client.newCall(request).execute().let { - responseCode = it.code() - responseBody = it.body()?.string() - } - } - } catch (e: IOException) { - return Pair(0, JsonObject()) - } - - return try { - Pair(responseCode, Gson().fromJson(responseBody, JsonObject::class.java)) - } catch (e: JsonSyntaxException) { - Pair(responseCode, JsonObject()) - } - } - - suspend fun getName(symbol: String): String? { - val (_, timesResponse) = withContext(Dispatchers.Default) { - makeRequest("getTimes", """{"symbol": "$symbol"}""") - } - if (!timesResponse.has("success")) - return null - - return timesResponse["success"].asJsonObject["bollard"].asJsonObject["name"].asString - } - - suspend fun getDirections(symbol: String): StopSegment? { - val name = getName(symbol) - val (_, directionsResponse) = withContext(Dispatchers.Default) { - makeRequest("getBollardsByStopPoint", """{"name": "$name"}""") - } - - if (!directionsResponse.has("success")) - return null - - return StopSegment(symbol, - directionsResponse["success"].asJsonObject["bollards"].asJsonArray.filter { - it.asJsonObject["bollard"].asJsonObject["tag"].asString == symbol - }[0].asJsonObject["directions"].asJsonArray.map { - it.asJsonObject.let { direction -> - Plate.ID(direction["lineName"].asString, symbol, direction["direction"].asString) - } - }.toSet()) - } - - suspend fun getMessage(shed: String): String? { - val (_, response) = makeRequest("findMessagesForBollard", """{"symbol": "$shed"}""") - - if (!response.has("success")) - return null - - if (response["success"].asJsonArray.size() == 0) - return null - - return response["success"].asJsonArray[0].asJsonObject["content"].asString - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt deleted file mode 100644 index 72340432b5fe1edc2821048998f5cac1ab93aa20..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmService.kt +++ /dev/null @@ -1,203 +0,0 @@ -package ml.adamsprogs.bimba.datasources - -import android.app.Service -import android.content.Intent -import android.os.Handler -import android.os.HandlerThread -import android.os.IBinder -import android.os.Process.THREAD_PRIORITY_BACKGROUND -import com.google.gson.JsonObject -import kotlinx.coroutines.* -import ml.adamsprogs.bimba.NetworkStateReceiver -import ml.adamsprogs.bimba.calendarFromIso -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Plate -import ml.adamsprogs.bimba.secondsAfterMidnight -import java.util.* -import kotlin.collections.* - -class VmService : Service() { - companion object { - const val ACTION_READY = "ml.adamsprogs.bimba.action.vm.ready" - const val EXTRA_DEPARTURES = "ml.adamsprogs.bimba.extra.vm.departures" - const val EXTRA_PLATE_ID = "ml.adamsprogs.bimba.extra.vm.plate" - const val EXTRA_STOP_CODE = "ml.adamsprogs.bimba.extra.vm.stop" - const val EXTRA_CODE = "ml.adamsprogs.bimba.extra.vm.code" - const val TICK_6_ZINA_TIM = 12500L - } - - private var handler: Handler? = null - private val tick6ZinaTim: Runnable = object : Runnable { - override fun run() { - handler!!.postDelayed(this, TICK_6_ZINA_TIM) - try { - for (plateId in requests.keys) - GlobalScope.launch { - downloadVM() - } - } catch (e: IllegalArgumentException) { - } - } - } - private val requests = HashMap<String, Int>() - private val vms = HashMap<String, Set<Plate>>() - - override fun onCreate() { - val thread = HandlerThread("ServiceStartArguments", THREAD_PRIORITY_BACKGROUND) - thread.start() - handler = Handler(thread.looper) - handler!!.postDelayed(tick6ZinaTim, TICK_6_ZINA_TIM) - } - - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - if (intent == null) - return START_STICKY - val stopCode = intent.getStringExtra("stop")!! - val action = intent.action - val once = intent.getBooleanExtra("once", false) - if (action == "request") { - if (isAlreadyRequested(stopCode)) { - incrementRequest(stopCode) - sendResult(stopCode) - } else { - if (!once) - addRequest(stopCode) - GlobalScope.launch { - downloadVM(stopCode) - } - } - } else if (action == "remove") { - decrementRequest(stopCode) - cleanRequests() - } - return START_STICKY - } - - private fun cleanRequests() { - val newRequests = requests.filter { it.value > 0 } - requests.clear() - newRequests.forEach { - requests[it.key] = it.value - } - } - - private fun addRequest(stopCode: String) { - if (requests[stopCode] == null) - requests[stopCode] = 0 - requests[stopCode] = requests[stopCode]!! + 1 - } - - private fun incrementRequest(stopCode: String) { - requests[stopCode] = requests[stopCode]!! + 1 - } - - private fun decrementRequest(stopCode: String) { - requests[stopCode] = requests[stopCode]!! - 1 - } - - private fun isAlreadyRequested(stopCode: String): Boolean { - return stopCode in requests - } - - - override fun onBind(intent: Intent): IBinder? { - return null - } - - override fun onDestroy() { - } - - @Synchronized - private suspend fun downloadVM() { - vms.forEach { - downloadVM(it.key) - } - } - - @Synchronized - private suspend fun downloadVM(stopCode: String) { - if (!NetworkStateReceiver.isNetworkAvailable()) { - vms[stopCode] = emptySet() - sendResult(stopCode, null, null, 0) - return - } - - val (code, javaRootMapObject) = withContext(Dispatchers.Default) { - VmClient.getVmClient().makeRequest("getTimes", """{"symbol": "$stopCode"}""") - } - - if (!javaRootMapObject.has("success")) { - sendResult(stopCode, null, null, code) - return - } - - val times = (javaRootMapObject["success"].asJsonObject)["times"].asJsonArray.map { it.asJsonObject } - parseTimes(stopCode, times) - } - - private fun parseTimes(stopCode: String, times: List<JsonObject>) { - val date = Calendar.getInstance() - val todayDay = "${date.get(Calendar.DATE)}".padStart(2, '0') - - val departures = HashMap<Plate.ID, HashSet<Departure>>() - - times.forEach { - val thisLine = it["line"].asString - val thisHeadsign = it["direction"].asString - val thisPlateId = Plate.ID(thisLine, stopCode, thisHeadsign) - if (departures[thisPlateId] == null) - departures[thisPlateId] = HashSet() - val departureDay = (it["departure"].asString).split("T")[0].split("-")[2] - val departureTime = calendarFromIso(it["departure"].asString).secondsAfterMidnight() - var ticketMachine = Departure.TICKET_MACHINE_NONE - if (it.has("driversTicketMachine")) { - if (it["driversTicketMachine"].asBoolean) - ticketMachine = Departure.TICKET_MACHINE_DRIVER - } - if (it.has("ticketMachine")) { - if (it["ticketMachine"].asBoolean) - ticketMachine = Departure.TICKET_MACHINE_AUTOMAT - } - val lowFloor = if (it.has("lowFloorBus")) it["lowFloorBus"].asBoolean else false - val departure = Departure(thisLine, listOf(-1), departureTime, lowFloor, - ArrayList(), it["direction"].asString, it["realTime"].asBoolean, - departureDay != todayDay, it["onStopPoint"].asBoolean, ticketMachine) - departures[thisPlateId]!!.add(departure) - } - - departures.forEach { - val departuresForPlate = HashMap<Int, HashSet<Departure>>() - departuresForPlate[-1] = it.value - val vm = HashSet<Plate>() - vm.add(Plate(it.key, departuresForPlate)) - vms[stopCode] = vm - if (departures.isEmpty()) - sendResult(stopCode, it.key, null) - else - sendResult(stopCode, it.key, it.value) - } - - } - - private fun sendResult(stopCode: String) { - vms[stopCode]?.forEach { - sendResult(it.id.stop, it.id, it.departures?.get(-1)) - } - - } - - private fun sendResult(stopCode: String, plateId: Plate.ID?, departures: HashSet<Departure>?, code: Int = 200) { - val broadcastIntent = Intent() - broadcastIntent.action = ACTION_READY - broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT) - if (departures != null) - broadcastIntent.putStringArrayListExtra(EXTRA_DEPARTURES, departures.map { it.toString() } as ArrayList) - broadcastIntent.putExtra(EXTRA_CODE, code) - broadcastIntent.putExtra(EXTRA_PLATE_ID, plateId) - broadcastIntent.putExtra(EXTRA_STOP_CODE, stopCode) - sendBroadcast(broadcastIntent) - } -} - -//note application stops the service on exit - diff --git a/app/src/main/java/ml/adamsprogs/bimba/extensions.kt b/app/src/main/java/ml/adamsprogs/bimba/extensions.kt deleted file mode 100644 index ec86bc5c93eca92d2228020a27517054304315a0..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/extensions.kt +++ /dev/null @@ -1,126 +0,0 @@ -package ml.adamsprogs.bimba - -import android.annotation.SuppressLint -import android.content.Context -import android.graphics.drawable.Drawable -import android.os.Build -import android.text.format.DateFormat -import android.view.View -import com.google.android.material.snackbar.Snackbar -import java.io.File -import java.io.InputStream -import java.io.OutputStream -import java.text.SimpleDateFormat -import java.util.* -import kotlin.collections.ArrayList - -internal fun Calendar.rollTime(seconds: Int): Calendar { - val hour = seconds / 3600 - val minute = (seconds % 3600) / 60 - val second = (seconds % 60) - this.set(Calendar.HOUR_OF_DAY, hour) - this.set(Calendar.MINUTE, minute) - this.set(Calendar.SECOND, second) - this.set(Calendar.MILLISECOND, 0) - return this -} - -internal fun Calendar.secondsAfterMidnight(): Int { - val hour = this.get(Calendar.HOUR_OF_DAY) - val minute = this.get(Calendar.MINUTE) - val second = this.get(Calendar.SECOND) - return hour * 3600 + minute * 60 + second -} - -internal fun Calendar.toIsoDate(): String { - val year = this.get(Calendar.YEAR) - val month = String.format("%02d", this.get(Calendar.MONTH) + 1) - val day = String.format("%02d", this.get(Calendar.DAY_OF_MONTH)) - return "$year$month$day" -} - -const val ISO_8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" -const val ISO_8601_DATE_ONLY_FORMAT = "yyyyMMdd" - -@SuppressLint("SimpleDateFormat") -fun calendarFromIso(iso: String): Calendar { - val calendar = Calendar.getInstance() - val dateFormat = SimpleDateFormat(ISO_8601_DATE_FORMAT) - val date = dateFormat.parse(iso) - calendar.time = date - return calendar -} - -@SuppressLint("SimpleDateFormat") -fun calendarFromIsoD(iso: String): Calendar { - val calendar = Calendar.getInstance() - val dateFormat = SimpleDateFormat(ISO_8601_DATE_ONLY_FORMAT) - val date = dateFormat.parse(iso) - calendar.time = date - return calendar -} - -fun getDrawable(id: Int, context: Context): Drawable { - @Suppress("DEPRECATION") - (return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) - context.resources.getDrawable(id, null) - else - context.resources.getDrawable(id)) -} - -internal fun CharSequence.safeSplit(vararg delimiters: String, ignoreCase: Boolean = false, limit: Int = 0): List<String>? { - if (this == "null") - return null - if (this == "") - return ArrayList() - return this.split(*delimiters, ignoreCase = ignoreCase, limit = limit) -} - -internal fun Context.getSecondaryExternalFilesDir(): File { - val dirs = this.getExternalFilesDirs(null) - return dirs[0] -// return dirs[dirs.size - 1] -} - -internal fun InputStream.listenableCopyTo(out: OutputStream, bufferSize: Int = DEFAULT_BUFFER_SIZE, listener: (Long) -> Unit): Long { - var bytesCopied: Long = 0 - val buffer = ByteArray(bufferSize) - var bytes = read(buffer) - while (bytes >= 0) { - out.write(buffer, 0, bytes) - bytesCopied += bytes - listener(bytesCopied) - bytes = read(buffer) - } - return bytesCopied -} - -internal fun Calendar.toNiceString(context: Context, withTime: Boolean = false): String { - val dateFormat = DateFormat.getMediumDateFormat(context) - val timeFormat = DateFormat.getTimeFormat(context) - val now = Calendar.getInstance() - val date = if (get(Calendar.YEAR) == now.get(Calendar.YEAR)) { - when { - get(Calendar.DAY_OF_YEAR) == now.get(Calendar.DAY_OF_YEAR) -> timeFormat.format(time) - now.apply { add(Calendar.DATE, -1) }.get(Calendar.DAY_OF_YEAR) == get(Calendar.DAY_OF_YEAR) -> "Yesterday" - else -> DateFormat.format("d MMM" as CharSequence, this.time) as String - } - } else - dateFormat.format(this.time) - - return if (withTime) { - val time = timeFormat.format(this.time) - "$date, $time" - } else - date -} - -fun showError(view: View, code: Int, context: Context) { - val message = when { - code == 0 -> context.getString(R.string.no_connectivity) - (code >= 500) and (code < 600) -> context.getString(R.string.server_error) - else -> "" - } - if (message != "") - Snackbar.make(view, message, Snackbar.LENGTH_LONG).show() -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt deleted file mode 100644 index 983fefa306c252ef87247964bac8106519239c52..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt +++ /dev/null @@ -1,86 +0,0 @@ -package ml.adamsprogs.bimba.models - -import android.content.Context -import ml.adamsprogs.bimba.Declinator -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.rollTime -import ml.adamsprogs.bimba.safeSplit -import java.util.* - -data class Departure(val line: String, val mode: List<Int>, val time: Int, val lowFloor: Boolean, //time in seconds since midnight - val modification: List<String>, val headsign: String, val vm: Boolean = false, - var tomorrow: Boolean = false, val onStop: Boolean = false, val ticketMachine: Int= TICKET_MACHINE_NONE) { - - val isModified: Boolean - get() { - return modification.isNotEmpty() - } - - override fun toString(): String { - return "$line|${mode.joinToString(";")}|$time|$lowFloor|${modification.joinToString(";")}|$headsign|$vm|$tomorrow|$onStop|$ticketMachine" - } - - fun copy(): Departure { - return Departure.fromString(this.toString()) - } - - companion object { - const val TICKET_MACHINE_NONE = 0 - const val TICKET_MACHINE_AUTOMAT = 1 - const val TICKET_MACHINE_DRIVER = 2 - fun fromString(string: String): Departure { - val array = string.split("|") - if (array.size != 10) - throw IllegalArgumentException() - val modification = array[4].safeSplit(";")!! - return Departure(array[0], - array[1].safeSplit(";")!!.map { Integer.parseInt(it) }, - Integer.parseInt(array[2]), array[3] == "true", - modification, array[5], array[6] == "true", - array[7] == "true", array[8] == "true", Integer.parseInt(array[9])) - } - } - - fun timeTill(relativeTo: Int): Int { - var time = this.time - if (this.tomorrow) - time += 24 * 60 * 60 - return (time - relativeTo) / 60 - } - - val lineText: String = line - - fun timeTillText(context: Context, relativeTime: Boolean = true): String { - val now = Calendar.getInstance() - val departureTime = Calendar.getInstance().rollTime(time) - if (tomorrow) - departureTime.add(Calendar.DAY_OF_MONTH, 1) - - val departureIn = ((departureTime.timeInMillis - now.timeInMillis) / (1000 * 60)).toInt() - - return if (departureIn > 60 || departureIn < 0 || !relativeTime) - context.getString(R.string.departure_at, "${String.format("%02d", departureTime.get(Calendar.HOUR_OF_DAY))}:${String.format("%02d", departureTime.get(Calendar.MINUTE))}") - else if (departureIn > 0 && !onStop) - context.getString(Declinator.decline(departureIn), departureIn.toString()) - else if (departureIn == 0 && !onStop) - context.getString(R.string.in_a_moment) - else if (departureIn == 0) - context.getString(R.string.now) - else - context.getString(R.string.just_departed) - } - - fun timeAtMessage(context: Context): String { - val departureTime = Calendar.getInstance().rollTime(time) - if (tomorrow) - departureTime.add(Calendar.DAY_OF_MONTH, 1) - - return context.getString(R.string.departure_at, - "${String.format("%02d", - departureTime.get(Calendar.HOUR_OF_DAY))}:${String.format("%02d", - departureTime.get(Calendar.MINUTE))}") + - if (isModified) - " " + modification.joinToString("; ", "(", ")") - else "" - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt deleted file mode 100644 index 5c7db919c7242c6f09154caa31b6706562f1bddc..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt +++ /dev/null @@ -1,169 +0,0 @@ -package ml.adamsprogs.bimba.models - -import android.content.Context -import android.os.Parcel -import android.os.Parcelable -import ml.adamsprogs.bimba.ProviderProxy -import ml.adamsprogs.bimba.safeSplit -import java.io.File -import java.math.BigInteger -import java.security.SecureRandom -import kotlin.collections.* - -class Favourite : Parcelable, ProviderProxy.OnDeparturesReadyListener { - private val cacheDir: File - private lateinit var listener: ProviderProxy.OnDeparturesReadyListener - var name: String - private set - var segments: HashSet<StopSegment> - private set - private var fullDepartures: Map<String, List<Departure>> = HashMap() - private val cache = HashMap<Plate.ID, List<Departure>>() - private var listenerId = "" - - val size - get() = segments.sumBy { - it.size - } - - private val providerProxy: ProviderProxy - - constructor(parcel: Parcel) { - this.name = parcel.readString()!! - @Suppress("UNCHECKED_CAST") - val set = HashSet<StopSegment>() - val array = parcel.readParcelableArray(StopSegment::class.java.classLoader)!! - array.forEach { - set.add(it as StopSegment) - } - this.segments = set - this.cacheDir = File(parcel.readString()) - val mapDir = File(parcel.readString()) - - val mapString = mapDir.readText() - - val map = HashMap<String, List<Departure>>() - mapString.safeSplit("%")!!.forEach { it -> - val (k, v) = it.split("#") - map[k] = v.split("&").map { Departure.fromString(it) } - } - this.fullDepartures = map - mapDir.delete() - providerProxy = ProviderProxy() - } - - constructor(name: String, segments: HashSet<StopSegment>, cache: Map<String, List<Departure>>, context: Context) { - this.fullDepartures = cache - this.name = name - this.segments = segments - this.cacheDir = context.cacheDir - providerProxy = ProviderProxy(context) - } - - constructor(name: String, timetables: HashSet<StopSegment>, context: Context) { - this.name = name - this.segments = timetables - this.cacheDir = context.cacheDir - providerProxy = ProviderProxy(context) - - } - - override fun describeContents(): Int { - return Parcelable.CONTENTS_FILE_DESCRIPTOR - } - - override fun writeToParcel(dest: Parcel?, flags: Int) { - dest?.writeString(name) - val parcelableSegments = segments.map { it }.toTypedArray() - dest?.writeParcelableArray(parcelableSegments, flags) - dest?.writeString(cacheDir.absolutePath) - - val bytes = ByteArray(4) { 0 } - SecureRandom().nextBytes(bytes) - val mapFile = File(cacheDir, BigInteger(1, bytes).toString(16)) - dest?.writeString(mapFile.absolutePath) - - var isFirst = true - var map = "" - fullDepartures.forEach { it -> - if (isFirst) - isFirst = false - else - map += '%' - - map += "${it.key}#${it.value.joinToString("&") { it.toString() }}" - } - mapFile.writeText(map) - } - - fun delete(plateId: Plate.ID): Boolean { - segments.forEach { - if (!it.remove(plateId)) - return false - } - removeFromCache(plateId) - return true - } - - fun rename(newName: String) { - name = newName - } - - companion object CREATOR : Parcelable.Creator<Favourite> { - override fun createFromParcel(parcel: Parcel): Favourite { - return Favourite(parcel) - } - - override fun newArray(size: Int): Array<Favourite?> { - return arrayOfNulls(size) - } - } - - fun nextDeparture() = - if (cache.isEmpty()) - null - else - cache.flatMap { it.value }.let { it -> - if (it.isEmpty()) - null - else - it.sortedBy { it.time }[0] - } - - - fun fullTimetable(): Map<String, List<Departure>> { - if (fullDepartures.isEmpty()) - fullDepartures = providerProxy.getFullTimetable(segments) - return fullDepartures - } - - private fun removeFromCache(plate: Plate.ID) { - val map = HashMap<String, List<Departure>>() - fullDepartures - fullDepartures.forEach { it -> - map[it.key] = it.value.filter { plate.line != it.line || plate.headsign != it.headsign } - } - fullDepartures = map - } - - fun subscribeForDepartures(listener: ProviderProxy.OnDeparturesReadyListener, context: Context): String { - this.listener = listener - listenerId = providerProxy.subscribeForDepartures(segments, this, context) - return listenerId - } - - override fun onDeparturesReady(departures: List<Departure>, plateId: Plate.ID?, code: Int) { - if (plateId == null) { - cache.clear() - cache[Plate.ID.dummy] = departures - } else { - cache.remove(Plate.ID.dummy) - cache[plateId] = departures - } - listener.onDeparturesReady(departures, plateId, code) - } - - fun unsubscribeFromDepartures(context: Context) { - providerProxy.unsubscribeFromDepartures(listenerId, context) - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt deleted file mode 100644 index d4f7d8cc0dd3dc9e147c63f4182cbc1e009c64e7..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt +++ /dev/null @@ -1,85 +0,0 @@ -package ml.adamsprogs.bimba.models - -import java.io.Serializable - -data class Plate(val id: ID, val departures: HashMap<Int, HashSet<Departure>>?) { - override fun toString(): String { - var result = "${id.line}=${id.stop}=${id.headsign}={" - if (departures != null) { - for ((service, column) in departures) { - result += service.toString() + ":" - for (departure in column) { - result += departure.toString() + ";" - } - } - } - result += "}" - return result - } - - companion object { - /*fun fromString(string: String): Plate { - val (lineStr, stopStr, headsign, departuresString) = string.split("=") - val departures = HashMap<Int, HashSet<Departure>>() - departuresString.replace("{", "").replace("}", "").split(";") - .filter { it != "" } - .forEach { - try { - val (serviceStr, depStr) = it.split(":") - val dep = Departure.fromString(depStr) - if (departures[serviceStr] == null) - departures[serviceStr] = HashSet() - departures[serviceStr]!!.add(dep) - } catch (e: IllegalArgumentException) { - } - } - return Plate(ID(lineStr, stopStr, headsign), departures) - } - - fun join(set: Set<Plate>): HashMap<String, ArrayList<Departure>> { - val departures = HashMap<String, ArrayList<Departure>>() - for (plate in set) { - for ((mode, d) in plate.departures!!) { - if (departures[mode] == null) - departures[mode] = ArrayList() - departures[mode]!!.addAll(d) - } - } - for ((mode, _) in departures) { - departures[mode]?.sortBy { it.time } - } - return departures - }*/ - } - - data class ID(val line: String, val stop: String, val headsign: String) : Serializable { - companion object { - val dummy = Plate.ID("", "", "") - - fun fromString(string: String): ID { - val (line, stop, headsign) = string.split("|") - return ID(line, - stop, headsign) - } - } - - override fun equals(other: Any?): Boolean { - if (other !is ID) - return false - return line == other.line && stop == other.stop && headsign.toLowerCase() == other.headsign.toLowerCase() - } - - override fun toString(): String { - return "$line|$stop|$headsign" - } - - override fun hashCode(): Int { - var result = line.hashCode() - result = 31 * result + stop.hashCode() - result = 31 * result + headsign.hashCode() - return result - } - - constructor(other: Plate.ID) : this(other.line, other.stop, other.headsign) - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt b/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt deleted file mode 100644 index e6ef8860315c2d2aca5a481267fb924954bf9ceb..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt +++ /dev/null @@ -1,87 +0,0 @@ -package ml.adamsprogs.bimba.models - -import android.os.Parcel -import android.os.Parcelable -import ml.adamsprogs.bimba.safeSplit - -data class StopSegment(val stop: String, var plates: Set<Plate.ID>?) : Parcelable { - constructor(parcel: Parcel) : this( - parcel.readSerializable() as String, - parcel.readString().safeSplit(";")?.map { Plate.ID.fromString(it) }?.toSet() - ) - - companion object CREATOR : Parcelable.Creator<StopSegment> { - override fun createFromParcel(parcel: Parcel): StopSegment { - return StopSegment(parcel) - } - - override fun newArray(size: Int): Array<StopSegment?> { - return arrayOfNulls(size) - } - } - - override fun writeToParcel(dest: Parcel?, flags: Int) { - dest?.writeSerializable(stop) - if (plates != null) - dest?.writeString(plates!!.joinToString(";") { it.toString() }) - else - dest?.writeString("null") - } - - override fun describeContents(): Int { - return Parcelable.CONTENTS_FILE_DESCRIPTOR - } - - override fun equals(other: Any?): Boolean { - if (other !is StopSegment) - return false - if (this.stop != other.stop) - return false - if (this.plates != null && other.plates == null) - return false - if (this.plates == null && other.plates != null) - return false - if (this.plates == null && other.plates == null) - return true - if (this.plates!!.size != other.plates!!.size) - return false - if (this.plates!!.containsAll(other.plates!!)) - return true - return false - } - - override fun hashCode(): Int { - var hashCode = stop.hashCode() - plates?.forEach { hashCode = 31 * hashCode + it.hashCode() } - return hashCode - } - - operator fun contains(plateId: Plate.ID): Boolean { - if (plates == null) - return plateId.stop == stop - return plates!!.contains(plateId) - } - - fun remove(plateId: Plate.ID): Boolean { - if (plates == null) - return false - - plates = plates!!.asSequence().filter { it != plateId }.toSet() - return true - } - - override fun toString(): String { - var s = "$stop: " - if (plates == null) - s += "NULL" - else { - s += "{" - s += plates!!.joinToString { it.toString() } - s += "}" - } - return s - } - - val size: Int - get() = plates?.size ?: 0 -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt deleted file mode 100644 index 363e7bb0640347a8ba1a3882954ead8ec6a670e4..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt +++ /dev/null @@ -1,547 +0,0 @@ -package ml.adamsprogs.bimba.models - -import android.annotation.SuppressLint -import android.content.Context -import android.database.Cursor -import android.database.CursorIndexOutOfBoundsException -import android.database.sqlite.SQLiteDatabase -import android.database.sqlite.SQLiteException -import android.util.SparseArray -import android.util.SparseBooleanArray -import ml.adamsprogs.bimba.* -import ml.adamsprogs.bimba.models.gtfs.Route -import ml.adamsprogs.bimba.models.gtfs.Stop -import ml.adamsprogs.bimba.models.gtfs.Trip -import ml.adamsprogs.bimba.models.suggestions.LineSuggestion -import ml.adamsprogs.bimba.models.suggestions.StopSuggestion -import java.io.File -import kotlin.collections.* -import java.util.Calendar as JCalendar - -class Timetable private constructor() { - companion object { - private var timetable: Timetable? = null - - fun getTimetable(context: Context? = null, force: Boolean = false): Timetable { - return if (timetable == null || force) - if (context != null) { - constructTimetable(context) - timetable!! - } else - throw IllegalArgumentException("new timetable requested and no `context` given") - else if (context != null) { - try { - constructTimetable(context) - timetable!! - } catch (e: Exception) { - timetable!! - } - } else - timetable!! - } - - private fun constructTimetable(context: Context) { - val timetable = Timetable() - val filesDir = context.getSecondaryExternalFilesDir() - val dbFile = File(filesDir, "timetable.db") - timetable.db = try { - SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READONLY) - } catch (e: SQLiteException) { - null - } - this.timetable = timetable - } - - fun delete(context: Context) { - val filesDir = context.getSecondaryExternalFilesDir() - val dbFile = File(filesDir, "timetable.db") - try { - dbFile.delete() - } catch (e: Exception) { - } - } - } - - private var db: SQLiteDatabase? = null - private var _stops: List<StopSuggestion>? = null - - fun refresh() { - } - - fun getStopSuggestions(/*context: Context, */force: Boolean = false): List<StopSuggestion> { - if (_stops != null && !force) - return _stops!! - - val zones = HashMap<String, String>() - - val cursor = db!!.rawQuery("select stop_name, zone_id from stops", null) - - while (cursor.moveToNext()) { - val name = cursor.getString(0) - val zone = cursor.getString(1) - zones[name] = zone - } - - cursor.close() - - _stops = zones.map { - /*todo - val colour = when (zones[it.key]) { - "A" -> "#${getColour(R.color.zoneA, context).toString(16)}" - "B" -> "#${getColour(R.color.zoneB, context).toString(16)}" - "C" -> "#${getColour(R.color.zoneC, context).toString(16)}" - else -> "#000000" - } - */ - StopSuggestion(it.key, it.value) - }.sorted() - return _stops!! - } - - fun getLineSuggestions(): List<LineSuggestion> { - val routes = ArrayList<LineSuggestion>() - val cursor = db!!.rawQuery("select * from routes", null) - - while (cursor.moveToNext()) { - val routeId = cursor.getString(0) - - routes.add(LineSuggestion(routeId, - createRouteFromCursorRow(cursor))) - } - - return routes.sortedBy { it.name } - } - - fun getHeadlinesForStop(stop: String): Map<String, Set<String>> { - val headsigns = HashMap<String, HashSet<String>>() - - var cursor = db!!.rawQuery("select stop_id, stop_code from stops where stop_name = ?", - arrayOf(stop)) - val stopIds = ArrayList<String>() - val stopCodes = SparseArray<String>() - while (cursor.moveToNext()) { - cursor.getInt(0).let { - stopIds.add(it.toString()) - stopCodes.put(it, cursor.getString(1)) - } - } - - cursor.close() - - val where = stopIds.joinToString(" or ", "where ") { "stop_id = ?" } - - cursor = db!!.rawQuery("select stop_id, route_id, trip_headsign " + - "from stop_times natural join trips " + - where, stopIds.toTypedArray()) - - while (cursor.moveToNext()) { - val stopCode = stopCodes[cursor.getInt(0)] - val route = cursor.getString(1) - val headsign = cursor.getString(2) - if (stopCode !in headsigns) - headsigns[stopCode] = HashSet() - headsigns[stopCode]!!.add("$route → $headsign") - } - - cursor.close() - - return headsigns - - /* - AWF03 -> {232 → Os. Rusa} - AWF04 -> {232 → Rondo Kaponiera} - AWF02 -> {76 → Pl. Bernardyński, 74 → Os. Sobieskiego, 603 → Pl. Bernardyński} - AWF01 ->{76 → Os. Dębina, 603 → Łęczyca/Dworcowa} - AWF42 -> {29 → Pl. Wiosny Ludów} - AWF41 -> {10 → Połabska, 29 → Dębiec, 15 → Budziszyńska, 10 → Dębiec, 15 → Os. Sobieskiego, 12 → Os. Sobieskiego, 6 → Junikowo, 18 → Ogrody, 2 → Ogrody} - AWF73 -> {10 → Franowo, 29 → Franowo, 6 → Miłostowo, 5 → Stomil, 18 → Franowo, 15 → Franowo, 12 → Starołęka, 74 → Os. Orła Białego} - */ - } - - fun getHeadlinesForStopCode(stop: String): StopSegment { - var cursor = db!!.rawQuery("select stop_id from stops where stop_code = ?", - arrayOf(stop)) - cursor.moveToFirst() - val stopId = cursor.getInt(0) - cursor.close() - - - cursor = db!!.rawQuery("select route_id, trip_headsign " + - "from stop_times natural join trips where stop_id = ? ", - arrayOf(stopId.toString())) - - val plates = HashSet<Plate.ID>() - - while (cursor.moveToNext()) { - val route = cursor.getString(0) - val headsign = cursor.getString(1) - plates.add(Plate.ID(route, stop, headsign)) - } - cursor.close() - return StopSegment(stop, plates) - } - - fun getStopName(stopCode: String): String { - val cursor = db!!.rawQuery("select stop_name from stops where stop_code = ?", - arrayOf(stopCode)) - cursor.moveToNext() - val name = cursor.getString(0) - cursor.close() - - return name - } - - fun getStopId(stopCode: String): String { - val cursor = db!!.rawQuery("select stop_id from stops where stop_code = ?", - arrayOf(stopCode)) - cursor.moveToNext() - val id = cursor.getString(0) - cursor.close() - - return id - } - - fun getStopCode(stopId: String): String { - val cursor = db!!.rawQuery("select stop_code from stops where stop_id = ?", - arrayOf(stopId)) - cursor.moveToNext() - val code = cursor.getString(0) - cursor.close() - - return code - } - - fun getStopDepartures(stopCode: String): Map<String, List<Departure>> { - val stopID = getStopId(stopCode) - val map = HashMap<String, ArrayList<Departure>>() - val cursor = db!!.rawQuery("select route_id, service_id, departure_time, " + - "wheelchair_accessible, stop_sequence, trip_id, trip_headsign, route_desc " + - "from stop_times natural join trips natural join routes where stop_id = ?", - arrayOf(stopID)) - - while (cursor.moveToNext()) { - val line = cursor.getString(0) - val service = cursor.getInt(1).toString() - val mode = calendarToMode(service) - val time = parseTime(cursor.getString(2)) - val lowFloor = cursor.getInt(3) == 1 - val stopSequence = cursor.getInt(4) - val tripId = createTripId(cursor.getString(5)) - val headsign = cursor.getString(6) - val desc = cursor.getString(7) - - val modifications = Route.createModifications(desc) - - val modification = explainModification(tripId, stopSequence, modifications) - val departure = Departure(line, mode, time, lowFloor, modification, headsign) - if (map[service] == null) - map[service] = ArrayList() - map[service]!!.add(departure) - } - - cursor.close() - map.forEach { it.value.sortBy { it.time } } - - return map - } - - fun getStopDeparturesBySegments(segments: Set<StopSegment>): Map<String, List<Departure>> { - val stopCodes = HashMap<String, Int>() - var cursor = db!!.rawQuery("select stop_id, stop_code from stops", emptyArray()) - while (cursor.moveToNext()) { - stopCodes[cursor.getString(1)] = cursor.getInt(0) - } - cursor.close() - - val wheres = segments.flatMap { - it.plates?.map { plate -> - "(stop_id = ${stopCodes[plate.stop]} and route_id = '${plate.line}' and trip_headsign = '${plate.headsign}')" - } ?: listOf("stop_id = ${stopCodes[it.stop]}") - }.joinToString(" or ") - - cursor = db!!.rawQuery("select route_id, service_id, departure_time, " + - "wheelchair_accessible, stop_sequence, trip_id, trip_headsign, route_desc " + - "from stop_times natural join trips natural join routes where $wheres", null) - - val map = parseDeparturesCursor(cursor) - cursor.close() - return map - } - - private fun parseDeparturesCursor(cursor: Cursor): Map<String, List<Departure>> { - val map = HashMap<String, ArrayList<Departure>>() - - while (cursor.moveToNext()) { - val line = cursor.getString(0) - val service = cursor.getInt(1).toString() - val mode = calendarToMode(service) - val time = parseTime(cursor.getString(2)) - val lowFloor = cursor.getInt(3) == 1 - val stopSequence = cursor.getInt(4) - val tripId = createTripId(cursor.getString(5)) - val headsign = cursor.getString(6) - val desc = cursor.getString(7) - - val modifications = Route.createModifications(desc) - - val modification = explainModification(tripId, stopSequence, modifications) - val departure = Departure(line, mode, time, lowFloor, modification, headsign) - if (map[service] == null) - map[service] = ArrayList() - map[service]!!.add(departure) - } - - map.forEach { it.value.sortBy { it.time } } - return map - } - - - private fun parseTime(time: String): Int { - val cal = JCalendar.getInstance() - val (h, m, s) = time.split(":") - cal.set(JCalendar.HOUR_OF_DAY, h.toInt()) - cal.set(JCalendar.MINUTE, m.toInt()) - cal.set(JCalendar.SECOND, s.toInt()) - return cal.secondsAfterMidnight() - } - - private fun calendarToMode(serviceId: String): List<Int> { - val days = ArrayList<Int>() - val cursor = db!!.rawQuery("select * from calendar where service_id = ?", - arrayOf(serviceId)) - - cursor.moveToNext() - (1 until 7).forEach { - if (cursor.getInt(it) == 1) days.add(it - 1) - } - - cursor.close() - return days - } - - private fun explainModification(tripId: Trip.ID, stopSequence: Int, routeModifications: Map<String, String>): List<String> { //todo<p:1> "kurs obsługiwany taborem niskopodłogowym" -> ignore - val explanations = ArrayList<String>() - tripId.modification.forEach { - if (it.stopRange != null) { - if (stopSequence in it.stopRange) - explanations.add(routeModifications[it.id]!!) - } else { - explanations.add(routeModifications[it.id]!!) - } - } - - return explanations - } - - private fun createRouteFromCursorRow(cursor: Cursor): Route { - val routeId = cursor.getString(0) - val agencyId = cursor.getInt(1).toString() - val shortName = cursor.getString(2) - val longName = cursor.getString(3) - val desc = cursor.getString(4) - val type = cursor.getInt(5) - val colour = cursor.getString(6).toInt(16) - val textColour = cursor.getString(7).toInt(16) - - return Route.create(routeId, agencyId, shortName, longName, desc, type, colour, textColour) - } - - private fun createTripId(rawId: String): Trip.ID { - if (rawId.contains('^')) { - var modification = rawId.split("^")[1] - val isMain = modification[modification.length - 1] == '+' - if (isMain) - modification = modification.subSequence(0, modification.length - 1) as String - val modifications = HashSet<Trip.ID.Modification>() - if (modification != "") { - modification.split(",").forEach { - try { - val (id, start, end) = it.split(":") - modifications.add(Trip.ID.Modification(id, IntRange(start.toInt(), end.toInt()))) - } catch (e: Exception) { - modifications.add(Trip.ID.Modification(it, null)) - } - } - } - return Trip.ID(rawId, rawId.split("^")[0], modifications, isMain) - } else - return Trip.ID(rawId, rawId, HashSet(), false) - } - - @SuppressLint("Recycle") - fun isEmpty(): Boolean { - if (db == null) - return true - var result: Boolean - var cursor: Cursor? = null - try { - cursor = db!!.rawQuery("select * from feed_info", null) - result = !cursor.moveToNext() - } catch (e: Exception) { - result = true - } finally { - cursor?.close() - } - return result - } - - fun getValidSince(): String { - val cursor = db!!.rawQuery("select feed_start_date from feed_info", null) - - cursor.moveToNext() - val validTill = cursor.getString(0) - - cursor.close() - return validTill - } - - fun getValidTill(): String { - val cursor = db!!.rawQuery("select feed_end_date from feed_info", null) - - cursor.moveToNext() - val validTill = cursor.getString(0) - - cursor.close() - return validTill - } - - fun getServiceForToday(): String? { - val today = JCalendar.getInstance() - return getServiceFor(today) - } - - fun getServiceForTomorrow(): String? { - val tomorrow = JCalendar.getInstance() - tomorrow.add(JCalendar.DAY_OF_MONTH, 1) - return getServiceFor(tomorrow) - } - - private fun getServiceFor(day: JCalendar): String? { - val dayColumn = arrayOf("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday")[((day.get(JCalendar.DAY_OF_WEEK) + 5) % 7)] - val cursor = db!!.rawQuery("select service_id from calendar where $dayColumn = 1 and start_date < ? and ? < end_date", arrayOf(day.toIsoDate(), day.toIsoDate())) - - cursor.moveToFirst() - return try { - cursor.getInt(0).let { - cursor.close() - it.toString() - } - } catch (e: CursorIndexOutOfBoundsException) { - cursor.close() - null - } - } - - fun getTripGraphs(id: String): Array<TripGraph> { - TODO("Not implemented") - /* - val graphs = arrayOf(TripGraph(), TripGraph()) - - val cursor = db!!.rawQuery("select trip_id, trip_headsign, direction_id, stop_id, " + - "stop_sequence, pickup_type, stop_name, zone_id " + - "from stop_times natural join trips natural join stops" + - "where route_id = ?", arrayOf(id)) - - while (cursor.moveToNext()) { - val trip = cursor.getString(0) - val headsign = cursor.getString(1) - val direction = cursor.getInt(2) - val stopId = cursor.getInt(3) - val sequence = cursor.getInt(4) - val pickupType = cursor.getInt(5) - val stopName = cursor.getString(6) - val zone = cursor.getString(7) - - if (trip.contains('+')) { - graphs[direction].mainTrip[stopId] = sequence - graphs[direction].headsign = headsign - } - - if (graphs[direction].otherTrips[trip] == null) - graphs[direction].otherTrips[trip] = HashMap() - graphs[direction].otherTrips[trip]?.put(sequence, Stop(stopId, null, stopName, null, null, zone[0], pickupType == 3)) - } - - cursor.close() - - graphs.forEach { - val thisTripGraph = it - it.otherTrips.forEach { - val tripId = it.key - val trip = it.value - it.value.keys.sortedBy { it }.forEach { - if (thisTripGraph.tripsMetadata[tripId] == "" || thisTripGraph.tripsMetadata[tripId] == "o") - if (thisTripGraph.mainTrip[trip[it]!!.id] != null) { - val mainLayer = thisTripGraph.mainTrip[trip[it]!!.id]!! - if (it == 0 || thisTripGraph.tripsMetadata[tripId]!![0] == 'o') { - thisTripGraph.tripsMetadata[tripId] = "o|$mainLayer|$it" - } else { - val startingLayer = mainLayer - it + 1 - thisTripGraph.tripsMetadata[tripId] = "i|$startingLayer|$it" - } - } - } - } - } - - return graphs*/ - } - - fun getServiceFirstDay(service: String): Int { - val cursor = db!!.rawQuery("select * from calendar where service_id = ?", arrayOf(service)) - cursor.moveToFirst() - var i = 1 - while ((cursor.getString(i) == "0") and (i < 8)) i++ - cursor.close() - return i - } - - fun getServiceDescription(service: String, context: Context): String { - val dayNames = SparseArray<String>() - dayNames.put(1, context.getString(R.string.Mon)) - dayNames.put(2, context.getString(R.string.Tue)) - dayNames.put(3, context.getString(R.string.Wed)) - dayNames.put(4, context.getString(R.string.Thu)) - dayNames.put(5, context.getString(R.string.Fri)) - dayNames.put(6, context.getString(R.string.Sat)) - dayNames.put(7, context.getString(R.string.Sun)) - - val cursor = db!!.rawQuery("select * from calendar where service_id = ?", arrayOf(service)) - cursor.moveToFirst() - val days = SparseBooleanArray() - for (i in 1..7) { - days.append(i, cursor.getString(i) == "1") - } - days.append(8, false) - val description = ArrayList<String>() - var start = 0 - - for (i in 1..8) { - if (!days[i] and (start > 0)) { - when { - i - start == 1 -> description.add(dayNames[start]) - i - start == 2 -> description.add("${dayNames[start]}, ${dayNames[start + 1]}") - i - start > 2 -> description.add("${dayNames[start]}–${dayNames[i - 1]}") - } - start = 0 - } - if (days[i] and (start == 0)) - start = i - } - - val startDate = calendarFromIsoD(cursor.getString(8)).toNiceString(context) - val endDate = calendarFromIsoD(cursor.getString(9)).toNiceString(context) - - cursor.close() - - return "${description.joinToString { it }} ($startDate–$endDate)" - } - - class TripGraph { - var headsign = "" - val mainTrip = HashMap<Int, Int>() - val otherTrips = HashMap<String, HashMap<Int, Stop>>() - val tripsMetadata = HashMap<String, String>() - } -} - diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/DeparturesAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/DeparturesAdapter.kt deleted file mode 100644 index 224ca7fe3e1250a0475ad7323b9e153f1b5ded27..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/DeparturesAdapter.kt +++ /dev/null @@ -1,93 +0,0 @@ -package ml.adamsprogs.bimba.models.adapters - -import android.app.AlertDialog -import android.content.Context -import android.content.DialogInterface -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.core.content.res.ResourcesCompat -import kotlinx.android.synthetic.main.row_departure.view.* -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.models.Departure - -class DeparturesAdapter(val context: Context, var departures: List<Departure>?, var relativeTime: Boolean) : - androidx.recyclerview.widget.RecyclerView.Adapter<DeparturesAdapter.ViewHolder>() { - - override fun getItemCount(): Int { - if (departures == null || departures!!.isEmpty()) - return 1 - return departures!!.size - } - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - holder.floorIcon.visibility = View.GONE - holder.infoIcon.visibility = View.GONE - - if (departures == null) { - return - } - - val line = holder.lineTextView - val time = holder.timeTextView - val direction = holder.directionTextView - if (departures!!.isEmpty()) { - time.text = context.getString(R.string.no_departures) - return - } - val departure = departures!![position] - - val timeString = departure.timeTillText(context, relativeTime) - - line.text = departure.lineText - time.text = timeString - direction.text = context.getString(R.string.departure_to, departure.headsign) - val icon = holder.typeIcon - if (departure.vm || departure.onStop) - icon.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_departure_vm, context.theme)) - else - icon.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_departure_timetable, context.theme)) - - if (departure.lowFloor) - holder.floorIcon.visibility = View.VISIBLE - if (departure.isModified) - holder.infoIcon.visibility = View.VISIBLE - if (departure.ticketMachine == Departure.TICKET_MACHINE_AUTOMAT) { - holder.ticketMachineIcon.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_ticket_machine, context.theme)) - holder.ticketMachineIcon.visibility = View.VISIBLE - } - if (departure.ticketMachine == Departure.TICKET_MACHINE_DRIVER) { - holder.ticketMachineIcon.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_ticket, context.theme)) - holder.ticketMachineIcon.visibility = View.VISIBLE - } - holder.root.setOnClickListener { - AlertDialog.Builder(context) - .setPositiveButton(context.getText(android.R.string.ok) - ) { dialog: DialogInterface, _: Int -> dialog.cancel() } - .setCancelable(true) - .setMessage(departure.timeAtMessage(context)) - .create().show() - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val context = parent.context - val inflater = LayoutInflater.from(context) - - val rowView = inflater.inflate(R.layout.row_departure, parent, false) - return ViewHolder(rowView) - } - - inner class ViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) { - val root = itemView.findViewById<View>(R.id.departureRow)!! - val lineTextView: TextView = itemView.findViewById(R.id.lineNumber) - val timeTextView: TextView = itemView.findViewById(R.id.departureTime) - val directionTextView: TextView = itemView.findViewById(R.id.departureDirection) - val typeIcon: ImageView = itemView.findViewById(R.id.departureTypeIcon) - val infoIcon: ImageView = itemView.findViewById(R.id.departureInfoIcon) - val floorIcon: ImageView = itemView.findViewById(R.id.departureFloorIcon) - val ticketMachineIcon: ImageView = itemView.findViewById(R.id.ticketMachineIcon) - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/FavouriteEditRowAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/FavouriteEditRowAdapter.kt deleted file mode 100644 index c4e638efb519ce0f8f0d74a1f83adf615a1fb30f..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/FavouriteEditRowAdapter.kt +++ /dev/null @@ -1,82 +0,0 @@ -package ml.adamsprogs.bimba.models.adapters - -import android.view.* -import android.widget.* -import kotlinx.coroutines.* -import kotlinx.coroutines.android.Main -import ml.adamsprogs.bimba.* -import ml.adamsprogs.bimba.collections.FavouriteStorage -import ml.adamsprogs.bimba.models.* - - -class FavouriteEditRowAdapter(private var favourite: Favourite, private val loadingView: View, private val listView: View) : - androidx.recyclerview.widget.RecyclerView.Adapter<FavouriteEditRowAdapter.ViewHolder>() { - - private val segments = HashMap<String, StopSegment>() - private val providerProxy = ProviderProxy() - private val favourites = FavouriteStorage.getFavouriteStorage() - private val platesList = ArrayList<Plate.ID>() - private val namesList = HashMap<Plate.ID, String>() - - init { - GlobalScope.launch { - favourite.segments.forEach { - if (it.plates == null) { - (providerProxy.fillStopSegment(it) ?: it).let { segment -> - segments[segment.stop] = segment - it.plates = segment.plates - } - } else { - segments[it.stop] = it - } - } - favourites[favourite.name] = favourite - - segments.flatMap { - it.value.plates ?: emptyList<Plate.ID>() - }.sortedBy { "${it.line}${it.stop}" }.forEach { - platesList.add(it) - namesList[it] = providerProxy.getStopName(it.stop).let { name -> - "${name ?: ""} (${it.stop}):\n${it.line} → ${it.headsign}" - } - } - launch(Dispatchers.Main) { - loadingView.visibility = View.GONE - listView.visibility = View.VISIBLE - this@FavouriteEditRowAdapter.notifyDataSetChanged() - } - } - } - - - override fun getItemCount(): Int = platesList.size - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - GlobalScope.launch { - val id = platesList[position] - val favouriteElement = namesList[id] - - holder.rowTextView.text = favouriteElement - holder.deleteButton.setOnClickListener { - favourites.delete(favourite.name, id) - favourite = favourites.favourites[favourite.name]!! - notifyItemRemoved(platesList.indexOf(id)) - platesList.remove(id) - namesList.remove(id) - } - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val context = parent.context - val inflater = LayoutInflater.from(context) - - val rowView = inflater.inflate(R.layout.row_favourite_edit, parent, false) - return ViewHolder(rowView) - } - - inner class ViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) { - val rowTextView: TextView = itemView.findViewById(R.id.favourite_edit_row) - val deleteButton: ImageView = itemView.findViewById(R.id.favourite_edit_delete) - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/FavouritesAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/FavouritesAdapter.kt deleted file mode 100644 index 1f1a1a174e5e1b149d16121b6347234d207b8a85..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/FavouritesAdapter.kt +++ /dev/null @@ -1,159 +0,0 @@ -package ml.adamsprogs.bimba.models.adapters - -import android.content.Context -import android.util.SparseBooleanArray -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.appcompat.widget.PopupMenu -import androidx.core.content.res.ResourcesCompat -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.android.Main -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.collections.FavouriteStorage -import ml.adamsprogs.bimba.models.Departure -import ml.adamsprogs.bimba.models.Favourite -import java.util.* - - -class FavouritesAdapter(private val appContext: Context, var favourites: FavouriteStorage, - private val onMenuItemClickListener: OnMenuItemClickListener, - private val onClickListener: ViewHolder.OnClickListener) : - androidx.recyclerview.widget.RecyclerView.Adapter<FavouritesAdapter.ViewHolder>() { - - private val selectedItems = SparseBooleanArray() - - private fun isSelected(position: Int) = getSelectedItems().contains(position) - - fun toggleSelection(position: Int) { - if (selectedItems.get(position, false)) { - selectedItems.delete(position) - } else { - selectedItems.put(position, true) - } - notifyItemChanged(position) - } - - fun clearSelection() { - selectedItems.clear() - notifyDataSetChanged() - } - - fun getSelectedItemCount() = selectedItems.size() - - fun getSelectedItems(): List<Int> { - val items = ArrayList<Int>(selectedItems.size()) - (0 until selectedItems.size()).mapTo(items) { selectedItems.keyAt(it) } - return items - } - - override fun getItemCount() = favourites.size - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - GlobalScope.launch(Dispatchers.Main) /*Main on all?*/ { - val favourite = favourites[position]!! - holder.nameTextView.text = favourite.name - - holder.selectedOverlay.visibility = if (isSelected(position)) View.VISIBLE else View.INVISIBLE - holder.moreButton.setOnClickListener { it -> - val popup = PopupMenu(appContext, it) - val inflater = popup.menuInflater - popup.setOnMenuItemClickListener { - when (it.itemId) { - R.id.favourite_edit -> onMenuItemClickListener.edit(favourite.name) - R.id.favourite_delete -> onMenuItemClickListener.delete(favourite.name) - else -> false - } - } - inflater.inflate(R.menu.favourite_actions, popup.menu) - popup.show() - } - - val nextDeparture = withContext(Dispatchers.Default) { - favourite.nextDeparture() - } - - val nextDepartureText: String - val nextDepartureLineText: String - if (nextDeparture != null) { - nextDepartureLineText = appContext.getString(R.string.departure_to_line, nextDeparture.line, nextDeparture.headsign) - nextDepartureText = nextDeparture.timeTillText(appContext) - } else { - nextDepartureText = appContext.getString(R.string.no_next_departure) - nextDepartureLineText = "" - } - holder.timeTextView.text = nextDepartureText - holder.lineTextView.text = nextDepartureLineText - if (nextDeparture != null) { - if (nextDeparture.vm || nextDeparture.onStop) - holder.typeIcon.setImageDrawable(ResourcesCompat.getDrawable(appContext.resources, R.drawable.ic_departure_vm, appContext.theme)) - else - holder.typeIcon.setImageDrawable(ResourcesCompat.getDrawable(appContext.resources, R.drawable.ic_departure_timetable, appContext.theme)) - if (nextDeparture.lowFloor) - holder.floorIcon.visibility = View.VISIBLE - if (nextDeparture.ticketMachine != Departure.TICKET_MACHINE_NONE) { - holder.ticketIcon.visibility = View.VISIBLE - if (nextDeparture.ticketMachine == Departure.TICKET_MACHINE_DRIVER) - holder.ticketIcon.setImageDrawable(ResourcesCompat.getDrawable(appContext.resources, R.drawable.ic_ticket, appContext.theme)) - if (nextDeparture.ticketMachine == Departure.TICKET_MACHINE_AUTOMAT) - holder.ticketIcon.setImageDrawable(ResourcesCompat.getDrawable(appContext.resources, R.drawable.ic_ticket_machine, appContext.theme)) - } - } - } - } - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val context = parent.context - val inflater = LayoutInflater.from(context) - - val rowView = inflater.inflate(R.layout.row_favourite, parent, false) - return ViewHolder(rowView, onClickListener) - } - - fun indexOf(name: String): Int { - return favourites.indexOf(name) - } - - operator fun get(index: String): Favourite? { - return favourites[index] - } - - class ViewHolder(itemView: View, private val listener: OnClickListener) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView), View.OnClickListener, View.OnLongClickListener { - override fun onLongClick(v: View?): Boolean { - return listener.onItemLongClicked(adapterPosition) - } - - override fun onClick(v: View?) { - listener.onItemClicked(adapterPosition) - } - - val selectedOverlay: View = itemView.findViewById(R.id.selected_overlay) - val nameTextView: TextView = itemView.findViewById(R.id.favourite_name) - val timeTextView: TextView = itemView.findViewById(R.id.favourite_time) - val lineTextView: TextView = itemView.findViewById(R.id.favourite_line) - val moreButton: ImageView = itemView.findViewById(R.id.favourite_more_button) - val typeIcon: ImageView = itemView.findViewById(R.id.departureTypeIcon) - val floorIcon: ImageView = itemView.findViewById(R.id.departureFloorIcon) - val ticketIcon: ImageView = itemView.findViewById(R.id.ticketMachineIcon) - - init { - itemView.setOnClickListener(this) - itemView.setOnLongClickListener(this) - } - - interface OnClickListener { - fun onItemClicked(position: Int) - fun onItemLongClicked(position: Int): Boolean - } - } - - interface OnMenuItemClickListener { - fun edit(name: String): Boolean - fun delete(name: String): Boolean - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/ServiceAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/ServiceAdapter.kt deleted file mode 100644 index 014cd4a7cf014ff56ec0ca3e54a77c90a769f805..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/ServiceAdapter.kt +++ /dev/null @@ -1,43 +0,0 @@ -package ml.adamsprogs.bimba.models.adapters - -import android.annotation.SuppressLint -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import android.view.LayoutInflater -import ml.adamsprogs.bimba.R -import android.app.Activity -import android.widget.ArrayAdapter -import ml.adamsprogs.bimba.ProviderProxy - - -class ServiceAdapter(context: Activity, resourceId: Int, list: List<RowItem>) : ArrayAdapter<ServiceAdapter.RowItem>(context, resourceId, list) { - - private val inflater: LayoutInflater = context.layoutInflater - - @SuppressLint("ViewHolder", "InflateParams") - override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - val rowItem: RowItem = getItem(position) - val rowView = inflater.inflate(R.layout.toolbar_spinner_item, null, true) - rowView.findViewById<TextView>(R.id.text).text = rowItem.description - - return rowView - } - - @SuppressLint("InflateParams") - override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup?): View { - val rowItem: RowItem = getItem(position) - val rowView = inflater.inflate(R.layout.toolbar_spinner_item, null, true) - rowView.findViewById<TextView>(R.id.text).text = rowItem.description - - return rowView - - } - - data class RowItem(val service: String, val description: String) : Comparable<RowItem> { - override fun compareTo(other: RowItem): Int { - val proxy = ProviderProxy() - return proxy.getServiceFirstDay(service).compareTo(proxy.getServiceFirstDay(other.service)) - } - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/SuggestionsAdapter.kt b/app/src/main/java/ml/adamsprogs/bimba/models/adapters/SuggestionsAdapter.kt deleted file mode 100644 index 6408a4506cde6c5d2fdf7a84a6024a78c5699881..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/adapters/SuggestionsAdapter.kt +++ /dev/null @@ -1,96 +0,0 @@ -package ml.adamsprogs.bimba.models.adapters - -import android.content.Context -import android.graphics.PorterDuff -import android.os.Build -import android.text.Html -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.core.content.ContextCompat.getColor -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.getDrawable -import ml.adamsprogs.bimba.models.suggestions.EmptySuggestion -import ml.adamsprogs.bimba.models.suggestions.GtfsSuggestion -import ml.adamsprogs.bimba.models.suggestions.LineSuggestion -import ml.adamsprogs.bimba.models.suggestions.StopSuggestion -import com.mancj.materialsearchbar.adapter.SuggestionsAdapter as SearchBarSuggestionsAdapter - -class SuggestionsAdapter(inflater: LayoutInflater, private val onSuggestionClickListener: OnSuggestionClickListener, private val context: Context) : - SearchBarSuggestionsAdapter<GtfsSuggestion, SuggestionsAdapter.ViewHolder>(inflater) { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val rowView = layoutInflater.inflate(R.layout.row_suggestion, parent, false) - return ViewHolder(rowView) - } - - override fun getSingleViewHeight(): Int = 48 - - override fun onBindSuggestionHolder(suggestion: GtfsSuggestion, holder: ViewHolder?, pos: Int) { - holder!!.root.setOnClickListener { - onSuggestionClickListener.onSuggestionClickListener(suggestion) - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - holder.text.text = Html.fromHtml(suggestion.getBody(context), Html.FROM_HTML_MODE_LEGACY) - } else { - @Suppress("DEPRECATION") - holder.text.text = Html.fromHtml(suggestion.getBody(context)) - } - - holder.text.setTextColor(getColor(context, R.color.textDark)) - - val icon = getDrawable(suggestion.getIcon(), context) - icon.mutate() - icon.colorFilter = null - if (suggestion is StopSuggestion) - when (suggestion.zone) { - "A" -> icon.setColorFilter(getColor(context, R.color.zoneA), PorterDuff.Mode.SRC_IN) - "B" -> icon.setColorFilter(getColor(context, R.color.zoneB), PorterDuff.Mode.SRC_IN) - "C" -> icon.setColorFilter(getColor(context, R.color.zoneC), PorterDuff.Mode.SRC_IN) - else -> icon.setColorFilter(getColor(context, R.color.textDark), PorterDuff.Mode.SRC_IN) - } - else if (suggestion is LineSuggestion) { - icon.setColorFilter(suggestion.getColour(), PorterDuff.Mode.SRC_IN) - holder.icon.setBackgroundColor(suggestion.getBgColour()) - } - holder.icon.setImageDrawable(icon) - - } - - fun updateSuggestions(newSuggestions: List<GtfsSuggestion>, query: String) { - suggestions = sort(newSuggestions, query).take(6) - suggestions_clone = suggestions - notifyDataSetChanged() - } - - private fun sort(suggestions: List<GtfsSuggestion>, query: String): List<GtfsSuggestion> { - val r = Regex(query, RegexOption.IGNORE_CASE) - return suggestions.sortedBy { - (r.find(it.name)?.range?.start?.toString()?.padStart(128, '0') ?: "")+it.name - } - } - - operator fun contains(suggestion: GtfsSuggestion): Boolean { - return suggestion in suggestions //|| suggestion in suggestions_clone - } - - inner class ViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView.ViewHolder(itemView) { - val root: View = itemView.findViewById(R.id.row_suggestion) - val icon: ImageView = itemView.findViewById(R.id.suggestion_row_image) - val text: TextView = itemView.findViewById(R.id.suggestion_row_text) - } - - interface OnSuggestionClickListener { - fun onSuggestionClickListener(suggestion: GtfsSuggestion) - } - - fun equals(other: List<GtfsSuggestion>): Boolean { - if ((suggestions.containsAll(other) and other.containsAll(suggestions))) - return true - if (other.isEmpty()) - if ((suggestions.isEmpty()) or (suggestions[0] is EmptySuggestion)) - return true - return false - } -} diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Calendar.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Calendar.kt deleted file mode 100644 index aad6742b778ffe1dda196494e374adb46cc4550d..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Calendar.kt +++ /dev/null @@ -1,4 +0,0 @@ -package ml.adamsprogs.bimba.models.gtfs - -data class Calendar(val monday: Boolean, val tuesday: Boolean, val wednesday: Boolean, val thursday: Boolean, - val friday: Boolean, val saturday: Boolean, val sunday: Boolean) \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Route.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Route.kt deleted file mode 100644 index c3021d8a3c0991b4cee3150a5a2f9751a2ea8764..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Route.kt +++ /dev/null @@ -1,85 +0,0 @@ -package ml.adamsprogs.bimba.models.gtfs - -import android.os.Parcel -import android.os.Parcelable - - -data class Route(val id: String, val agency: String, val shortName: String, - val longName: String, val description: String, val type: Int, val colour: Int, - val textColour: Int, val modifications: Map<String, String>) : Parcelable { - companion object CREATOR : Parcelable.Creator<Route> { - const val TYPE_BUS = 3 - const val TYPE_TRAM = 0 - - override fun createFromParcel(parcel: Parcel): Route { - return Route(parcel) - } - - override fun newArray(size: Int): Array<Route?> { - return arrayOfNulls(size) - } - - fun create(id: String, agency: String, shortName: String, longName: String, - desc: String, type: Int, colour: Int, textColour: Int): Route { - return if (desc.contains("|")) { - val (to, from) = desc.split("|") - val fromSplit = from.split("^") - val toSplit = to.split("^") - val description = "${toSplit[0]}|${fromSplit[0]}" - val modifications = createModifications(desc) - Route(id, agency, shortName, longName, description, - type, colour, textColour, modifications) - } else { - val toSplit = desc.split("^") - val description = toSplit[0] - val modifications = createModifications(desc) - Route(id, agency, shortName, longName, description, - type, colour, textColour, modifications) - } - } - - fun createModifications(desc: String): Map<String, String> { - val (to, from) = if(desc.contains('|')) desc.split("|") else listOf(desc, null) - val toSplit = to!!.split("^") - val fromSplit = from?.split("^") - val modifications = HashMap<String, String>() - toSplit.slice(1 until toSplit.size).forEach { - val (k, v) = it.split(" - ") - modifications[k] = v - } - fromSplit?.slice(1 until fromSplit.size)?.forEach { - val (k,v) = it.split(" - ") - modifications[k] = v - } - return modifications - } - } - - @Suppress("UNCHECKED_CAST") - constructor(parcel: Parcel) : this( - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readString(), - parcel.readInt(), - parcel.readInt(), - parcel.readInt(), - parcel.readSerializable() as HashMap<String, String>) - - override fun writeToParcel(parcel: Parcel, flags: Int) { - parcel.writeString(id) - parcel.writeString(agency) - parcel.writeString(shortName) - parcel.writeString(longName) - parcel.writeString(description) - parcel.writeInt(type) - parcel.writeInt(colour) - parcel.writeInt(textColour) - parcel.writeSerializable(modifications as HashMap) - } - - override fun describeContents(): Int { - return Parcelable.CONTENTS_FILE_DESCRIPTOR - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Stop.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Stop.kt deleted file mode 100644 index a98a2517e0fe34ae0e559e46c9d398ae51605de1..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Stop.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ml.adamsprogs.bimba.models.gtfs - -data class Stop(val id: Int, val code: String?, val name: String, val latitude: Float?, val Longitude: Float?, val zone: Char, val onDemand: Boolean = false) { - override fun toString() = "$id: $name ($zone)" -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Trip.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Trip.kt deleted file mode 100644 index db797a31de4ba22531ebe14266ed73ed38e72254..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Trip.kt +++ /dev/null @@ -1,9 +0,0 @@ -package ml.adamsprogs.bimba.models.gtfs - -data class Trip(val routeId: String, val serviceId: String, val id: ID, - val headsign: String, val direction: Int, val shapeId: String, - val wheelchairAccessible: Boolean) { - data class ID(val rawId:String, val id: String, val modification: Set<Modification>, val isMain: Boolean) { - data class Modification(val id: String, val stopRange: IntRange?) - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/EmptySuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/EmptySuggestion.kt deleted file mode 100644 index 6d1ae4255e29b82a47db5d82c5261e273dad8f82..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/EmptySuggestion.kt +++ /dev/null @@ -1,37 +0,0 @@ -package ml.adamsprogs.bimba.models.suggestions - -import android.content.Context -import ml.adamsprogs.bimba.R - -class EmptySuggestion : GtfsSuggestion("Empty") { - override fun equals(other: Any?): Boolean { - return other != null && other is EmptySuggestion - } - - override fun getIcon(): Int { - return R.drawable.ic_error_outline - } - - override fun getColour(): Int { - return 0xffffff - } - - override fun getBgColour(): Int { - return 0x000000 - } - - override fun getBody(context: Context): String { - return context.getString(R.string.nothing_found) - } - - override fun compareTo(other: GtfsSuggestion): Int { - return if (other is EmptySuggestion) - 0 - else - -1 - } - - override fun hashCode(): Int { - return name.hashCode() - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt deleted file mode 100644 index 06338fb9e936e9f0580b142ef5995ed419508c5a..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ml.adamsprogs.bimba.models.suggestions - -import android.content.Context - -abstract class GtfsSuggestion(val name: String) : Comparable<GtfsSuggestion> { - abstract fun getIcon(): Int - - abstract fun getColour(): Int - - abstract fun getBgColour(): Int - - abstract fun getBody(context: Context): String - - abstract override fun equals(other: Any?): Boolean - - abstract override fun hashCode(): Int -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt deleted file mode 100644 index b6b11e162b21b5beb4d5b85e276fdcc156e4f408..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt +++ /dev/null @@ -1,49 +0,0 @@ -package ml.adamsprogs.bimba.models.suggestions - -import android.content.Context -import ml.adamsprogs.bimba.R -import ml.adamsprogs.bimba.models.gtfs.Route - -class LineSuggestion(name: String, private val route: Route) : GtfsSuggestion(name) { - override fun getIcon(): Int { - return when (route.type) { - Route.TYPE_BUS -> R.drawable.ic_bus - Route.TYPE_TRAM -> R.drawable.ic_tram - else -> R.drawable.ic_vehicle - } - } - - override fun getBody(context: Context): String { - return name - } - - override fun getColour(): Int { - return route.colour - } - - override fun getBgColour(): Int { - return route.textColour - } - - override fun compareTo(other: GtfsSuggestion): Int { - return if (other is LineSuggestion) - name.padStart(3, '0').compareTo(other.name.padStart(3, '0')) - else - name.compareTo(other.name) - } - - override fun equals(other: Any?): Boolean { - if (other == null || other !is GtfsSuggestion) - return false - return if (other is LineSuggestion) - name.padStart(3, '0') == other.name.padStart(3, '0') - else - name == other.name - } - - override fun hashCode(): Int { - var result = route.hashCode() - result = 31 * result + name.hashCode() - return result - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt deleted file mode 100644 index 88c4f19b68dc32e2d87aee7437e21870d9fc7093..0000000000000000000000000000000000000000 --- a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt +++ /dev/null @@ -1,39 +0,0 @@ -package ml.adamsprogs.bimba.models.suggestions - -import android.content.Context -import ml.adamsprogs.bimba.R - -class StopSuggestion(name: String, val zone: String) : GtfsSuggestion(name) { - - override fun getBody(context: Context): String { - return name - } - - override fun getIcon(): Int { - return R.drawable.ic_stop - } - - override fun getColour(): Int { - return 0xffffff - } - - override fun getBgColour(): Int { - return 0x000000 - } - - override fun compareTo(other: GtfsSuggestion): Int { - return name.compareTo(other.name) - } - - override fun equals(other: Any?): Boolean { - if (other == null || other !is GtfsSuggestion) - return false - return name == other.name - } - - override fun hashCode(): Int { - var result = zone.hashCode() - result = 31 * result + name.hashCode() - return result - } -} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt b/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt new file mode 100644 index 0000000000000000000000000000000000000000..34a162856469ff0e7d78c1277a3e48375f4e35e4 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt @@ -0,0 +1,22 @@ +package xyz.apiote.bimba.czwek + +import org.osmdroid.config.Configuration +import java.io.File + +// todo [3.1] style + +class Bimba : android.app.Application() { + override fun onCreate() { + super.onCreate() + Configuration.getInstance() + .let { config -> + config.load( + applicationContext, + applicationContext.getSharedPreferences("shp", MODE_PRIVATE) + ) + config.osmdroidBasePath = File(applicationContext.cacheDir.absolutePath, "osmdroid") + + config.osmdroidTileCache = File(config.osmdroidBasePath.absolutePath, "tile") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/Api.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/Api.kt new file mode 100644 index 0000000000000000000000000000000000000000..b0ead8725723cdf1579ad1ff8cb9148ffeef32ab --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/Api.kt @@ -0,0 +1,155 @@ +package xyz.apiote.bimba.czwek.api + +import android.content.Context +import android.content.Context.MODE_PRIVATE +import android.net.ConnectivityManager +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import xyz.apiote.bimba.czwek.R +import java.io.IOException +import java.io.InputStream +import java.net.HttpURLConnection +import java.net.MalformedURLException +import java.net.URL +import java.net.URLEncoder + +// todo [3.1] constants + +// todo [3.1] create Repository between models and api/fs +// todo [3.1] in Repository check if responses are BARE or HTML + +data class Server(val host: String, val token: String, val feeds: String, val apiPath: String) { + companion object { + fun get(context: Context): Server { + val preferences = context.getSharedPreferences("shp", MODE_PRIVATE) + val host = preferences.getString("host", "bimba.apiote.xyz")!! + return Server( + host, preferences.getString("token", "")!!, + preferences.getString("${host}_feeds", "")!!, + preferences.getString("apiPath", "")!!, + ) + } + } +} + +data class Result(val stream: InputStream?, val error: Error?) + +data class Error(val statusCode: Int, val stringResource: Int, val imageResource: Int) + +suspend fun getBimba(cm: ConnectivityManager, server: Server): Result { + return try { + rawRequest( + URL("${hostWithScheme(server.host)}/.well-known/traffic-api"), server, cm, emptyArray() + ) + } catch (e: MalformedURLException) { + Result(null, Error(0, R.string.error_url, R.drawable.error_url)) + } +} + +suspend fun getFeeds(cm: ConnectivityManager, server: Server): Result { + return try { + rawRequest( + URL("${server.apiPath}/"), server, cm, arrayOf(1u) + ) + } catch (_: MalformedURLException) { + Result(null, Error(0, R.string.error_url, R.drawable.error_url)) + } +} + +suspend fun queryQueryables( + cm: ConnectivityManager, server: Server, query: String, limit: Int? = null +): Result { + val params = mutableMapOf("q" to query) + if (limit != null) { + params["limit"] = limit.toString() + } + return request(server, "queryables", params, cm, arrayOf(1u)) +} + +suspend fun locateQueryables(cm: ConnectivityManager, server: Server, near: PositionV1): Result { + return request(server, "queryables", mapOf("near" to near.toString()), cm, arrayOf(1u)) +} + +suspend fun getLocatablesIn( + cm: ConnectivityManager, server: Server, bl: PositionV1, tr: PositionV1 +): Result { + return request( + server, "locatables", mapOf("lb" to bl.toString(), "rt" to tr.toString()), cm, arrayOf(1u) + ) +} + +suspend fun getDepartures( + cm: ConnectivityManager, server: Server, stop: String, line: String? = null +): Result { + val params = mutableMapOf("code" to stop) + if (line != null) { + params["line"] = line + } + return request(server, "departures", params, cm, arrayOf(1u)) +} + +suspend fun rawRequest( + url: URL, server: Server, cm: ConnectivityManager, responseVersion: Array<UInt> +): Result { + @Suppress("DEPRECATION") // fixme later(API_29, API_23) https://developer.android.com/reference/android/net/ConnectivityManager#getActiveNetwork() + if (cm.activeNetworkInfo == null) { + return Result(null, Error(0, R.string.error_offline, R.drawable.error_net)) + } + return withContext(Dispatchers.IO) { + val c = (url.openConnection() as HttpURLConnection).apply { + setRequestProperty("X-Bimba-Token", server.token) + responseVersion.forEach { addRequestProperty("Accept", "application/$it+bare") } + } + try { + if (c.responseCode == 200) { + Result(c.inputStream, null) + } else { + val (string, image) = when (c.responseCode) { + 400 -> Pair(R.string.error_400, R.drawable.error_app) + 401 -> Pair(R.string.error_401, R.drawable.error_sec) + 403 -> Pair(R.string.error_403, R.drawable.error_sec) + 404 -> Pair(R.string.error_404, R.drawable.error_search) + 429 -> Pair(R.string.error_429, R.drawable.error_limit) + 500 -> Pair(R.string.error_50x, R.drawable.error_server) + 502 -> Pair(R.string.error_50x, R.drawable.error_server) + 503 -> Pair(R.string.error_50x, R.drawable.error_server) + 504 -> Pair(R.string.error_50x, R.drawable.error_server) + else -> Pair(R.string.error_unknown, R.drawable.error_other) + } + Result(c.errorStream, Error(c.responseCode, string, image)) + } + } catch (e: IOException) { + Result(null, Error(0, R.string.error_connecting, R.drawable.error_server)) + } + } +} + +suspend fun request( + server: Server, + resource: String, + params: Map<String, String>, + cm: ConnectivityManager, + responseVersion: Array<UInt> +): Result { + return withContext(Dispatchers.IO) { + val url = URL( // todo [3.1] scheme, host, path, constructed query + "${server.apiPath}/${server.feeds}/$resource${ + params.map { + "${it.key}=${ + URLEncoder.encode( + it.value, "utf-8" + ) + }" + }.joinToString("&", "?") + }" + ) + rawRequest(url, server, cm, responseVersion) + } +} + +fun hostWithScheme(host: String): String = + if (host.startsWith("http://") or host.startsWith("https://")) { + host + } else { + "https://$host" + } \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/Responses.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/Responses.kt new file mode 100644 index 0000000000000000000000000000000000000000..e8dd16c9f3c4b61219bd49d49bee82ed08978bd4 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/Responses.kt @@ -0,0 +1,272 @@ +package xyz.apiote.bimba.czwek.api + +import xyz.apiote.fruchtfleisch.Reader +import java.io.InputStream + +class UnknownResponseVersion(val resource: String, val version: ULong) : Exception() + +interface DeparturesResponse { + companion object { + fun unmarshal(stream: InputStream): DeparturesResponse { + val reader = Reader(stream) + return when (val v = reader.readUInt().toULong()) { + 0UL -> { + DeparturesResponseDev.unmarshal(stream) + } + 1UL -> { + DeparturesResponseV1.unmarshal(stream) + } + else -> { + throw UnknownResponseVersion("Departures", v) + } + } + } + } +} + +data class DeparturesResponseV1( + val alerts: List<AlertV1>, + val departures: List<DepartureV1>, + val stop: StopV1 +) : DeparturesResponse { + companion object { + fun unmarshal(stream: InputStream): DeparturesResponseV1 { + val alerts = mutableListOf<AlertV1>() + val departures = mutableListOf<DepartureV1>() + + val reader = Reader(stream) + val alertsNum = reader.readUInt().toULong() + for (i in 0UL until alertsNum) { + val alert = AlertV1.unmarshal(stream) + alerts.add(alert) + } + val departuresNum = reader.readUInt().toULong() + for (i in 0UL until departuresNum) { + val departure = DepartureV1.unmarshal(stream) + departures.add(departure) + } + + return DeparturesResponseV1(alerts, departures, StopV1.unmarshal(stream)) + } + } +} + +data class DeparturesResponseDev( + val alerts: List<AlertV1>, + val departures: List<DepartureV1>, + val stop: StopV1 +) : DeparturesResponse { + companion object { + fun unmarshal(stream: InputStream): DeparturesResponseDev { + val alerts = mutableListOf<AlertV1>() + val departures = mutableListOf<DepartureV1>() + + val reader = Reader(stream) + val alertsNum = reader.readUInt().toULong() + for (i in 0UL until alertsNum) { + val alert = AlertV1.unmarshal(stream) + alerts.add(alert) + } + val departuresNum = reader.readUInt().toULong() + for (i in 0UL until departuresNum) { + val departure = DepartureV1.unmarshal(stream) + departures.add(departure) + } + + return DeparturesResponseDev(alerts, departures, StopV1.unmarshal(stream)) + } + } +} + +interface QueryablesResponse { + companion object { + fun unmarshal(stream: InputStream): QueryablesResponse { + val reader = Reader(stream) + return when (val v = reader.readUInt().toULong()) { + 0UL -> { + QueryablesResponseDev.unmarshal(stream) + } + 1UL -> { + QueryablesResponseV1.unmarshal(stream) + } + else -> { + throw UnknownResponseVersion("Queryables", v) + } + } + } + } +} + +data class QueryablesResponseV1(val queryables: List<QueryableV1>) : QueryablesResponse { + companion object { + fun unmarshal(stream: InputStream): QueryablesResponseV1 { + val queryables = mutableListOf<QueryableV1>() + val reader = Reader(stream) + val n = reader.readUInt().toULong() + for (i in 0UL until n) { + when (val r = reader.readUInt().toULong()) { + 0UL -> { + queryables.add(StopV1.unmarshal(stream)) + } + /*1UL -> { + queryables.add(Line.unmarshal(stream)) + }*/ + else -> { + throw UnknownResourceVersion("Queryable/$r", 1u) + } + } + } + return QueryablesResponseV1(queryables) + } + } +} + +data class QueryablesResponseDev(val queryables: List<QueryableV1>) : QueryablesResponse { + companion object { + fun unmarshal(stream: InputStream): QueryablesResponseDev { + val queryables = mutableListOf<QueryableV1>() + val reader = Reader(stream) + val n = reader.readUInt().toULong() + for (i in 0UL until n) { + when (val r = reader.readUInt().toULong()) { + 0UL -> { + queryables.add(StopV1.unmarshal(stream)) + } + /*1UL -> { + queryables.add(Line.unmarshal(stream)) + }*/ + else -> { + throw UnknownResourceVersion("Queryable/$r", 1u) + } + } + } + return QueryablesResponseDev(queryables) + } + } +} + +interface FeedsResponse { + companion object { + fun unmarshal(stream: InputStream): FeedsResponse { + val reader = Reader(stream) + return when (val v = reader.readUInt().toULong()) { + 0UL -> { + FeedsResponseDev.unmarshal(stream) + } + 1UL -> { + FeedsResponseV1.unmarshal(stream) + } + else -> { + throw UnknownResponseVersion("Feeds", v) + } + } + } + } +} + +data class FeedsResponseDev( + val feeds: List<FeedInfoV1> +) : FeedsResponse { + companion object { + fun unmarshal(stream: InputStream): FeedsResponseDev { + val feeds = mutableListOf<FeedInfoV1>() + val reader = Reader(stream) + val n = reader.readUInt().toULong() + for (i in 0UL until n) { + feeds.add(FeedInfoV1.unmarshal(stream)) + } + return FeedsResponseDev(feeds) + } + } +} + +data class FeedsResponseV1( + val feeds: List<FeedInfoV1> +) : FeedsResponse { + companion object { + fun unmarshal(stream: InputStream): FeedsResponseV1 { + val feeds = mutableListOf<FeedInfoV1>() + val reader = Reader(stream) + val n = reader.readUInt().toULong() + for (i in 0UL until n) { + feeds.add(FeedInfoV1.unmarshal(stream)) + } + return FeedsResponseV1(feeds) + } + } +} + +interface LocatablesResponse { + companion object { + fun unmarshal(stream: InputStream): LocatablesResponse { + val reader = Reader(stream) + return when (val v = reader.readUInt().toULong()) { + 0UL -> { + LocatablesResponseDev.unmarshal(stream) + } + 1UL -> { + LocatablesResponseV1.unmarshal(stream) + } + else -> { + throw UnknownResponseVersion("Locatables", v) + } + } + } + } +} + +data class LocatablesResponseV1(val locatables: List<Locatable>) : LocatablesResponse { + companion object { + fun unmarshal(stream: InputStream): LocatablesResponseV1 { + val locatables = mutableListOf<Locatable>() + val reader = Reader(stream) + val n = reader.readUInt().toULong() + for (i in 0UL until n) { + when (val r = reader.readUInt().toULong()) { + 0UL -> { + locatables.add(StopV1.unmarshal(stream)) + } + 1UL -> { + locatables.add(VehicleV1.unmarshal(stream)) + } + else -> { + throw UnknownResourceVersion("Locatable/$r", 1u) + } + } + } + return LocatablesResponseV1(locatables) + } + } +} +data class LocatablesResponseDev(val locatables: List<Locatable>) : LocatablesResponse { + companion object { + fun unmarshal(stream: InputStream): LocatablesResponseDev { + val locatables = mutableListOf<Locatable>() + val reader = Reader(stream) + val n = reader.readUInt().toULong() + for (i in 0UL until n) { + when (val r = reader.readUInt().toULong()) { + 0UL -> { + locatables.add(StopV1.unmarshal(stream)) + } + 1UL -> { + locatables.add(VehicleV1.unmarshal(stream)) + } + else -> { + throw UnknownResourceVersion("Locatable/$r", 1u) + } + } + } + return LocatablesResponseDev(locatables) + } + } +} + +data class ErrorResponse(val field: String, val message: String) { + companion object { + fun unmarshal(stream: InputStream): ErrorResponse { + val reader = Reader(stream) + return ErrorResponse(reader.readString(), reader.readString()) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt new file mode 100644 index 0000000000000000000000000000000000000000..cf7adc236dc9653c04b5173789855dd53e10d317 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt @@ -0,0 +1,662 @@ +package xyz.apiote.bimba.czwek.api + +import android.content.Context +import android.graphics.* +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Drawable +import android.graphics.drawable.LayerDrawable +import android.os.Parcelable +import android.text.format.DateUtils +import android.util.Log +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.graphics.ColorUtils.HSLToColor +import androidx.core.graphics.drawable.toBitmap +import kotlinx.parcelize.Parcelize +import org.yaml.snakeyaml.Yaml +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.dpToPixel +import xyz.apiote.bimba.czwek.dpToPixelI +import xyz.apiote.fruchtfleisch.Reader +import java.io.InputStream +import java.time.Instant +import java.time.ZoneId +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle +import java.time.temporal.ChronoUnit +import java.util.* +import java.util.zip.Adler32 +import kotlin.math.abs +import kotlin.math.pow + +class TrafficFormatException(override val message: String) : IllegalArgumentException() +class UnknownResourceVersion(val resource: String, val version: ULong) : Exception() + +data class BimbaInfo( + val contact: Map<String, String>, +) + +data class Bimba( + val info: BimbaInfo, + val servers: List<Map<String, String>>, + val security: List<Map<String, List<*>>> +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun unmarshal(stream: InputStream): Bimba { + val map = Yaml().load(stream) as HashMap<String, *> + val contact = + if (map["info"] is Map<*, *> && (map["info"] as Map<*, *>).keys.all { it is String }) { + (map["info"] as Map<String, *>)["contact"] + } else { + throw TrafficFormatException("invalid info format") + } + val contactMap = + if (contact is Map<*, *> && contact.all { it.key is String && it.value is String }) { + contact as Map<String, String> + } else { + throw TrafficFormatException("invalid contact format") + } + val servers = if (map["servers"] is List<*> && (map["servers"] as List<*>).all { server -> + server is Map<*, *> && server.all { it.key is String && it.value is String } + }) { + map["servers"] as List<Map<String, String>> + } else { + throw TrafficFormatException("invalid servers format") + } + val security = + if (map["security"] is List<*> && (map["security"] as List<*>).all { security -> + security is Map<*, *> && security.all { it.key is String && it.value is List<*> } + }) { + map["security"] as List<Map<String, List<*>>> + } else { + throw TrafficFormatException("invalid security format") + } + val bimba = Bimba(BimbaInfo(contactMap), servers, security) + bimba.validate() + return bimba + } + } + + fun isPrivate(): Boolean { + return security.size == 1 && security[0]["api_key"] != null + } + + fun isRateLimited(): Boolean { + val items = security.foldRight(0b00) { map, acc -> + acc or when { + map.containsKey("api_key") -> 0b10 + map.isEmpty() -> 0b01 + else -> 0b00 + } + } + Log.i("Rate limited", "${this}, $items") + return security.size == 2 && items == 0b11 + } + + private fun validate() { + if (servers.isEmpty() || servers[0]["url"] == null) { + throw TrafficFormatException("no server in info") + } + if (security.isEmpty()) { + throw TrafficFormatException("no security") + } + } +} + +@Parcelize +data class PositionV1( + val latitude: Double, val longitude: Double +) : Parcelable { + fun isZero(): Boolean { + return latitude == 0.0 && longitude == 0.0 + } + + override fun toString(): String = "$latitude,$longitude" + + + companion object { + fun unmarshal(stream: InputStream): PositionV1 { + val reader = Reader(stream) + return PositionV1( + reader.readFloat64(), reader.readFloat64() + ) + } + } +} + +data class FeedInfoV1( + val name: String, + val id: String, + val attribution: String, + val description: String, + val lastUpdate: ZonedDateTime +) { + companion object { + fun unmarshal(stream: InputStream): FeedInfoV1 { + val reader = Reader(stream) + return FeedInfoV1( + reader.readString(), + reader.readString(), + reader.readString(), + reader.readString(), + ZonedDateTime.parse(reader.readString(), DateTimeFormatter.ISO_DATE_TIME) + ) + } + } + + fun formatDate(): String { + return lastUpdate.format( + DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).withLocale(Locale.getDefault()) + ) + } +} + +data class AlertV1( + val header: String, + val Description: String, + val Url: String, + val Cause: ULong, // todo [3.1] enum + val Effect: ULong // todo [3.1] enum +) { + companion object { + fun unmarshal(stream: InputStream): AlertV1 { + val reader = Reader(stream) + val header = reader.readString() + val description = reader.readString() + val url = reader.readString() + val cause = reader.readUInt().toULong() + val effect = reader.readUInt().toULong() + return AlertV1(header, description, url, cause, effect) + } + } +} + +data class Time( + val Hour: UInt, val Minute: UInt, val Second: UInt, val DayOffset: Byte, val Zone: String +) { + companion object { + fun unmarshal(stream: InputStream): Time { + val reader = Reader(stream) + return Time( + reader.readUInt().toULong().toUInt(), + reader.readUInt().toULong().toUInt(), + reader.readUInt().toULong().toUInt(), + reader.readI8(), + reader.readString() + ) + } + } +} + +data class ColourV1(val R: UByte, val G: UByte, val B: UByte) { + companion object { + fun unmarshal(stream: InputStream): ColourV1 { + val reader = Reader(stream) + return ColourV1( + reader.readU8(), reader.readU8(), reader.readU8() + ) + } + } + + fun toInt(): Int { + var rgb = 0xff + rgb = (rgb shl 8) + R.toInt() + rgb = (rgb shl 8) + G.toInt() + rgb = (rgb shl 8) + B.toInt() + return rgb + } +} + +data class VehicleV1( + val ID: String, + val Position: PositionV1, + val Capabilities: UShort, + val Speed: Float, + val Line: LineStubV1, + val Headsign: String, + val CongestionLevel: ULong, + val OccupancyStatus: ULong +) : Locatable { + enum class Capability(val bit: UShort) { + RAMP(0b0001u), LOW_FLOOR(0b0010u), LOW_ENTRY(0b0001_0000_0000u), AC(0b0100u), BIKE(0b1000u), VOICE( + 0b0001_0000u + ), + TICKET_MACHINE(0b0010_0000u), TICKET_DRIVER(0b0100_0000u), USB_CHARGING(0b1000_0000u) + } + + override fun id(): String = ID + + override fun icon(context: Context, scale: Float): Drawable { + return BitmapDrawable(context.resources, Line.icon(context, scale)) + } + + override fun location(): PositionV1 = Position + + fun congestion(context: Context): String { + return when (val r = CongestionLevel.toUInt()) { // todo [3.1] enum + 0u -> context.getString(R.string.congestion_unknown) + 1u -> context.getString(R.string.congestion_smooth) + 2u -> context.getString(R.string.congestion_stop_and_go) + 3u -> context.getString(R.string.congestion_congestion) + 4u -> context.getString(R.string.congestion_jams) + else -> throw UnknownResourceVersion("Congestion/$r", 1u) + } + } + + fun occupancy(context: Context): String { + return when (val r = OccupancyStatus.toUInt()) { // todo [3.1] enum + 0u -> context.getString(R.string.occupancy_unknown) + 1u -> context.getString(R.string.occupancy_empty) + 2u -> context.getString(R.string.occupancy_many_seats) + 3u -> context.getString(R.string.occupancy_few_seats) + 4u -> context.getString(R.string.occupancy_standing_only) + 5u -> context.getString(R.string.occupancy_crowded) + 6u -> context.getString(R.string.occupancy_full) + 7u -> context.getString(R.string.occupancy_wont_let) + else -> throw UnknownResourceVersion("Occupancy/$r", 1u) + } + } + + companion object { + fun unmarshal(stream: InputStream): VehicleV1 { + val reader = Reader(stream) + return VehicleV1( + reader.readString(), + PositionV1.unmarshal(stream), + reader.readU16(), + reader.readFloat32(), + LineStubV1.unmarshal(stream), + reader.readString(), + reader.readUInt().toULong(), + reader.readUInt().toULong() + ) + } + } + + fun getCapability(field: Capability): Boolean { + return Capabilities.and(field.bit) != (0).toUShort() + } +} + +data class LineStubV1( + val name: String, val kind: LineTypeV1, val colour: ColourV1 +) : LineAbstract { + companion object { + fun unmarshal(stream: InputStream): LineStubV1 { + val reader = Reader(stream) + return LineStubV1( + reader.readString(), + LineTypeV1.of(reader.readUInt().toULong().toUInt()), + ColourV1.unmarshal(stream) + ) + } + } + + fun icon(context: Context, scale: Float = 1f): Bitmap { + return super.icon(context, kind, colour, scale) + } +} + +data class DepartureV1( + val ID: String, + val time: Time, + val status: ULong, + val isRealtime: Boolean, + val vehicle: VehicleV1, + val boarding: UByte +) { + + fun statusText(context: Context?): String { + val now = Instant.now().atZone(ZoneId.systemDefault()) + val departureTime = ZonedDateTime.of( + now.year, now.monthValue, now.dayOfMonth, + time.Hour.toInt(), time.Minute.toInt(), time.Second.toInt(), 0, ZoneId.of(time.Zone) + ).plus(time.DayOffset.toLong(), ChronoUnit.DAYS) + return when (val r = status.toUInt()) { + 0u -> DateUtils.getRelativeTimeSpanString( + departureTime.toEpochSecond() * 1000, + now.toEpochSecond() * 1000, + DateUtils.MINUTE_IN_MILLIS, + DateUtils.FORMAT_ABBREV_RELATIVE + ).toString() + 1u -> context?.getString(R.string.departure_momentarily) ?: "momentarily" + 2u -> context?.getString(R.string.departure_now) ?: "now" + 3u -> context?.getString(R.string.departure_departed) ?: "departed" + else -> throw UnknownResourceVersion("VehicleStatus/$r", 1u) + } + } + + fun timeString(context: Context): String { + return if (isRealtime) { + context.getString( + R.string.at_time_realtime, time.Hour.toInt(), time.Minute.toInt(), time.Second.toInt() + ) + } else { + context.getString(R.string.at_time, time.Hour.toInt(), time.Minute.toInt()) + } + } + + fun boardingText(context: Context): String { + // todo [3.x] probably should take into account (on|off)-boarding only, on demand + return when { + boarding == (0b0000_0000).toUByte() -> context.getString(R.string.no_boarding) + boarding.and(0b0011_0011u) == (0b0000_0001).toUByte() -> context.getString(R.string.on_boarding) + boarding.and(0b0011_0011u) == (0b0001_0000).toUByte() -> context.getString(R.string.off_boarding) + boarding.and(0b0011_0011u) == (0b0001_0001).toUByte() -> context.getString(R.string.boarding) + else -> context.getString(R.string.on_demand) + } + } + + companion object { + fun unmarshal(stream: InputStream): DepartureV1 { + val reader = Reader(stream) + val id = reader.readString() + val time = Time.unmarshal(stream) + val status = reader.readUInt().toULong() + val isRealtime = reader.readBoolean() + val vehicle = VehicleV1.unmarshal(stream) + val boarding = reader.readU8() + return DepartureV1(id, time, status, isRealtime, vehicle, boarding) + } + } +} + +interface QueryableV1 +interface Locatable { + fun icon(context: Context, scale: Float = 1f): Drawable + fun location(): PositionV1 + fun id(): String +} + +class ErrorLocatable(val stringResource: Int) : Locatable { + override fun icon(context: Context, scale: Float): Drawable { + return AppCompatResources.getDrawable(context, R.drawable.error_other)!! + } + + override fun location(): PositionV1 { + return PositionV1(0.0, 0.0) + } + + override fun id(): String { + return "ERROR" + } +} + +@Parcelize +data class StopV1( + val code: String, + val name: String, + val zone: String, + val position: PositionV1, + val changeOptions: List<ChangeOptionV1> +) : QueryableV1, Locatable, Parcelable { + + override fun icon(context: Context, scale: Float): Drawable { + val saturationArray = arrayOf(0.5f, 0.65f, 0.8f) + val sal = saturationArray.size + val lightnessArray = arrayOf(.5f) + val lal = lightnessArray.size + val md = Adler32().let { + it.update(name.toByteArray()) + it.value + } + val h = md % 359f + val s = saturationArray[(md / 360 % sal).toInt()] + val l = lightnessArray[(md / 360 / sal % lal).toInt()] + val fg = AppCompatResources.getDrawable(context, R.drawable.stop) + val bg = AppCompatResources.getDrawable(context, R.drawable.stop_bg)!!.mutate().apply { + setTint(HSLToColor(arrayOf(h, s, l).toFloatArray())) + } + return BitmapDrawable( + context.resources, + LayerDrawable(arrayOf(bg, fg)).mutate() + .toBitmap(dpToPixelI(24f / scale), dpToPixelI(24f / scale), Bitmap.Config.ARGB_8888) + ) + } + + override fun id(): String = code + + override fun location(): PositionV1 = position + + override fun toString(): String { + var result = "$name ($code) [$zone] $position\n" + for (chOpt in changeOptions) result += "${chOpt.line} → ${chOpt.headsign}\n" + return result + } + + fun changeOptions(context: Context): Pair<String, String> { + return Pair(changeOptions.groupBy { it.line } + .map { Pair(it.key, it.value.joinToString { co -> co.headsign }) }.joinToString { + context.getString( + R.string.vehicle_headsign, it.first, it.second + ) + }, + changeOptions.groupBy { it.line } + .map { Pair(it.key, it.value.joinToString { co -> co.headsign }) }.joinToString { + context.getString( + R.string.vehicle_headsign_content_description, it.first, it.second + ) + }) + } + + companion object { + fun unmarshal(stream: InputStream): StopV1 { + val reader = Reader(stream) + val code = reader.readString() + val name = reader.readString() + val zone = reader.readString() + val position = PositionV1.unmarshal(stream) + val chOptionsNum = reader.readUInt().toULong() + val changeOptions = mutableListOf<ChangeOptionV1>() + for (i in 0UL until chOptionsNum) { + changeOptions.add(ChangeOptionV1.unmarshal(stream)) + } + return StopV1( + name = name, code = code, zone = zone, position = position, changeOptions = changeOptions + ) + } + } +} + +interface LineAbstract { + fun textColour(c: ColourV1): Int { + val black = relativeLuminance(ColourV1(0u, 0u, 0u)) + .05 + val white = relativeLuminance(ColourV1(255u, 255u, 255u)) + .05 + val colour = relativeLuminance(c) + .05 + return if ((white / colour) > (colour / black)) { + Color.WHITE + } else { + Color.BLACK + } + } + + private fun relativeLuminance(colour: ColourV1): Double { + val r = fromSRGB(colour.R.toDouble() / 0xff) + val g = fromSRGB(colour.G.toDouble() / 0xff) + val b = fromSRGB(colour.B.toDouble() / 0xff) + return 0.2126 * r + 0.7152 * g + 0.0722 * b + } + + private fun fromSRGB(part: Double): Double { + return if (part <= 0.03928) { + part / 12.92 + } else { + ((part + 0.055) / 1.055).pow(2.4) + } + } + + fun icon(context: Context, type: LineTypeV1, colour: ColourV1, scale: Float): Bitmap { + val drawingBitmap = Bitmap.createBitmap( + dpToPixelI(24f / scale), dpToPixelI(24f / scale), Bitmap.Config.ARGB_8888 + ) + val canvas = Canvas(drawingBitmap) + + canvas.drawPath(getSquirclePath( + dpToPixel(.8f / scale), dpToPixel(.8f / scale), dpToPixelI(11.2f / scale) + ), Paint().apply { color = textColour(colour) }) + canvas.drawPath(getSquirclePath( + dpToPixel(1.6f / scale), dpToPixel(1.6f / scale), dpToPixelI(10.4f / scale) + ), Paint().apply { color = colour.toInt() }) + + val iconID = when (type) { + LineTypeV1.BUS -> R.drawable.bus_black + LineTypeV1.TRAM -> R.drawable.tram_black + LineTypeV1.UNKNOWN -> R.drawable.vehicle_black + } + val icon = AppCompatResources.getDrawable(context, iconID)?.mutate()?.apply { + setTint(textColour(colour)) + }?.toBitmap(dpToPixelI(19.2f / scale), dpToPixelI(19.2f / scale), Bitmap.Config.ARGB_8888) + canvas.drawBitmap( + icon!!, dpToPixel(2.4f / scale), dpToPixel(2.4f / scale), Paint() + ) + return drawingBitmap + } + + private fun getSquirclePath( + left: Float, top: Float, radius: Int + ): Path { + val radiusToPow = (radius * radius * radius).toDouble() + val path = Path() + path.moveTo(-radius.toFloat(), 0f) + for (x in -radius..radius) path.lineTo( + x.toFloat(), Math.cbrt(radiusToPow - abs(x * x * x)).toFloat() + ) + for (x in radius downTo -radius) path.lineTo( + x.toFloat(), -Math.cbrt(radiusToPow - abs(x * x * x)).toFloat() + ) + path.close() + val matrix = Matrix() + matrix.postTranslate((left + radius), (top + radius)) + path.transform(matrix) + return path + } +} + +data class Line( + val colour: ColourV1, + val type: LineTypeV1, + val headsignsThere: List<String>, + val headsignsBack: List<String>, + val graphThere: LineGraph, + val graphBack: LineGraph, + val name: String +) : QueryableV1, LineAbstract { + override fun toString(): String { + return "$name ($type) [$colour]\n→ [${headsignsThere.joinToString()}]\n→ [${headsignsBack.joinToString()}]\n" + } + + fun icon(context: Context, scale: Float = 1f): Bitmap { + return super.icon(context, type, colour, scale) + } + + companion object { + fun unmarshal(stream: InputStream): Line { + val reader = Reader(stream) + val colour = ColourV1.unmarshal(stream) + val type = reader.readUInt() + val headsignsThereNum = reader.readUInt().toULong() + val headsignsThere = mutableListOf<String>() + for (i in 0UL until headsignsThereNum) { + headsignsThere.add(reader.readString()) + } + val headsignsBackNum = reader.readUInt().toULong() + val headsignsBack = mutableListOf<String>() + for (i in 0UL until headsignsBackNum) { + headsignsBack.add(reader.readString()) + } + val graphThere = LineGraph.unmarshal(stream) + val graphBack = LineGraph.unmarshal(stream) + val name = reader.readString() + return Line( + name = name, + colour = colour, + type = LineTypeV1.of(type.toULong().toUInt()), + headsignsThere = headsignsThere, + headsignsBack = headsignsBack, + graphThere = graphThere, + graphBack = graphBack + ) + } + } +} + +enum class LineTypeV1 { + UNKNOWN, TRAM, BUS; + + companion object { + fun of(type: UInt): LineTypeV1 { + return when (type) { + 0u -> valueOf("UNKNOWN") + 1u -> valueOf("TRAM") + 2u -> valueOf("BUS") + else -> throw UnknownResourceVersion("LineType/$type", 1u) + } + } + } +} + +@Parcelize +data class ChangeOptionV1(val line: String, val headsign: String):Parcelable { + companion object { + fun unmarshal(stream: InputStream): ChangeOptionV1 { + val reader = Reader(stream) + return ChangeOptionV1(line = reader.readString(), headsign = reader.readString()) + } + } +} + +data class LineGraph( + val stops: List<StopStub>, + val nextNodes: Map<Long, List<Long>>, + val prevNodes: Map<Long, List<Long>> +) { + companion object { + fun unmarshal(stream: InputStream): LineGraph { + val reader = Reader(stream) + val stopsNum = reader.readUInt().toULong() + val stops = mutableListOf<StopStub>() + for (i in 0UL until stopsNum) { + stops.add(StopStub.unmarshal(stream)) + } + val nextNodesNum = reader.readUInt().toULong() + val nextNodes = mutableMapOf<Long, List<Long>>() + for (i in 0UL until nextNodesNum) { + val from = reader.readInt().toLong() + val toNum = reader.readUInt().toULong() + val to = mutableListOf<Long>() + for (j in 0UL until toNum) { + to.add(reader.readInt().toLong()) + } + nextNodes[from] = to + } + val prevNodesNum = reader.readUInt().toULong() + val prevNodes = mutableMapOf<Long, List<Long>>() + for (i in 0UL until prevNodesNum) { + val from = reader.readInt().toLong() + val toNum = reader.readUInt().toULong() + val to = mutableListOf<Long>() + for (j in 0UL until toNum) { + to.add(reader.readInt().toLong()) + } + prevNodes[from] = to + } + + return LineGraph(stops = stops, nextNodes = nextNodes, prevNodes = prevNodes) + } + } +} + +data class StopStub(val name: String, val code: String, val zone: String, val onDemand: Boolean) { + companion object { + fun unmarshal(stream: InputStream): StopStub { + val reader = Reader(stream) + return StopStub( + code = reader.readString(), + name = reader.readString(), + zone = reader.readString(), + onDemand = reader.readBoolean() + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..d9948e433a7a53bcfc8b905ad9771c7e84603820 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/MainActivity.kt @@ -0,0 +1,202 @@ +package xyz.apiote.bimba.czwek.dashboard + +import android.Manifest +import android.content.Intent +import android.content.pm.PackageManager +import android.os.Bundle +import android.view.View +import android.widget.Toast +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat +import androidx.core.content.edit +import androidx.core.view.WindowCompat +import androidx.core.view.get +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentManager.FragmentLifecycleCallbacks +import androidx.navigation.fragment.NavHostFragment +import androidx.navigation.ui.setupWithNavController +import com.google.android.material.bottomnavigation.BottomNavigationView +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.Line +import xyz.apiote.bimba.czwek.api.QueryableV1 +import xyz.apiote.bimba.czwek.api.StopV1 +import xyz.apiote.bimba.czwek.dashboard.ui.home.HomeFragment +import xyz.apiote.bimba.czwek.dashboard.ui.map.MapFragment +import xyz.apiote.bimba.czwek.dashboard.ui.voyage.VoyageFragment +import xyz.apiote.bimba.czwek.databinding.ActivityMainBinding +import xyz.apiote.bimba.czwek.departures.DeparturesActivity +import xyz.apiote.bimba.czwek.search.ResultsActivity +import xyz.apiote.bimba.czwek.settings.ServerChooserActivity +import xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity + + +class MainActivity : AppCompatActivity() { + private lateinit var binding: ActivityMainBinding + private lateinit var locationPermissionRequest: ActivityResultLauncher<Array<String>> + + private lateinit var permissionAsker: Fragment + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + + getSharedPreferences("shp", MODE_PRIVATE).edit(true) { + putBoolean("firstRun", false) + } + + supportFragmentManager.registerFragmentLifecycleCallbacks( + object : FragmentLifecycleCallbacks() { + override fun onFragmentViewCreated( + fm: FragmentManager, f: Fragment, v: View, savedInstanceState: Bundle? + ) { + setNavbarIcons(f) + super.onFragmentViewCreated(fm, f, v, savedInstanceState) + } + }, true + ) + + binding.navigationDrawer.setNavigationItemSelectedListener { + when (it.itemId) { + R.id.drawer_servers -> { + startActivity(Intent(this, ServerChooserActivity::class.java)) + } + R.id.drawer_cities -> { + startActivity(Intent(this, FeedChooserActivity::class.java)) + } + } + false + } + + WindowCompat.setDecorFitsSystemWindows(window, false) + val navView: BottomNavigationView = binding.bottomNavigation + val navHostFragment = + supportFragmentManager.findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment + val navController = navHostFragment.navController + navView.setupWithNavController(navController) + + locationPermissionRequest = registerForActivityResult( + ActivityResultContracts.RequestMultiplePermissions() + ) { permissions -> + when { + permissions[Manifest.permission.ACCESS_FINE_LOCATION] ?: false || + permissions[Manifest.permission.ACCESS_COARSE_LOCATION] ?: false -> { + when (permissionAsker) { + is HomeFragment -> { + showResults(ResultsActivity.Mode.MODE_LOCATION) + } + is MapFragment -> { + (permissionAsker as MapFragment).showLocation() + } + } + } + else -> { + // todo(ux,ui) dialog + Toast.makeText(this, "No location access given", Toast.LENGTH_SHORT).show() + } + } + } + } + + @Suppress( + "OVERRIDE_DEPRECATION", + "DEPRECATION" + ) // fixme later https://developer.android.com/reference/androidx/activity/OnBackPressedDispatcher + override fun onBackPressed() { + if (binding.container.isDrawerOpen(binding.navigationDrawer)) { + binding.container.closeDrawer(binding.navigationDrawer) + } else { + super.onBackPressed() + } + } + + fun onNavigationClicked() { + if (binding.container.isDrawerOpen(binding.navigationDrawer)) { + binding.container.closeDrawer(binding.navigationDrawer) + } else { + binding.container.openDrawer(binding.navigationDrawer) + } + } + + fun onGpsClicked(fragment: Fragment) { + when (PackageManager.PERMISSION_GRANTED) { + ContextCompat.checkSelfPermission( + this, + Manifest.permission.ACCESS_COARSE_LOCATION + ) -> { + when (fragment) { + is HomeFragment -> { + showResults(ResultsActivity.Mode.MODE_LOCATION) + } + is MapFragment -> { + fragment.showLocation() + } + } + } + else -> { + permissionAsker = fragment + locationPermissionRequest.launch( + arrayOf( + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION + ) + ) + } + } + } + + fun onSuggestionClicked(queryable: QueryableV1) { + when (queryable) { + is StopV1 -> { + val intent = Intent(this, DeparturesActivity::class.java).apply { + putExtra("code", queryable.code) + putExtra("name", queryable.name) + } + startActivity(intent) + } + is Line -> { + TODO("[3.1] start line graph activity") + } + } + } + + fun onSearchClicked(text: CharSequence?) { + showResults(ResultsActivity.Mode.MODE_SEARCH, text.toString()) + } + + private fun showResults(mode: ResultsActivity.Mode, query: String = "") { + /* todo [3.1] (ux,low) animation + https://developer.android.com/guide/fragments/animate + https://github.com/raheemadamboev/fab-explosion-animation-app + */ + val intent = Intent(this, ResultsActivity::class.java).apply { + putExtra("mode", mode) + putExtra("query", query) + } + startActivity(intent) + } + + private fun setNavbarIcons(f: Fragment) { + // todo [voyage-planning] + // binding.bottomNavigation.menu[2].setIcon(R.drawable.voyage_outline) + binding.bottomNavigation.menu[1].setIcon(R.drawable.home_outline) + binding.bottomNavigation.menu[0].setIcon(R.drawable.map_outline) + when (f) { + is HomeFragment -> { + binding.bottomNavigation.menu[1].setIcon(R.drawable.home_black) + } + is VoyageFragment -> { + binding.bottomNavigation.menu[2].setIcon(R.drawable.voyage_black) + } + is MapFragment -> { + binding.bottomNavigation.menu[0].setIcon(R.drawable.map_black) + } + else -> { + binding.bottomNavigation.menu[1].setIcon(R.drawable.home_black) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..816339a9a11fdffc30fa1df3a6b2de20c054aefc --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeFragment.kt @@ -0,0 +1,92 @@ +package xyz.apiote.bimba.czwek.dashboard.ui.home + +import android.content.Context +import android.net.ConnectivityManager +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import com.mancj.materialsearchbar.MaterialSearchBar +import com.mancj.materialsearchbar.MaterialSearchBar.BUTTON_NAVIGATION +import xyz.apiote.bimba.czwek.api.QueryableV1 +import xyz.apiote.bimba.czwek.dashboard.MainActivity +import xyz.apiote.bimba.czwek.databinding.FragmentHomeBinding +import xyz.apiote.bimba.czwek.search.BimbaSuggestionsAdapter + +// todo [3.1] search: https://github.com/material-components/material-components-android/blob/master/docs/components/Search.md + +class HomeFragment : Fragment() { + private var _binding: FragmentHomeBinding? = null + private val binding get() = _binding!! + + private var lastSuggestions = listOf<QueryableV1>() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = FragmentHomeBinding.inflate(inflater, container, false) + + val homeViewModel = + ViewModelProvider(this)[HomeViewModel::class.java] + homeViewModel.queryables.observe(viewLifecycleOwner) { + binding.searchBar.updateLastSuggestions(it) + } + + val root = binding.root + ViewCompat.setOnApplyWindowInsetsListener(root) { view, windowInsets -> + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + view.layoutParams = (view.layoutParams as FrameLayout.LayoutParams).apply { + topMargin = insets.top + } + WindowInsetsCompat.CONSUMED + } + + binding.searchBar.lastSuggestions = lastSuggestions + val cm = requireContext().getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + binding.searchBar.addTextChangeListener( + homeViewModel.SearchBarWatcher(requireContext(), cm) + ) + binding.searchBar.setOnSearchActionListener(object : MaterialSearchBar.OnSearchActionListener { + override fun onButtonClicked(buttonCode: Int) { + when (buttonCode) { + BUTTON_NAVIGATION -> { + (context as MainActivity).onNavigationClicked() + } + } + } + + override fun onSearchStateChanged(enabled: Boolean) { + } + + override fun onSearchConfirmed(text: CharSequence?) { + binding.searchBar.clearSuggestions() + (context as MainActivity).onSearchClicked(text) + } + }) + binding.searchBar.setCardViewElevation(0) + binding.searchBar.setCustomSuggestionAdapter(BimbaSuggestionsAdapter(layoutInflater, context) { + binding.searchBar.clearSuggestions() + (context as MainActivity).onSuggestionClicked(it) + }) + + binding.floatingActionButton.setOnClickListener { + binding.searchBar.clearSuggestions() + (context as MainActivity).onGpsClicked(this) + } + // todo [3.1] (ux,low) on searchbar focus && if != '' -> populate suggestions + + return binding.root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..72f6efd2bb9b254905f1172adef1f9ac98a07ba0 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/home/HomeViewModel.kt @@ -0,0 +1,88 @@ +package xyz.apiote.bimba.czwek.dashboard.ui.home + +import android.content.Context +import android.net.ConnectivityManager +import android.os.Handler +import android.os.Looper +import android.text.Editable +import android.text.TextWatcher +import android.util.Log +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.launch +import xyz.apiote.bimba.czwek.api.* + +class HomeViewModel : ViewModel() { + private val mutableQueryables = MutableLiveData<List<QueryableV1>>() + val queryables: LiveData<List<QueryableV1>> = mutableQueryables + + fun getQueryables(cm: ConnectivityManager, server: Server, query: String) { + viewModelScope.launch { + val result = queryQueryables(cm, server, query, limit = 6) + if (result.error != null) { + // note intentionally no error showing in suggestions + if (result.stream != null) { + Log.e("Suggestion", "${b2s(result.stream.readBytes())}") + return@launch + Log.e( + "Suggestion", + "${result.error.statusCode}, ${ErrorResponse.unmarshal(result.stream).message}" + ) + } else { + Log.e("Suggestion", "${result.error.statusCode}") + } + } else { + mutableQueryables.value = + when (val response = QueryablesResponse.unmarshal(result.stream!!)) { + is QueryablesResponseDev -> response.queryables + is QueryablesResponseV1 -> response.queryables + else -> null + } + } + } + } + + private fun b2s(b: ByteArray): String { + var s = "" + b.forEach { + if (it in 32..127) { + s += Char(it.toInt()) + } else { + s += "\\x$it" + } + } + return s + } + + inner class SearchBarWatcher( + private val context: Context, + private val cm: ConnectivityManager + ) : + TextWatcher { + private val handler = Handler(Looper.getMainLooper()) + private var workRunnable = Runnable {} + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { + } + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + } + + override fun afterTextChanged(s: Editable?) { + handler.removeCallbacks(workRunnable) + workRunnable = Runnable { + val text = s.toString() + getQueryables( + cm, + Server.get(context), text + ) + } + handler.postDelayed( + workRunnable, + 750 + ) // todo(ux,low) make good time (probably between 500, 1000ms) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/map/MapFragment.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/map/MapFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..b688de9e98fd5a9be8c9e142a98faa029b3c5ca8 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/map/MapFragment.kt @@ -0,0 +1,244 @@ +package xyz.apiote.bimba.czwek.dashboard.ui.map + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Context.MODE_PRIVATE +import android.content.SharedPreferences +import android.content.res.Configuration.* +import android.graphics.Bitmap +import android.net.ConnectivityManager +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.content.edit +import androidx.core.graphics.drawable.toBitmap +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import com.google.android.material.snackbar.Snackbar +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.ErrorLocatable +import xyz.apiote.bimba.czwek.api.PositionV1 +import xyz.apiote.bimba.czwek.api.Server +import xyz.apiote.bimba.czwek.dashboard.MainActivity +import xyz.apiote.bimba.czwek.databinding.FragmentMapBinding +import xyz.apiote.bimba.czwek.dpToPixelI +import org.osmdroid.config.Configuration +import org.osmdroid.events.MapListener +import org.osmdroid.events.ScrollEvent +import org.osmdroid.events.ZoomEvent +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.CustomZoomButtonsController +import org.osmdroid.views.overlay.Marker +import org.osmdroid.views.overlay.TilesOverlay +import org.osmdroid.views.overlay.gestures.RotationGestureOverlay +import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider +import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay + +// todo[3.1] empty state on no network + +class MapFragment : Fragment() { + + private var maybeBinding: FragmentMapBinding? = null + private val binding get() = maybeBinding!! + + private lateinit var locationOverlay: MyLocationNewOverlay + private lateinit var mapViewModel: MapViewModel + + private val handler = Handler(Looper.getMainLooper()) + private var workRunnable = Runnable {} + + private var snack: Snackbar? = null + + @SuppressLint("ClickableViewAccessibility") + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + mapViewModel = + ViewModelProvider(this)[MapViewModel::class.java] + + observeLocatables() + + maybeBinding = FragmentMapBinding.inflate(inflater, container, false) + val root: View = binding.root + + binding.map.setTileSource(TileSourceFactory.MAPNIK) + if (((context?.resources?.configuration?.uiMode ?: UI_MODE_NIGHT_UNDEFINED) + and UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES + ) { + binding.map.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS) + } + binding.map.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER) + binding.map.setMultiTouchControls(true) + binding.map.overlays.add(RotationGestureOverlay(binding.map).apply { isEnabled = true }) + + locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding.map) + context?.let { + centreMap(it.getSharedPreferences("shp", MODE_PRIVATE)) + + locationOverlay.setDirectionIcon( + AppCompatResources.getDrawable(it, R.drawable.navigation_arrow)?.mutate() + ?.toBitmap(dpToPixelI(36f), dpToPixelI(36f), Bitmap.Config.ARGB_8888) + ) + locationOverlay.setDirectionAnchor(.5f, .5f) + locationOverlay.setPersonIcon( + AppCompatResources.getDrawable(it, R.drawable.navigation_circle)?.mutate() + ?.toBitmap(dpToPixelI(24f), dpToPixelI(24f), Bitmap.Config.ARGB_8888) + ) + locationOverlay.setPersonAnchor(.5f, .5f) + } + + binding.floatingActionButton.setOnClickListener { + (context as MainActivity).onGpsClicked(this) + } + + binding.map.addMapListener(object : MapListener { + override fun onScroll(event: ScrollEvent?): Boolean { + return onMapMove() + } + + override fun onZoom(event: ZoomEvent?): Boolean { + return onMapMove() + } + }) + + binding.map.setOnTouchListener { _, _ -> + binding.floatingActionButton.show() + false + } + + return root + } + + private fun onMapMove(): Boolean { + snack?.dismiss() + return delayGetLocatables() + } + + private fun delayGetLocatables(delay: Long = 1000): Boolean { + handler.removeCallbacks(workRunnable) + workRunnable = Runnable { + getLocatables() + } + handler.postDelayed(workRunnable, delay) + return true + } + + private fun observeLocatables() { + mapViewModel.locatables.observe(viewLifecycleOwner) { + binding.map.overlays.removeAll { marker -> + marker is Marker + } + + if (it.size == 1 && it[0] is ErrorLocatable) { + Snackbar.make(binding.root, (it[0] as ErrorLocatable).stringResource, Snackbar.LENGTH_LONG).show() + return@observe + } + + it.forEach { locatable -> + val marker = Marker(binding.map) + marker.position = GeoPoint(locatable.location().latitude, locatable.location().longitude) + marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) + marker.icon = context?.let { ctx -> locatable.icon(ctx, 2f) } + + context?.let { ctx -> + marker.setOnMarkerClickListener { _, _ -> + MapBottomSheet(locatable).apply { + (ctx as MainActivity?)?.supportFragmentManager?.let { fm -> + show(fm, MapBottomSheet.TAG) + } + } + true + } + } + binding.map.overlays.add(marker) + } + + binding.map.invalidate() + } + } + + fun showLocation() { + snack = + Snackbar.make(binding.root, getString(R.string.waiting_position), Snackbar.LENGTH_INDEFINITE) + snack!!.show() + binding.floatingActionButton.hide() + binding.map.overlays.removeAll { + it is MyLocationNewOverlay + } + locationOverlay.enableFollowLocation() + binding.map.overlays.add(locationOverlay) + locationOverlay.runOnFirstFix { + snack?.dismiss() + } + } + + private fun getLocatables() { + maybeBinding?.let { binding -> + val (bl, tr) = binding.map.boundingBox.let { + Pair( + PositionV1(it.latSouth, it.lonWest), + PositionV1(it.latNorth, it.lonEast) + ) + } + context?.let { + val cm = it.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + mapViewModel.getLocatablesIn( + cm, + Server.get(it), bl, tr + ) + } + delayGetLocatables(30000) + } + } + + private fun centreMap(preferences: SharedPreferences) { + maybeBinding?.map?.controller?.apply { + setZoom(preferences.getFloat("mapZoom", 17.0f).toDouble()) + val startPoint = GeoPoint( + preferences.getFloat("mapCentreLat", 52.39511f).toDouble(), + preferences.getFloat("mapCentreLon", 16.89506f).toDouble() + ) + setCenter(startPoint) + } + } + + override fun onResume() { + super.onResume() + binding.map.onResume() + locationOverlay.enableMyLocation() + context?.let { ctx -> + ctx.getSharedPreferences("shp", MODE_PRIVATE).let { + Configuration.getInstance() + .load(ctx, it) + centreMap(it) + } + } + } + + override fun onPause() { + super.onPause() + binding.map.onPause() + locationOverlay.disableMyLocation() + val centre = binding.map.mapCenter + context?.let { ctx -> + ctx.getSharedPreferences("shp", MODE_PRIVATE).edit(true) { + this.putFloat("mapCentreLat", centre.latitude.toFloat()) + this.putFloat("mapCentreLon", centre.longitude.toFloat()) + this.putFloat("mapZoom", binding.map.zoomLevelDouble.toFloat()) + } + } + handler.removeCallbacks(workRunnable) + } + + override fun onDestroyView() { + super.onDestroyView() + maybeBinding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/map/MapViewModel.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/map/MapViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..3a22298fe73acead5ecb23f43b9c171fe5c6deee --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/map/MapViewModel.kt @@ -0,0 +1,170 @@ +package xyz.apiote.bimba.czwek.dashboard.ui.map + +import android.content.ActivityNotFoundException +import android.content.Intent +import android.net.ConnectivityManager +import android.net.Uri +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.ImageView +import android.widget.TextView +import android.widget.Toast +import androidx.constraintlayout.widget.Group +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import kotlinx.coroutines.launch +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.* +import xyz.apiote.bimba.czwek.departures.DeparturesActivity + +class MapViewModel : ViewModel() { + + private val _locatables = MutableLiveData<List<Locatable>>() + val locatables: MutableLiveData<List<Locatable>> = _locatables + + fun getLocatablesIn(cm: ConnectivityManager, server: Server, bl: PositionV1, tr: PositionV1) { + viewModelScope.launch { + val result = xyz.apiote.bimba.czwek.api.getLocatablesIn(cm, server, bl, tr) + if (result.error != null) { + _locatables.value = listOf(ErrorLocatable(result.error.stringResource)) + if (result.stream != null) { + Log.w( + "Map", + "${result.error.statusCode}, ${ErrorResponse.unmarshal(result.stream).message}" + ) + } else { + Log.w("Map", "${result.error.statusCode}") + } + return@launch + } else { + _locatables.value = when (val response = LocatablesResponse.unmarshal(result.stream!!)) { + is LocatablesResponseDev -> response.locatables + is LocatablesResponseV1 -> response.locatables + else -> null + } + } + } + } +} + +class MapBottomSheet(private val locatable: Locatable) : BottomSheetDialogFragment() { + companion object { + const val TAG = "MapBottomSheet" + } + + private fun showVehicle(content: View, vehicle: VehicleV1) { + content.findViewById<Group>(R.id.stop_group).visibility = View.GONE + content.findViewById<Group>(R.id.vehicle_group).visibility = View.VISIBLE + + context?.let { ctx -> + content.findViewById<TextView>(R.id.title).apply { + text = ctx.getString(R.string.vehicle_headsign, vehicle.Line.name, vehicle.Headsign) + contentDescription = ctx.getString( + R.string.vehicle_headsign_content_description, + vehicle.Line.name, + vehicle.Headsign + ) + } + // todo units -- [3.1] settings or system-based + content.findViewById<TextView>(R.id.speed_text).text = + ctx.getString(R.string.speed_in_km_per_h, vehicle.Speed * 3.6) + content.findViewById<TextView>(R.id.congestion_text).text = vehicle.congestion(ctx) + content.findViewById<TextView>(R.id.occupancy_text).text = vehicle.occupancy(ctx) + content.findViewById<ImageView>(R.id.ac).visibility = + if (vehicle.getCapability(VehicleV1.Capability.AC)) { + View.VISIBLE + } else { + View.GONE + } + content.findViewById<ImageView>(R.id.bike).visibility = + if (vehicle.getCapability(VehicleV1.Capability.BIKE)) { + View.VISIBLE + } else { + View.GONE + } + content.findViewById<ImageView>(R.id.voice).visibility = + if (vehicle.getCapability(VehicleV1.Capability.VOICE)) { + View.VISIBLE + } else { + View.GONE + } + content.findViewById<ImageView>(R.id.ticket).visibility = + if (vehicle.let { + it.getCapability(VehicleV1.Capability.TICKET_DRIVER) || it.getCapability(VehicleV1.Capability.TICKET_MACHINE) + }) { + View.VISIBLE + } else { + View.GONE + } + content.findViewById<ImageView>(R.id.usb).visibility = + if (vehicle.getCapability(VehicleV1.Capability.USB_CHARGING)) { + View.VISIBLE + } else { + View.GONE + } + } + } + + private fun showStop(content: View, stop: StopV1) { + context?.let { ctx -> + content.findViewById<Group>(R.id.stop_group).visibility = View.VISIBLE + content.findViewById<Group>(R.id.vehicle_group).visibility = View.GONE + content.findViewById<TextView>(R.id.title).text = + context?.getString(R.string.stop_title, stop.name, stop.code) + content.findViewById<Button>(R.id.departures_button).setOnClickListener { + val intent = Intent(ctx, DeparturesActivity::class.java).apply { + putExtra("code", stop.code) + putExtra("name", stop.name) + } + startActivity(intent) + } + content.findViewById<Button>(R.id.navigation_button).setOnClickListener { + try { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse("geo:${stop.location().latitude},${stop.location().longitude}") + ) + ) + } catch (_: ActivityNotFoundException) { + Toast.makeText(context, ctx.getString(R.string.no_map_app), Toast.LENGTH_SHORT).show() + } + } + + stop.changeOptions(ctx).let { changeOptions -> + content.findViewById<TextView>(R.id.change_options).apply { + text = changeOptions.first + contentDescription = changeOptions.second + } + } + } + } + + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val content = inflater.inflate(R.layout.map_bottom_sheet, container, false) + content.apply { + when (locatable) { + is VehicleV1 -> { + showVehicle(this, locatable) + } + is StopV1 -> { + showStop(this, locatable) + } + } + } + //(dialog as BottomSheetDialog).behavior.peekHeight = dpToPixelI(90f) + + return content + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/voyage/VoyageFragment.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/voyage/VoyageFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..0e1f56ca0b9ce6d8a357cec9e38a20e5e64c97fa --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/voyage/VoyageFragment.kt @@ -0,0 +1,42 @@ +package xyz.apiote.bimba.czwek.dashboard.ui.voyage + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.fragment.app.Fragment +import androidx.lifecycle.ViewModelProvider +import xyz.apiote.bimba.czwek.databinding.FragmentVoyageBinding + +class VoyageFragment : Fragment() { + + private var _binding: FragmentVoyageBinding? = null + + // This property is only valid between onCreateView and + // onDestroyView. + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val voyageViewModel = + ViewModelProvider(this)[VoyageViewModel::class.java] + + _binding = FragmentVoyageBinding.inflate(inflater, container, false) + val root: View = binding.root + + val textView: TextView = binding.textDashboard + voyageViewModel.text.observe(viewLifecycleOwner) { + textView.text = it + } + return root + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/voyage/VoyageViewModel.kt b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/voyage/VoyageViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..6b1b923755b427a935e8ca9192c5c91136635b93 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/dashboard/ui/voyage/VoyageViewModel.kt @@ -0,0 +1,13 @@ +package xyz.apiote.bimba.czwek.dashboard.ui.voyage + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel + +class VoyageViewModel : ViewModel() { + + private val _text = MutableLiveData<String>().apply { + value = "This is voyage Fragment" + } + val text: LiveData<String> = _text +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/departures/Departures.kt b/app/src/main/java/xyz/apiote/bimba/czwek/departures/Departures.kt new file mode 100644 index 0000000000000000000000000000000000000000..35f871c5fc86be2a7acbee7525b3d45496e97c2e --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/departures/Departures.kt @@ -0,0 +1,266 @@ +package xyz.apiote.bimba.czwek.departures + +import android.annotation.SuppressLint +import android.content.Context +import android.content.DialogInterface +import android.content.res.Configuration.* +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.DepartureV1 +import xyz.apiote.bimba.czwek.api.VehicleV1 +import xyz.apiote.bimba.czwek.dpToPixelI +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.util.GeoPoint +import org.osmdroid.views.CustomZoomButtonsController +import org.osmdroid.views.MapView +import org.osmdroid.views.overlay.Marker +import org.osmdroid.views.overlay.TilesOverlay +import org.osmdroid.views.overlay.gestures.RotationGestureOverlay +import java.util.* + + +class BimbaDepartureViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val root: View = itemView.findViewById(R.id.departure) + val lineIcon: ImageView = itemView.findViewById(R.id.line_icon) + val departureTime: TextView = itemView.findViewById(R.id.departure_time) + val lineName: TextView = itemView.findViewById(R.id.departure_line) + val headsign: TextView = itemView.findViewById(R.id.departure_headsign) + + companion object { + fun bind( + departure: DepartureV1, + holder: BimbaDepartureViewHolder?, + context: Context?, + onClickListener: (DepartureV1) -> Unit + ) { + holder?.root?.setOnClickListener { + onClickListener(departure) + } + holder?.lineIcon?.setImageBitmap(departure.vehicle.Line.icon(context!!)) + holder?.lineIcon?.contentDescription = departure.vehicle.Line.kind.name + holder?.lineName?.text = departure.vehicle.Line.name + holder?.headsign?.text = context?.getString(R.string.departure_headsign, departure.vehicle.Headsign) + holder?.headsign?.contentDescription = + context?.getString(R.string.departure_headsign_content_description, departure.vehicle.Headsign) + + holder?.departureTime?.text = departure.statusText(context) + } + } +} + +class BimbaDeparturesAdapter( + private val inflater: LayoutInflater, + private val context: Context?, + private var departures: List<DepartureV1>, + private val onClickListener: ((DepartureV1) -> Unit) +) : + RecyclerView.Adapter<BimbaDepartureViewHolder>() { + + private var departuresPositions: MutableMap<String, Int> = HashMap() + + init { + departures.forEachIndexed { i, departure -> + departuresPositions[departure.ID] = i + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BimbaDepartureViewHolder { + val rowView = inflater.inflate(R.layout.departure, parent, false) + return BimbaDepartureViewHolder(rowView) + } + + override fun onBindViewHolder(holder: BimbaDepartureViewHolder, position: Int) { + BimbaDepartureViewHolder.bind(departures[position], holder, context, onClickListener) + } + + override fun getItemCount(): Int = departures.size + + fun get(ID: String): DepartureV1? { + val position = departuresPositions[ID] + return if (position == null) { + null + } else { + departures[position] + } + } + + @SuppressLint("NotifyDataSetChanged") // todo [3.1] DiffUtil + fun update(departures: List<DepartureV1>) { + val newPositions: MutableMap<String, Int> = HashMap() + departures.forEachIndexed { i, departure -> + newPositions[departure.ID] = i + } + + this.departures = departures + departuresPositions = newPositions + notifyDataSetChanged() + } +} + +class DepartureBottomSheet(private var departure: DepartureV1) : BottomSheetDialogFragment() { + companion object { + const val TAG = "DepartureBottomSheet" + } + + private var cancelCallback: (() -> Unit)? = null + + fun setOnCancel(callback: () -> Unit) { + cancelCallback = callback + } + + override fun onCancel(dialog: DialogInterface) { + super.onCancel(dialog) + cancelCallback?.let { it() } + } + + fun departureID(): String { + return departure.ID + } + + fun update(departure: DepartureV1) { + this.departure = departure + this.view?.let { context?.let { ctx -> setContent(it, ctx) } } + } + + private fun setContent(view: View, ctx: Context) { + view.apply { + findViewById<TextView>(R.id.time).text = departure.timeString(ctx) + + findViewById<ImageView>(R.id.rt_icon).apply { + visibility = if (departure.isRealtime) { + View.VISIBLE + } else { + View.GONE + } + } + findViewById<ImageView>(R.id.wheelchair_icon).apply { + visibility = if (departure.vehicle.let { + it.getCapability(VehicleV1.Capability.LOW_FLOOR) || it.getCapability(VehicleV1.Capability.LOW_ENTRY) || it.getCapability( + VehicleV1.Capability.RAMP + ) + }) { + View.VISIBLE + } else { + View.GONE + } + } + + findViewById<TextView>(R.id.line).apply { + contentDescription = getString( + R.string.vehicle_headsign_content_description, + departure.vehicle.Line.name, + departure.vehicle.Headsign + ) + text = getString(R.string.vehicle_headsign, departure.vehicle.Line.name, departure.vehicle.Headsign) + } + + findViewById<TextView>(R.id.boarding_text).text = departure.boardingText(ctx) + // todo units -- [3.1] settings or system-based + findViewById<TextView>(R.id.speed_text).text = + getString(R.string.speed_in_km_per_h, departure.vehicle.Speed * 3.6) + findViewById<TextView>(R.id.congestion_text).text = departure.vehicle.congestion(ctx) + findViewById<TextView>(R.id.occupancy_text).text = departure.vehicle.occupancy(ctx) + + findViewById<ImageView>(R.id.ac).visibility = + if (departure.vehicle.getCapability(VehicleV1.Capability.AC)) { + View.VISIBLE + } else { + View.GONE + } + findViewById<ImageView>(R.id.bike).visibility = + if (departure.vehicle.getCapability(VehicleV1.Capability.BIKE)) { + View.VISIBLE + } else { + View.GONE + } + findViewById<ImageView>(R.id.voice).visibility = + if (departure.vehicle.getCapability(VehicleV1.Capability.VOICE)) { + View.VISIBLE + } else { + View.GONE + } + findViewById<ImageView>(R.id.ticket).visibility = + if (departure.vehicle.let { + it.getCapability(VehicleV1.Capability.TICKET_DRIVER) || it.getCapability(VehicleV1.Capability.TICKET_MACHINE) + }) { + View.VISIBLE + } else { + View.GONE + } + findViewById<ImageView>(R.id.usb).visibility = + if (departure.vehicle.getCapability(VehicleV1.Capability.USB_CHARGING)) { + View.VISIBLE + } else { + View.GONE + } + findViewById<MapView>(R.id.map).let { map -> + if (departure.vehicle.Position.isZero()) { + map.visibility = View.GONE + return@let + } + map.controller.apply { // todo[3.1] glide to centre, not jump + setZoom(19.0f.toDouble()) + setCenter( + GeoPoint( + departure.vehicle.location().latitude, + departure.vehicle.location().longitude + ) + ) + } + + map.overlays.removeAll { marker -> + marker is Marker + } + val marker = Marker(map).apply { + position = + GeoPoint(departure.vehicle.location().latitude, departure.vehicle.location().longitude) + setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) + icon = context?.let { ctx -> departure.vehicle.icon(ctx, 2f) } + setOnClickListener {} + } + map.overlays.add(marker) + map.invalidate() + } + } + } + + @SuppressLint("ClickableViewAccessibility") + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val content = inflater.inflate(R.layout.departure_bottom_sheet, container, false) + + context?.let { ctx -> + content.apply { + findViewById<MapView>(R.id.map).let { map -> + map.setTileSource(TileSourceFactory.MAPNIK) + if (((context?.resources?.configuration?.uiMode ?: UI_MODE_NIGHT_UNDEFINED) + and UI_MODE_NIGHT_MASK) == UI_MODE_NIGHT_YES + ) { + map.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS) + } + map.zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER) + map.setOnTouchListener { _, _ -> true } + map.setMultiTouchControls(true) + map.overlays.add(RotationGestureOverlay(map).apply { isEnabled = true }) + } + + setContent(this, ctx) + + (dialog as BottomSheetDialog).behavior.peekHeight = dpToPixelI(180f) + + } + } + return content + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/departures/DeparturesActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/departures/DeparturesActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..a8813189a98bdebfaccbc5705bd3c0a1863d8049 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/departures/DeparturesActivity.kt @@ -0,0 +1,154 @@ +package xyz.apiote.bimba.czwek.departures + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.content.res.ResourcesCompat +import androidx.core.view.WindowCompat +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.coroutines.* +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.* +import xyz.apiote.bimba.czwek.databinding.ActivityDeparturesBinding + +class DeparturesActivity : AppCompatActivity() { + private var _binding: ActivityDeparturesBinding? = null + private val binding get() = _binding!! + + private lateinit var adapter: BimbaDeparturesAdapter + + private val handler = Handler(Looper.getMainLooper()) + private var runnable = Runnable {} + + private var openBottomSheet: DepartureBottomSheet? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + _binding = ActivityDeparturesBinding.inflate(layoutInflater) + setContentView(binding.root) + + binding.collapsingLayout.apply { + title = getName() + val tf = ResourcesCompat.getFont(this@DeparturesActivity, R.font.yellowcircle8) + setCollapsedTitleTypeface(tf) + setExpandedTitleTypeface(tf) + } + + binding.departuresRecycler.layoutManager = LinearLayoutManager(this) + adapter = BimbaDeparturesAdapter(layoutInflater, this, listOf()) { + DepartureBottomSheet(it).apply { + show(supportFragmentManager, DepartureBottomSheet.TAG) + openBottomSheet = this + setOnCancel { openBottomSheet = null } + } + } + binding.departuresRecycler.adapter = adapter + WindowCompat.setDecorFitsSystemWindows(window, false) + } + + override fun onResume() { + super.onResume() + getDepartures() + } + + override fun onPause() { + super.onPause() + handler.removeCallbacks(runnable) + } + + private fun getName(): String { + return when (intent?.action) { + Intent.ACTION_VIEW -> getCode() + null -> intent?.extras?.getString("name") ?: "" + else -> "" + } + } + + private fun getCode(): String { + @Suppress("SpellCheckingInspection") + return when (intent?.action) { + Intent.ACTION_VIEW -> intent?.data?.getQueryParameter("przystanek") ?: "" + null -> intent?.extras?.getString("code") ?: "" + else -> "" + } + } + + private fun getDepartures() { + val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + MainScope().launch { + val result = getDepartures( + cm, + Server.get(this@DeparturesActivity), getCode() + ) + + if (result.error != null) { + showError(result.error) + if (result.stream != null) { + val response = ErrorResponse.unmarshal(result.stream) + Log.w("Departures", "${result.error.statusCode}, ${response.message}") + } else { + Log.w( + "Departures", + "${result.error.statusCode}, ${getString(result.error.stringResource)}" + ) + } + return@launch + } + val (departures, stop) = when (val response = DeparturesResponse.unmarshal(result.stream!!)) { + is DeparturesResponseDev -> Pair(response.departures, response.stop) + is DeparturesResponseV1 -> Pair(response.departures, response.stop) + else -> Pair(null, null) + } + updateItems(departures!!, stop!!) + openBottomSheet?.departureID()?.let { adapter.get(it) }?.let { openBottomSheet?.update(it) } + } + handler.removeCallbacks(runnable) + runnable = Runnable { getDepartures() } + handler.postDelayed(runnable, 30 * 1000) + } + + private fun showError(error: Error) { + binding.departuresProgress.visibility = View.GONE + binding.departuresRecycler.visibility = View.GONE + binding.errorImage.visibility = View.VISIBLE + binding.errorText.visibility = View.VISIBLE + + binding.errorText.text = getString(error.stringResource) + binding.errorImage.setImageDrawable(AppCompatResources.getDrawable(this, error.imageResource)) + } + + private fun updateItems(departures: List<DepartureV1>, stop: StopV1) { + binding.departuresProgress.visibility = View.GONE + adapter.update(departures) + binding.collapsingLayout.apply { + title = stop.name + } + if (departures.isEmpty()) { + binding.errorImage.visibility = View.VISIBLE + binding.errorText.visibility = View.VISIBLE + binding.departuresRecycler.visibility = View.GONE + + binding.errorText.text = getString(R.string.no_departures) + binding.errorImage.setImageDrawable( + AppCompatResources.getDrawable( + this, + R.drawable.error_search + ) + ) + } else { + binding.departuresOverlay.visibility = View.GONE + binding.errorImage.visibility = View.GONE + binding.errorText.visibility = View.GONE + binding.departuresRecycler.visibility = View.VISIBLE + } + // todo [3.1] alerts + // todo [3.1] stop info + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/FirstRunActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/FirstRunActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..0b82651e9a1acf4f7bfa8a20b80a4aae3fcda946 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/FirstRunActivity.kt @@ -0,0 +1,23 @@ +package xyz.apiote.bimba.czwek.onboarding + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen +import xyz.apiote.bimba.czwek.dashboard.MainActivity + +class FirstRunActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() + super.onCreate(savedInstanceState) + + val preferences = getSharedPreferences("shp", MODE_PRIVATE) + val intent = if (preferences.getBoolean("firstRun", true)) { + Intent(this, OnboardingActivity::class.java) + } else { + Intent(this, MainActivity::class.java) + } + startActivity(intent) + finish() + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..4d5f9e20752b529f3885d9155f26630118633c94 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/onboarding/OnboardingActivity.kt @@ -0,0 +1,73 @@ +package xyz.apiote.bimba.czwek.onboarding + +import android.content.Intent +import android.graphics.Typeface +import android.os.Bundle +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.style.RelativeSizeSpan +import android.text.style.StyleSpan +import android.widget.Button +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.databinding.ActivityOnboardingBinding +import xyz.apiote.bimba.czwek.settings.ServerChooserActivity + +class OnboardingActivity : AppCompatActivity() { + private var _binding: ActivityOnboardingBinding? = null + private val binding get() = _binding!! + + private val activityLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (!getSharedPreferences("shp", MODE_PRIVATE).getBoolean("firstRun", true)) { + finish() + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + _binding = ActivityOnboardingBinding.inflate(layoutInflater) + setContentView(binding.root) + + + prepareButton( + binding.buttonSimple, + getString(R.string.onboarding_simple), + getString(R.string.onboarding_simple_action), + true + ) + prepareButton( + binding.buttonAdvanced, + getString(R.string.onboarding_advanced), + getString(R.string.onboarding_advanced_action), + false + ) + } + + private fun prepareButton(button: Button, title: String, description: String, simple: Boolean) { + button.text = SpannableStringBuilder().apply { + append( + title, + StyleSpan(Typeface.BOLD), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + append("\n") + append( + description, + RelativeSizeSpan(.75f), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE + ) + } + button.setOnClickListener { + moveOn(simple) + } + } + + private fun moveOn(simple: Boolean) { + val intent = Intent(this, ServerChooserActivity::class.java).apply { + putExtra("simple", simple) + } + activityLauncher.launch(intent) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt b/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt new file mode 100644 index 0000000000000000000000000000000000000000..81cc5bbe9e2f9f1759cfbb9c76c7c70a185049b4 --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/search/Results.kt @@ -0,0 +1,133 @@ +package xyz.apiote.bimba.czwek.search + +import android.annotation.SuppressLint +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.mancj.materialsearchbar.adapter.SuggestionsAdapter +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.Line +import xyz.apiote.bimba.czwek.api.QueryableV1 +import xyz.apiote.bimba.czwek.api.StopV1 + +class BimbaViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val root: View = itemView.findViewById(R.id.suggestion) + val icon: ImageView = itemView.findViewById(R.id.suggestion_image) + val title: TextView = itemView.findViewById(R.id.suggestion_title) + val description: TextView = itemView.findViewById(R.id.suggestion_description) + + companion object { + fun bind( + queryable: QueryableV1, + holder: BimbaViewHolder?, + context: Context?, + onClickListener: (QueryableV1) -> Unit + ) { + when (queryable) { + is StopV1 -> bindStop(queryable, holder, context) + //is Line -> bindLine(queryable, holder, context) + } + holder?.root?.setOnClickListener { + onClickListener(queryable) + } + } + + private fun bindStop(stop: StopV1, holder: BimbaViewHolder?, context: Context?) { + holder?.icon?.apply { + setImageDrawable(stop.icon(context!!)) + contentDescription = context.getString(R.string.stop_content_description) + } + holder?.title?.text = context?.getString(R.string.stop_title, stop.name, stop.code) + context?.let { + stop.changeOptions(it).let { changeOptions -> + holder?.description?.apply { + text = changeOptions.first + contentDescription = changeOptions.second + } + } + } + } + + private fun bindLine(line: Line, holder: BimbaViewHolder?, context: Context?) { + holder?.icon?.apply { + setImageBitmap(line.icon(context!!)) + contentDescription = line.type.name + colorFilter = null + } + holder?.title?.text = line.name + holder?.description?.text = context?.getString( + R.string.line_headsigns, + line.headsignsThere.joinToString { it }, + line.headsignsBack.joinToString { it }) + holder?.description?.contentDescription = context?.getString( + R.string.line_headsigns_content_description, + line.headsignsThere.joinToString { it }, + line.headsignsBack.joinToString { it }) + } + } +} + +interface Adapter { + fun createViewHolder( + inflater: LayoutInflater, + layout: Int, + parent: ViewGroup + ): BimbaViewHolder { + val rowView = inflater.inflate(layout, parent, false) + return BimbaViewHolder(rowView) + } + + fun bindSuggestionHolder( + queryable: QueryableV1, + holder: BimbaViewHolder?, + context: Context?, + onClickListener: (QueryableV1) -> Unit + ) { + BimbaViewHolder.bind(queryable, holder, context, onClickListener) + } +} + +class BimbaResultsAdapter( + private val inflater: LayoutInflater, + private val context: Context?, + private var queryables: List<QueryableV1>, + private val onClickListener: ((QueryableV1) -> Unit) +) : + RecyclerView.Adapter<BimbaViewHolder>(), Adapter { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BimbaViewHolder { + return createViewHolder(inflater, R.layout.result, parent) + } + + override fun onBindViewHolder(holder: BimbaViewHolder, position: Int) { + bindSuggestionHolder(queryables[position], holder, context, onClickListener) + } + + override fun getItemCount(): Int = queryables.size + + @SuppressLint("NotifyDataSetChanged") // todo [3.1] DiffUtil + fun update(queryables: List<QueryableV1>) { + this.queryables = queryables + notifyDataSetChanged() + } +} + +class BimbaSuggestionsAdapter( + inflater: LayoutInflater, + private val context: Context?, + private val onClickListener: ((QueryableV1) -> Unit) +) : + SuggestionsAdapter<QueryableV1, BimbaViewHolder>(inflater), Adapter { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BimbaViewHolder { + return createViewHolder(layoutInflater, R.layout.suggestion, parent) + } + + override fun getSingleViewHeight(): Int = 72 + + override fun onBindSuggestionHolder(queryable: QueryableV1, holder: BimbaViewHolder?, pos: Int) { + bindSuggestionHolder(queryable, holder, context, onClickListener) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..0bb34efb22825f913e597157e6d40d025455559b --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/search/ResultsActivity.kt @@ -0,0 +1,198 @@ +package xyz.apiote.bimba.czwek.search + +import android.content.Context +import android.content.Intent +import android.location.Location +import android.location.LocationListener +import android.location.LocationManager +import android.net.ConnectivityManager +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.view.WindowCompat +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.coroutines.* +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.* +import xyz.apiote.bimba.czwek.databinding.ActivityResultsBinding +import xyz.apiote.bimba.czwek.departures.DeparturesActivity +import java.io.InputStream + +class ResultsActivity : AppCompatActivity(), LocationListener { + enum class Mode { + MODE_LOCATION, MODE_SEARCH + } + + private var _binding: ActivityResultsBinding? = null + private val binding get() = _binding!! + + private lateinit var adapter: BimbaResultsAdapter + + private val handler = Handler(Looper.getMainLooper()) + private var runnable = Runnable {} + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + _binding = ActivityResultsBinding.inflate(layoutInflater) + setContentView(binding.root) + + binding.resultsRecycler.layoutManager = LinearLayoutManager(this) + adapter = BimbaResultsAdapter(layoutInflater, this, listOf()) { + when (it) { + is StopV1 -> { + val intent = Intent(this, DeparturesActivity::class.java).apply { + putExtra("code", it.code) + putExtra("name", it.name) + } + startActivity(intent) + } + is Line -> { + TODO("[3.1] start line graph activity") + } + } + } + binding.resultsRecycler.adapter = adapter + setSupportActionBar(binding.topAppBar) + + WindowCompat.setDecorFitsSystemWindows(window, false) + + @Suppress("DEPRECATION") // fixme later getSerializable in API>=33 + when (intent.extras?.get("mode")) { + Mode.MODE_LOCATION -> { + supportActionBar?.title = getString(R.string.stops_nearby) + locate() + } + Mode.MODE_SEARCH -> { + val query = intent.extras?.getString("query")!! + supportActionBar?.title = getString(R.string.results_for, query) + getQueryablesByQuery(Server.get(this), query) + } + } + } + + private fun locate() { + try { + val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + locationManager.requestLocationUpdates( + LocationManager.GPS_PROVIDER, 1000 * 60 * 10, 100f, this + ) + handler.removeCallbacks(runnable) + runnable = Runnable { + showError(Error(0, R.string.error_gps, R.drawable.error_gps)) + } + handler.postDelayed(runnable, 60 * 1000) + locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) + ?.let { onLocationChanged(it) } + } catch (_: SecurityException) { + // this won’t happen because we don’t start this activity without location permission + } + } + + override fun onLocationChanged(location: Location) { + handler.removeCallbacks(runnable) + getQueryablesByLocation(Server.get(this), PositionV1(location.latitude, location.longitude)) + } + + override fun onResume() { + super.onResume() + @Suppress("DEPRECATION") // fixme later getSerializable in API>=33 + if (intent.extras?.get("mode") == Mode.MODE_LOCATION) { + locate() + } + } + + override fun onPause() { + super.onPause() + val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + locationManager.removeUpdates(this) + handler.removeCallbacks(runnable) + } + + override fun onDestroy() { + super.onDestroy() + val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager + locationManager.removeUpdates(this) + handler.removeCallbacks(runnable) + } + + private fun getQueryablesByQuery(server: Server, query: String) { + val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + MainScope().launch { + val result = queryQueryables(cm, server, query) + if (result.error != null) { + if (result.stream != null) { + val response = ErrorResponse.unmarshal(result.stream) + Log.w("Results", "${result.error.statusCode}, ${response.message}") + } else { + Log.w( + "Results", + "${result.error.statusCode}, ${getString(result.error.stringResource)}" + ) + } + showError(result.error) + } else { + updateItems(unmarshallQueryablesResponse(result.stream!!)!!) + } + } + } + + private fun getQueryablesByLocation(server: Server, position: PositionV1) { + val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + MainScope().launch { + val result = locateQueryables(cm, server, position) + if (result.error != null) { + Log.e("Results.location", "$result") + showError(result.error) + } else { + updateItems(unmarshallQueryablesResponse(result.stream!!)!!) + } + } + } + + private fun showError(error: Error) { + binding.resultsProgress.visibility = View.GONE + binding.resultsRecycler.visibility = View.GONE + binding.errorImage.visibility = View.VISIBLE + binding.errorText.visibility = View.VISIBLE + + binding.errorText.text = getString(error.stringResource) + binding.errorImage.setImageDrawable(AppCompatResources.getDrawable(this, error.imageResource)) + } + + private fun updateItems(queryables: List<QueryableV1>) { + binding.resultsProgress.visibility = View.GONE + adapter.update(queryables) + if (queryables.isEmpty()) { + binding.errorImage.visibility = View.VISIBLE + binding.errorText.visibility = View.VISIBLE + binding.resultsRecycler.visibility = View.GONE + + binding.errorText.text = getString(R.string.error_404) + binding.errorImage.setImageDrawable( + AppCompatResources.getDrawable( + this, + R.drawable.error_search + ) + ) + } else { + binding.resultsOverlay.visibility = View.GONE + binding.errorImage.visibility = View.GONE + binding.errorText.visibility = View.GONE + binding.resultsRecycler.visibility = View.VISIBLE + } + } + + private suspend fun unmarshallQueryablesResponse(stream: InputStream): List<QueryableV1>? { + return withContext(Dispatchers.IO) { + when (val response = QueryablesResponse.unmarshal(stream)) { + is QueryablesResponseDev -> response.queryables + is QueryablesResponseV1 -> response.queryables + else -> null + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/ServerChooserActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/ServerChooserActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..80c0975d04174d0958a97d6e5f3f03342c3ea17f --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/ServerChooserActivity.kt @@ -0,0 +1,155 @@ +package xyz.apiote.bimba.czwek.settings + +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.net.ConnectivityManager +import android.os.Bundle +import android.util.Log +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.content.edit +import androidx.core.widget.addTextChangedListener +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.yaml.snakeyaml.error.YAMLException +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.Bimba +import xyz.apiote.bimba.czwek.api.Server +import xyz.apiote.bimba.czwek.api.TrafficFormatException +import xyz.apiote.bimba.czwek.api.getBimba +import xyz.apiote.bimba.czwek.databinding.ActivityServerChooserBinding +import xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity + +class ServerChooserActivity : AppCompatActivity() { + private var _binding: ActivityServerChooserBinding? = null + private val binding get() = _binding!! + + private val activityLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (!preferences.getBoolean("inFeedsTransaction", true)) { + finish() + } + } + + private lateinit var preferences: SharedPreferences + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + preferences = getSharedPreferences("shp", MODE_PRIVATE) + + if (intent.getBooleanExtra("simple", false)) { + setServer("bimba.apiote.xyz", "") + checkServer(true) + } else { + + _binding = ActivityServerChooserBinding.inflate(layoutInflater) + setContentView(binding.root) + + preferences.edit(true) { + putBoolean("inFeedsTransaction", true) + } + + binding.button.isEnabled = false + binding.serverField.editText!!.addTextChangedListener { editable -> + binding.button.isEnabled = !editable.isNullOrBlank() + } + + if (!preferences.getBoolean("firstRun", true)) { + Server.get(this).let { server -> + binding.serverField.editText!!.setText(server.host) + binding.tokenField.editText!!.setText(server.token) + } + } + + binding.button.setOnClickListener { + setServer( + binding.serverField.editText!!.text.toString(), + binding.tokenField.editText!!.text.toString() + ) + checkServer(false) + } + } + } + + private fun showDialog( + title: Int, description: Int, icon: Int, onPositive: (() -> Unit)? + ) { + MaterialAlertDialogBuilder(this).setIcon(AppCompatResources.getDrawable(this, icon)) + .setTitle(getString(title)).setMessage(getString(description)) + .setNegativeButton(resources.getString(R.string.cancel)) { _, _ -> }.apply { + if (onPositive != null) { + setPositiveButton(resources.getString(R.string.cont)) { _, _ -> + onPositive() + } + } + }.show() + } + + private fun checkServer(isSimple: Boolean) { + val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + MainScope().launch { + val result = getBimba(cm, Server.get(this@ServerChooserActivity)) + if (result.error != null) { + showDialog(R.string.error, result.error.stringResource, result.error.imageResource, null) + Log.w( + "ServerChooser", "${result.error.statusCode}, ${getString(result.error.stringResource)}" + ) + return@launch + } + val bimba = try { + withContext(Dispatchers.IO) { + Bimba.unmarshal(result.stream!!) + } + } catch (e: YAMLException) { + Log.w("ServerChooser", e.message ?: "YAML error") + showDialog(R.string.error, R.string.error_traffic_spec, R.drawable.error_server, null) + return@launch + } catch (e: TrafficFormatException) { + Log.w("ServerChooser", e.message) + showDialog(R.string.error, R.string.error_traffic_spec, R.drawable.error_server, null) + return@launch + } + val token = preferences.getString("token", "") + updateServer(bimba.servers[0]["url"]!!) + + if (bimba.isPrivate() && token == "") { + showDialog(R.string.error, R.string.server_private_question, R.drawable.error_sec, null) + return@launch + } + if (bimba.isRateLimited() && token == "" && !isSimple) { + showDialog( + R.string.rate_limit, R.string.server_rate_limited_question, R.drawable.error_limit + ) { + runFeedsActivity() + } + return@launch + } + runFeedsActivity() + } + } + + private fun setServer(hostname: String, token: String) { + preferences.edit(true) { + putString("host", hostname) + putString("token", token) + } + } + + private fun updateServer(apiPath: String) { + preferences.edit(true) { + putString("apiPath", apiPath) + } + } + + private fun runFeedsActivity() { + activityLauncher.launch(Intent(this, FeedChooserActivity::class.java)) + if (intent.getBooleanExtra("simple", false)) { + finish() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..c7ee64b4a4e8c7615ec942ab0725ade256e0551f --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedChooserActivity.kt @@ -0,0 +1,108 @@ +package xyz.apiote.bimba.czwek.settings.feeds + +import android.content.Context +import android.content.Intent +import android.net.ConnectivityManager +import android.os.Bundle +import android.util.Log +import android.view.View +import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.content.res.AppCompatResources +import androidx.core.content.edit +import androidx.recyclerview.widget.LinearLayoutManager +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import xyz.apiote.bimba.czwek.api.* +import xyz.apiote.bimba.czwek.dashboard.MainActivity +import xyz.apiote.bimba.czwek.databinding.ActivityFeedChooserBinding + +class FeedChooserActivity : AppCompatActivity() { + private var _binding: ActivityFeedChooserBinding? = null + private val binding get() = _binding!! + + private lateinit var adapter: BimbaFeedInfoAdapter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + _binding = ActivityFeedChooserBinding.inflate(layoutInflater) + setContentView(binding.root) + + setUpRecycler() + getServer() + + binding.button.setOnClickListener { + moveOn() + } + } + + private fun setUpRecycler() { + binding.resultsRecycler.layoutManager = LinearLayoutManager(this) + adapter = BimbaFeedInfoAdapter(layoutInflater, listOf(), this) { + FeedBottomSheet(it).show(supportFragmentManager, FeedBottomSheet.TAG) + } + binding.resultsRecycler.adapter = adapter + } + + private fun getServer() { + binding.progress.visibility = View.VISIBLE + binding.resultsRecycler.visibility = View.GONE + + MainScope().launch { + val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + Log.i("FeedChooser", "${Server.get(this@FeedChooserActivity)}") + val result = getFeeds(cm, Server.get(this@FeedChooserActivity)) + if (result.error != null) { + showError(result.error.imageResource, result.error.stringResource) + if (result.stream != null) { + val response = ErrorResponse.unmarshal(result.stream) + Log.w("FeedChooser", "${result.error.statusCode}, ${response.message}") + } else { + Log.w( + "FeedChooser", + "${result.error.statusCode}, ${getString(result.error.stringResource)}" + ) + } + return@launch + } + val feeds = when (val response = FeedsResponse.unmarshal(result.stream!!)) { + is FeedsResponseDev -> response.feeds + is FeedsResponseV1 -> response.feeds + else -> null + } + updateItems(feeds!!) + } + } + + private fun moveOn() { + val preferences = getSharedPreferences("shp", MODE_PRIVATE) + preferences.edit(true) { + putBoolean("inFeedsTransaction", false) + } + if (preferences.getBoolean("firstRun", true)) { + val intent = Intent(this, MainActivity::class.java) + startActivity(intent) + } + finish() + } + + private fun showError(image: Int, text: Int) { + binding.progress.visibility = View.GONE + binding.resultsRecycler.visibility = View.GONE + binding.errorImage.apply { + visibility = View.VISIBLE + setImageDrawable(AppCompatResources.getDrawable(this@FeedChooserActivity, image)) + } + binding.errorText.apply { + visibility = View.VISIBLE + setText(text) + } + + } + + private fun updateItems(feeds: List<FeedInfoV1>) { + binding.feedsOverlay.visibility = View.GONE + binding.resultsRecycler.visibility = View.VISIBLE + binding.button.visibility = View.VISIBLE + adapter.update(feeds) + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedInfos.kt b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedInfos.kt new file mode 100644 index 0000000000000000000000000000000000000000..ff9d63e7b907ebbdfca83abc145d1feb02bda4aa --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/settings/feeds/FeedInfos.kt @@ -0,0 +1,102 @@ +package xyz.apiote.bimba.czwek.settings.feeds + +import android.annotation.SuppressLint +import android.content.Context +import android.content.Context.MODE_PRIVATE +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.core.content.edit +import androidx.recyclerview.widget.RecyclerView +import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.google.android.material.materialswitch.MaterialSwitch +import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.FeedInfoV1 + + +class BimbaFeedInfoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val root: View = itemView.findViewById(R.id.feed) + val switch: MaterialSwitch = itemView.findViewById(R.id.feed_switch) + val name: TextView = itemView.findViewById(R.id.feed_name) + + companion object { + fun bind( + feed: FeedInfoV1, + context: Context, + holder: BimbaFeedInfoViewHolder?, + onClickListener: (FeedInfoV1) -> Unit + ) { + val shp = context.getSharedPreferences("shp", MODE_PRIVATE) + val host = shp.getString("host", "bimba.apiote.xyz")!! + val enabledFeeds = + shp.getString("${host}_feeds", "")!!.split(",").associateWith { }.toMutableMap() + + holder?.root?.setOnClickListener { + onClickListener(feed) + } + holder?.name?.text = feed.name + holder?.switch?.apply { + isChecked = feed.id in enabledFeeds + setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + enabledFeeds[feed.id] = Unit + } else { + enabledFeeds.remove(feed.id) + } + shp.edit(true) { + putString( + "${host}_feeds", + enabledFeeds.map { it.key }.filter { it != "" }.joinToString(separator = ",") + ) + } + } + } + } + } +} + +class BimbaFeedInfoAdapter( + private val inflater: LayoutInflater, + private var feeds: List<FeedInfoV1>, + private val context: Context, + private val onClickListener: ((FeedInfoV1) -> Unit) +) : + RecyclerView.Adapter<BimbaFeedInfoViewHolder>() { + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BimbaFeedInfoViewHolder { + val rowView = inflater.inflate(R.layout.feedinfo, parent, false) + return BimbaFeedInfoViewHolder(rowView) + } + + override fun onBindViewHolder(holder: BimbaFeedInfoViewHolder, position: Int) { + BimbaFeedInfoViewHolder.bind(feeds[position], context, holder, onClickListener) + } + + override fun getItemCount(): Int = feeds.size + + @SuppressLint("NotifyDataSetChanged") // todo [3.1] DiffUtil + fun update(items: List<FeedInfoV1>) { + feeds = items + notifyDataSetChanged() + } +} + +class FeedBottomSheet(private var feed: FeedInfoV1) : BottomSheetDialogFragment() { + companion object { + const val TAG = "DepartureBottomSheet" + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + val content = inflater.inflate(R.layout.feed_bottom_sheet, container, false) + content.findViewById<TextView>(R.id.title).text = feed.name + content.findViewById<TextView>(R.id.description).text = feed.description + content.findViewById<TextView>(R.id.attribution).text = feed.attribution + content.findViewById<TextView>(R.id.update_time).text = feed.formatDate() + return content + } +} \ No newline at end of file diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/utils.kt b/app/src/main/java/xyz/apiote/bimba/czwek/utils.kt new file mode 100644 index 0000000000000000000000000000000000000000..a5afaa2cdb25fd6504138df76cd957a7bac1b73d --- /dev/null +++ b/app/src/main/java/xyz/apiote/bimba/czwek/utils.kt @@ -0,0 +1,12 @@ +package xyz.apiote.bimba.czwek + +import android.content.res.Resources +import android.util.DisplayMetrics +import kotlin.math.roundToInt + +fun dpToPixel(dp: Float): Float { + val metrics: DisplayMetrics = Resources.getSystem().displayMetrics + return dp * (metrics.densityDpi / 160f) +} + +fun dpToPixelI(dp: Float): Int = dpToPixel(dp).roundToInt() \ No newline at end of file diff --git a/app/src/main/play/en-GB/listing/featureGraphic/feature-graphic.png b/app/src/main/play/en-GB/listing/featureGraphic/feature-graphic.png deleted file mode 100644 index 1333d62dd12eb83080efd9850179902cbe689da6..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/featureGraphic/feature-graphic.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/fulldescription b/app/src/main/play/en-GB/listing/fulldescription deleted file mode 100644 index 1286c61843fc2318c517f450fc3faa935dd2104d..0000000000000000000000000000000000000000 --- a/app/src/main/play/en-GB/listing/fulldescription +++ /dev/null @@ -1,6 +0,0 @@ -With this app You can check the public transport timetable in Poznań agglomeration (run by ZTM Poznań), and thanks to the Virtual Monitor You can see when exactly a bus or tram will arrive. - -Current features: -* checking departures by stop (based on offline timetable and Virtual Monitor), -* creating favourite stops with next departure visible on main screen, -* checking departures by favourite diff --git a/app/src/main/play/en-GB/listing/icon/logo.png b/app/src/main/play/en-GB/listing/icon/logo.png deleted file mode 100644 index 7a9bd078b1aed42188fe767423683c64a468312e..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/icon/logo.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/phoneScreenshots/Dash.png b/app/src/main/play/en-GB/listing/phoneScreenshots/Dash.png deleted file mode 100644 index b3d55c2a98f3e70f19d7b97b39e7947bc9946b44..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/phoneScreenshots/Dash.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/phoneScreenshots/StopActivity.png b/app/src/main/play/en-GB/listing/phoneScreenshots/StopActivity.png deleted file mode 100644 index a85d7e9dfdcb7b81b3a8a7d5097923c885356065..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/phoneScreenshots/StopActivity.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/phoneScreenshots/modification.png b/app/src/main/play/en-GB/listing/phoneScreenshots/modification.png deleted file mode 100644 index 2f536117feeb2ef180b3be65e36fee4154c94e4f..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/phoneScreenshots/modification.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/phoneScreenshots/searchStop.png b/app/src/main/play/en-GB/listing/phoneScreenshots/searchStop.png deleted file mode 100644 index 93683ba47b92fa3429623a0222488e0df516df93..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/phoneScreenshots/searchStop.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/phoneScreenshots/stopSpecify.png b/app/src/main/play/en-GB/listing/phoneScreenshots/stopSpecify.png deleted file mode 100644 index a67350f5939563ab794be2ec1ef89be4f6f5e5f5..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/phoneScreenshots/stopSpecify.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/promoGraphic/promo-graphic.png b/app/src/main/play/en-GB/listing/promoGraphic/promo-graphic.png deleted file mode 100644 index 6e15268c85de20ae2ea38d0d3cfa85aa913e4f93..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/en-GB/listing/promoGraphic/promo-graphic.png and /dev/null differ diff --git a/app/src/main/play/en-GB/listing/shortdescription b/app/src/main/play/en-GB/listing/shortdescription deleted file mode 100644 index 59cba7356e35c4b1d6c521a6ef2ccf0aad7663f8..0000000000000000000000000000000000000000 --- a/app/src/main/play/en-GB/listing/shortdescription +++ /dev/null @@ -1 +0,0 @@ -First Free Software Poznań Wandering Guide diff --git a/app/src/main/play/en-GB/whatsnew b/app/src/main/play/en-GB/whatsnew deleted file mode 100644 index f51e399bb993cfc28ffdb3b04ec6ee640f43bd2c..0000000000000000000000000000000000000000 --- a/app/src/main/play/en-GB/whatsnew +++ /dev/null @@ -1,28 +0,0 @@ -[2.2.2] – 2019-03-11 -==================== - -Changed -------- - -* drop HTML formatting in PEKA messages - -[2.2.1] – 2019-03-04 -==================== - -Changed -------- - -* white icons (low floor, tickets) in night mode - -[2.2.0] – 2019-02-26 -==================== - -Added ------ - -+ showing low floor and ticket checkouts in VM departures - -Changed -------- - -* departures empty state is semi-transparent diff --git a/app/src/main/play/pl-PL/listing/featureGraphic/feature-graphic.png b/app/src/main/play/pl-PL/listing/featureGraphic/feature-graphic.png deleted file mode 100644 index 932fab1b2a7e57bd6709623abc11d7b9250e7071..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/featureGraphic/feature-graphic.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/fulldescription b/app/src/main/play/pl-PL/listing/fulldescription deleted file mode 100644 index 3ef17ffaa0a5a4859a47b32488199b00d06c4beb..0000000000000000000000000000000000000000 --- a/app/src/main/play/pl-PL/listing/fulldescription +++ /dev/null @@ -1,6 +0,0 @@ -Dzięki tej aplikacji możesz sprawdzić rozkład jazdy w aglomeracji poznańskiej (obsługiwany przez ZTM Poznań), a dzięki Wirtualnemu Monitorowi możesz zobaczyć, kiedy dokładnie przyjedzie autobus lub tramwaj. - -Aktualne funkcje: -* sprawdzanie czasu odjazdów na przystankach (na podstawie rozkładu offline i Wirtualnego Monitora), -* tworzenie ulubionych przystanków, które pokazują najbliższy odjazd na ekranie głównym. -* sprawdzanie czasu odjazdów w ulubionych diff --git a/app/src/main/play/pl-PL/listing/icon/logo.png b/app/src/main/play/pl-PL/listing/icon/logo.png deleted file mode 100644 index 7a9bd078b1aed42188fe767423683c64a468312e..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/icon/logo.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/phoneScreenshots/Dash.png b/app/src/main/play/pl-PL/listing/phoneScreenshots/Dash.png deleted file mode 100644 index 8293e13ec0502b1ca39633a7b8c2f497e6f2fca3..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/phoneScreenshots/Dash.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/phoneScreenshots/StopActivity.png b/app/src/main/play/pl-PL/listing/phoneScreenshots/StopActivity.png deleted file mode 100644 index 4df78339578128289b152e676c58051fded2c12f..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/phoneScreenshots/StopActivity.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/phoneScreenshots/StopSpecify.png b/app/src/main/play/pl-PL/listing/phoneScreenshots/StopSpecify.png deleted file mode 100644 index 67b81dc87ef810057208d330df299de0a3f9bd50..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/phoneScreenshots/StopSpecify.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/phoneScreenshots/modification.png b/app/src/main/play/pl-PL/listing/phoneScreenshots/modification.png deleted file mode 100644 index f15b3b0ab78817a7c0ab9aeff43dcdb034e7e8cb..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/phoneScreenshots/modification.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/phoneScreenshots/searchStop.png b/app/src/main/play/pl-PL/listing/phoneScreenshots/searchStop.png deleted file mode 100644 index a9a0b5a548af7881e9061d5a17b537debd2826a7..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/phoneScreenshots/searchStop.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/promoGraphic/promo-graphic.png b/app/src/main/play/pl-PL/listing/promoGraphic/promo-graphic.png deleted file mode 100644 index 6e15268c85de20ae2ea38d0d3cfa85aa913e4f93..0000000000000000000000000000000000000000 Binary files a/app/src/main/play/pl-PL/listing/promoGraphic/promo-graphic.png and /dev/null differ diff --git a/app/src/main/play/pl-PL/listing/shortdescription b/app/src/main/play/pl-PL/listing/shortdescription deleted file mode 100644 index 647bf882f7d590a818458e81cecba6a464c2c8fe..0000000000000000000000000000000000000000 --- a/app/src/main/play/pl-PL/listing/shortdescription +++ /dev/null @@ -1 +0,0 @@ -Pierwszy wolny spacerownik poznański diff --git a/app/src/main/play/pl-PL/whatsnew b/app/src/main/play/pl-PL/whatsnew deleted file mode 100644 index 720cbfab9b37820534cd0d2878ab82129fcae1be..0000000000000000000000000000000000000000 --- a/app/src/main/play/pl-PL/whatsnew +++ /dev/null @@ -1,28 +0,0 @@ -[2.2.2] – 2019-03-11 -==================== - -Changed -------- - -* porzucenie formatowania HTML w wiadomościach PEKA - -[2.2.1] – 2019-03-04 -==================== - -Changed -------- - -* białe ikony (niskopodłogowy, bilety) w trybie nocnym - -[2.2.0] – 2019-02-26 -==================== - -Dodane ------- - -+ oznaczanie odjazdów WM niskopodłogowych i z możliwością kupna biletów - -Zmienione ---------- - -* pusty stan odjazdów jest półprzezroczysty diff --git a/app/src/main/res/drawable/ac.xml b/app/src/main/res/drawable/ac.xml new file mode 100644 index 0000000000000000000000000000000000000000..95dfbd1694a17e2a90e69a2af23b1a7116ea12cd --- /dev/null +++ b/app/src/main/res/drawable/ac.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,11h-4.17l3.24,-3.24 -1.41,-1.42L15,11h-2V9l4.66,-4.66 -1.42,-1.41L13,6.17V2h-2v4.17L7.76,2.93 6.34,4.34 11,9v2H9L4.34,6.34 2.93,7.76 6.17,11H2v2h4.17l-3.24,3.24 1.41,1.42L9,13h2v2l-4.66,4.66 1.42,1.41L11,17.83V22h2v-4.17l3.24,3.24 1.42,-1.41L13,15v-2h2l4.66,4.66 1.41,-1.42L17.83,13H22z"/> +</vector> diff --git a/app/src/main/res/drawable/bike.xml b/app/src/main/res/drawable/bike.xml new file mode 100644 index 0000000000000000000000000000000000000000..1c5af85fe1c842642c65d6ae5f592f2dfd898cda --- /dev/null +++ b/app/src/main/res/drawable/bike.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18.18,10l-1.7,-4.68C16.19,4.53 15.44,4 14.6,4H12v2h2.6l1.46,4h-4.81l-0.36,-1H12V7H7v2h1.75l1.82,5H9.9c-0.44,-2.23 -2.31,-3.88 -4.65,-3.99C2.45,9.87 0,12.2 0,15c0,2.8 2.2,5 5,5c2.46,0 4.45,-1.69 4.9,-4h4.2c0.44,2.23 2.31,3.88 4.65,3.99c2.8,0.13 5.25,-2.19 5.25,-5c0,-2.8 -2.2,-5 -5,-5H18.18zM7.82,16c-0.4,1.17 -1.49,2 -2.82,2c-1.68,0 -3,-1.32 -3,-3s1.32,-3 3,-3c1.33,0 2.42,0.83 2.82,2H5v2H7.82zM14.1,14h-1.4l-0.73,-2H15C14.56,12.58 14.24,13.25 14.1,14zM19,18c-1.68,0 -3,-1.32 -3,-3c0,-0.93 0.41,-1.73 1.05,-2.28l0.96,2.64l1.88,-0.68l-0.97,-2.67c0.03,0 0.06,-0.01 0.09,-0.01c1.68,0 3,1.32 3,3S20.68,18 19,18z"/> +</vector> diff --git a/app/src/main/res/drawable/bus_black.xml b/app/src/main/res/drawable/bus_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..e2b18a05948d28b39cd2b4bfb102cac858c738bf --- /dev/null +++ b/app/src/main/res/drawable/bus_black.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#000000" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M4,16c0,0.88 0.39,1.67 1,2.22L5,20c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h8v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1.78c0.61,-0.55 1,-1.34 1,-2.22L20,6c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10zM7.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5S6.67,14 7.5,14s1.5,0.67 1.5,1.5S8.33,17 7.5,17zM16.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM18,11L6,11L6,6h12v5z"/> +</vector> diff --git a/app/src/main/res/drawable/crowd.xml b/app/src/main/res/drawable/crowd.xml new file mode 100644 index 0000000000000000000000000000000000000000..76bd1cd501a769b0b3cdda828de7d686ba8baf10 --- /dev/null +++ b/app/src/main/res/drawable/crowd.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,12.75c1.63,0 3.07,0.39 4.24,0.9c1.08,0.48 1.76,1.56 1.76,2.73L18,18H6l0,-1.61c0,-1.18 0.68,-2.26 1.76,-2.73C8.93,13.14 10.37,12.75 12,12.75zM4,13c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2C2,12.1 2.9,13 4,13zM5.13,14.1C4.76,14.04 4.39,14 4,14c-0.99,0 -1.93,0.21 -2.78,0.58C0.48,14.9 0,15.62 0,16.43V18l4.5,0v-1.61C4.5,15.56 4.73,14.78 5.13,14.1zM20,13c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2C18,12.1 18.9,13 20,13zM24,16.43c0,-0.81 -0.48,-1.53 -1.22,-1.85C21.93,14.21 20.99,14 20,14c-0.39,0 -0.76,0.04 -1.13,0.1c0.4,0.68 0.63,1.46 0.63,2.29V18l4.5,0V16.43zM12,6c1.66,0 3,1.34 3,3c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3C9,7.34 10.34,6 12,6z"/> +</vector> diff --git a/app/src/main/res/drawable/departure.xml b/app/src/main/res/drawable/departure.xml new file mode 100644 index 0000000000000000000000000000000000000000..9bf1a5d515b626ebbfc9e9b6dcfc59240d614229 --- /dev/null +++ b/app/src/main/res/drawable/departure.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M16,1c-2.4,0 -4.52,1.21 -5.78,3.05 0.01,-0.01 0.01,-0.02 0.02,-0.03C9.84,4 9.42,4 9,4c-4.42,0 -8,0.5 -8,4v10c0,0.88 0.39,1.67 1,2.22L2,22c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h8v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1.78c0.61,-0.55 1,-1.34 1,-2.22v-3.08c3.39,-0.49 6,-3.39 6,-6.92 0,-3.87 -3.13,-7 -7,-7zM4.5,19c-0.83,0 -1.5,-0.67 -1.5,-1.5S3.67,16 4.5,16s1.5,0.67 1.5,1.5S5.33,19 4.5,19zM3,13L3,8h6c0,1.96 0.81,3.73 2.11,5L3,13zM13.5,19c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM16,13c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM16.5,4L15,4v5l3.62,2.16 0.75,-1.23 -2.87,-1.68z"/> +</vector> diff --git a/app/src/main/res/drawable/error_app.xml b/app/src/main/res/drawable/error_app.xml new file mode 100644 index 0000000000000000000000000000000000000000..adaa37eb80f7276f9ac19caec2c1c8c9fca932de --- /dev/null +++ b/app/src/main/res/drawable/error_app.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM15.5,12c0,-1.38 1.12,-2.5 2.5,-2.5 0.42,0 0.8,0.11 1.15,0.29l-3.36,3.36c-0.18,-0.35 -0.29,-0.73 -0.29,-1.15zM18,14.5c-0.42,0 -0.8,-0.11 -1.15,-0.29l3.36,-3.36c0.18,0.35 0.29,0.73 0.29,1.15 0,1.38 -1.12,2.5 -2.5,2.5zM17,18L7,18L7,6h10v1h2L19,3c0,-1.1 -0.9,-2 -2,-2L7,1c-1.1,0 -2,0.9 -2,2v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2v-4h-2v1z"/> +</vector> diff --git a/app/src/main/res/drawable/error_gps.xml b/app/src/main/res/drawable/error_gps.xml new file mode 100644 index 0000000000000000000000000000000000000000..d83a38e79abe3672f08f1e811d88e184ddadc1e4 --- /dev/null +++ b/app/src/main/res/drawable/error_gps.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06c-1.13,0.12 -2.19,0.46 -3.16,0.97l1.5,1.5C10.16,5.19 11.06,5 12,5c3.87,0 7,3.13 7,7 0,0.94 -0.19,1.84 -0.52,2.65l1.5,1.5c0.5,-0.96 0.84,-2.02 0.97,-3.15L23,13v-2h-2.06zM3,4.27l2.04,2.04C3.97,7.62 3.25,9.23 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c1.77,-0.2 3.38,-0.91 4.69,-1.98L19.73,21 21,19.73 4.27,3 3,4.27zM16.27,17.54C15.09,18.45 13.61,19 12,19c-3.87,0 -7,-3.13 -7,-7 0,-1.61 0.55,-3.09 1.46,-4.27l9.81,9.81z"/> +</vector> diff --git a/app/src/main/res/drawable/error_limit.xml b/app/src/main/res/drawable/error_limit.xml new file mode 100644 index 0000000000000000000000000000000000000000..03344fd1addcf979b8cdc1c4cb33cf699add2401 --- /dev/null +++ b/app/src/main/res/drawable/error_limit.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M23,5.5V20c0,2.2 -1.8,4 -4,4h-7.3c-1.08,0 -2.1,-0.43 -2.85,-1.19L1,14.83c0,0 1.26,-1.23 1.3,-1.25c0.22,-0.19 0.49,-0.29 0.79,-0.29c0.22,0 0.42,0.06 0.6,0.16C3.73,13.46 8,15.91 8,15.91V4c0,-0.83 0.67,-1.5 1.5,-1.5S11,3.17 11,4v7h1V1.5C12,0.67 12.67,0 13.5,0S15,0.67 15,1.5V11h1V2.5C16,1.67 16.67,1 17.5,1S19,1.67 19,2.5V11h1V5.5C20,4.67 20.67,4 21.5,4S23,4.67 23,5.5z"/> +</vector> diff --git a/app/src/main/res/drawable/error_net.xml b/app/src/main/res/drawable/error_net.xml new file mode 100644 index 0000000000000000000000000000000000000000..dde6900202fa85a63b608e96248a012b815f8d1d --- /dev/null +++ b/app/src/main/res/drawable/error_net.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M23.64,7c-0.45,-0.34 -4.93,-4 -11.64,-4 -1.5,0 -2.89,0.19 -4.15,0.48L18.18,13.8 23.64,7zM17.04,15.22L3.27,1.44 2,2.72l2.05,2.06C1.91,5.76 0.59,6.82 0.36,7l11.63,14.49 0.01,0.01 0.01,-0.01 3.9,-4.86 3.32,3.32 1.27,-1.27 -3.46,-3.46z"/> +</vector> diff --git a/app/src/main/res/drawable/error_other.xml b/app/src/main/res/drawable/error_other.xml new file mode 100644 index 0000000000000000000000000000000000000000..a4c7fcdbf80efb3e3fc7daebf5cf6634412ca8b0 --- /dev/null +++ b/app/src/main/res/drawable/error_other.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/> +</vector> diff --git a/app/src/main/res/drawable/error_search.xml b/app/src/main/res/drawable/error_search.xml new file mode 100644 index 0000000000000000000000000000000000000000..66931d11070e03fd2d2f20c26700a0d77a45c17a --- /dev/null +++ b/app/src/main/res/drawable/error_search.xml @@ -0,0 +1,6 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5C16,5.91 13.09,3 9.5,3C6.08,3 3.28,5.64 3.03,9h2.02C5.3,6.75 7.18,5 9.5,5C11.99,5 14,7.01 14,9.5S11.99,14 9.5,14c-0.17,0 -0.33,-0.03 -0.5,-0.05v2.02C9.17,15.99 9.33,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57L14,14.71v0.79l5,4.99L20.49,19L15.5,14z"/> + <path android:fillColor="@android:color/white" android:pathData="M6.47,10.82l-2.47,2.47l-2.47,-2.47l-0.71,0.71l2.47,2.47l-2.47,2.47l0.71,0.71l2.47,-2.47l2.47,2.47l0.71,-0.71l-2.47,-2.47l2.47,-2.47z"/> +</vector> diff --git a/app/src/main/res/drawable/error_sec.xml b/app/src/main/res/drawable/error_sec.xml new file mode 100644 index 0000000000000000000000000000000000000000..e6842fb025a6ca3102a2f1da225a2e0048ca2f66 --- /dev/null +++ b/app/src/main/res/drawable/error_sec.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,2L4,5v6.09c0,5.05 3.41,9.76 8,10.91c4.59,-1.15 8,-5.86 8,-10.91V5L12,2zM15.5,14.09l-1.41,1.41L12,13.42L9.91,15.5L8.5,14.09L10.59,12L8.5,9.91L9.91,8.5L12,10.59l2.09,-2.09l1.41,1.41L13.42,12L15.5,14.09z"/> +</vector> diff --git a/app/src/main/res/drawable/error_server.xml b/app/src/main/res/drawable/error_server.xml new file mode 100644 index 0000000000000000000000000000000000000000..6fddd7413b943415429acce7c9d329dd06e2c98b --- /dev/null +++ b/app/src/main/res/drawable/error_server.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M11,8.17L6.49,3.66C8.07,2.61 9.96,2 12,2c5.52,0 10,4.48 10,10c0,2.04 -0.61,3.93 -1.66,5.51l-1.46,-1.46C19.59,14.87 20,13.48 20,12c0,-3.35 -2.07,-6.22 -5,-7.41V5c0,1.1 -0.9,2 -2,2h-2V8.17zM21.19,21.19l-1.41,1.41l-2.27,-2.27C15.93,21.39 14.04,22 12,22C6.48,22 2,17.52 2,12c0,-2.04 0.61,-3.93 1.66,-5.51L1.39,4.22l1.41,-1.41L21.19,21.19zM11,18c-1.1,0 -2,-0.9 -2,-2v-1l-4.79,-4.79C4.08,10.79 4,11.38 4,12c0,4.08 3.05,7.44 7,7.93V18z"/> +</vector> diff --git a/app/src/main/res/drawable/error_url.xml b/app/src/main/res/drawable/error_url.xml new file mode 100644 index 0000000000000000000000000000000000000000..a8ffe8655e79b9f68645b52061550fd59a8742d9 --- /dev/null +++ b/app/src/main/res/drawable/error_url.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1 0,1.43 -0.98,2.63 -2.31,2.98l1.46,1.46C20.88,15.61 22,13.95 22,12c0,-2.76 -2.24,-5 -5,-5zM16,11h-2.19l2,2L16,13zM2,4.27l3.11,3.11C3.29,8.12 2,9.91 2,12c0,2.76 2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1 0,-1.59 1.21,-2.9 2.76,-3.07L8.73,11L8,11v2h2.73L13,15.27L13,17h1.73l4.01,4L20,19.74 3.27,3 2,4.27z"/> +</vector> diff --git a/app/src/main/res/drawable/feeds_cities.xml b/app/src/main/res/drawable/feeds_cities.xml new file mode 100644 index 0000000000000000000000000000000000000000..7324708d81054028bfebfd981910557dff919acb --- /dev/null +++ b/app/src/main/res/drawable/feeds_cities.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#000000" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15,11L15,5l-3,-3 -3,3v2L3,7v14h18L21,11h-6zM7,19L5,19v-2h2v2zM7,15L5,15v-2h2v2zM7,11L5,11L5,9h2v2zM13,19h-2v-2h2v2zM13,15h-2v-2h2v2zM13,11h-2L11,9h2v2zM13,7h-2L11,5h2v2zM19,19h-2v-2h2v2zM19,15h-2v-2h2v2z"/> +</vector> diff --git a/app/src/main/res/drawable/feeds_servers.xml b/app/src/main/res/drawable/feeds_servers.xml new file mode 100644 index 0000000000000000000000000000000000000000..4a19b1b7c5a7d45a14c3fe2b89c426917130299b --- /dev/null +++ b/app/src/main/res/drawable/feeds_servers.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#000000" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,13H4c-0.55,0 -1,0.45 -1,1v6c0,0.55 0.45,1 1,1h16c0.55,0 1,-0.45 1,-1v-6c0,-0.55 -0.45,-1 -1,-1zM7,19c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM20,3H4c-0.55,0 -1,0.45 -1,1v6c0,0.55 0.45,1 1,1h16c0.55,0 1,-0.45 1,-1V4c0,-0.55 -0.45,-1 -1,-1zM7,9c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/> +</vector> diff --git a/app/src/main/res/drawable/gps_black.xml b/app/src/main/res/drawable/gps_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..163afecbe1383daef7f8c60f9d47b953b215bff9 --- /dev/null +++ b/app/src/main/res/drawable/gps_black.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="#000000" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z" /> +</vector> diff --git a/app/src/main/res/drawable/home_black.xml b/app/src/main/res/drawable/home_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..3f84525033ec8e08025d8ab4d84173f1bc47ab97 --- /dev/null +++ b/app/src/main/res/drawable/home_black.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" /> +</vector> diff --git a/app/src/main/res/drawable/home_outline.xml b/app/src/main/res/drawable/home_outline.xml new file mode 100644 index 0000000000000000000000000000000000000000..0a8b6b30cdc7ce7fcdabbda270b20ac23e18ca0a --- /dev/null +++ b/app/src/main/res/drawable/home_outline.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="#000000" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,5.69l5,4.5V18h-2v-6H9v6H7v-7.81l5,-4.5M12,3L2,12h3v8h6v-6h2v6h6v-8h3L12,3z" /> +</vector> diff --git a/app/src/main/res/drawable/ic_bus.xml b/app/src/main/res/drawable/ic_bus.xml deleted file mode 100644 index e16e2597920506417f854cec25afe7cf0747dd15..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_bus.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M4,16c0,0.88 0.39,1.67 1,2.22L5,20c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h8v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1.78c0.61,-0.55 1,-1.34 1,-2.22L20,6c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10zM7.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5S6.67,14 7.5,14s1.5,0.67 1.5,1.5S8.33,17 7.5,17zM16.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM18,11L6,11L6,6h12v5z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml deleted file mode 100644 index 3775b0ea66b25b8cd834f6babf32f4a1ef4615f2..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_delete.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_departure_timetable.xml b/app/src/main/res/drawable/ic_departure_timetable.xml deleted file mode 100644 index e91498fb185aafc77724e5a25c4a89f55c9e03cb..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_departure_timetable.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportHeight="24.0" - android:viewportWidth="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M19,3C12,2.48 12,2.482 5,3 3.89,3 3.01,3.9 3.01,5L3,19c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5C21,3.9 20.1,3 19,3ZM19,19L5,19L5,8h14z" /> - <path - android:fillColor="@color/textDark" - android:pathData="m17,12h-5v5h5z" /> -</vector> diff --git a/app/src/main/res/drawable/ic_departure_vm.xml b/app/src/main/res/drawable/ic_departure_vm.xml deleted file mode 100644 index c460a7a31588a447c614289fe52ebd2fcca24fa3..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_departure_vm.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12,4C9.11,4 6.6,5.639 5.35,8.039C2.34,8.359 -0,10.91 0,14C0,17.31 2.69,20 6,20L19,20C21.76,20 24,17.76 24,15C24,12.36 21.95,10.219 19.35,10.039C18.67,6.589 15.64,4 12,4zM4.404,10.652L5.922,10.652L7.418,15.643L8.922,10.652L10.443,10.652L8.133,17.289L6.707,17.289L4.404,10.652zM11.072,10.652L12.859,10.652L14.563,15.465L16.258,10.652L18.055,10.652L18.055,17.289L16.682,17.289L16.682,15.475L16.818,12.344L15.027,17.289L14.09,17.289L12.303,12.348L12.439,15.475L12.439,17.289L11.072,17.289L11.072,10.652z" - android:fillColor="@color/textDark" /> -</vector> diff --git a/app/src/main/res/drawable/ic_download.xml b/app/src/main/res/drawable/ic_download.xml deleted file mode 100644 index a2b16c14e56813b9d6c53f6dee2a9d82729164c0..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_download.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" - android:fillColor="#000000"/> -</vector> diff --git a/app/src/main/res/drawable/ic_error_outline.xml b/app/src/main/res/drawable/ic_error_outline.xml deleted file mode 100644 index a07a0f90acf868ee9698d8f7b559545f4984939d..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_error_outline.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M11,15h2v2h-2zM11,7h2v6h-2zM11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_favourite.xml b/app/src/main/res/drawable/ic_favourite.xml deleted file mode 100644 index 2b8138c8e93c98773cf50fe0f2e02b0210879a70..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_favourite.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21z" - android:fillColor="#000000"/> -</vector> diff --git a/app/src/main/res/drawable/ic_favourite_empty.xml b/app/src/main/res/drawable/ic_favourite_empty.xml deleted file mode 100644 index b36536b997c2bac42f2b4b09bae0e2de03d08917..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_favourite_empty.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M22,9.24l-7.19,-0.62L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27 18.18,21l-1.63,-7.03L22,9.24zM12,15.4l-3.76,2.27 1,-4.28 -3.32,-2.88 4.38,-0.38L12,6.1l1.71,4.04 4.38,0.38 -3.32,2.88 1,4.28L12,15.4z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_info.xml b/app/src/main/res/drawable/ic_info.xml deleted file mode 100644 index c7e6ec796e60cb7fd7c509d5dee88ad745ca0f1d..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_info.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml index 9ea90121701967a2ab3c15a770b76def16c7a050..3945c5372aa671389652eff30b20b1cdd0ae56fc 100644 --- a/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,36 +1,40 @@ <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="108dp" - android:height="108dp" - android:viewportWidth="638.8894" - android:viewportHeight="638.8894"> - <group android:translateX="173.03255" - android:translateY="173.03255"> - <path - android:pathData="m62.962,292.5v0c-3.7,-0.9 -5.7,-3.8 -4.3,-6.5l32.3,-62.9c1.3,-2.6 5.5,-4 9.2,-3v0c3.7,0.9 5.7,3.8 4.3,6.5L72.162,289.5c-1.3,2.6 -5.4,4 -9.2,3z" - android:fillColor="#54AF39"/> - <path - android:pathData="m229.662,292.5v0c3.7,-0.9 5.7,-3.8 4.3,-6.5l-32.3,-62.9c-1.3,-2.6 -5.5,-4 -9.2,-3v0c-3.7,0.9 -5.7,3.8 -4.3,6.5l32.3,62.9c1.3,2.6 5.5,4 9.2,3z" - android:fillColor="#54AF39"/> - <path - android:pathData="m151.362,36.9 l-0.6,0.2c-1.8,0.7 -3.8,-0.3 -4.5,-2.1l-9.6,-26.7c-0.7,-1.8 0.3,-3.8 2.1,-4.5l0.6,-0.2c1.8,-0.7 3.8,0.3 4.5,2.1l9.6,26.7c0.7,1.9 -0.3,3.9 -2.1,4.5z" - android:fillColor="#54AF39"/> - <path - android:pathData="m180.662,3.8v0c0,2.1 -1.7,3.8 -3.8,3.8h-61c-2.1,0 -3.8,-1.7 -3.8,-3.8v0c0,-2.1 1.7,-3.8 3.8,-3.8h61c2.1,0 3.8,1.7 3.8,3.8z" - android:fillColor="#54AF39"/> - <path - android:pathData="M218.762,236.7L73.862,236.7c-13.3,0 -24,-10.8 -24,-24v-108C49.862,63.4 83.362,29.8 124.762,29.8h43.3c41.3,0 74.9,33.5 74.9,74.9v108c-0.1,13.2 -10.9,24 -24.2,24z" - android:fillColor="#54AF39"/> - <path - android:pathData="M212.562,146.2L80.062,146.2c-5.6,0 -10.2,-4.5 -10.2,-10.2v-34.9c0,-16.9 13.7,-30.6 30.6,-30.6L192.162,70.5c16.9,0 30.6,13.7 30.6,30.6v34.9c-0.1,5.7 -4.6,10.2 -10.2,10.2z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M161.462,55.5L131.162,55.5c-3.2,0 -5.7,-2.6 -5.7,-5.7v0c0,-3.2 2.6,-5.7 5.7,-5.7h30.3c3.2,0 5.7,2.6 5.7,5.7v0c0,3.1 -2.6,5.7 -5.7,5.7z" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M87.062,191.9m-14.8,0a14.8,14.8 0,1 1,29.6 0a14.8,14.8 0,1 1,-29.6 0" - android:fillColor="#FFFFFF"/> - <path - android:pathData="M205.662,191.9m-14.8,0a14.8,14.8 0,1 1,29.6 0a14.8,14.8 0,1 1,-29.6 0" - android:fillColor="#FFFFFF"/> - </group> + android:width="108dp" + android:height="108dp" + android:viewportWidth="108" + android:viewportHeight="108"> + <group android:scaleX="0.16904335" + android:scaleY="0.16904335"> + <group + android:translateX="173.03255" + android:translateY="173.03255"> + <path + android:fillColor="#54AF39" + android:pathData="m62.962,292.5v0c-3.7,-0.9 -5.7,-3.8 -4.3,-6.5l32.3,-62.9c1.3,-2.6 5.5,-4 9.2,-3v0c3.7,0.9 5.7,3.8 4.3,6.5L72.162,289.5c-1.3,2.6 -5.4,4 -9.2,3z" /> + <path + android:fillColor="#54AF39" + android:pathData="m229.662,292.5v0c3.7,-0.9 5.7,-3.8 4.3,-6.5l-32.3,-62.9c-1.3,-2.6 -5.5,-4 -9.2,-3v0c-3.7,0.9 -5.7,3.8 -4.3,6.5l32.3,62.9c1.3,2.6 5.5,4 9.2,3z" /> + <path + android:fillColor="#54AF39" + android:pathData="m151.362,36.9 l-0.6,0.2c-1.8,0.7 -3.8,-0.3 -4.5,-2.1l-9.6,-26.7c-0.7,-1.8 0.3,-3.8 2.1,-4.5l0.6,-0.2c1.8,-0.7 3.8,0.3 4.5,2.1l9.6,26.7c0.7,1.9 -0.3,3.9 -2.1,4.5z" /> + <path + android:fillColor="#54AF39" + android:pathData="m180.662,3.8v0c0,2.1 -1.7,3.8 -3.8,3.8h-61c-2.1,0 -3.8,-1.7 -3.8,-3.8v0c0,-2.1 1.7,-3.8 3.8,-3.8h61c2.1,0 3.8,1.7 3.8,3.8z" /> + <path + android:fillColor="#54AF39" + android:pathData="M218.762,236.7L73.862,236.7c-13.3,0 -24,-10.8 -24,-24v-108C49.862,63.4 83.362,29.8 124.762,29.8h43.3c41.3,0 74.9,33.5 74.9,74.9v108c-0.1,13.2 -10.9,24 -24.2,24z" /> + <path + android:fillColor="#FFFFFF" + android:pathData="M212.562,146.2L80.062,146.2c-5.6,0 -10.2,-4.5 -10.2,-10.2v-34.9c0,-16.9 13.7,-30.6 30.6,-30.6L192.162,70.5c16.9,0 30.6,13.7 30.6,30.6v34.9c-0.1,5.7 -4.6,10.2 -10.2,10.2z" /> + <path + android:fillColor="#FFFFFF" + android:pathData="M161.462,55.5L131.162,55.5c-3.2,0 -5.7,-2.6 -5.7,-5.7v0c0,-3.2 2.6,-5.7 5.7,-5.7h30.3c3.2,0 5.7,2.6 5.7,5.7v0c0,3.1 -2.6,5.7 -5.7,5.7z" /> + <path + android:fillColor="#FFFFFF" + android:pathData="M87.062,191.9m-14.8,0a14.8,14.8 0,1 1,29.6 0a14.8,14.8 0,1 1,-29.6 0" /> + <path + android:fillColor="#FFFFFF" + android:pathData="M205.662,191.9m-14.8,0a14.8,14.8 0,1 1,29.6 0a14.8,14.8 0,1 1,-29.6 0" /> + </group> + </group> </vector> diff --git a/app/src/main/res/drawable/ic_low_floor.xml b/app/src/main/res/drawable/ic_low_floor.xml deleted file mode 100644 index ee8013952cf5c8a7452b47c737c2517549eb8bba..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_low_floor.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M12,4m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/> - <path - android:fillColor="@color/textDark" - android:pathData="M19,13v-2c-1.54,0.02 -3.09,-0.75 -4.07,-1.83l-1.29,-1.43c-0.17,-0.19 -0.38,-0.34 -0.61,-0.45 -0.01,0 -0.01,-0.01 -0.02,-0.01L13,7.28c-0.35,-0.2 -0.75,-0.3 -1.19,-0.26C10.76,7.11 10,8.04 10,9.09L10,15c0,1.1 0.9,2 2,2h5v5h2v-5.5c0,-1.1 -0.9,-2 -2,-2h-3v-3.45c1.29,1.07 3.25,1.94 5,1.95zM12.83,18c-0.41,1.16 -1.52,2 -2.83,2 -1.66,0 -3,-1.34 -3,-3 0,-1.31 0.84,-2.41 2,-2.83L9,12.1c-2.28,0.46 -4,2.48 -4,4.9 0,2.76 2.24,5 5,5 2.42,0 4.44,-1.72 4.9,-4h-2.07z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_merge.xml b/app/src/main/res/drawable/ic_merge.xml deleted file mode 100644 index 18a93f7c4dbc2e9ccf2a0c1748eb98f8c4fb09a0..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_merge.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportHeight="24.0" - android:viewportWidth="24.0"> - <path - android:fillColor="#ffffffff" - android:pathData="M17,20.41L18.41,19 15,15.59 13.59,17 17,20.41zM7.5,8H11v5.59L5.59,19 7,20.41l6,-6V8h3.5L12,3.5 7.5,8z" /> -</vector> diff --git a/app/src/main/res/drawable/ic_message.xml b/app/src/main/res/drawable/ic_message.xml deleted file mode 100644 index d2876bfad9b41c533cbcab6156b7585e326a5644..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_message.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_more.xml b/app/src/main/res/drawable/ic_more.xml deleted file mode 100644 index 32698689639ff2e219056beced56019d70168b3e..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_more.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" - android:fillColor="@color/textDark"/> -</vector> diff --git a/app/src/main/res/drawable/ic_refresh.xml b/app/src/main/res/drawable/ic_refresh.xml deleted file mode 100644 index 40184c4b85dc0e3eec059ec810bfb833490f47ce..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_refresh.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml deleted file mode 100644 index bb988c1e7b6e67ca36b9e4bea05d1b0a54188b96..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_settings.xml +++ /dev/null @@ -1,10 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:autoMirrored="true" - android:viewportHeight="24.0" - android:viewportWidth="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z" /> -</vector> diff --git a/app/src/main/res/drawable/ic_stop.xml b/app/src/main/res/drawable/ic_stop.xml deleted file mode 100644 index eaf0afaf749baa0f6837f340a2d48419d69cd848..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_stop.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M12,2C8.13,2 5,5.13 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9C19,5.13 15.87,2 12,2zM12,5.758C13.547,5.758 14.799,5.933 14.799,7.158L14.799,10.656C14.799,10.964 14.663,11.241 14.449,11.434L14.449,12.057C14.449,12.249 14.292,12.406 14.1,12.406L13.75,12.406C13.558,12.406 13.4,12.249 13.4,12.057L13.4,11.707L10.6,11.707L10.6,12.057C10.6,12.249 10.442,12.406 10.25,12.406L9.9,12.406C9.708,12.406 9.551,12.249 9.551,12.057L9.551,11.434C9.337,11.241 9.201,10.964 9.201,10.656L9.201,7.158C9.201,5.933 10.453,5.758 12,5.758zM9.9,7.158L9.9,8.908L14.1,8.908L14.1,7.158L9.9,7.158zM10.426,9.957C10.135,9.957 9.9,10.192 9.9,10.482C9.9,10.773 10.135,11.008 10.426,11.008C10.716,11.008 10.951,10.773 10.951,10.482C10.951,10.192 10.716,9.957 10.426,9.957zM13.574,9.957C13.284,9.957 13.049,10.192 13.049,10.482C13.049,10.773 13.284,11.008 13.574,11.008C13.865,11.008 14.1,10.773 14.1,10.482C14.1,10.192 13.865,9.957 13.574,9.957z" - android:fillColor="#000000"/> -</vector> diff --git a/app/src/main/res/drawable/ic_texthandle_end.xml b/app/src/main/res/drawable/ic_texthandle_end.xml deleted file mode 100644 index 923f2b49a542f61b7fa1b19c720cba506b6767fb..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_texthandle_end.xml +++ /dev/null @@ -1,8 +0,0 @@ -<vector android:autoMirrored="true" android:height="24dp" - android:viewportHeight="88" android:viewportWidth="176" - android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillAlpha="1" android:fillColor="#54af39" - android:pathData="M88,0A44,44 0,0 1,132 44,44 44,0 0,1 88,88 44,44 0,0 1,44 44V0Z" - android:strokeAlpha="1" android:strokeColor="#00000000" - android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="0.01982322"/> -</vector> diff --git a/app/src/main/res/drawable/ic_texthandle_middle.xml b/app/src/main/res/drawable/ic_texthandle_middle.xml deleted file mode 100644 index da3c7962d98b2e2ef0113080f7491bad6e6c6dc6..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_texthandle_middle.xml +++ /dev/null @@ -1,7 +0,0 @@ -<vector android:height="24dp" android:viewportHeight="88" - android:viewportWidth="88" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillAlpha="1" android:fillColor="#54af39" - android:pathData="m69.7747,25.7746a36.4509,36.4508 0,0 1,0 51.5492,36.4509 36.4508,0 0,1 -51.5494,0 36.4509,36.4508 0,0 1,0 -51.5492L44,0Z" - android:strokeAlpha="1" android:strokeColor="#00000000" - android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="0.01642212"/> -</vector> diff --git a/app/src/main/res/drawable/ic_texthandle_start.xml b/app/src/main/res/drawable/ic_texthandle_start.xml deleted file mode 100644 index 577a11d14e6d46dade232eca4176dbcf8f469879..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_texthandle_start.xml +++ /dev/null @@ -1,8 +0,0 @@ -<vector android:autoMirrored="true" android:height="24dp" - android:viewportHeight="88" android:viewportWidth="176" - android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillAlpha="1" android:fillColor="#54af39" - android:pathData="M88,0A44,44 0,0 0,44 44,44 44,0 0,0 88,88 44,44 0,0 0,132 44V0Z" - android:strokeAlpha="1" android:strokeColor="#00000000" - android:strokeLineCap="round" android:strokeLineJoin="round" android:strokeWidth="0.01982322"/> -</vector> diff --git a/app/src/main/res/drawable/ic_ticket.xml b/app/src/main/res/drawable/ic_ticket.xml deleted file mode 100644 index bac81d8c4f7287a9046ffce81489ad5a5580039f..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_ticket.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="@color/textDark" - android:pathData="M22,10L22,6c0,-1.11 -0.9,-2 -2,-2L4,4c-1.1,0 -1.99,0.89 -1.99,2v4c1.1,0 1.99,0.9 1.99,2s-0.89,2 -2,2v4c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2v-4c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2zM13,17.5h-2v-2h2v2zM13,13h-2v-2h2v2zM13,8.5h-2v-2h2v2z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_ticket_machine.xml b/app/src/main/res/drawable/ic_ticket_machine.xml deleted file mode 100644 index 54ae501704b5f0035bd6f904e7987e3386f3c0db..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_ticket_machine.xml +++ /dev/null @@ -1,51 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:pathData="M3.25,2l17.5,0l0,20l-17.5,0z" - android:strokeAlpha="1" - android:strokeLineJoin="round" - android:strokeWidth="0.93728513" - android:fillColor="@color/cardColor" - android:strokeColor="#00000000" - android:fillAlpha="1" - android:strokeLineCap="round"/> - <path - android:pathData="m13.7109,5.0742c-1.3615,0 -2.4673,1.1057 -2.4673,2.4672 0,1.3615 1.1057,2.4672 2.4673,2.4672 0.2537,0 0.4944,-0.0488 0.7248,-0.12l0,-0.9861c-0.1124,0.0637 -0.2367,0.115 -0.3771,0.1412l0,0.4719l-0.6574,0l0,-0.4761c-0.4218,-0.0888 -0.7798,-0.3599 -0.807,-0.8386l0.4825,0c0.0247,0.2591 0.2018,0.4594 0.6532,0.4594 0.4834,0 0.5921,-0.2413 0.5921,-0.3919 0,-0.2046 -0.1073,-0.396 -0.6574,-0.5268 -0.6117,-0.1486 -1.0303,-0.4002 -1.0303,-0.906 0,-0.4241 0.3427,-0.7007 0.7669,-0.7923l0,-0.4761l0.6574,0l0,0.4825c0.1547,0.0375 0.274,0.1088 0.3771,0.1918l0,-1.0473c-0.2304,-0.0712 -0.4711,-0.12 -0.7248,-0.12zM13.7298,6.4247c-0.37,0 -0.59,0.1678 -0.59,0.4045 0,0.2072 0.1591,0.3415 0.6574,0.4699 0.2254,0.0575 0.4514,0.1404 0.6384,0.2634l0,-0.6764l-0.158,0c-0.0123,-0.2736 -0.1581,-0.4614 -0.5478,-0.4614z" - android:strokeWidth="0.19732159" - android:fillColor="@color/textDark"/> - <path - android:pathData="M14.3915,3.8496l1.0435,0l0,7.397l-1.0435,0z" - android:strokeAlpha="1" - android:strokeWidth="0" - android:fillColor="@color/textDark" - android:strokeColor="@color/textDark" - android:fillAlpha="1"/> - <path - android:pathData="M6.5208,14.0367l10.9584,0l0,2.0727l-10.9584,0z" - android:strokeAlpha="1" - android:strokeLineJoin="round" - android:strokeWidth="0.88379633" - android:fillColor="@color/textDark" - android:strokeColor="@color/textDark" - android:fillAlpha="1" - android:strokeLineCap="round"/> - <path - android:pathData="M3.25,2L3.25,22L20.75,22L20.75,2ZM4.5,3.25L19.5,3.25L19.5,20.75L4.5,20.75Z" - android:strokeAlpha="1" - android:strokeLineJoin="round" - android:strokeWidth="1.00509846" - android:fillColor="@color/textDark" - android:strokeColor="@color/textDark" - android:fillAlpha="1" - android:strokeLineCap="round"/> - <group> - <clip-path android:pathData="M-3,-3l30,0l0,30L-3,27z M 0,0"/> - <path - android:fillColor="@color/textDark" - android:pathData="m 9.8554688,14.806641 v 3.580078 c 0,0.294849 0.2422602,0.537109 0.5371092,0.537109 h 1.072266 c 0,-0.294849 0.240307,-0.537109 0.535156,-0.537109 0.294849,0 0.535156,0.24226 0.535156,0.537109 h 1.072266 c 0.29753,0 0.537109,-0.24226 0.537109,-0.537109 v -3.580078 z m 0.6699222,1.167968 H 11.0625 v 0.535157 h -0.537109 z m 1.207031,0 h 0.535156 v 0.535157 h -0.535156 z m 1.205078,0 h 0.537109 v 0.535157 H 12.9375 Z" - android:strokeWidth="0.26804501"/> - </group> -</vector> diff --git a/app/src/main/res/drawable/ic_timetable_departure.xml b/app/src/main/res/drawable/ic_timetable_departure.xml deleted file mode 100644 index 2a0bc4f2efc8c8d09bec309e12cd8e77320abedf..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_timetable_departure.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:pathData="M19,3C12,2.48 12,2.482 5,3 3.89,3 3.01,3.9 3.01,5L3,19c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5C21,3.9 20.1,3 19,3ZM19,19L5,19L5,8h14z" - android:fillColor="#ffffff"/> - <path - android:pathData="m17,12h-5v5h5z" - android:fillColor="#ffffff"/> -</vector> diff --git a/app/src/main/res/drawable/ic_timetable_full.xml b/app/src/main/res/drawable/ic_timetable_full.xml deleted file mode 100644 index 9518500e07590223e10da0b58f7218ff47e066f2..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_timetable_full.xml +++ /dev/null @@ -1,5 +0,0 @@ -<vector android:autoMirrored="true" android:height="24dp" - android:viewportHeight="24.0" android:viewportWidth="24.0" - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#ffffff" android:pathData="M17,10L7,10v2L17,12ZM19,3C12,2.48 12,2.482 5,3 3.89,3 3.01,3.9 3.01,5L3,19c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5C21,3.9 20.1,3 19,3ZM19,19L5,19L5,8L19,8ZM14,14L7,14v2h7z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_traffic.xml b/app/src/main/res/drawable/ic_traffic.xml deleted file mode 100644 index bf022cdda4939866e398ea8f7cd71e8015f188ab..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_traffic.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#ffffff" - android:pathData="M20,10h-3L17,8.86c1.72,-0.45 3,-2 3,-3.86h-3L17,4c0,-0.55 -0.45,-1 -1,-1L8,3c-0.55,0 -1,0.45 -1,1v1L4,5c0,1.86 1.28,3.41 3,3.86L7,10L4,10c0,1.86 1.28,3.41 3,3.86L7,15L4,15c0,1.86 1.28,3.41 3,3.86L7,20c0,0.55 0.45,1 1,1h8c0.55,0 1,-0.45 1,-1v-1.14c1.72,-0.45 3,-2 3,-3.86h-3v-1.14c1.72,-0.45 3,-2 3,-3.86zM12,19c-1.11,0 -2,-0.9 -2,-2s0.89,-2 2,-2c1.1,0 2,0.9 2,2s-0.89,2 -2,2zM12,14c-1.11,0 -2,-0.9 -2,-2s0.89,-2 2,-2c1.1,0 2,0.9 2,2s-0.89,2 -2,2zM12,9c-1.11,0 -2,-0.9 -2,-2 0,-1.11 0.89,-2 2,-2 1.1,0 2,0.89 2,2 0,1.1 -0.89,2 -2,2z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_tram.xml b/app/src/main/res/drawable/ic_tram.xml deleted file mode 100644 index ecef589606701c868fa9caa9a9576b57948efe58..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_tram.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M19,16.94L19,8.5c0,-2.79 -2.61,-3.4 -6.01,-3.49l0.76,-1.51L17,3.5L17,2L7,2v1.5h4.75l-0.76,1.52C7.86,5.11 5,5.73 5,8.5v8.44c0,1.45 1.19,2.66 2.59,2.97L6,21.5v0.5h2.23l2,-2L14,20l2,2h2v-0.5L16.5,20h-0.08c1.69,0 2.58,-1.37 2.58,-3.06zM12,18.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM17,14L7,14L7,9h10v5z"/> -</vector> diff --git a/app/src/main/res/drawable/ic_vehicle.xml b/app/src/main/res/drawable/ic_vehicle.xml deleted file mode 100644 index ae6f37bcc062fe9cba244f5a8af0bc67bf16e3c6..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/ic_vehicle.xml +++ /dev/null @@ -1,9 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24.0" - android:viewportHeight="24.0"> - <path - android:fillColor="#FF000000" - android:pathData="M4,15.5C4,17.43 5.57,19 7.5,19L6,20.5v0.5h12v-0.5L16.5,19c1.93,0 3.5,-1.57 3.5,-3.5L20,5c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10.5zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM18,10L6,10L6,5h12v5z"/> -</vector> diff --git a/app/src/main/res/drawable/inari.xml b/app/src/main/res/drawable/inari.xml new file mode 100644 index 0000000000000000000000000000000000000000..da25ef47d0c88263da2cc9acce30d60b253a96a3 --- /dev/null +++ b/app/src/main/res/drawable/inari.xml @@ -0,0 +1,55 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="66.982dp" + android:height="55.716dp" + android:viewportWidth="66.982" + android:viewportHeight="55.716"> + <path + android:pathData="M0,12.887a5.574,5.313 0,1 0,11.148 0a5.574,5.313 0,1 0,-11.148 0z" + android:strokeWidth="0.352122" + android:fillColor="#567ca0"/> + <path + android:pathData="M4.96,18.166h0.986v33.42h-0.986z" + android:strokeWidth="0.264866" + android:fillColor="#b5c5c5"/> + <path + android:pathData="M3.431,25.325h4.196v7.813h-4.196z" + android:strokeWidth="0.264583" + android:fillColor="#798595"/> + <path + android:pathData="m0.313,51.665h10.617v3.857c-3.618,0.267 -7.151,0.248 -10.617,0z" + android:strokeWidth="0.264583" + android:fillColor="#3f413c"/> + <path + android:pathData="m16.302,33.054 l5.762,-3.254 5.651,-0.183 6.147,0.293 4.652,2.215 -0.004,1.039 -3.422,2.396 -13.591,0.269z" + android:strokeLineJoin="miter" + android:strokeWidth="0.264583" + android:fillColor="#53221b" + android:strokeColor="#00000000" + android:strokeLineCap="butt"/> + <path + android:pathData="m27.594,26.553l0,12.511 0,0.722l0.484,0l0,-0.722 0,-12.511z" + android:strokeWidth="0.265" + android:fillColor="#5d1c18"/> + <path + android:pathData="m38.514,32.125c0.179,-0.709 -0.377,-1.396 -0.856,-1.87 -0.554,-0.544 -1.324,-1.41 -1.884,-1.957 -0.993,-0.578 -2.003,-0.898 -2.924,-1.586 -0.712,-0.696 -1.613,-0.546 -2.504,-0.857 -0.988,-0.383 -2.037,-0.15 -3.061,-0.164 -1.123,0.124 -2.255,0.275 -3.382,0.4 -0.863,0.156 -1.682,0.488 -2.422,0.946 -0.867,0.262 -1.547,0.826 -2.186,1.446 -0.789,0.558 -1.352,1.341 -2.037,2.012 -0.795,0.588 -0.88,1.652 -0.956,2.561l5.762,-3.254 5.651,-0.183 6.147,0.293z" + android:strokeLineJoin="miter" + android:strokeWidth="0.264583" + android:fillColor="#da4e59" + android:strokeColor="#00000000" + android:strokeLineCap="butt"/> + <path + android:pathData="m27.594,39.786h1.3v0c0,0 0.183,2.349 -0.63,2.355 -0.816,0.007 -0.67,-2.355 -0.67,-2.355z" + android:strokeWidth="0.264583" + android:fillColor="#743027"/> + <path + android:pathData="m55.478,2.524c1.557,0.025 3.113,0.049 4.67,0.074 0.066,-0.391 0.147,-0.813 0.248,-1.21 0.227,-0.373 0.095,-0.844 0.268,-1.202 0.148,-0.137 0.648,-0.364 0.706,0.058 0.115,0.42 0.124,0.927 -0.058,1.329 -0.101,0.353 -0.223,0.723 -0.389,1.032 1.599,0.008 3.198,0.017 4.796,0.025 0.197,0.326 0.599,0.218 0.915,0.392 0.456,0.096 0.354,0.596 0.295,1.009 -0.327,0.229 -0.432,0.655 -0.831,0.805 -0.229,0.283 -0.572,0.536 -0.982,0.358 -0.512,0.157 -1.007,-0.001 -1.518,-0.007 -0.386,-0.018 -0.684,0.241 -1.046,0.366 -0.398,0.176 -0.773,0.436 -1.058,0.758 -0.435,0.481 -0.955,0.035 -1.48,0.066 -0.417,-0.12 -0.696,-0.414 -1.077,-0.616 -0.429,-0.214 -0.84,-0.472 -1.2,-0.787 -0.401,-0.252 -0.878,-0.38 -1.181,-0.768 -0.3,-0.356 -0.88,-0.394 -1.031,-0.862 -0.081,-0.249 -0.155,-0.575 -0.048,-0.82z" + android:strokeLineJoin="miter" + android:strokeWidth="0.264583" + android:fillColor="#586c24" + android:strokeColor="#00000000" + android:strokeLineCap="butt"/> + <path + android:pathData="m7.458,15.993 l-2.092,-1.223 -2.194,1.03 0.517,-2.368 -1.658,-1.768 2.412,-0.24 1.169,-2.123 0.974,2.22 2.38,0.456 -1.81,1.612z" + android:fillColor="#ffe438" + android:strokeColor="#00000000"/> +</vector> diff --git a/app/src/main/res/drawable/logo_splash.xml b/app/src/main/res/drawable/logo_splash.xml deleted file mode 100644 index d47ebc499c362c425b5022bc55fd47e9145e7e92..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/logo_splash.xml +++ /dev/null @@ -1,12 +0,0 @@ -<vector android:height="192dp" android:viewportHeight="293" - android:viewportWidth="298" android:width="192dp" xmlns:android="http://schemas.android.com/apk/res/android"> - <path android:fillColor="#54AF39" android:pathData="m62.925,292.677l0,0c-3.69,-0.897 -5.684,-3.789 -4.288,-6.482l32.209,-62.723c1.296,-2.593 5.485,-3.989 9.174,-2.992l0,0c3.69,0.897 5.684,3.789 4.288,6.482L72.099,289.685c-1.296,2.593 -5.385,3.989 -9.174,2.992z"/> - <path android:fillColor="#54AF39" android:pathData="m229.156,292.677l0,0c3.69,-0.897 5.684,-3.789 4.288,-6.482l-32.209,-62.723c-1.296,-2.593 -5.485,-3.989 -9.174,-2.992l0,0c-3.69,0.897 -5.684,3.789 -4.288,6.482l32.209,62.723c1.296,2.593 5.485,3.989 9.174,2.992z"/> - <path android:fillColor="#54AF39" android:pathData="m151.076,37.797 l-0.598,0.199c-1.795,0.698 -3.789,-0.299 -4.487,-2.094l-9.573,-26.625c-0.698,-1.795 0.299,-3.789 2.094,-4.487l0.598,-0.199c1.795,-0.698 3.789,0.299 4.487,2.094l9.573,26.625c0.698,1.895 -0.299,3.889 -2.094,4.487z"/> - <path android:fillColor="#54AF39" android:pathData="m180.294,4.79l0,0c0,2.094 -1.695,3.789 -3.789,3.789l-60.828,0c-2.094,0 -3.789,-1.695 -3.789,-3.789l0,0c0,-2.094 1.695,-3.789 3.789,-3.789l60.828,0c2.094,0 3.789,1.695 3.789,3.789z"/> - <path android:fillColor="#54AF39" android:pathData="M218.286,237.034L73.795,237.034c-13.263,0 -23.932,-10.77 -23.932,-23.932l0,-107.696C49.862,64.222 83.268,30.717 124.551,30.717l43.178,0c41.184,0 74.689,33.406 74.689,74.689l0,107.696c-0.1,13.163 -10.869,23.932 -24.132,23.932z"/> - <path android:fillColor="#FFFFFF" android:pathData="M212.104,146.789L79.977,146.789c-5.584,0 -10.171,-4.487 -10.171,-10.171l0,-34.802c0,-16.852 13.661,-30.514 30.514,-30.514L191.761,71.302c16.852,0 30.514,13.661 30.514,30.514l0,34.802c-0.1,5.684 -4.587,10.171 -10.171,10.171z"/> - <path android:fillColor="#FFFFFF" android:pathData="M161.148,56.344L130.933,56.344c-3.191,0 -5.684,-2.593 -5.684,-5.684l0,0c0,-3.191 2.593,-5.684 5.684,-5.684l30.215,0c3.191,0 5.684,2.593 5.684,5.684l0,0c0,3.091 -2.593,5.684 -5.684,5.684z"/> - <path android:fillColor="#FFFFFF" android:pathData="M86.957,192.36m-14.758,0a14.758,14.758 0,1 1,29.517 0a14.758,14.758 0,1 1,-29.517 0"/> - <path android:fillColor="#FFFFFF" android:pathData="M205.223,192.36m-14.758,0a14.758,14.758 0,1 1,29.517 0a14.758,14.758 0,1 1,-29.517 0"/> -</vector> diff --git a/app/src/main/res/drawable/map_black.xml b/app/src/main/res/drawable/map_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..7e18171d1dbc285c53c53fb4bdcd4acebc216c02 --- /dev/null +++ b/app/src/main/res/drawable/map_black.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="#000000" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48V20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48V3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM15,19l-6,-2.11V5l6,2.11V19z" /> +</vector> diff --git a/app/src/main/res/drawable/map_outline.xml b/app/src/main/res/drawable/map_outline.xml new file mode 100644 index 0000000000000000000000000000000000000000..7d60b16d2a17887332a400f41434d035dac33a12 --- /dev/null +++ b/app/src/main/res/drawable/map_outline.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="#000000" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48L3,20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48L21,3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM10,5.47l4,1.4v11.66l-4,-1.4L10,5.47zM5,6.46l3,-1.01v11.7l-3,1.16L5,6.46zM19,17.54l-3,1.01L16,6.86l3,-1.16v11.84z" /> +</vector> diff --git a/app/src/main/res/drawable/navigation_arrow.xml b/app/src/main/res/drawable/navigation_arrow.xml new file mode 100644 index 0000000000000000000000000000000000000000..c29f851f60d8cbd8b38d63085504c6cde84c2ffc --- /dev/null +++ b/app/src/main/res/drawable/navigation_arrow.xml @@ -0,0 +1,8 @@ +<vector android:height="24dp" android:tint="?colorPrimary" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" + android:fillColor="@android:color/white" + android:pathData="M7.72,17.7l3.47,-1.53 0.81,-0.36 0.81,0.36 3.47,1.53L12,7.27z" android:strokeAlpha="0.3"/> + <path android:fillColor="@android:color/white" android:pathData="M4.5,20.29l0.71,0.71L12,18l6.79,3 0.71,-0.71L12,2 4.5,20.29zM12.81,16.17l-0.81,-0.36 -0.81,0.36 -3.47,1.53L12,7.27l4.28,10.43 -3.47,-1.53z"/> +</vector> diff --git a/app/src/main/res/drawable/navigation_circle.xml b/app/src/main/res/drawable/navigation_circle.xml new file mode 100644 index 0000000000000000000000000000000000000000..535e8520e6bde8d1784a1fb26a1ba701a26dfd74 --- /dev/null +++ b/app/src/main/res/drawable/navigation_circle.xml @@ -0,0 +1,8 @@ +<vector android:height="24dp" android:tint="?colorPrimary" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillAlpha="0.3" + android:fillColor="@android:color/white" + android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" android:strokeAlpha="0.3"/> + <path android:fillColor="@android:color/white" android:pathData="M12,2C6.47,2 2,6.47 2,12c0,5.53 4.47,10 10,10s10,-4.47 10,-10C22,6.47 17.53,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8c0,-4.42 3.58,-8 8,-8s8,3.58 8,8C20,16.42 16.42,20 12,20z"/> +</vector> diff --git a/app/src/main/res/drawable/open_outside.xml b/app/src/main/res/drawable/open_outside.xml new file mode 100644 index 0000000000000000000000000000000000000000..2a44988cc484c69541ae1cf9e3db3b1745c12626 --- /dev/null +++ b/app/src/main/res/drawable/open_outside.xml @@ -0,0 +1,5 @@ +<vector android:autoMirrored="true" android:height="24dp" + android:tint="?attr/colorOnSurface" android:viewportHeight="24" + android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,19H5V5h7V3H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2v7zM14,3v2h3.59l-9.83,9.83 1.41,1.41L19,6.41V10h2V3h-7z"/> +</vector> diff --git a/app/src/main/res/drawable/radar.xml b/app/src/main/res/drawable/radar.xml new file mode 100644 index 0000000000000000000000000000000000000000..4a9b66f5dfd56a6902bcb4f73c755edfbb32a8d6 --- /dev/null +++ b/app/src/main/res/drawable/radar.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19.74,18.33C21.15,16.6 22,14.4 22,12c0,-5.52 -4.48,-10 -10,-10S2,6.48 2,12s4.48,10 10,10c2.4,0 4.6,-0.85 6.33,-2.26c0.27,-0.22 0.53,-0.46 0.78,-0.71c0.03,-0.03 0.05,-0.06 0.07,-0.08C19.38,18.75 19.57,18.54 19.74,18.33zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8c0,1.85 -0.63,3.54 -1.69,4.9l-1.43,-1.43c0.69,-0.98 1.1,-2.17 1.1,-3.46c0,-3.31 -2.69,-6 -6,-6s-6,2.69 -6,6s2.69,6 6,6c1.3,0 2.51,-0.42 3.49,-1.13l1.42,1.42C15.54,19.37 13.85,20 12,20zM13.92,12.51c0.17,-0.66 0.02,-1.38 -0.49,-1.9l-0.02,-0.02c-0.77,-0.77 -2,-0.78 -2.78,-0.04c-0.01,0.01 -0.03,0.02 -0.05,0.04c-0.78,0.78 -0.78,2.05 0,2.83l0.02,0.02c0.52,0.51 1.25,0.67 1.91,0.49l1.51,1.51c-0.6,0.36 -1.29,0.58 -2.04,0.58c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4s4,1.79 4,4c0,0.73 -0.21,1.41 -0.56,2L13.92,12.51z" /> +</vector> diff --git a/app/src/main/res/drawable/speed.xml b/app/src/main/res/drawable/speed.xml new file mode 100644 index 0000000000000000000000000000000000000000..8bd6c25c1798adb28ad2093bf615d11565b828ec --- /dev/null +++ b/app/src/main/res/drawable/speed.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20.38,8.57l-1.23,1.85a8,8 0,0 1,-0.22 7.58L5.07,18A8,8 0,0 1,15.58 6.85l1.85,-1.23A10,10 0,0 0,3.35 19a2,2 0,0 0,1.72 1h13.85a2,2 0,0 0,1.74 -1,10 10,0 0,0 -0.27,-10.44zM10.59,15.41a2,2 0,0 0,2.83 0l5.66,-8.49 -8.49,5.66a2,2 0,0 0,0 2.83z"/> +</vector> diff --git a/app/src/main/res/drawable/splash_screen.xml b/app/src/main/res/drawable/splash_screen.xml deleted file mode 100644 index 0630c0b6c2ab6efb60de91917e757d8307cc5535..0000000000000000000000000000000000000000 --- a/app/src/main/res/drawable/splash_screen.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - - <item android:drawable="@color/colorPrimary" /> - <item - android:gravity="center" - android:drawable="@drawable/logo_splash"/> - -</layer-list> \ No newline at end of file diff --git a/app/src/main/res/drawable/stop.xml b/app/src/main/res/drawable/stop.xml new file mode 100644 index 0000000000000000000000000000000000000000..6152d3c023e5b38f7777e0e0ea49369a119b4833 --- /dev/null +++ b/app/src/main/res/drawable/stop.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M2,12C2,6.48 6.48,2 12,2s10,4.48 10,10 -4.48,10 -10,10S2,17.52 2,12zM12,18c3.31,0 6,-2.69 6,-6s-2.69,-6 -6,-6 -6,2.69 -6,6 2.69,6 6,6z"/> +</vector> diff --git a/app/src/main/res/drawable/stop_bg.xml b/app/src/main/res/drawable/stop_bg.xml new file mode 100644 index 0000000000000000000000000000000000000000..2bbe61ebf84e1af6e37ab94e17428476dca002a0 --- /dev/null +++ b/app/src/main/res/drawable/stop_bg.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:pathData="M2.807,12a9.193,9.193 0,1 0,18.386 0a9.193,9.193 0,1 0,-18.386 0z" + android:fillColor="@android:color/black"/> +</vector> diff --git a/app/src/main/res/drawable/ticket.xml b/app/src/main/res/drawable/ticket.xml new file mode 100644 index 0000000000000000000000000000000000000000..fff78c3e5c8aa8da77179e6da442ffd733e8590a --- /dev/null +++ b/app/src/main/res/drawable/ticket.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M22,10V6c0,-1.11 -0.9,-2 -2,-2H4C2.9,4 2.01,4.89 2.01,6v4C3.11,10 4,10.9 4,12s-0.89,2 -2,2v4c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2v-4c-1.1,0 -2,-0.9 -2,-2S20.9,10 22,10zM13,17.5h-2v-2h2V17.5zM13,13h-2v-2h2V13zM13,8.5h-2v-2h2V8.5z"/> +</vector> diff --git a/app/src/main/res/drawable/traffic.xml b/app/src/main/res/drawable/traffic.xml new file mode 100644 index 0000000000000000000000000000000000000000..a90fc1adaa70dfaabc28ac064f12b98bd2bdd3a0 --- /dev/null +++ b/app/src/main/res/drawable/traffic.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,10h-3L17,8.86c1.72,-0.45 3,-2 3,-3.86h-3L17,4c0,-0.55 -0.45,-1 -1,-1L8,3c-0.55,0 -1,0.45 -1,1v1L4,5c0,1.86 1.28,3.41 3,3.86L7,10L4,10c0,1.86 1.28,3.41 3,3.86L7,15L4,15c0,1.86 1.28,3.41 3,3.86L7,20c0,0.55 0.45,1 1,1h8c0.55,0 1,-0.45 1,-1v-1.14c1.72,-0.45 3,-2 3,-3.86h-3v-1.14c1.72,-0.45 3,-2 3,-3.86zM12,19c-1.11,0 -2,-0.9 -2,-2s0.89,-2 2,-2c1.1,0 2,0.9 2,2s-0.89,2 -2,2zM12,14c-1.11,0 -2,-0.9 -2,-2s0.89,-2 2,-2c1.1,0 2,0.9 2,2s-0.89,2 -2,2zM12,9c-1.11,0 -2,-0.9 -2,-2 0,-1.11 0.89,-2 2,-2 1.1,0 2,0.89 2,2 0,1.1 -0.89,2 -2,2z"/> +</vector> diff --git a/app/src/main/res/drawable/tram_black.xml b/app/src/main/res/drawable/tram_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..989349cbc9a456e6458fff607d6ad99c1e9d1c79 --- /dev/null +++ b/app/src/main/res/drawable/tram_black.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#000000" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M19,16.94L19,8.5c0,-2.79 -2.61,-3.4 -6.01,-3.49l0.76,-1.51L17,3.5L17,2L7,2v1.5h4.75l-0.76,1.52C7.86,5.11 5,5.73 5,8.5v8.44c0,1.45 1.19,2.66 2.59,2.97L6,21.5v0.5h2.23l2,-2L14,20l2,2h2v-0.5L16.5,20h-0.08c1.69,0 2.58,-1.37 2.58,-3.06zM12,18.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM17,14L7,14L7,9h10v5z"/> +</vector> diff --git a/app/src/main/res/drawable/transfer.xml b/app/src/main/res/drawable/transfer.xml new file mode 100644 index 0000000000000000000000000000000000000000..9bbd348b35582a1b326e1945f339eb2f550c23f1 --- /dev/null +++ b/app/src/main/res/drawable/transfer.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M16.49,15.5v-1.75L14,16.25l2.49,2.5L16.49,17L22,17v-1.5zM19.51,19.75L14,19.75v1.5h5.51L19.51,23L22,20.5 19.51,18zM9.5,5.5c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM5.75,8.9L3,23h2.1l1.75,-8L9,17v6h2v-7.55L8.95,13.4l0.6,-3C10.85,12 12.8,13 15,13v-2c-1.85,0 -3.45,-1 -4.35,-2.45l-0.95,-1.6C9.35,6.35 8.7,6 8,6c-0.25,0 -0.5,0.05 -0.75,0.15L2,8.3L2,13h2L4,9.65l1.75,-0.75"/> +</vector> diff --git a/app/src/main/res/drawable/usb.xml b/app/src/main/res/drawable/usb.xml new file mode 100644 index 0000000000000000000000000000000000000000..be1c47a4c753e537073fbab2636757cbb623a2c3 --- /dev/null +++ b/app/src/main/res/drawable/usb.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M15,7v4h1v2h-3V5h2l-3,-4 -3,4h2v8H8v-2.07c0.7,-0.37 1.2,-1.08 1.2,-1.93 0,-1.21 -0.99,-2.2 -2.2,-2.2 -1.21,0 -2.2,0.99 -2.2,2.2 0,0.85 0.5,1.56 1.2,1.93V13c0,1.11 0.89,2 2,2h3v3.05c-0.71,0.37 -1.2,1.1 -1.2,1.95 0,1.22 0.99,2.2 2.2,2.2 1.21,0 2.2,-0.98 2.2,-2.2 0,-0.85 -0.49,-1.58 -1.2,-1.95V15h3c1.11,0 2,-0.89 2,-2v-2h1V7h-4z"/> +</vector> diff --git a/app/src/main/res/drawable/vehicle_black.xml b/app/src/main/res/drawable/vehicle_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..5a564641966c51b347cffdc46b8967bc498796b8 --- /dev/null +++ b/app/src/main/res/drawable/vehicle_black.xml @@ -0,0 +1,5 @@ +<vector android:height="24dp" android:tint="#000000" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,4L5,4C3.34,4 2,5.34 2,7v8c0,1.66 1.34,3 3,3l-1,1v1h1l2,-2.03L9,18v-5L4,13L4,5.98L13,6v2h2L15,7c0,-1.66 -1.34,-3 -3,-3zM5,14c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM20.57,9.66c-0.14,-0.4 -0.52,-0.66 -0.97,-0.66h-7.19c-0.46,0 -0.83,0.26 -0.98,0.66L10,13.77l0.01,5.51c0,0.38 0.31,0.72 0.69,0.72h0.62c0.38,0 0.68,-0.38 0.68,-0.76L12,18h8v1.24c0,0.38 0.31,0.76 0.69,0.76h0.61c0.38,0 0.69,-0.34 0.69,-0.72l0.01,-1.37v-4.14l-1.43,-4.11zM12.41,10h7.19l1.03,3h-9.25l1.03,-3zM12,16c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1zM20,16c-0.55,0 -1,-0.45 -1,-1s0.45,-1 1,-1 1,0.45 1,1 -0.45,1 -1,1z"/> +</vector> diff --git a/app/src/main/res/drawable/voice.xml b/app/src/main/res/drawable/voice.xml new file mode 100644 index 0000000000000000000000000000000000000000..5025538b7a1049c792bec4ed32094a28e4325965 --- /dev/null +++ b/app/src/main/res/drawable/voice.xml @@ -0,0 +1,8 @@ +<vector android:height="24dp" android:tint="?attr/colorOnSurface" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M10,9m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"/> + <path android:fillColor="@android:color/white" android:pathData="M16.39,15.56C14.71,14.7 12.53,14 10,14c-2.53,0 -4.71,0.7 -6.39,1.56C2.61,16.07 2,17.1 2,18.22V21h16v-2.78C18,17.1 17.39,16.07 16.39,15.56z"/> + <path android:fillColor="@android:color/white" android:pathData="M16,1h-2c0,4.97 4.03,9 9,9V8C19.14,8 16,4.86 16,1z"/> + <path android:fillColor="@android:color/white" android:pathData="M20,1h-2c0,2.76 2.24,5 5,5V4C21.35,4 20,2.65 20,1z"/> +</vector> diff --git a/app/src/main/res/drawable/voyage_black.xml b/app/src/main/res/drawable/voyage_black.xml new file mode 100644 index 0000000000000000000000000000000000000000..64e7679467a84913e63d3c35fe2a7593046316c5 --- /dev/null +++ b/app/src/main/res/drawable/voyage_black.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="#000000" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M21.71,11.29l-9,-9c-0.39,-0.39 -1.02,-0.39 -1.41,0l-9,9c-0.39,0.39 -0.39,1.02 0,1.41l9,9c0.39,0.39 1.02,0.39 1.41,0l9,-9c0.39,-0.38 0.39,-1.01 0,-1.41zM14,14.5V12h-4v3H8v-4c0,-0.55 0.45,-1 1,-1h5V7.5l3.5,3.5 -3.5,3.5z" /> +</vector> diff --git a/app/src/main/res/drawable/voyage_outline.xml b/app/src/main/res/drawable/voyage_outline.xml new file mode 100644 index 0000000000000000000000000000000000000000..9818555ef3e8d71d8f9cfeb13831e94c194c88d8 --- /dev/null +++ b/app/src/main/res/drawable/voyage_outline.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:tint="#000000" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="@android:color/white" + android:pathData="M22.43,10.59l-9.01,-9.01c-0.75,-0.75 -2.07,-0.76 -2.83,0l-9,9c-0.78,0.78 -0.78,2.04 0,2.82l9,9c0.39,0.39 0.9,0.58 1.41,0.58 0.51,0 1.02,-0.19 1.41,-0.58l8.99,-8.99c0.79,-0.76 0.8,-2.02 0.03,-2.82zM12.01,20.99l-9,-9 9,-9 9,9 -9,9zM8,11v4h2v-3h4v2.5l3.5,-3.5L14,7.5L14,10L9,10c-0.55,0 -1,0.45 -1,1z" /> +</vector> diff --git a/app/src/main/res/drawable/wheelchair.xml b/app/src/main/res/drawable/wheelchair.xml new file mode 100644 index 0000000000000000000000000000000000000000..4bba0d4e74fafecb1856557c12e547e2064af8e8 --- /dev/null +++ b/app/src/main/res/drawable/wheelchair.xml @@ -0,0 +1,6 @@ +<vector android:autoMirrored="true" android:height="24dp" + android:tint="?attr/colorOnSurface" android:viewportHeight="24" + android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,4m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/> + <path android:fillColor="@android:color/white" android:pathData="M19,13v-2c-1.54,0.02 -3.09,-0.75 -4.07,-1.83l-1.29,-1.43c-0.17,-0.19 -0.38,-0.34 -0.61,-0.45 -0.01,0 -0.01,-0.01 -0.02,-0.01L13,7.28c-0.35,-0.2 -0.75,-0.3 -1.19,-0.26C10.76,7.11 10,8.04 10,9.09L10,15c0,1.1 0.9,2 2,2h5v5h2v-5.5c0,-1.1 -0.9,-2 -2,-2h-3v-3.45c1.29,1.07 3.25,1.94 5,1.95zM12.83,18c-0.41,1.16 -1.52,2 -2.83,2 -1.66,0 -3,-1.34 -3,-3 0,-1.31 0.84,-2.41 2,-2.83L9,12.1c-2.28,0.46 -4,2.48 -4,4.9 0,2.76 2.24,5 5,5 2.42,0 4.44,-1.72 4.9,-4h-2.07z"/> +</vector> diff --git a/app/src/main/res/font/yellowcircle8.otf b/app/src/main/res/font/yellowcircle8.otf new file mode 100644 index 0000000000000000000000000000000000000000..d7fe02a6e3eb6c6c6eab115c4b1e60c0f36bb63a Binary files /dev/null and b/app/src/main/res/font/yellowcircle8.otf differ diff --git a/app/src/main/res/layout/activity_dash.xml b/app/src/main/res/layout/activity_dash.xml deleted file mode 100644 index beab223ec802c3d476e8b6cb3854326a13508063..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/activity_dash.xml +++ /dev/null @@ -1,71 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/drawer_layout" - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <androidx.constraintlayout.widget.ConstraintLayout - android:id="@+id/main_layout" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:clipChildren="false"> - - <com.google.android.material.appbar.AppBarLayout - android:id="@+id/appbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@color/colorAccentDark" - android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay" - android:visibility="invisible" - app:layout_constraintTop_toTopOf="parent"> - - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:layout_weight="1" - android:background="@color/colorAccentDark" - app:layout_scrollFlags="scroll|enterAlways" - app:popupTheme="@style/AppTheme.PopupOverlay" /> - </com.google.android.material.appbar.AppBarLayout> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/favourites_list" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_marginTop="8dp" - android:scrollbars="none" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/search_view" /> - - <com.mancj.materialsearchbar.MaterialSearchBar - android:id="@+id/search_view" - style="@style/SearchBarTheme" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:fadeScrollbars="false" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:mt_hint="@string/search_placeholder" - app:mt_navIconEnabled="true" - app:mt_placeholder="@string/search_placeholder" - app:mt_roundedSearchBarEnabled="true" - app:mt_searchBarColor="@color/cardColor" - app:mt_speechMode="false" /> - </androidx.constraintlayout.widget.ConstraintLayout> - - <com.google.android.material.navigation.NavigationView - android:id="@+id/drawer" - android:layout_width="240dp" - android:layout_height="match_parent" - android:layout_gravity="start" - app:menu="@menu/menu_drawer" /> -</androidx.drawerlayout.widget.DrawerLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_departures.xml b/app/src/main/res/layout/activity_departures.xml new file mode 100644 index 0000000000000000000000000000000000000000..328035a5a820483133b82c8089449684124bd5ac --- /dev/null +++ b/app/src/main/res/layout/activity_departures.xml @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingBottom="16dp"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/departures_overlay" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.google.android.material.progressindicator.CircularProgressIndicator + android:id="@+id/departures_progress" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:indeterminate="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/error_image" + android:layout_width="92dp" + android:layout_height="92dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:ignore="ContentDescription" + tool:src="@drawable/error_net" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/error_text" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/error_image" + tool:text="No connection" /> + </androidx.constraintlayout.widget.ConstraintLayout> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fitsSystemWindows="true"> + + <com.google.android.material.appbar.CollapsingToolbarLayout + android:id="@+id/collapsing_layout" + style="?attr/collapsingToolbarLayoutMediumStyle" + android:layout_width="match_parent" + android:layout_height="?attr/collapsingToolbarLayoutMediumSize" + app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" + app:maxLines="2"> + + <com.google.android.material.appbar.MaterialToolbar + android:id="@+id/departures_app_bar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:elevation="0dp" + app:layout_collapseMode="pin" /> + + </com.google.android.material.appbar.CollapsingToolbarLayout> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/departures_recycler" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" + android:fitsSystemWindows="true" + android:visibility="gone" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> + +</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit_favourite.xml b/app/src/main/res/layout/activity_edit_favourite.xml deleted file mode 100644 index 68b83202b85739fae328d3d5a44d2e7c371e9565..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/activity_edit_favourite.xml +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/dialog_favourite" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:orientation="vertical"> - - <com.google.android.material.appbar.AppBarLayout - android:id="@+id/appbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay" - app:layout_constraintTop_toTopOf="parent"> - - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:layout_weight="1" - android:background="@color/colorPrimary" - app:layout_scrollFlags="scroll|enterAlways" - app:popupTheme="@style/AppTheme.PopupOverlay" /> - </com.google.android.material.appbar.AppBarLayout> - - <TextView - android:id="@+id/name_label" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:labelFor="@id/favourite_name_edit" - android:text="@string/favourite_name" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/appbar" /> - - <EditText - android:id="@+id/favourite_name_edit" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginEnd="8dp" - android:ems="10" - android:importantForAutofill="no" - android:inputType="text" - android:text="" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/name_label" - tools:ignore="UnusedAttribute" /> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/favourite_edit_list" - android:layout_width="0dp" - android:layout_height="0dp" - android:layout_marginTop="8dp" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/favourite_name_edit"> - - </androidx.recyclerview.widget.RecyclerView> - - <ProgressBar - android:id="@+id/favourite_edit_loading" - style="@style/Widget.AppCompat.ProgressBar" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="@+id/favourite_edit_list" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/favourite_name_edit" /> - -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_feed_chooser.xml b/app/src/main/res/layout/activity_feed_chooser.xml new file mode 100644 index 0000000000000000000000000000000000000000..2995a2b237ba74aa7f1cfc7055c7b641820fbd13 --- /dev/null +++ b/app/src/main/res/layout/activity_feed_chooser.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tool:context="xyz.apiote.bimba.czwek.settings.feeds.FeedChooserActivity"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/feeds_overlay" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.google.android.material.progressindicator.CircularProgressIndicator + android:id="@+id/progress" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:indeterminate="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/error_image" + android:layout_width="92dp" + android:layout_height="92dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:ignore="ContentDescription" + tool:src="@drawable/error_net" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/error_text" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/error_image" + tool:text="No connection" /> + </androidx.constraintlayout.widget.ConstraintLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/results_recycler" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:layout_marginBottom="8dp" + android:visibility="gone" + app:layout_behavior="@string/appbar_scrolling_view_behavior" + app:layout_constraintBottom_toTopOf="@+id/button" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <Button + android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" + android:text="@string/save" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_line_specify.xml b/app/src/main/res/layout/activity_line_specify.xml deleted file mode 100644 index ce51c5661d1f2e400fc2ea279aceb915ae4310ef..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/activity_line_specify.xml +++ /dev/null @@ -1,56 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/main_content" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:fitsSystemWindows="true" - tools:context="ml.adamsprogs.bimba.activities.LineSpecifyActivity"> - - <com.google.android.material.appbar.AppBarLayout - android:id="@+id/appbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay"> - - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:layout_weight="1" - android:background="?attr/colorPrimary" - app:layout_scrollFlags="scroll|enterAlways" - app:popupTheme="@style/AppTheme.PopupOverlay" - app:title="@string/app_name"> - - </androidx.appcompat.widget.Toolbar> - - <com.google.android.material.tabs.TabLayout - android:id="@+id/tabs" - android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <com.google.android.material.tabs.TabItem - android:id="@+id/tabItem" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/tab_text_line_to" /> - - <com.google.android.material.tabs.TabItem - android:id="@+id/tabItem2" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="@string/tab_text_line_fro" /> - - </com.google.android.material.tabs.TabLayout> - </com.google.android.material.appbar.AppBarLayout> - - <androidx.viewpager.widget.ViewPager - android:id="@+id/container" - android:layout_width="match_parent" - android:layout_height="match_parent" - app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - -</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..1d378b8e473132ec02ff62392656497537026224 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/container" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <androidx.coordinatorlayout.widget.CoordinatorLayout + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <com.google.android.material.appbar.MaterialToolbar + android:id="@+id/top_app_bar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + app:title="" /> + </com.google.android.material.appbar.AppBarLayout> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <androidx.fragment.app.FragmentContainerView + android:id="@+id/nav_host_fragment_activity_main" + android:name="androidx.navigation.fragment.NavHostFragment" + android:layout_width="match_parent" + android:layout_height="0dp" + app:defaultNavHost="true" + app:layout_constraintBottom_toTopOf="@+id/bottom_navigation" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:navGraph="@navigation/front_navigation" /> + + <com.google.android.material.bottomnavigation.BottomNavigationView + android:id="@+id/bottom_navigation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:menu="@menu/bottom_nav_menu" /> + </androidx.constraintlayout.widget.ConstraintLayout> + </androidx.coordinatorlayout.widget.CoordinatorLayout> + + <com.google.android.material.navigation.NavigationView + android:id="@+id/navigation_drawer" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_gravity="start" + app:menu="@menu/drawer" /> + + +</androidx.drawerlayout.widget.DrawerLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_onboarding.xml b/app/src/main/res/layout/activity_onboarding.xml new file mode 100644 index 0000000000000000000000000000000000000000..657b251858872a2863f33e5ed13e3a86eaff5d88 --- /dev/null +++ b/app/src/main/res/layout/activity_onboarding.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tool:context="xyz.apiote.bimba.czwek.onboarding.OnboardingActivity"> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/guideline2" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_percent=".125" /> + + <com.google.android.material.textview.MaterialTextView + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:text="@string/onboarding_question" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@+id/guideline2" /> + + <Button + android:id="@+id/button_simple" + style="?attr/materialButtonOutlinedStyle" + android:layout_width="200dp" + android:layout_height="100dp" + android:layout_marginBottom="16dp" + app:cornerRadius="10dp" + app:layout_constraintBottom_toTopOf="@+id/guideline" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/guideline" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="horizontal" + app:layout_constraintGuide_percent=".5" /> + + <Button + android:id="@+id/button_advanced" + style="?attr/materialButtonOutlinedStyle" + android:layout_width="200dp" + android:layout_height="100dp" + android:layout_marginTop="16dp" + app:cornerRadius="10dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/guideline" /> + + <com.google.android.material.textview.MaterialTextView + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:layout_marginBottom="16dp" + android:text="@string/seatbelts_everyone" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.BodySmall" + android:textStyle="italic" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_results.xml b/app/src/main/res/layout/activity_results.xml new file mode 100644 index 0000000000000000000000000000000000000000..5a4a9eaf2035a901b8502d56a822ae2be4853f4d --- /dev/null +++ b/app/src/main/res/layout/activity_results.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingBottom="16dp"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/results_overlay" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <com.google.android.material.progressindicator.CircularProgressIndicator + android:id="@+id/results_progress" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:indeterminate="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/error_image" + android:layout_width="92dp" + android:layout_height="92dp" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:ignore="ContentDescription" + tool:src="@drawable/error_net" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/error_text" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="16dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + android:visibility="gone" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/error_image" + tool:text="No connection" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <com.google.android.material.appbar.AppBarLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:fitsSystemWindows="true" + app:liftOnScroll="true"> + + <com.google.android.material.appbar.MaterialToolbar + android:id="@+id/top_app_bar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + app:title="@string/title_activity_results" /> + + </com.google.android.material.appbar.AppBarLayout> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/results_recycler" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:clipToPadding="false" + android:fitsSystemWindows="true" + android:visibility="gone" + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> +</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_server_chooser.xml b/app/src/main/res/layout/activity_server_chooser.xml new file mode 100644 index 0000000000000000000000000000000000000000..e441ede9d9dcddf5c313710d0470c9b4bc936e0f --- /dev/null +++ b/app/src/main/res/layout/activity_server_chooser.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tool:context="xyz.apiote.bimba.czwek.settings.ServerChooserActivity"> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/server_field" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" + android:hint="@string/bimba_server_address_hint" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="textUri" /> + + </com.google.android.material.textfield.TextInputLayout> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/token_field" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" + android:hint="@string/bimba_server_token_hint" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/server_field"> + + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </com.google.android.material.textfield.TextInputLayout> + + <Button + android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:text="@string/bimba_server_continue_button" + app:layout_constraintEnd_toEndOf="@+id/token_field" + app:layout_constraintStart_toStartOf="@+id/token_field" + app:layout_constraintTop_toBottomOf="@+id/token_field" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml deleted file mode 100644 index b5342c25185db6b54c6e668d71cd9667334a5b6d..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/activity_settings.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="match_parent" - xmlns:app="http://schemas.android.com/apk/res-auto"> - - <com.google.android.material.appbar.AppBarLayout - android:id="@+id/appbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent"> - - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:layout_weight="1" - android:background="?attr/colorPrimary" - app:layout_scrollFlags="scroll|enterAlways" - app:popupTheme="@style/AppTheme.PopupOverlay" - app:title="@string/title_activity_settings"> - - </androidx.appcompat.widget.Toolbar> - </com.google.android.material.appbar.AppBarLayout> - - <fragment - android:id="@+id/settings_fragment" - android:name="ml.adamsprogs.bimba.activities.SettingsActivity$MainPreferenceFragment" - android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginEnd="8dp" - android:layout_marginStart="8dp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/appbar" /> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_stop.xml b/app/src/main/res/layout/activity_stop.xml deleted file mode 100644 index e3edb3af00ca28936faa18d73db9c50a732294c0..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/activity_stop.xml +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/stop_layout" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:fitsSystemWindows="true" - tools:context="ml.adamsprogs.bimba.activities.StopActivity"> - - <com.google.android.material.appbar.AppBarLayout - android:id="@+id/appbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="0dp" - android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay" - app:layout_constraintTop_toTopOf="parent"> - - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:layout_weight="1" - android:background="?attr/colorPrimary" - app:layout_scrollFlags="scroll|enterAlways" - app:popupTheme="@style/AppTheme.PopupOverlay" - app:title="@string/app_name"> - - </androidx.appcompat.widget.Toolbar> - - <Spinner - android:id="@+id/dateSpinner" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginLeft="8dp" - android:layout_marginEnd="8dp" - android:layout_marginRight="8dp" - android:layout_marginBottom="8dp" - android:layout_weight="1" - android:visibility="gone" /> - </com.google.android.material.appbar.AppBarLayout> - - <include - android:id="@+id/banner" - layout="@layout/banner" - android:layout_width="match_parent" - android:layout_height="120dp" - android:visibility="gone" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/appbar" /> - - <ImageView - android:id="@+id/emptyStateIcon" - android:layout_width="48dp" - android:layout_height="48dp" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/departures_empty_state_icon" - android:tint="@color/textDarkMedium" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/banner" - app:srcCompat="@drawable/ic_traffic" /> - - <TextView - android:id="@+id/emptyStateText" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:text="@string/no_departures" - android:textColor="@color/textDarkMedium" - android:visibility="gone" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/emptyStateIcon" /> - - <ProgressBar - android:id="@+id/progressBar" - style="?android:attr/progressBarStyle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:visibility="visible" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/banner" /> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/departuresList" - android:layout_width="0dp" - android:layout_height="0dp" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/banner" /> - - <com.google.android.material.floatingactionbutton.FloatingActionButton - android:id="@+id/fab" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end|bottom" - android:layout_margin="@dimen/fab_margin" - android:layout_marginEnd="16dp" - android:layout_marginBottom="16dp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:srcCompat="@drawable/ic_favourite" /> - -</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/activity_stop_specify.xml b/app/src/main/res/layout/activity_stop_specify.xml deleted file mode 100644 index c71d7141f81900a26b50ef6fbf0d56a6eec10c20..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/activity_stop_specify.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context="ml.adamsprogs.bimba.activities.StopSpecifyActivity"> - - <ProgressBar - android:id="@+id/progressBar" - style="?android:attr/progressBarStyle" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/appbar" /> - - <com.google.android.material.appbar.AppBarLayout - android:id="@+id/appbar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingTop="@dimen/appbar_padding_top" - android:theme="@style/AppTheme.AppBarOverlay" - app:layout_constraintTop_toTopOf="parent"> - - <androidx.appcompat.widget.Toolbar - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="?attr/actionBarSize" - android:layout_weight="1" - android:background="@color/colorPrimary" - app:popupTheme="@style/AppTheme.PopupOverlay" - app:title="@string/app_name" /> - </com.google.android.material.appbar.AppBarLayout> - - <androidx.recyclerview.widget.RecyclerView - android:id="@+id/list_view" - android:layout_width="0dp" - android:layout_height="0dp" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/appbar" /> - -</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/banner.xml b/app/src/main/res/layout/banner.xml deleted file mode 100644 index edb12b05be6566596ba970dff8c2db13821df70b..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/banner.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="120dp" - android:orientation="vertical"> - - <View - android:id="@+id/banner_separator" - android:layout_width="fill_parent" - android:layout_height="1dp" - android:background="#90909090" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintEnd_toStartOf="parent" - app:layout_constraintStart_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" /> - - <Button - android:id="@+id/banner_more" - style="@style/Widget.AppCompat.Button.Borderless.Colored" - android:layout_width="wrap_content" - android:layout_height="36dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:text="@string/more" - android:textAppearance="@style/TextAppearance.AppCompat.Button" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> - - <TextView - android:id="@+id/banner_text" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="24dp" - android:layout_marginEnd="16dp" - android:layout_marginBottom="20dp" - android:ellipsize="end" - android:maxLines="2" - android:minLines="1" - android:singleLine="false" - android:text="" - android:textAppearance="@style/TextAppearance.AppCompat.Body2" - app:layout_constraintBottom_toTopOf="@+id/banner_more" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toEndOf="@+id/banner_icon" - app:layout_constraintTop_toTopOf="parent" /> - - <ImageView - android:id="@+id/banner_icon" - android:layout_width="40dp" - android:layout_height="40dp" - android:layout_marginStart="16dp" - android:contentDescription="@string/vm_message_icon" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="@+id/banner_text" - app:srcCompat="@drawable/ic_message" /> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/departure.xml b/app/src/main/res/layout/departure.xml new file mode 100644 index 0000000000000000000000000000000000000000..dc95cff290d969279967a19552d8e2a10722323e --- /dev/null +++ b/app/src/main/res/layout/departure.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:id="@+id/departure" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/line_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginStart="8dp" + app:layout_constraintBottom_toTopOf="@+id/departure_headsign" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@+id/departure_time" + tool:srcCompat="@drawable/bus_black" + tool:ignore="ContentDescription" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/departure_time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:text="1hr" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/departure_line" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + app:layout_constraintStart_toEndOf="@+id/line_icon" + app:layout_constraintTop_toTopOf="parent" + tool:text="Metropolitan" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/departure_headsign" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.Material3.BodySmall" + app:layout_constraintStart_toStartOf="@+id/departure_line" + app:layout_constraintTop_toBottomOf="@+id/departure_line" + tool:text="» Tower Hill" /> + + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/departure_bottom_sheet.xml b/app/src/main/res/layout/departure_bottom_sheet.xml new file mode 100644 index 0000000000000000000000000000000000000000..0eb2ee87737e2abcc637c176d0f78a0fef6e1a8f --- /dev/null +++ b/app/src/main/res/layout/departure_bottom_sheet.xml @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="16dp"> + + <com.google.android.material.bottomsheet.BottomSheetDragHandleView + android:id="@+id/drag_handle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="48dp" + android:textAppearance="@style/TextAppearance.Material3.DisplaySmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:text="at 12:10:30" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/offset" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="4dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + android:visibility="gone" + app:layout_constraintBaseline_toBaselineOf="@+id/time" + app:layout_constraintStart_toEndOf="@+id/time" + tool:text="(+2 min)" /> + + <ImageView + android:id="@+id/rt_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginStart="16dp" + android:contentDescription="@string/realtime_content_description" + app:layout_constraintBottom_toBottomOf="@+id/time" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@+id/time" + app:srcCompat="@drawable/radar" /> + + <ImageView + android:id="@+id/wheelchair_icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_marginStart="8dp" + android:contentDescription="@string/wheelchair_content_description" + app:layout_constraintStart_toEndOf="@id/rt_icon" + app:layout_constraintTop_toTopOf="@+id/rt_icon" + app:srcCompat="@drawable/wheelchair" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/line" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/time" /> + + <ImageView + android:id="@+id/boarding_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/boarding_text" + app:layout_constraintEnd_toStartOf="@+id/boarding_text" + app:layout_constraintTop_toTopOf="@+id/boarding_text" + app:srcCompat="@drawable/transfer" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/boarding_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="180dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toEndOf="@id/middle" + app:layout_constraintTop_toTopOf="parent" + tool:text="on demand" /> + + <ImageView + android:id="@+id/speed_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/speed_text" + app:layout_constraintEnd_toStartOf="@+id/speed_text" + app:layout_constraintTop_toTopOf="@+id/speed_text" + app:srcCompat="@drawable/speed" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/speed_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toStartOf="@+id/middle" + app:layout_constraintTop_toBottomOf="@id/boarding_text" + tool:text="10 Vl" /> + + <ImageView + android:id="@+id/congestion_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/congestion_text" + app:layout_constraintStart_toStartOf="@+id/middle" + app:layout_constraintTop_toTopOf="@+id/congestion_text" + app:srcCompat="@drawable/traffic" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/congestion_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="180dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintStart_toEndOf="@id/congestion_icon" + app:layout_constraintTop_toTopOf="parent" + tool:text="smooth traffic" /> + + <ImageView + android:id="@+id/occupancy_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/occupancy_text" + app:layout_constraintStart_toStartOf="@+id/middle" + app:layout_constraintTop_toTopOf="@+id/occupancy_text" + app:srcCompat="@drawable/crowd" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/occupancy_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintStart_toEndOf="@id/occupancy_icon" + app:layout_constraintTop_toBottomOf="@id/congestion_text" + tool:text="empty vehicle" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/middle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_percent=".5" /> + + <androidx.constraintlayout.helper.widget.Flow + android:id="@+id/capabilities" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="8dp" + app:constraint_referenced_ids="ac,bike,voice,ticket,usb" + app:flow_horizontalGap="4dp" + app:flow_horizontalStyle="packed" + app:flow_verticalGap="4dp" + app:flow_wrapMode="chain" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/occupancy_text" /> + + <ImageView + android:id="@+id/ac" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/air_condition_content_description" + app:srcCompat="@drawable/ac" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/bike" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/bicycles_allowed_content_description" + app:srcCompat="@drawable/bike" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/voice" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/voice_announcements_content_description" + app:srcCompat="@drawable/voice" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/ticket" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/tickets_sold_content_description" + app:srcCompat="@drawable/ticket" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/usb" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/usb_charging_content_description" + app:srcCompat="@drawable/usb" + tool:ignore="MissingConstraints" /> + + <org.osmdroid.views.MapView + android:id="@+id/map" + android:layout_width="match_parent" + android:layout_height="250dp" + android:layout_margin="16dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/capabilities" /> +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/feed_bottom_sheet.xml b/app/src/main/res/layout/feed_bottom_sheet.xml new file mode 100644 index 0000000000000000000000000000000000000000..41e7751df918a60fbb5f4f62925ae1705581ca86 --- /dev/null +++ b/app/src/main/res/layout/feed_bottom_sheet.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingBottom="16dp"> + + <com.google.android.material.bottomsheet.BottomSheetDragHandleView + android:id="@+id/drag_handle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/title" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="48dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.DisplaySmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:text="Poznań ZTM" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/description" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/title" + tool:text="Feed for Poznań" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/attribution" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.BodyMedium" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/description" + tool:text="(c) Poznań" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/update_time" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.BodyMedium" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/attribution" + tool:text="Last update: 2023-01-01" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/feedinfo.xml b/app/src/main/res/layout/feedinfo.xml new file mode 100644 index 0000000000000000000000000000000000000000..26ed2b036981ea9db8718aa65d08cde15b330ffe --- /dev/null +++ b/app/src/main/res/layout/feedinfo.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/feed" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/feed_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:layout_marginBottom="16dp" + android:text="" + android:textAppearance="@style/TextAppearance.Material3.HeadlineMedium" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.materialswitch.MaterialSwitch + android:id="@+id/feed_switch" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" + android:text="" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml new file mode 100644 index 0000000000000000000000000000000000000000..6ace86db683233a7d0443fe2e126f2cb19cbe25b --- /dev/null +++ b/app/src/main/res/layout/fragment_home.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:tag="@string/title_home" + tool:context="xyz.apiote.bimba.czwek.dashboard.ui.home.HomeFragment"> + + <com.mancj.materialsearchbar.MaterialSearchBar + android:id="@+id/search_bar" + style="@style/Theme.Bimba.SearchBar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:mt_hint="" + app:mt_navIconEnabled="true" + app:mt_placeholder="@string/search_placeholder" + app:mt_roundedSearchBarEnabled="true" /> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/floating_action_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:contentDescription="@string/home_fab_description" + android:src="@drawable/gps_black" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" /> + + <ImageView + android:id="@+id/inari" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginStart="16dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" + android:alpha="0.25" + android:src="@drawable/inari" + app:layout_constraintBottom_toTopOf="@+id/floating_action_button" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/search_bar" + tool:ignore="ContentDescription" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_line_specify.xml b/app/src/main/res/layout/fragment_line_specify.xml deleted file mode 100644 index 1a630b9bd7f0c510d4405a24e72d7d6f3b40249b..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/fragment_line_specify.xml +++ /dev/null @@ -1,22 +0,0 @@ -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/constraintLayout" - android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context="ml.adamsprogs.bimba.activities.LineSpecifyActivity$PlaceholderFragment"> - - <TextView - android:id="@+id/section_label" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/activity_vertical_margin" - android:layout_marginEnd="@dimen/activity_horizontal_margin" - android:layout_marginStart="@dimen/activity_horizontal_margin" - android:layout_marginTop="@dimen/activity_vertical_margin" - app:layout_constraintLeft_toLeftOf="parent" - app:layout_constraintTop_toTopOf="@+id/constraintLayout" - tools:layout_constraintLeft_creator="1" - tools:layout_constraintTop_creator="1" /> - -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_map.xml b/app/src/main/res/layout/fragment_map.xml new file mode 100644 index 0000000000000000000000000000000000000000..a7e78704ab09536045868577128dfd17f0323a63 --- /dev/null +++ b/app/src/main/res/layout/fragment_map.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tool:context="xyz.apiote.bimba.czwek.dashboard.ui.map.MapFragment"> + + <org.osmdroid.views.MapView + android:id="@+id/map" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/floating_action_button" + style="?attr/floatingActionButtonSmallStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:contentDescription="@string/home_fab_description" + android:src="@drawable/gps_black" /> +</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_voyage.xml b/app/src/main/res/layout/fragment_voyage.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f62cca177204072a86e1efc21078da574c0aded --- /dev/null +++ b/app/src/main/res/layout/fragment_voyage.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tool:context="xyz.apiote.bimba.czwek.dashboard.ui.voyage.VoyageFragment"> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/text_dashboard" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textSize="20sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/map_bottom_sheet.xml b/app/src/main/res/layout/map_bottom_sheet.xml new file mode 100644 index 0000000000000000000000000000000000000000..ee43994f8c22280a3fda028fd21149ee94138d3b --- /dev/null +++ b/app/src/main/res/layout/map_bottom_sheet.xml @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="16dp"> + + <com.google.android.material.bottomsheet.BottomSheetDragHandleView + android:id="@+id/drag_handle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" /> + + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/title" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="48dp" + android:layout_marginEnd="8dp" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <androidx.constraintlayout.widget.Group + android:id="@+id/stop_group" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:constraint_referenced_ids="change_options,departures_button,navigation_button" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/change_options" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:textAppearance="@style/TextAppearance.Material3.BodyMedium" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/title" /> + + <Button + android:id="@+id/departures_button" + style="@style/Widget.Material3.Button.TextButton.Icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="4dp" + android:text="@string/show_departures" + app:icon="@drawable/departure" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/change_options" /> + + <Button + android:id="@+id/navigation_button" + style="@style/Widget.Material3.Button.TextButton.Icon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_margin="4dp" + android:text="@string/open_in_maps_app" + app:icon="@drawable/open_outside" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/departures_button" /> + + <androidx.constraintlayout.widget.Group + android:id="@+id/vehicle_group" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:constraint_referenced_ids="speed_icon,speed_text,congestion_icon,congestion_text,occupancy_icon,occupancy_text,ac,bike,voice,ticket,usb" /> + + <ImageView + android:id="@+id/speed_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/speed_text" + app:layout_constraintEnd_toStartOf="@+id/speed_text" + app:layout_constraintTop_toTopOf="@+id/speed_text" + app:srcCompat="@drawable/speed" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/speed_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintEnd_toStartOf="@+id/middle" + app:layout_constraintTop_toBottomOf="@id/title" + tool:text="10 Vl" /> + + <ImageView + android:id="@+id/congestion_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/congestion_text" + app:layout_constraintStart_toStartOf="@+id/middle" + app:layout_constraintTop_toTopOf="@+id/congestion_text" + app:srcCompat="@drawable/traffic" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/congestion_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintStart_toEndOf="@id/congestion_icon" + app:layout_constraintTop_toBottomOf="@id/title" + tool:text="smooth traffic" /> + + <ImageView + android:id="@+id/occupancy_icon" + android:layout_width="16dp" + android:layout_height="16dp" + android:layout_marginStart="8dp" + android:layout_marginEnd="8dp" + android:importantForAccessibility="no" + app:layout_constraintBottom_toBottomOf="@+id/occupancy_text" + app:layout_constraintStart_toStartOf="@+id/middle" + app:layout_constraintTop_toTopOf="@+id/occupancy_text" + app:srcCompat="@drawable/crowd" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/occupancy_text" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:textAppearance="@style/TextAppearance.Material3.BodyLarge" + app:layout_constraintStart_toEndOf="@id/occupancy_icon" + app:layout_constraintTop_toBottomOf="@id/congestion_text" + tool:text="empty vehicle" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/middle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintGuide_percent=".5" /> + + <androidx.constraintlayout.helper.widget.Flow + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="16dp" + android:layout_marginEnd="8dp" + app:constraint_referenced_ids="ac,bike,voice,ticket,usb" + app:flow_horizontalGap="4dp" + app:flow_horizontalStyle="packed" + app:flow_verticalGap="4dp" + app:flow_wrapMode="chain" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/occupancy_text" /> + + <ImageView + android:id="@+id/ac" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/air_condition_content_description" + app:srcCompat="@drawable/ac" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/bike" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/bicycles_allowed_content_description" + app:srcCompat="@drawable/bike" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/voice" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/voice_announcements_content_description" + app:srcCompat="@drawable/voice" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/ticket" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/tickets_sold_content_description" + app:srcCompat="@drawable/ticket" + tool:ignore="MissingConstraints" /> + + <ImageView + android:id="@+id/usb" + android:layout_width="24dp" + android:layout_height="24dp" + android:contentDescription="@string/usb_charging_content_description" + app:srcCompat="@drawable/usb" + tool:ignore="MissingConstraints" /> + + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/app/src/main/res/layout/result.xml b/app/src/main/res/layout/result.xml new file mode 100644 index 0000000000000000000000000000000000000000..01fcf7e803bb9022ef16c39446fc50f1d5814e0c --- /dev/null +++ b/app/src/main/res/layout/result.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:id="@+id/suggestion" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <ImageView + android:id="@+id/suggestion_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:ignore="ContentDescription" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/suggestion_title" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:text="" + android:textAppearance="@style/Theme.Bimba.SearchResult.Title" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/suggestion_image" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/suggestion_description" + style="@style/Theme.Bimba.SearchResult.Description" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginEnd="8dp" + android:text="" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="@+id/suggestion_title" + app:layout_constraintTop_toBottomOf="@+id/suggestion_title" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/row_departure.xml b/app/src/main/res/layout/row_departure.xml deleted file mode 100644 index 97799f72f76c48eaf9c07f349817cb8f5540494c..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/row_departure.xml +++ /dev/null @@ -1,90 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/departureRow" - android:layout_width="match_parent" - android:layout_height="wrap_content" - tools:layout_editor_absoluteX="0dp" - tools:layout_editor_absoluteY="25dp"> - - <TextView - android:id="@+id/lineNumber" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginBottom="8dp" - android:layout_marginEnd="16dp" - android:layout_marginStart="16dp" - android:layout_marginTop="8dp" - android:text="" - android:textAppearance="@style/TextAppearance.AppCompat.Title" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/departureTime" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <ImageView - android:id="@+id/departureTypeIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:contentDescription="@string/departure_type_icon_description" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/departureTime" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="64dp" - android:layout_marginTop="8dp" - android:text="@string/departure_row_getting_departures" - android:textAppearance="@style/TextAppearance.AppCompat.Headline" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/departureDirection" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="8dp" - android:text="" - app:layout_constraintStart_toStartOf="@+id/departureTime" - app:layout_constraintTop_toBottomOf="@+id/departureTime" /> - - <ImageView - android:id="@+id/departureInfoIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/departure_info" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/departureFloorIcon" - app:srcCompat="@drawable/ic_info" /> - - <ImageView - android:id="@+id/departureFloorIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/departure_floor" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:srcCompat="@drawable/ic_low_floor" /> - - <ImageView - android:id="@+id/ticketMachineIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/ticket_machine_icon" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/departureInfoIcon" /> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/row_favourite.xml b/app/src/main/res/layout/row_favourite.xml deleted file mode 100644 index 55f434bf6bf45f264e38c57fcacc3713a855de5a..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/row_favourite.xml +++ /dev/null @@ -1,106 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - android:id="@+id/favourite_card" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_margin="4dp" - android:foreground="?android:attr/selectableItemBackground" - tools:layout_editor_absoluteX="8dp" - tools:layout_editor_absoluteY="128dp"> - - <View - android:id="@+id/selected_overlay" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:background="@color/colorAccent" - android:visibility="invisible" /> - - <androidx.constraintlayout.widget.ConstraintLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <TextView - android:id="@+id/favourite_name" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="21dp" - android:text="" - android:textAppearance="@style/TextAppearance.AppCompat.Subhead" - app:layout_constraintStart_toStartOf="@+id/favourite_time" - app:layout_constraintTop_toTopOf="parent" - tools:layout_editor_absoluteX="16dp" - tools:layout_editor_absoluteY="21dp" /> - - <TextView - android:id="@+id/favourite_time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:ellipsize="end" - android:text="@string/loading" - android:textAppearance="@style/TextAppearance.AppCompat.Headline" - app:layout_constraintStart_toStartOf="@+id/favourite_line" - app:layout_constraintTop_toBottomOf="@+id/favourite_name" /> - - <TextView - android:id="@+id/favourite_line" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="16dp" - android:ellipsize="end" - android:text="" - android:textAppearance="@style/TextAppearance.AppCompat.Subhead" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/ticketMachineIcon" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/favourite_time" /> - - <ImageView - android:id="@+id/departureTypeIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/departure_type_icon_description" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" /> - - <ImageView - android:id="@+id/departureFloorIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/departure_floor" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/departureTypeIcon" - app:srcCompat="@drawable/ic_low_floor" /> - - <ImageView - android:id="@+id/ticketMachineIcon" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginEnd="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/ticket_machine_icon" - android:visibility="gone" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/departureFloorIcon" /> - - <ImageView - android:id="@+id/favourite_more_button" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="8dp" - android:contentDescription="@string/favourite_row_more_button" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:srcCompat="@drawable/ic_more" /> - </androidx.constraintlayout.widget.ConstraintLayout> - -</androidx.cardview.widget.CardView> \ No newline at end of file diff --git a/app/src/main/res/layout/row_favourite_edit.xml b/app/src/main/res/layout/row_favourite_edit.xml deleted file mode 100644 index 18e99b529d051bc5490f8f6826e8e9acbbdd8568..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/row_favourite_edit.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical"> - - - <TextView - android:id="@+id/favourite_edit_row" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="16dp" - android:layout_marginEnd="16dp" - android:layout_marginBottom="16dp" - android:text="" - android:textAlignment="viewStart" - android:textAppearance="@style/TextAppearance.AppCompat" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toStartOf="@+id/favourite_edit_delete" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <ImageView - android:id="@+id/favourite_edit_delete" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginTop="16dp" - android:layout_marginEnd="8dp" - android:layout_marginBottom="16dp" - android:contentDescription="@string/favourite_element_delete_button" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintTop_toTopOf="parent" - app:srcCompat="@drawable/ic_delete" /> - -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/row_shed.xml b/app/src/main/res/layout/row_shed.xml deleted file mode 100644 index 4be60699faeef456d8a654e9e1133d9debe00f1a..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/row_shed.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/shed_row" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_margin="4dp" - android:foreground="?android:attr/selectableItemBackground" - app:cardElevation="2dp"> - - <androidx.constraintlayout.widget.ConstraintLayout - android:layout_width="match_parent" - android:layout_height="match_parent"> - - <TextView - android:id="@+id/stop_code" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:text="" - android:textAppearance="@style/TextAppearance.AppCompat.Headline" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/stop_headlines" - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_marginBottom="6dp" - android:layout_marginEnd="8dp" - android:layout_marginStart="8dp" - android:layout_marginTop="6dp" - android:text="" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@+id/stop_code" /> - </androidx.constraintlayout.widget.ConstraintLayout> -</androidx.cardview.widget.CardView> \ No newline at end of file diff --git a/app/src/main/res/layout/row_suggestion.xml b/app/src/main/res/layout/row_suggestion.xml deleted file mode 100644 index 6c2b77d5f75e48124c32f4a5c74d57c598a50067..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/row_suggestion.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - android:id="@+id/row_suggestion" - android:layout_width="match_parent" - android:layout_height="48dp" - android:foreground="?android:attr/selectableItemBackground" - android:orientation="vertical"> - - - <ImageView - android:id="@+id/suggestion_row_image" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:layout_marginBottom="8dp" - android:contentDescription="@string/suggestion_row_image" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - - <TextView - android:id="@+id/suggestion_row_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_marginStart="8dp" - android:layout_marginTop="8dp" - android:text="" - android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title" - app:layout_constraintStart_toEndOf="@+id/suggestion_row_image" - app:layout_constraintTop_toTopOf="parent" /> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/suggestion.xml b/app/src/main/res/layout/suggestion.xml new file mode 100644 index 0000000000000000000000000000000000000000..1d681d33fae944bf52f8243a589aab9b1aefdcce --- /dev/null +++ b/app/src/main/res/layout/suggestion.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:id="@+id/suggestion" + android:layout_width="match_parent" + android:layout_height="72dp"> + + <ImageView + android:id="@+id/suggestion_image" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginBottom="8dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + tool:ignore="ContentDescription" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/suggestion_title" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:text="" + android:textAppearance="@style/Theme.Bimba.SearchResult.Title" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toEndOf="@+id/suggestion_image" + app:layout_constraintTop_toTopOf="parent" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/suggestion_description" + style="@style/Theme.Bimba.SearchResult.Description" + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_marginEnd="8dp" + android:ellipsize="end" + android:maxLines="4" + android:text="" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="@+id/suggestion_title" + app:layout_constraintTop_toBottomOf="@+id/suggestion_title" /> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/app/src/main/res/layout/toolbar_spinner_item.xml b/app/src/main/res/layout/toolbar_spinner_item.xml deleted file mode 100644 index 1cb3890d88df2edaeec0cf238d7d7afb271c3f9c..0000000000000000000000000000000000000000 --- a/app/src/main/res/layout/toolbar_spinner_item.xml +++ /dev/null @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<TextView xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/text" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:ellipsize="end" - android:singleLine="true" - android:textAlignment="inherit" - android:textColor="@color/text_on_toolbar" /> diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml new file mode 100644 index 0000000000000000000000000000000000000000..3631e523fcafffa65395d79c36b61911ef55aeda --- /dev/null +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/navigation_map" + android:icon="@drawable/map_outline" + android:title="@string/title_map" /> + <item + android:id="@+id/navigation_home" + android:icon="@drawable/home_outline" + android:title="@string/title_home" /> + <!-- todo [voyage planning] + <item + android:id="@+id/navigation_voyage" + android:icon="@drawable/voyage_outline" + android:title="@string/title_voyage" />--> +</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/drawer.xml b/app/src/main/res/menu/drawer.xml new file mode 100644 index 0000000000000000000000000000000000000000..1b5fd35ca8d68a9c9a1937534cd1188ab25e7703 --- /dev/null +++ b/app/src/main/res/menu/drawer.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:id="@+id/drawer_feeds" + android:title="@string/title_feeds"> + <menu> + <item + android:id="@+id/drawer_servers" + android:checkable="true" + android:icon="@drawable/feeds_servers" + android:title="@string/title_servers" /> + <item + android:id="@+id/drawer_cities" + android:checkable="true" + android:icon="@drawable/feeds_cities" + android:title="@string/title_cities" /> + </menu> + </item> + <!-- other settings --> +</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/favourite_actions.xml b/app/src/main/res/menu/favourite_actions.xml deleted file mode 100644 index bf229e060737d7e460e0ce3529001eec33b63c61..0000000000000000000000000000000000000000 --- a/app/src/main/res/menu/favourite_actions.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android"> - <item - android:id="@+id/favourite_edit" - android:orderInCategory="100" - android:title="@string/action_edit" /> - <item - android:id="@+id/favourite_delete" - android:orderInCategory="200" - android:title="@string/action_delete" /> -</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_drawer.xml b/app/src/main/res/menu/menu_drawer.xml deleted file mode 100644 index 97188f56a4a54264e7c38e98989bbe959d299c4e..0000000000000000000000000000000000000000 --- a/app/src/main/res/menu/menu_drawer.xml +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android"> - <!--<group android:id="@+id/drawer_group_activities"> - <item - android:id="@+id/drawer_home" - android:icon="@drawable/ic_home" - android:title="@string/home" /> - </group>--> - <group> - <item - android:id="@+id/drawer_refresh" - android:icon="@drawable/ic_refresh" - android:title="@string/refresh" /> - <!--<item - android:id="@+id/drawer_help" - android:icon="@drawable/ic_help" - android:title="@string/help" />--> - <item - android:id="@+id/drawer_settings" - android:icon="@drawable/ic_settings" - android:title="@string/settings" - /> - </group> - <group android:enabled="false"> - <item - android:id="@+id/drawer_validity_since" - android:title="" /> - <item - android:id="@+id/drawer_validity_till" - android:title="" /> - </group> -</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_favourite_merge.xml b/app/src/main/res/menu/menu_favourite_merge.xml deleted file mode 100644 index 9342fb336b87d362d276538d787572c1e907dc59..0000000000000000000000000000000000000000 --- a/app/src/main/res/menu/menu_favourite_merge.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto"> - <item - android:id="@+id/action_merge" - android:orderInCategory="100" - android:title="@string/action_merge" - android:icon="@drawable/ic_merge" - app:showAsAction="always" /> -</menu> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_stop.xml b/app/src/main/res/menu/menu_stop.xml deleted file mode 100644 index f5eeafa161d8425f01c97b62b4816477ecc797e0..0000000000000000000000000000000000000000 --- a/app/src/main/res/menu/menu_stop.xml +++ /dev/null @@ -1,11 +0,0 @@ -<menu xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" - tools:context="ml.adamsprogs.bimba.activities.StopActivity"> - <item - android:id="@+id/action_change_type" - android:orderInCategory="100" - android:title="@string/action_change_type" - android:icon="@drawable/ic_timetable_full" - app:showAsAction="always" /> -</menu> diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index f26e79972c16204e3c29ca8686c84c8e17047863..a9744c7cd4682fe9080a4a27e8f4859f501f06eb 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 1ef879eb9735fc3de899f011625881cf535c711b..6364fe6da49d9ff739c08de256cb37a4d8a5c5b0 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 97892c1a73464d78ebaf32f6b008b36c92b85d38..d19adfb1c0fa38628e439d78e6262243a6df3910 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 201d7b04f97aed589ad7c6f6c53cb414a9504572..c1c8209e7415618e90b871ba3e74dfb25a1d9e7d 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 1754a35d58a6965a198441317a9f2bea4280f512..7d9006cfca07b8dfc460bf137eae0b166a20cbfd 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index ce24ee2d42727940dcba4567849562839530a27b..b242332300544ba52b80329f9dc7fe9973714a57 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 1029f94018ee1f94f43dc68e45ebdcca7ae67dbd..03b6b50be1b0316ed59ff6ef31113213b3741e6f 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 79dded633e2021ec81e58e7be6aa4bed5a564940..a5286e592e3f3f3fa753ac4ed58e177081a4ffde 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index d3b73fa5e4376f81d9e7dc824cf87993fca770e8..0ffae16cd06387530a542a006f798ae1e9a04f32 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 1586dc63387afea8dcc76f31f0d51bab07308a12..2fc5cda344d134cde5c05927ae56b0b98e1f8cff 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/navigation/front_navigation.xml b/app/src/main/res/navigation/front_navigation.xml new file mode 100644 index 0000000000000000000000000000000000000000..7dd5662bedc71ec157a816703d9b2402048f5186 --- /dev/null +++ b/app/src/main/res/navigation/front_navigation.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<navigation xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tool="http://schemas.android.com/tools" + android:id="@+id/front_navigation" + app:startDestination="@+id/navigation_home"> + + <fragment + android:id="@+id/navigation_home" + android:name="xyz.apiote.bimba.czwek.dashboard.ui.home.HomeFragment" + android:label="@string/title_home" + tool:layout="@layout/fragment_home" /> + + <fragment + android:id="@+id/navigation_map" + android:name="xyz.apiote.bimba.czwek.dashboard.ui.map.MapFragment" + android:label="@string/title_map" + tool:layout="@layout/fragment_map" /> + + <fragment + android:id="@+id/navigation_voyage" + android:name="xyz.apiote.bimba.czwek.dashboard.ui.voyage.VoyageFragment" + android:label="@string/title_voyage" + tool:layout="@layout/fragment_voyage" /> +</navigation> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 1837105e06b078e212608ec54f3543aeacafedb1..d715893aa6f22b49f7237f704316c3c47ed9c19e 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,21 +1,77 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <color name="colorPrimary">#3a3a3b</color> - <color name="colorPrimaryDark">#141415</color> - <color name="colorAccent">#54af39</color> - <color name="colorAccentDark">#197f00</color> - <color name="colorAccent2">#be7e3e</color> + <color name="bimba_grey">#3a3a3b</color> + <color name="bimba_grey_dark">#141415</color> + <color name="bimba_green">#54af39</color> + <color name="bimba_green_container">#9afa79</color> + <color name="bimba_green_container_text">#032100</color> + <color name="bimba_green_dark">#197f00</color> + <color name="bimba_orange">#be7e3e</color> + <color name="black">#FF000000</color> + <color name="white">#FFFFFFFF</color> - <color name="zoneA">#00a650</color> - <color name="zoneB">#ed1c24</color> - <color name="zoneC">#ffc107</color> + <color name="seed">#54af39</color> + <color name="md_theme_light_primary">#1A6D00</color> <!-- 40 --> + <color name="md_theme_light_onPrimary">#FFFFFF</color> <!-- 100 --> + <color name="md_theme_light_primaryContainer">#9AFA79</color> <!-- 90 --> + <color name="md_theme_light_onPrimaryContainer">#032100</color> <!-- 10 --> + <color name="md_theme_light_secondary">#6A5F00</color> <!-- 40 --> + <color name="md_theme_light_onSecondary">#FFFFFF</color> <!-- 100 --> + <color name="md_theme_light_secondaryContainer">#F9E447</color> <!-- 90 --> + <color name="md_theme_light_onSecondaryContainer">#201C00</color> <!-- 10 --> + <color name="md_theme_light_tertiary">#8C4F00</color> <!-- 40 --> + <color name="md_theme_light_onTertiary">#FFFFFF</color> <!-- 100 --> + <color name="md_theme_light_tertiaryContainer">#FFDCC0</color> <!-- 90 --> + <color name="md_theme_light_onTertiaryContainer">#2D1600</color> <!-- 10 --> - <color name="tram">#00adef</color> - <color name="bus">#c4212a</color> - <color name="text_on_toolbar">#ffffff</color> + <color name="md_theme_light_error">#BA1A1A</color> + <color name="md_theme_light_errorContainer">#FFDAD6</color> + <color name="md_theme_light_onError">#FFFFFF</color> + <color name="md_theme_light_onErrorContainer">#410002</color> - <color name="textDark">#de000000</color> - <color name="textDarkMedium">#99000000</color> - <color name="textDarkDisabled">#45000000</color> - <color name="cardColor">#ffffff</color> -</resources> + <color name="md_theme_light_background">#FCFCFF</color> <!-- primary 99 --> + <color name="md_theme_light_onBackground">#001D33</color> <!-- primary 10 --> + <color name="md_theme_light_surface">#FCFCFF</color> <!-- primary 99 --> + <color name="md_theme_light_onSurface">#001D33</color> <!-- primary 10 --> + <color name="md_theme_light_surfaceVariant">#DFE4D7</color> <!-- neutral 90 --> + <color name="md_theme_light_onSurfaceVariant">#43483F</color> <!-- neutral 30 --> + <color name="md_theme_light_outline">#73796E</color> <!-- neutral 50 --> + <color name="md_theme_light_inverseOnSurface">#E8F2FF</color> <!-- neutral 95 --> + <color name="md_theme_light_inverseSurface">#003353</color> <!-- neutral 20 --> + <color name="md_theme_light_inversePrimary">#7FDC60</color> <!-- 80 --> + <color name="md_theme_light_shadow">#000000</color> <!-- 0 --> + <color name="md_theme_light_surfaceTint">#1A6D00</color> <!-- primary 40 --> + <color name="md_theme_light_surfaceTintColor">#1A6D00</color> <!-- primary 40 --> + + <color name="md_theme_dark_primary">#7FDC60</color> <!-- 80 --> + <color name="md_theme_dark_onPrimary">#093900</color> <!-- 20 --> + <color name="md_theme_dark_primaryContainer">#115300</color> <!-- 30 --> + <color name="md_theme_dark_onPrimaryContainer">#9AFA79</color> <!-- 90 --> + <color name="md_theme_dark_secondary">#DCC82A</color> <!-- 80 --> + <color name="md_theme_dark_onSecondary">#373100</color> <!-- 20 --> + <color name="md_theme_dark_secondaryContainer">#504700</color> <!-- 30 --> + <color name="md_theme_dark_onSecondaryContainer">#F9E447</color> <!-- 90 --> + <color name="md_theme_dark_tertiary">#FFB875</color> <!-- 80 --> + <color name="md_theme_dark_onTertiary">#4B2800</color> <!-- 20 --> + <color name="md_theme_dark_tertiaryContainer">#6B3B00</color> <!-- 30 --> + <color name="md_theme_dark_onTertiaryContainer">#FFDCC0</color> <!-- 90 --> + + <color name="md_theme_dark_error">#FFB4AB</color> + <color name="md_theme_dark_errorContainer">#93000A</color> + <color name="md_theme_dark_onError">#690005</color> + <color name="md_theme_dark_onErrorContainer">#FFDAD6</color> + + <color name="md_theme_dark_background">#001D33</color> <!-- primary 10 --> + <color name="md_theme_dark_onBackground">#CEE5FF</color> <!-- primary 90 --> + <color name="md_theme_dark_surface">#001D33</color> <!-- primary 10 --> + <color name="md_theme_dark_onSurface">#CEE5FF</color> <!-- primary 90 --> + <color name="md_theme_dark_surfaceVariant">#43483F</color> <!-- neutral 30 --> + <color name="md_theme_dark_onSurfaceVariant">#C3C8BC</color> <!-- --> + <color name="md_theme_dark_outline">#8D9387</color> <!-- unused --> + <color name="md_theme_dark_inverseOnSurface">#001D33</color> <!-- primary 10 --> + <color name="md_theme_dark_inverseSurface">#CEE5FF</color> <!-- primary 90 --> + <color name="md_theme_dark_inversePrimary">#1A6D00</color> <!-- primary 40 --> + <color name="md_theme_dark_shadow">#000000</color> <!-- 0 --> + <color name="md_theme_dark_surfaceTint">#7FDC60</color> <!-- primary 80 --> + <color name="md_theme_dark_surfaceTintColor">#7FDC60</color> <!-- primary 80 --> +</resources> \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml deleted file mode 100644 index d1cd0246f80ac882c028743baba512892ebf7262..0000000000000000000000000000000000000000 --- a/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ -<resources> - <dimen name="activity_horizontal_margin">16dp</dimen> - <dimen name="activity_vertical_margin">16dp</dimen> - <dimen name="fab_margin">16dp</dimen> - <dimen name="appbar_padding_top">8dp</dimen> -</resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 658e61ad08d71e4210f3055d01d01be567e76430..f32859adeab279291dc0da8294a9124ae7224571 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,76 +1,87 @@ <resources> - <string name="app_name" translatable="false">Bimba</string> - <string name="timetable_downloaded">New timetable downloaded</string> - <string name="title_activity_stop" translatable="false">StopActivity</string> - <string name="action_change_type">Type</string> - <string name="departure_type_icon_description" translatable="false">departure type (timetable, VM)</string> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">At %1$s</string> - <string name="timetable_downloading">Downloading timetable</string> - <string name="timetable_downloading_progress" translatable="false">%1$1.2f MiB/%2$1.2f MiB</string> - <string name="timetable_decompressing">Decompressing timetable</string> - <string name="search_placeholder">Stop…</string> - <string name="no_connectivity_cant_update">No connectivity – can’t update timetable</string> - <string name="no_connectivity">No connectivity</string> - <string name="timetable_up_to_date">Timetable is up-to-date</string> - <string name="error_try_later">Error. Try again later</string> - <string name="now">Now</string> - <string name="stop_already_fav">This stop is already in favourites</string> - <string name="favourite_row_more_button" translatable="false">favourite row more button</string> - <string name="action_edit">Edit</string> - <string name="action_delete">Delete</string> - <string name="favourite_name">Favourite name</string> - <string name="edit_favourite_title">Edit ‘%1$s’</string> - <string name="favourite_element_delete_button" translatable="false">favourite element delete button</string> - <string name="no_next_departure">No next departure</string> - <string name="action_merge">Merge</string> - <string name="merge_favourites">Merge favourites</string> - <string name="loading">Loading…</string> - <string name="departure_in__singular_genitive">In %1$s minute</string> - <string name="departure_in__plural_genitive">In %1$s minutes</string> - <string name="departure_in__plural_nominative">In %1$s minutes</string> - - <string name="refresh">Update timetable</string> - <string name="title_activity_help">Help</string> - <string name="departure_row_getting_departures">Getting departures…</string> - <string name="valid_since">Valid since %1$s</string> - <string name="valid_till">Valid till %1$s</string> - <string name="departure_floor" translatable="false">departure floor type (lowFloor)</string> - <string name="departure_info" translatable="false">departure info icon</string> - - <string name="no_departures">No departures</string> - <string name="title_activity_main" translatable="false">LineSpecifyActivity</string> - <string name="tab_text_line_to">To</string> - <string name="tab_text_line_fro">Fro</string> - <string name="timetable_validity_finished">Timetable validity has ended. Connect to the Internet to download a new one in order to continue.</string> - <string name="timetable_validity_today">Timetable validity ends today.</string> - <string name="timetable_validity_tomorrow">Timetable validity ends tomorrow.</string> - <string name="just_departed">Just departed</string> - <string name="validity_offline_unavailable">Offline timetable unavailable</string> - <string name="pref_category_timetable">Timetable</string> - <string name="timetable_source_url" translatable="false">https://bimba.tk/gtfs</string> - <string name="key_timetable_source_url" translatable="false">key_timetable_source_url</string> - <string name="title_timetable_source_url">Timetable source</string> - <string name="title_activity_settings">Settings</string> - <string name="settings">Settings</string> - <string name="key_timetable_automatic_update" translatable="false">key_timetable_automatic_update</string> - <string name="title_timetable_automatic_update">Automatic updates</string> - - <string name="Mon">Mon</string> - <string name="Tue">Tue</string> - <string name="Wed">Wed</string> - <string name="Thu">Thu</string> - <string name="Fri">Fri</string> - <string name="Sat">Sat</string> - <string name="Sun">Sun</string> - <string name="summary_timetable_automatic_update">Automatically check for and download timetable updates</string> - <string name="server_error">Server error</string> - <string name="suggestion_row_image" translatable="false">suggestion row image</string> - <string name="nothing_found">Not found</string> - <string name="departures_empty_state_icon" translatable="false">departures empty state icon</string> - <string name="in_a_moment">In a moment</string> - <string name="more">More</string> - <string name="vm_message_icon" translatable="false">vm message icon</string> - <string name="ticket_machine_icon" translatable="false">ticket machine icon</string> -</resources> + <string name="app_name">Bimba</string> + <string name="title_home">Home</string> + <string name="title_map">Map</string> + <string name="title_voyage">Voyage</string> + <string name="home_fab_description">GPS icon</string> + <string name="search_placeholder">Search stops and lines</string> + <string name="title_activity_results">Results</string> + <string name="cont">Continue</string> + <string name="save">Save</string> + <string name="error_400">The application made a malformed request</string> + <string name="error_401">A token is needed to use this server</string> + <string name="error_403">The token you provided is incorrect</string> + <string name="error_404">Not found</string> + <string name="error_429">Rate limit exceeded. Try again later</string> + <string name="error_50x">There was an error on the sever. Try again later</string> + <string name="error_unknown">Unknown error happened</string> + <string name="error_connecting">Error connecting to the server. Try again later</string> <!-- send a bug report to bimba@git.apiote.xyz, details are: url=$URL, response=$response --> + <string name="error_offline">You are offline. Connect to the Internet</string> + <string name="error_gps">Cannot obtain location</string> + <string name="no_departures">No departures</string> + <string name="waiting_position">waiting for position</string> + <string name="vehicle_headsign">%s » %s</string> + <string name="vehicle_headsign_content_description">%s towards %s</string> + <string name="speed_in_km_per_h">%.3f km/h</string> + <string name="congestion_unknown">unknown</string> + <string name="congestion_smooth">smooth</string> + <string name="congestion_stop_and_go">stop and go</string> + <string name="congestion_congestion">congestion</string> + <string name="congestion_jams">jams</string> + <string name="occupancy_unknown">unknown</string> + <string name="occupancy_empty">empty</string> + <string name="occupancy_many_seats">many seats</string> + <string name="occupancy_few_seats">few seats</string> + <string name="occupancy_standing_only">standing only</string> + <string name="occupancy_crowded">crowded</string> + <string name="occupancy_full">full</string> + <string name="occupancy_wont_let">won’t let in</string> + <string name="stop_title">%s [%s]</string> + <string name="no_map_app">No maps app installed</string> + <string name="departure_headsign">» %s</string> + <string name="departure_headsign_content_description">towards %s</string> + <string name="departure_momentarily">momentarily</string> + <string name="departure_departed">departed</string> + <string name="departure_now">now</string> + <string name="at_time">at %02d:%02d</string> + <string name="at_time_realtime">at %02d:%02d:%02d</string> + <string name="on_demand">on demand</string> + <string name="no_boarding">no boarding</string> + <string name="on_boarding">on-boarding</string> + <string name="off_boarding">off-boarding</string> + <string name="boarding">can board</string> + <string name="line_headsigns">%s «» %s</string> + <string name="line_headsigns_content_description">between %s and %s</string> + <string name="stops_nearby">Stops nearby</string> + <string name="results_for">Results for ‘%s’</string> + <string name="bimba_server_address_hint">Bimba server</string> + <string name="bimba_server_token_hint">Token</string> + <string name="bimba_server_continue_button">Continue</string> + <string name="realtime_content_description">departure is realtime</string> + <string name="wheelchair_content_description">vehicle is wheelchair accessible</string> + <string name="air_condition_content_description">air conditioning</string> + <string name="bicycles_allowed_content_description">bicycles allowed</string> + <string name="voice_announcements_content_description">voice announcements</string> + <string name="tickets_sold_content_description">tickets sold on board</string> + <string name="usb_charging_content_description">USB charging</string> + <string name="show_departures">Show departures</string> + <string name="open_in_maps_app">Open in maps app</string> + <string name="stop_content_description">stop</string> + <string name="seatbelts_everyone">Seatbelts, everyone!</string> <!-- taken from ‘Magic School Bus’. Should be translated like in the series --> + <string name="onboarding_question">How would you like to start?</string> + <string name="onboarding_simple">Simple</string> + <string name="onboarding_simple_action">choose cities</string> + <string name="onboarding_advanced">Advanced</string> + <string name="onboarding_advanced_action">choose server</string> + <string name="cancel">Cancel</string> + <string name="error">Error</string> + <string name="rate_limit">Rate limit</string> + <string name="server_rate_limited_question">This server is rate-limited and no token was given. Do you want to continue?</string> + <string name="server_private_question">This server is private and no token was given</string> + <string name="last_update">Last update: %s</string> + <string name="title_feeds">Feeds</string> + <string name="title_servers">Servers</string> + <string name="title_cities">Cities</string> + <string name="error_url">Malformed URL provided</string> + <string name="error_traffic_spec">Cannot verify traffic server</string> +</resources> \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml deleted file mode 100644 index b957c902a4f271f8a32a4ccb889929ea847c6e6b..0000000000000000000000000000000000000000 --- a/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> - <item name="colorPrimary">@color/colorPrimary</item> - <item name="colorPrimaryDark">@color/colorPrimaryDark</item> - <item name="colorAccent">@color/colorAccent</item> - </style> - - <style name="SplashTheme" parent="Theme.AppCompat.DayNight.NoActionBar"> - <item name="colorPrimary">@color/colorPrimary</item> - <item name="colorPrimaryDark">@color/colorPrimaryDark</item> - <item name="android:windowBackground">@drawable/splash_screen</item> - </style> - - <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> - - <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> - - <style name="SearchBarTheme" parent="MaterialSearchBarLight"> - <item name="mt_navIconTint">@color/textDark</item> - <item name="mt_backIconTint">@color/textDark</item> - <item name="mt_clearIconTint">@color/textDark</item> - <item name="mt_searchIconTint">@color/textDark</item> - <item name="mt_textCursorTint">@color/colorAccent</item> - <item name="mt_highlightedTextColor">@color/colorAccent</item> - <item name="mt_handlesTintEnabled">true</item> - <item name="mt_leftTextSelectorTint">@color/colorAccent</item> - <item name="mt_rightTextSelectorTint">@color/colorAccent</item> - <item name="mt_middleTextSelectorTint">@color/colorAccent</item> - <item name="mt_leftTextSelectorDrawable"> - @drawable/ic_texthandle_start - </item> - <item name="mt_middleTextSelectorDrawable"> - @drawable/ic_texthandle_middle - </item> - <item name="mt_rightTextSelectorDrawable"> - @drawable/ic_texthandle_end - </item> - </style> - -</resources> diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000000000000000000000000000000000000..dc24f789c068396350617f6166ef162d6478a0bc --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,72 @@ +<resources xmlns:tool="http://schemas.android.com/tools"> + + <style name="Theme.Bimba" parent="Theme.Material3.Light.NoActionBar"> + <item name="android:fontFamily">@font/yellowcircle8</item> + <item name="colorPrimary">@color/md_theme_light_primary</item> + <item name="colorOnPrimary">@color/md_theme_light_onPrimary</item> + <item name="colorPrimaryContainer">@color/md_theme_light_primaryContainer</item> + <item name="colorOnPrimaryContainer">@color/md_theme_light_onPrimaryContainer</item> + <item name="colorSecondary">@color/md_theme_light_secondary</item> + <item name="colorOnSecondary">@color/md_theme_light_onSecondary</item> + <item name="colorSecondaryContainer">@color/md_theme_light_secondaryContainer</item> + <item name="colorOnSecondaryContainer">@color/md_theme_light_onSecondaryContainer</item> + <item name="colorTertiary">@color/md_theme_light_tertiary</item> + <item name="colorOnTertiary">@color/md_theme_light_onTertiary</item> + <item name="colorTertiaryContainer">@color/md_theme_light_tertiaryContainer</item> + <item name="colorOnTertiaryContainer">@color/md_theme_light_onTertiaryContainer</item> + <item name="colorError">@color/md_theme_light_error</item> + <item name="colorErrorContainer">@color/md_theme_light_errorContainer</item> + <item name="colorOnError">@color/md_theme_light_onError</item> + <item name="colorOnErrorContainer">@color/md_theme_light_onErrorContainer</item> + <item name="android:colorBackground">@color/md_theme_light_background</item> + <item name="colorOnBackground">@color/md_theme_light_onBackground</item> + <item name="colorSurface">@color/md_theme_light_surface</item> + <item name="colorOnSurface">@color/md_theme_light_onSurface</item> + <item name="colorSurfaceVariant">@color/md_theme_light_surfaceVariant</item> + <item name="colorOnSurfaceVariant">@color/md_theme_light_onSurfaceVariant</item> + <item name="colorOutline">@color/md_theme_light_outline</item> + <item name="colorOnSurfaceInverse">@color/md_theme_light_inverseOnSurface</item> + <item name="colorSurfaceInverse">@color/md_theme_light_inverseSurface</item> + <item name="colorPrimaryInverse">@color/md_theme_light_inversePrimary</item> + + <item name="statusBarBackground">@android:color/transparent</item> + <item name="android:statusBarColor">@android:color/transparent</item> + <item name="android:enforceStatusBarContrast" tool:targetApi="q">false</item> + <item name="lightStatusBar">true</item> + </style> + + <declare-styleable name="Theme.Bimba"> + <attr name="lightStatusBar" format="boolean" /> + </declare-styleable> + + <style name="Theme.Bimba.SearchBar" parent="MaterialSearchBarLight"> + <item name="mt_searchBarColor">@color/md_theme_light_surfaceVariant</item> + <item name="mt_textColor">@color/md_theme_light_onSurfaceVariant</item> + <item name="mt_placeholderColor">@color/md_theme_light_onSurfaceVariant + </item> <!-- todo(ui) grey out --> + <item name="mt_backIconTint">@color/md_theme_light_onSurfaceVariant</item> + <item name="mt_navIconTint">@color/md_theme_light_onSurfaceVariant</item> + <item name="mt_searchIconTint">@color/md_theme_light_onSurfaceVariant</item> + <item name="mt_menuIconTint">@color/md_theme_light_onSurfaceVariant</item> + <item name="mt_clearIconTint">@color/md_theme_light_onSurfaceVariant</item> + </style> + + <style name="Theme.Bimba.SearchResult.Title" parent="Theme.Bimba"> + <item name="android:textColor">@color/md_theme_light_onSurfaceVariant</item> + <item name="android:textSize">16sp</item> + </style> + + <style name="Theme.Bimba.SearchResult.Description" parent="Theme.Bimba"> + <item name="android:textColor">@color/md_theme_light_onSurfaceVariant + </item> <!-- todo(ui) grey out --> + <item name="android:textSize">9sp</item> + </style> + + <style name="Theme.Bimba.Splash" parent="Theme.SplashScreen"> + <item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_foreground</item> + <item name="windowSplashScreenIconBackgroundColor">@color/ic_launcher_background</item> + <item name="postSplashScreenTheme">@style/Theme.Bimba</item> + </style> + + <style name="Theme.Bimba.Style" /> +</resources> \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml deleted file mode 100644 index e45666bc1b5d4f67b6646206d6a314359479c076..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-de/strings.xml +++ /dev/null @@ -1,58 +0,0 @@ -<resources> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">Um %1$s</string> - <string name="now">Jetzt</string> - <string name="departure_in__singular_genitive">In %1$s Minute</string> - <string name="departure_in__plural_genitive">In %1$s Minuten</string> - <string name="departure_in__plural_nominative">In %1$s Minuten</string> - - <string name="timetable_downloaded">Neuer Fahrplan heruntergeladen</string> - <string name="action_change_type">Typ</string> - <string name="timetable_downloading">Fahrplan wird heruntergeladen</string> - <string name="search_placeholder">Haltestelle…</string> - <string name="no_connectivity_cant_update">Kein Verbindung – kann nicht den Fahrplan aktualisieren</string> - <string name="no_connectivity">Kein Verbindung</string> - <string name="timetable_up_to_date">Fahrplan ist aktuell</string> - <string name="error_try_later">Fehler. Versuch später noch einmal</string> - <string name="stop_already_fav">Diese Haltestelle ist bereits eine Lieblingshaltestelle</string> - <string name="action_edit">Bearbeiten</string> - <string name="action_delete">Löschen</string> - <string name="favourite_name">Lieblingshaltestelles Name</string> - <string name="edit_favourite_title">„%1$s“ bearbeiten</string> - <string name="no_next_departure">Keine nächste Abfahrt</string> - <string name="action_merge">Zusammenfügen</string> - <string name="merge_favourites">Lieblingshaltestellen zusammenfügen</string> - <string name="loading">Laden…</string> - <string name="refresh">Fahrplan aktualisieren</string> - <string name="title_activity_help">Hilfe</string> - <string name="valid_since">Gilt seit %1$s</string> - <string name="valid_till">Gilt bis %1$s</string> - <string name="departure_row_getting_departures">Abfahrten sammeln…</string> - <string name="no_departures">Keine Abfahrten</string> - <string name="tab_text_line_to">Hin</string> - <string name="tab_text_line_fro">Her</string> - <string name="timetable_validity_today">Fahrplan gilt nur bis heute.</string> - <string name="timetable_validity_finished">Die Gültigkeit des Zeitplans ist beendet. Verbind mit dem Internet, um eine neue herunterzuladen und um fortzufahren.</string> - <string name="timetable_validity_tomorrow">Fahrplan gilt nur bis morgen.</string> - <string name="just_departed">Gerade gegangen</string> - <string name="validity_offline_unavailable">Offline-Fahrplan ist nicht verfügbar</string> - <string name="pref_category_timetable">Fahrplan</string> - <string name="title_timetable_source_url">Quelle des Fahrplans</string> - <string name="title_activity_settings">Einstellungen</string> - <string name="settings">Einstellungen</string> - <string name="timetable_decompressing">Fahrplan wird entpackt</string> - <string name="Mon">Mo.</string> - <string name="Tue">Di.</string> - <string name="Wed">Mi.</string> - <string name="Thu">Do.</string> - <string name="Fri">Fr.</string> - <string name="Sat">Sa.</string> - <string name="Sun">So.</string> - <string name="title_timetable_automatic_update">Automatische Updates</string> - <string name="summary_timetable_automatic_update">Automatisch nach Fahrplanaktualisierungen suchen und diese herunterladen</string> - <string name="server_error">Serverfehler</string> - <string name="nothing_found">Nicht gefunden</string> - <string name="in_a_moment">Gleich</string> - <string name="more">Mehr</string> -</resources> diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml deleted file mode 100644 index 6a3c5754965e35da0716f027162c09739f645ae4..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-it/strings.xml +++ /dev/null @@ -1,57 +0,0 @@ -<resources> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">Alle %1$s</string> - <string name="departure_in__singular_genitive">Tra %1$s minuto</string> - <string name="departure_in__plural_genitive">Tra %1$s minuti</string> - <string name="departure_in__plural_nominative">Tra %1$s minuti</string> - <string name="title_activity_help">Aiuto</string> - <string name="valid_since">Valido da %1$s</string> - <string name="valid_till">Valido a %1$s</string> - <string name="timetable_downloaded">Nuovo orario è stato scaricato</string> - <string name="action_change_type">Tipo</string> - <string name="timetable_downloading">Scaricando l’orario</string> - <string name="search_placeholder">Fermata…</string> - <string name="no_connectivity_cant_update">Nessuna connettività – non si riesce aggiornare l’orario</string> - <string name="no_connectivity">Nessuna connettività</string> - <string name="timetable_up_to_date">L’orario sta aggiornato</string> - <string name="error_try_later">Errore. Riprova più tardi</string> - <string name="now">Adesso</string> - <string name="stop_already_fav">Questa fermata è già un favorito</string> - <string name="action_edit">Modifica</string> - <string name="action_delete">Cancella</string> - <string name="favourite_name">Il nome del favorito</string> - <string name="edit_favourite_title">Modifica «%1$s»</string> - <string name="no_next_departure">Nessuna partenza successiva</string> - <string name="action_merge">Unisci</string> - <string name="merge_favourites">Unisci le favorite</string> - <string name="loading">Caricamento in corso…</string> - <string name="refresh">Aggiorna l’orario</string> - <string name="departure_row_getting_departures">Ottenere le partenze…</string> - <string name="no_departures">Nessune partenze</string> - <string name="tab_text_line_to">Avanti</string> - <string name="tab_text_line_fro">Indietro</string> - <string name="timetable_validity_today">L’orario è valido solo fino ad oggi.</string> - <string name="timetable_validity_finished">"La validità dell’orario è terminata. Connetti a Internet per scaricarne uno nuovo e continuare. "</string> - <string name="timetable_validity_tomorrow">L’orario è valido solo fino a domani.</string> - <string name="just_departed">Appena partito</string> - <string name="validity_offline_unavailable">L’orario offline non è disponibile</string> - <string name="pref_category_timetable">Orario</string> - <string name="title_timetable_source_url">Fonte dell’Orario</string> - <string name="title_activity_settings">Impostazioni</string> - <string name="settings">Impostazioni</string> - <string name="timetable_decompressing">Decomprimendo l’orario</string> - <string name="Mon">lun</string> - <string name="Tue">mar</string> - <string name="Wed">mer</string> - <string name="Thu">gio</string> - <string name="Fri">ven</string> - <string name="Sat">sab</string> - <string name="Sun">dom</string> - <string name="summary_timetable_automatic_update">Controlla e scarica automaticamente gli aggiornamenti dell’orario</string> - <string name="title_timetable_automatic_update">Aggiornamenti automatici</string> - <string name="server_error">Errore del server</string> - <string name="nothing_found">Non trovato</string> - <string name="in_a_moment">In un momento</string> - <string name="more">Più</string> -</resources> diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml deleted file mode 100644 index a17e646959c11a4b4716bb7b800264a91cb92e80..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-night/colors.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <color name="textDark">#deffffff</color> - <color name="textDarkMedium">#99ffffff</color> - <color name="textDarkDisabled">#45ffffff</color> - <color name="cardColor">#424242</color> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 471cf22213b51f84eff2aca9f8e51a90fca5adbf..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <style name="SearchBarTheme" parent="MaterialSearchBarDark"> - <item name="mt_navIconTint">@color/textDark</item> - <item name="mt_backIconTint">@color/textDark</item> - <item name="mt_clearIconTint">@color/textDark</item> - <item name="mt_searchIconTint">@color/textDark</item> - <item name="mt_textCursorTint">@color/colorAccent</item> - <item name="mt_highlightedTextColor">@color/colorAccent</item> - <item name="mt_handlesTintEnabled">true</item> - <item name="mt_leftTextSelectorTint">@color/colorAccent</item> - <item name="mt_rightTextSelectorTint">@color/colorAccent</item> - <item name="mt_middleTextSelectorTint">@color/colorAccent</item> - <item name="mt_leftTextSelectorDrawable"> - @drawable/ic_texthandle_start - </item> - <item name="mt_middleTextSelectorDrawable"> - @drawable/ic_texthandle_middle - </item> - <item name="mt_rightTextSelectorDrawable"> - @drawable/ic_texthandle_end - </item> - </style> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000000000000000000000000000000000000..64131505cc055ae8432e5e6f350e280e352cd614 --- /dev/null +++ b/app/src/main/res/values-night/themes.xml @@ -0,0 +1,62 @@ +<resources xmlns:tool="http://schemas.android.com/tools"> + + <style name="Theme.Bimba" parent="Theme.Material3.Dark.NoActionBar"> + <item name="android:fontFamily">@font/yellowcircle8</item> + <item name="colorPrimary">@color/md_theme_dark_primary</item> + <item name="colorOnPrimary">@color/md_theme_dark_onPrimary</item> + <item name="colorPrimaryContainer">@color/md_theme_dark_primaryContainer</item> + <item name="colorOnPrimaryContainer">@color/md_theme_dark_onPrimaryContainer</item> + <item name="colorSecondary">@color/md_theme_dark_secondary</item> + <item name="colorOnSecondary">@color/md_theme_dark_onSecondary</item> + <item name="colorSecondaryContainer">@color/md_theme_dark_secondaryContainer</item> + <item name="colorOnSecondaryContainer">@color/md_theme_dark_onSecondaryContainer</item> + <item name="colorTertiary">@color/md_theme_dark_tertiary</item> + <item name="colorOnTertiary">@color/md_theme_dark_onTertiary</item> + <item name="colorTertiaryContainer">@color/md_theme_dark_tertiaryContainer</item> + <item name="colorOnTertiaryContainer">@color/md_theme_dark_onTertiaryContainer</item> + <item name="colorError">@color/md_theme_dark_error</item> + <item name="colorErrorContainer">@color/md_theme_dark_errorContainer</item> + <item name="colorOnError">@color/md_theme_dark_onError</item> + <item name="colorOnErrorContainer">@color/md_theme_dark_onErrorContainer</item> + <item name="android:colorBackground">@color/md_theme_dark_background</item> + <item name="colorOnBackground">@color/md_theme_dark_onBackground</item> + <item name="colorSurface">@color/md_theme_dark_surface</item> + <item name="colorOnSurface">@color/md_theme_dark_onSurface</item> + <item name="colorSurfaceVariant">@color/md_theme_dark_surfaceVariant</item> + <item name="colorOnSurfaceVariant">@color/md_theme_dark_onSurfaceVariant</item> + <item name="colorOutline">@color/md_theme_dark_outline</item> + <item name="colorOnSurfaceInverse">@color/md_theme_dark_inverseOnSurface</item> + <item name="colorSurfaceInverse">@color/md_theme_dark_inverseSurface</item> + <item name="colorPrimaryInverse">@color/md_theme_dark_inversePrimary</item> + + <item name="statusBarBackground">@android:color/transparent</item> + <item name="android:statusBarColor">@android:color/transparent</item> + <item name="android:enforceStatusBarContrast" tool:targetApi="q">false</item> + <item name="lightStatusBar">false</item> + </style> + + <declare-styleable name="Theme.Bimba"> + <attr name="lightStatusBar" format="boolean" /> + </declare-styleable> + + <style name="Theme.Bimba.SearchBar" parent="MaterialSearchBarLight"> + <item name="mt_searchBarColor">@color/md_theme_dark_surfaceVariant</item> + <item name="mt_textColor">@color/md_theme_dark_onSurfaceVariant</item> + <item name="mt_placeholderColor">@color/md_theme_dark_onSurfaceVariant</item> <!-- todo(ui) grey out --> + <item name="mt_backIconTint">@color/md_theme_dark_onSurfaceVariant</item> + <item name="mt_navIconTint">@color/md_theme_dark_onSurfaceVariant</item> + <item name="mt_searchIconTint">@color/md_theme_dark_onSurfaceVariant</item> + <item name="mt_menuIconTint">@color/md_theme_dark_onSurfaceVariant</item> + <item name="mt_clearIconTint">@color/md_theme_dark_onSurfaceVariant</item> + </style> + + <style name="Theme.Bimba.SearchResult.Title" parent="Theme.Bimba"> + <item name="android:textColor">@color/md_theme_dark_onSurfaceVariant</item> + <item name="android:textSize">16sp</item> + </style> + + <style name="Theme.Bimba.SearchResult.Description" parent="Theme.Bimba"> + <item name="android:textColor">@color/md_theme_dark_onSurfaceVariant</item> <!-- todo(ui) grey out --> + <item name="android:textSize">9sp</item> + </style> +</resources> \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml deleted file mode 100644 index 5722111696a88735ec67c0c2aff9eebd8ddc7252..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-nl/strings.xml +++ /dev/null @@ -1,59 +0,0 @@ -<resources> - <string name="timetable_downloaded">De nieuwe dienstregeling is gedownload</string> - <string name="action_change_type">Type</string> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">Op %1$s</string> - <string name="timetable_downloading">Bezig met downloaden van dienstregeling</string> - <string name="search_placeholder">Halte…</string> - <string name="no_connectivity_cant_update">Geen internetverbinding – de dienstregeling kan niet worden bijgewerkt.</string> - <string name="no_connectivity">Geen internetverbinding</string> - <string name="timetable_up_to_date">De dienstregeling is volledig bijgewerkt.</string> - <string name="error_try_later">Fout; probeer het later opnieuw.</string> - <string name="now">Nu</string> - <string name="stop_already_fav">Deze halte staat al bij je favorieten</string> - <string name="action_edit">Bewerken</string> - <string name="action_delete">Verwijderen</string> - <string name="favourite_name">Naam van favoriet</string> - <string name="edit_favourite_title">‘%1$s’ bewerken</string> - <string name="no_next_departure">Geen vertrektijden</string> - <string name="action_merge">Samenvoegen</string> - <string name="merge_favourites">Favorieten samenvoegen</string> - <string name="loading">Bezig met laden…</string> - <string name="departure_in__singular_genitive">Over %1$s minuut</string> - <string name="departure_in__plural_genitive">Over %1$s minuten</string> - <string name="departure_in__plural_nominative">Over %1$s minuten</string> - - <string name="refresh">Dienstregeling bijwerken</string> - <string name="title_activity_help">Hulp</string> - <string name="departure_row_getting_departures">Bezig met ophalen van vertrektijden…</string> - <string name="valid_since">Ingegaan op %1$s</string> - <string name="valid_till">Verloopt op %1$s</string> - - <string name="no_departures">Geen vertrektijden</string> - <string name="tab_text_line_to">Naar</string> - <string name="tab_text_line_fro">Van</string> - <string name="timetable_validity_finished">De dienstregeling is verlopen. Maak verbinding met het internet om een nieuwe te downloaden.</string> - <string name="timetable_validity_today">De dienstregeling verloopt vandaag.</string> - <string name="timetable_validity_tomorrow">De dienstregeling verloopt morgen.</string> - <string name="just_departed">Zojuist vertrokken</string> - <string name="validity_offline_unavailable">Offline dienstregeling is niet beschikbaar</string> - <string name="pref_category_timetable">Dienstregeling</string> - <string name="title_timetable_source_url">Bron van de dienstregeling</string> - <string name="title_activity_settings">Instellingen</string> - <string name="settings">Instellingen</string> - <string name="timetable_decompressing">Bezig met uitpakken van dienstregeling</string> - <string name="Mon">ma</string> - <string name="Tue">di</string> - <string name="Wed">wo</string> - <string name="Thu">do</string> - <string name="Fri">vr</string> - <string name="Sat">za</string> - <string name="Sun">zo</string> - <string name="title_timetable_automatic_update">Automatische updates</string> - <string name="summary_timetable_automatic_update">Automatisch controleren en download dienstregeling updates</string> - <string name="server_error">Serverfout</string> - <string name="more">Meer</string> - <string name="in_a_moment">In een ogenblik</string> - <string name="nothing_found">Niet gevonden</string> -</resources> diff --git a/app/src/main/res/values-notnight/colors.xml b/app/src/main/res/values-notnight/colors.xml deleted file mode 100644 index 2dbc91375d0d6af1a61b7634050086b1e5a1c301..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-notnight/colors.xml +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <color name="textDark">#de000000</color> - <color name="textDarkMedium">#99000000</color> - <color name="textDarkDisabled">#45000000</color> - <color name="cardColor">#ffffff</color> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-notnight/styles.xml b/app/src/main/res/values-notnight/styles.xml deleted file mode 100644 index 91c96a627f637c75c0a16c6de17ca84e7963284f..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-notnight/styles.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <style name="SearchBarTheme" parent="MaterialSearchBarLight"> - <item name="mt_navIconTint">@color/textDark</item> - <item name="mt_backIconTint">@color/textDark</item> - <item name="mt_clearIconTint">@color/textDark</item> - <item name="mt_searchIconTint">@color/textDark</item> - <item name="mt_textCursorTint">@color/colorAccent</item> - <item name="mt_highlightedTextColor">@color/colorAccent</item> - <item name="mt_handlesTintEnabled">true</item> - <item name="mt_leftTextSelectorTint">@color/colorAccent</item> - <item name="mt_rightTextSelectorTint">@color/colorAccent</item> - <item name="mt_middleTextSelectorTint">@color/colorAccent</item> - <item name="mt_leftTextSelectorDrawable"> - @drawable/ic_texthandle_start - </item> - <item name="mt_middleTextSelectorDrawable"> - @drawable/ic_texthandle_middle - </item> - <item name="mt_rightTextSelectorDrawable"> - @drawable/ic_texthandle_end - </item> - </style> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml deleted file mode 100644 index 0fc914f811da656b43c9cfe73dd1c435d79a56e1..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-pl/strings.xml +++ /dev/null @@ -1,58 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="timetable_downloaded">Pobrano nowy rozkład</string> - <string name="action_change_type">Typ</string> - <string name="departure_at">O %1$s</string> - <string name="departure_to">→ %1$s</string> - <string name="timetable_downloading">Pobieranie rozkładu</string> - <string name="search_placeholder">Przystanek…</string> - <string name="timetable_up_to_date">Rozkład jest aktualny</string> - <string name="no_connectivity_cant_update">Brak połączenia z Internetem – nie można zaktualizować rozkładu</string> - <string name="no_connectivity">Brak połączenia z Internetem</string> - <string name="error_try_later">Błąd. Spróbuj ponownie później</string> - <string name="now">Teraz</string> - <string name="stop_already_fav">Ten przystanek już jest pośród ulubionych</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="action_delete">Usuń</string> - <string name="action_edit">Edytuj</string> - <string name="edit_favourite_title">Edytuj „%1$s”</string> - <string name="favourite_name">Nazwa ulubionego</string> - <string name="no_next_departure">Brak następnego odjazdu</string> - <string name="action_merge">Połącz</string> - <string name="merge_favourites">Połącz ulubione</string> - <string name="loading">Ładowanie…</string> - <string name="departure_in__singular_genitive">Za %1$s minutę</string> - <string name="departure_in__plural_genitive">Za %1$s minut</string> - <string name="departure_in__plural_nominative">Za %1$s minuty</string> - <string name="refresh">Zaktualizuj rozkład</string> - <string name="title_activity_help">Pomoc</string> - <string name="departure_row_getting_departures">Zbieranie odjazdów…</string> - <string name="valid_since">Ważny od %1$s</string> - <string name="valid_till">Ważny do %1$s</string> - <string name="no_departures">Brak odjazdów</string> - <string name="tab_text_line_to">Tam</string> - <string name="tab_text_line_fro">Z powrotem</string> - <string name="timetable_validity_today">Rozkład obowiązuje tylko do dzisiaj.</string> - <string name="timetable_validity_finished">Rozkład przestał obowiązywać. Połącz się z Internetem, aby pobrać nowy i kontynuować.</string> - <string name="timetable_validity_tomorrow">Rozkład obowiązuje tylko do jutra.</string> - <string name="just_departed">Właśnie odjechał</string> - <string name="validity_offline_unavailable">Rozkład offline jest niedostępny</string> - <string name="pref_category_timetable">Rozkład</string> - <string name="title_timetable_source_url">Źródło rozkładu</string> - <string name="title_activity_settings">Ustawienia</string> - <string name="settings">Ustawienia</string> - <string name="timetable_decompressing">Rozpakowywanie rozkładu</string> - <string name="Mon">pon.</string> - <string name="Tue">wt.</string> - <string name="Wed">śr.</string> - <string name="Thu">czw.</string> - <string name="Fri">pt.</string> - <string name="Sat">sob.</string> - <string name="Sun">niedz.</string> - <string name="summary_timetable_automatic_update">Automatycznie sprawdzaj i pobieraj aktualizacje rozkładu</string> - <string name="title_timetable_automatic_update">Automatyczne aktualizacje</string> - <string name="server_error">Błąd servera</string> - <string name="nothing_found">Nie znaleziono</string> - <string name="in_a_moment">Za moment</string> - <string name="more">Więcej</string> -</resources> \ No newline at end of file diff --git a/app/src/main/res/values-v23/themes.xml b/app/src/main/res/values-v23/themes.xml new file mode 100644 index 0000000000000000000000000000000000000000..f2e49e303ea6be52b864cd335f562c03667883b5 --- /dev/null +++ b/app/src/main/res/values-v23/themes.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <style name="Theme.Bimba.Style" parent="Theme.Bimba"> + <item name="android:windowLightStatusBar">?attr/lightStatusBar</item> + <item name="android:statusBarColor">?attr/statusBarBackground</item> + </style> +</resources> \ No newline at end of file diff --git a/app/src/main/res/values-w820dp/dimens.xml b/app/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc816444614bd64f68a372d1f93211628ee51d..0000000000000000000000000000000000000000 --- a/app/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ -<resources> - <!-- Example customization of dimensions originally defined in res/values/dimens.xml - (such as screen margins) for screens with more than 820dp of available width. This - would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> - <dimen name="activity_horizontal_margin">64dp</dimen> -</resources> diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000000000000000000000000000000000000..9157acd18cdf838751e15affe9aad8ea49f91b49 --- /dev/null +++ b/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Sample backup rules file; uncomment and customize as necessary. + See https://developer.android.com/guide/topics/data/autobackup + for details. + Note: This file is ignored for devices older that API 31 + See https://developer.android.com/about/versions/12/backup-restore +--> +<full-backup-content> +</full-backup-content> \ No newline at end of file diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000000000000000000000000000000000000..dbd7d6cff871fd2450b0f9c01fc1143b79092776 --- /dev/null +++ b/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Sample data extraction rules file; uncomment and customize as necessary. + See https://developer.android.com/about/versions/12/backup-restore#xml-changes + for details. +--> +<data-extraction-rules> + <cloud-backup> + <!-- Use <include> and <exclude> to control what is backed up. + <include .../> + <exclude .../> + --> + </cloud-backup> + <!-- + <device-transfer> + <include .../> + <exclude .../> + </device-transfer> + --> +</data-extraction-rules> \ No newline at end of file diff --git a/app/src/main/res/xml/pref_main.xml b/app/src/main/res/xml/pref_main.xml deleted file mode 100644 index e35091e5b4688366446865e6123a4cfe880fd70b..0000000000000000000000000000000000000000 --- a/app/src/main/res/xml/pref_main.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - <PreferenceCategory android:title="@string/pref_category_timetable"> - <EditTextPreference - android:defaultValue="@string/timetable_source_url" - android:key="@string/key_timetable_source_url" - android:summary="@string/timetable_source_url" - android:title="@string/title_timetable_source_url" /> - - <!-- todo intent get file (import) --> - <!-- todo reset source --> - <SwitchPreference - android:defaultValue="false" - android:key="@string/key_timetable_automatic_update" - android:summary="@string/summary_timetable_automatic_update" - android:title="@string/title_timetable_automatic_update" /> - </PreferenceCategory> -</PreferenceScreen> diff --git a/build.gradle b/build.gradle index 2db418dde841cfe37dc15e0d5f1cd140f603dfa2..73d1e088368f91b43d6e9b60b37550773df667cd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,31 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - ext.kotlin_version = '1.3.21' - repositories { - jcenter() - maven { url 'https://maven.google.com' } - //maven { url 'https://dl.bintray.com/guardian/android' } // TooLargeTool - google() - } - dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files - } -} - -allprojects { - repositories { - jcenter() - maven { url 'https://maven.google.com' } - //maven { url 'https://dl.bintray.com/guardian/android' } // TooLargeTool - google() - } +plugins { + id 'com.android.application' version '7.4.2' apply false + id 'com.android.library' version '7.4.2' apply false + id 'org.jetbrains.kotlin.android' version '1.7.10' apply false + id 'org.jetbrains.kotlin.jvm' version '1.7.20' apply false + id "org.jetbrains.kotlin.plugin.parcelize" version "1.8.20" apply false } task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/fruchtfleisch/.gitignore b/fruchtfleisch/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..42afabfd2abebf31384ca7797186a27a4b7dbee8 --- /dev/null +++ b/fruchtfleisch/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/fruchtfleisch/build.gradle b/fruchtfleisch/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..e7ceb4cce7d2dcbc650fa806ead2fcfa26ba232e --- /dev/null +++ b/fruchtfleisch/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'java-library' + id 'org.jetbrains.kotlin.jvm' +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 +} +dependencies { + //implementation 'org.jetbrains.kotlin:kotlin-reflect:1.8.10' +} \ No newline at end of file diff --git a/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt b/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt new file mode 100644 index 0000000000000000000000000000000000000000..9d49df734169f7b2934d7897e89311653de7139c --- /dev/null +++ b/fruchtfleisch/src/main/java/xyz/apiote/fruchtfleisch/Reader.kt @@ -0,0 +1,128 @@ +package xyz.apiote.fruchtfleisch + +import java.io.EOFException +import java.io.InputStream +import java.lang.Double.longBitsToDouble +import java.lang.Float.intBitsToFloat + +data class IntVar(private val v: Long) { + fun toLong() = v +} +data class UIntVar(private val v: ULong) { + fun toULong() = v +} + +@Suppress("MemberVisibilityCanBePrivate", "unused", "BooleanMethodIsAlwaysInverted") +class Reader(private val stream: InputStream) { + fun readUInt(): UIntVar { + var result: ULong = 0UL + var i = 0 + var s = 0 + while (true) { + val b = stream.read() + if (b < 0) { + throw EOFException("while reading byte") + } + if (b < 0x80) { + if (i > 9 || (i == 9 && b > 1)) { + TODO("throw int overflow") + } + result = result.or(b.toULong().shl(s)) + break + } + i++ + s += 7 + } + return UIntVar(result) + } + + fun readInt(): IntVar { + val unsigned = readUInt().toULong() + var signed = unsigned.shr(1).toLong() + if (unsigned.and(1UL) != 0UL) { + signed = signed.inv() + } + return IntVar(signed) + } + + fun readU8(): UByte { + val b = stream.read() + if (b < 0) { + throw EOFException("while reading byte") + } + return b.toUByte() + } + + fun readU16(): UShort { + val b1 = readU8() + val b2 = readU8() + return (b2.toUInt().shl(8) or b1.toUInt()).toUShort() + } + + fun readU32(): UInt { + val b1 = readU8() + val b2 = readU8() + val b3 = readU8() + val b4 = readU8() + return b4.toUInt().shl(24) or b3.toUInt().shl(16) or b2.toUInt().shl(8) or b1.toUInt() + } + + fun readU64(): ULong { + val b1 = readU8() + val b2 = readU8() + val b3 = readU8() + val b4 = readU8() + val b5 = readU8() + val b6 = readU8() + val b7 = readU8() + val b8 = readU8() + return b8.toULong().shl(56) or b7.toULong().shl(48) or b6.toULong().shl(40) or b5.toULong().shl(32) or b4.toULong().shl(24) or b3.toULong().shl(16) or b2.toULong().shl(8) or b1.toULong() + } + + fun readI8(): Byte { + return readU8().toByte() + } + + fun readI16(): Short { + return readU16().toShort() + } + + fun readI32(): Int { + return readU32().toInt() + } + + fun readI64(): Long { + return readU64().toLong() + } + + fun readFloat32(): Float { + return intBitsToFloat(readI32()) + } + + fun readFloat64(): Double { + return longBitsToDouble(readI64()) + } + + fun readData(n: Int): ByteArray { + val data = ByteArray(n) + var left = n + while (left > 0) { + val r = stream.read(data, n - left, left) + left -= r + } + return data + } + + fun readString(): String { + val length = readU8() + return readData(length.toInt()).decodeToString() + } + + fun readBoolean(): Boolean { + return when (readU8().toUInt()) { + 0u -> false + 1u -> true + else -> TODO("throw wrong value") + } + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 13372aef5e24af05341d49695ee84e5f9b594659..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0a09c6d65a64c76aa4d5b2cb098701791d95d346..72a0f4c89357e1fdc5ad0b2d63031ab0a9475f5b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Aug 29 11:31:16 CEST 2017 +#Tue Aug 09 15:48:25 CEST 2022 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip +zipStoreBase=GRADLE_USER_HOME diff --git a/gradle.properties b/gradle.properties index 307d50280f7a5c9eb7f6dee93d377854a8ba7d19..cd0519bb2a9450033b80e5906f766b71d176014f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,20 +1,23 @@ # Project-wide Gradle settings. - # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. - # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html - # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. -org.gradle.jvmargs=-Xmx1536m -kotlin.coroutines=enable -android.useAndroidX=true -android.enableJetifier=true - +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app"s APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/gradlew b/gradlew index 9d82f78915133e1c35a6ea51252590fb38efac2f..4f906e0c811fc9e230eb44819f509cd0627f2600 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,20 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## ## @@ -6,20 +22,38 @@ ## Gradle start up script for UN*X ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,27 +75,13 @@ ;; MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then @@ -85,7 +106,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -105,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -134,27 +156,30 @@ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282aa6885fb573c106b3551f7275c5f17e8e..107acd32c4e687021ef32db511e8a206129b88ec 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -8,20 +24,23 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,34 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/i18n/ids b/i18n/ids deleted file mode 100644 index 024d90586180baa9e7719ff8f489c4d5a23d2832..0000000000000000000000000000000000000000 --- a/i18n/ids +++ /dev/null @@ -1,52 +0,0 @@ -timetable_downloaded = New timetable downloaded -action_change_type = Type -departure_to = → %1$s -departure_to_line = %1$s → %2$s -departure_at = At %1$s -timetable_downloading = Downloading timetable -timetable_decompressing = Decompressing timetable -search_placeholder = Stop… -no_connectivity_cant_update = No connectivity – can’t update timetable -no_connectivity = No connectivity -timetable_up_to_date = Timetable is up-to-date -error_try_later = Error. Try again later -now = Now -stop_already_fav = This stop is already in favourites -action_edit = Edit -action_delete = Delete -favourite_name = Favourite name -edit_favourite_title = Edit ‘%1$s’ -no_next_departure = No next departure -action_merge = Merge -merge_favourites = Merge favourites -loading = Loading… -departure_in__singular_genitive = In %1$s minute -departure_in__plural_genitive = In %1$s minutes _plgen -departure_in__plural_nominative = In %1$s minutes _plnom -refresh = Update timetable -title_activity_help = Help -departure_row_getting_departures = Getting departures… -valid_since = Valid since %1$s -valid_till = Valid till %1$s -no_departures = No departures -tab_text_line_to = To -tab_text_line_fro = Fro -timetable_validity_finished = Timetable validity has ended. Connect to the Internet to download a new one in order to continue. -timetable_validity_today = Timetable validity ends today. -timetable_validity_tomorrow = Timetable validity ends tomorrow. -just_departed = Just departed -validity_offline_unavailable = Offline timetable unavailable -pref_category_timetable = Timetable -title_timetable_source_url = Timetable source -title_activity_settings = Settings -settings = Settings -title_timetable_automatic_update = Automatic updates -Mon = Mon -Tue = Tue -Wed = Wed -Thu = Thu -Fri = Fri -Sat = Sat -Sun = Sun -summary_timetable_automatic_update = Automatically check for and download timetable updates -server_error = Server error diff --git a/i18n/messages.en.uk.po b/i18n/messages.en.uk.po deleted file mode 100644 index 343c4c0dbf756333ff6849567b7eab2d1ea0130a..0000000000000000000000000000000000000000 --- a/i18n/messages.en.uk.po +++ /dev/null @@ -1,111 +0,0 @@ -#, fuzzy -msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Transfer-Encoding: 8bit\n" -"Content-Type: text/plain; charset=UTF-8\n" - -msgid "New timetable downloaded" -msgstr "New timetable downloaded" -msgid "Type" -msgstr "Type" -msgid "→ %1$s" -msgstr "→ %1$s" -msgid "%1$s → %2$s" -msgstr "%1$s → %2$s" -msgid "At %1$s" -msgstr "At %1$s" -msgid "Downloading timetable" -msgstr "Downloading timetable" -msgid "Decompressing timetable" -msgstr "Decompressing timetable" -msgid "Stop…" -msgstr "Stop…" -msgid "No connectivity – can’t update timetable" -msgstr "No connectivity – can’t update timetable" -msgid "No connectivity" -msgstr "No connectivity" -msgid "Timetable is up-to-date" -msgstr "Timetable is up-to-date" -msgid "Error. Try again later" -msgstr "Error. Try again later" -msgid "Now" -msgstr "Now" -msgid "This stop is already in favourites" -msgstr "This stop is already in favourites" -msgid "Edit" -msgstr "Edit" -msgid "Delete" -msgstr "Delete" -msgid "Favourite name" -msgstr "Favourite name" -msgid "Edit ‘%1$s’" -msgstr "Edit ‘%1$s’" -msgid "No next departure" -msgstr "No next departure" -msgid "Merge" -msgstr "Merge" -msgid "Merge favourites" -msgstr "Merge favourites" -msgid "Loading…" -msgstr "Loading…" -msgid "In %1$s minute" -msgstr "In %1$s minute" -msgid "In %1$s minutes _plnom" -msgstr "In %1$s minutes" -msgid "In %1$s minutes _plgen" -msgstr "In %1$s minutes" -msgid "Update timetable" -msgstr "Update timetable" -msgid "Help" -msgstr "Help" -msgid "Getting departures…" -msgstr "Getting departures…" -msgid "Valid since %1$s" -msgstr "Valid since %1$s" -msgid "Valid till %1$s" -msgstr "Valid till %1$s" -msgid "No departures" -msgstr "No departures" -msgid "To" -msgstr "To" -msgid "Fro" -msgstr "Fro" -msgid "Timetable validity has ended. Connect to the Internet to download a new one in order to continue." -msgstr "Timetable validity has ended. Connect to the Internet to download a new one in order to continue." -msgid "Timetable validity ends today." -msgstr "Timetable validity ends today." -msgid "Timetable validity ends tomorrow." -msgstr "Timetable validity ends tomorrow." -msgid "Just departed" -msgstr "Just departed" -msgid "Offline timetable unavailable" -msgstr "Offline timetable unavailable" -msgid "Timetable" -msgstr "Timetable" -msgid "Timetable source" -msgstr "Timetable source" -msgid "Settings" -msgstr "Settings" -msgid "Settings" -msgstr "Settings" -msgid "Automatic updates" -msgstr "Automatic updates" -msgid "Mon" -msgstr "Mon" -msgid "Tue" -msgstr "Tue" -msgid "Wed" -msgstr "Wed" -msgid "Thu" -msgstr "Thu" -msgid "Fri" -msgstr "Fri" -msgid "Sat" -msgstr "Sat" -msgid "Sun" -msgstr "Sun" -msgid "Automatically check for and download timetable updates" -msgstr "Automatically check for and download timetable updates" -msgid "Server error" -msgstr "Server error" diff --git a/i18n/messages.pl.po b/i18n/messages.pl.po deleted file mode 100644 index 0d41090206c8ce8c4d1174918da09af66af03bdd..0000000000000000000000000000000000000000 --- a/i18n/messages.pl.po +++ /dev/null @@ -1,111 +0,0 @@ -#, fuzzy -msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Transfer-Encoding: 8bit\n" -"Content-Type: text/plain; charset=UTF-8\n" - -msgid "New timetable downloaded" -msgstr "Pobrano nowy rozkład" -msgid "Type" -msgstr "Typ" -msgid "At %1$s" -msgstr "O %1$s" -msgid "→ %1$s" -msgstr "→ %1$s" -msgid "Downloading timetable" -msgstr "Pobieranie rozkładu" -msgid "Stop…" -msgstr "Przystanek…" -msgid "Timetable is up-to-date" -msgstr "Rozkład jest aktualny" -msgid "No connectivity – can’t update timetable" -msgstr "Brak połączenia z Internetem – nie można zaktualizować rozkładu" -msgid "No connectivity" -msgstr "Brak połączenia z Internetem" -msgid "Error. Try again later" -msgstr "Błąd. Spróbuj ponownie później" -msgid "Now" -msgstr "Teraz" -msgid "This stop is already in favourites" -msgstr "Ten przystanek już jest pośród ulubionych" -msgid "%1$s → %2$s" -msgstr "%1$s → %2$s" -msgid "Delete" -msgstr "Usuń" -msgid "Edit" -msgstr "Edytuj" -msgid "Edit ‘%1$s’" -msgstr "Edytuj „%1$s”" -msgid "Favourite name" -msgstr "Nazwa ulubionego" -msgid "No next departure" -msgstr "Brak następnego odjazdu" -msgid "Merge" -msgstr "Połącz" -msgid "Merge favourites" -msgstr "Połącz ulubione" -msgid "Loading…" -msgstr "Ładowanie…" -msgid "In %1$s minute" -msgstr "Za %1$s minutę" -msgid "In %1$s minutes _plgen" -msgstr "Za %1$s minut" -msgid "In %1$s minutes _plnom" -msgstr "Za %1$s minuty" -msgid "Update timetable" -msgstr "Zaktualizuj rozkład" -msgid "Help" -msgstr "Pomoc" -msgid "Getting departures…" -msgstr "Zbieranie odjazdów…" -msgid "Valid since %1$s" -msgstr "Ważny od %1$s" -msgid "Valid till %1$s" -msgstr "Ważny do %1$s" -msgid "No departures" -msgstr "Brak odjazdów" -msgid "To" -msgstr "Tam" -msgid "Fro" -msgstr "Z powrotem" -msgid "Timetable validity ends today." -msgstr "Rozkład obowiązuje tylko do dzisiaj." -msgid "Timetable validity has ended. Connect to the Internet to download a new one in order to continue." -msgstr "Rozkład przestał obowiązywać. Połącz się z Internetem, aby pobrać nowy i kontynuować." -msgid "Timetable validity ends tomorrow." -msgstr "Rozkład obowiązuje tylko do jutra." -msgid "Just departed" -msgstr "Właśnie odjechał" -msgid "Offline timetable unavailable" -msgstr "Rozkład offline jest niedostępny" -msgid "Timetable" -msgstr "Rozkład" -msgid "Timetable source" -msgstr "Źródło rozkładu" -msgid "Settings" -msgstr "Ustawienia" -msgid "Settings" -msgstr "Ustawienia" -msgid "Decompressing timetable" -msgstr "Rozpakowywanie rozkładu" -msgid "Mon" -msgstr "pon." -msgid "Tue" -msgstr "wt." -msgid "Wed" -msgstr "śr." -msgid "Thu" -msgstr "czw." -msgid "Fri" -msgstr "pt." -msgid "Sat" -msgstr "sob." -msgid "Sun" -msgstr "niedz." -msgid "Automatically check for and download timetable updates" -msgstr "Automatycznie sprawdzaj i pobieraj aktualizacje rozkładu" -msgid "Automatic updates" -msgstr "Automatyczne aktualizacje" -msgid "Server error" -msgstr "Błąd servera" diff --git a/i18n/messages.pot b/i18n/messages.pot deleted file mode 100644 index a85bef4664f60f0835ae9ae580b7298bcd27061d..0000000000000000000000000000000000000000 --- a/i18n/messages.pot +++ /dev/null @@ -1,161 +0,0 @@ -#, fuzzy -msgid "" -msgstr "" -"MIME-Version: 1.0\n" -"Content-Transfer-Encoding: 8bit\n" -"Content-Type: text/plain; charset=UTF-8\n" - -msgid "New timetable downloaded" -msgstr "" - -msgid "Type" -msgstr "" - -msgid "→ %1$s" -msgstr "" - -msgid "%1$s → %2$s" -msgstr "" - -msgid "At %1$s" -msgstr "" - -msgid "Downloading timetable" -msgstr "" - -msgid "Decompressing timetable" -msgstr "" - -msgid "Stop…" -msgstr "" - -msgid "No connectivity – can’t update timetable" -msgstr "" - -msgid "No connectivity" -msgstr "" - -msgid "Timetable is up-to-date" -msgstr "" - -msgid "Error. Try again later" -msgstr "" - -msgid "Now" -msgstr "" - -msgid "This stop is already in favourites" -msgstr "" - -msgid "Edit" -msgstr "" - -msgid "Delete" -msgstr "" - -msgid "Favourite name" -msgstr "" - -msgid "Edit ‘%1$s’" -msgstr "" - -msgid "No next departure" -msgstr "" - -msgid "Merge" -msgstr "" - -msgid "Merge favourites" -msgstr "" - -msgid "Loading…" -msgstr "" - -msgid "In %1$s minute" -msgstr "" - -#. minutes – plural nominative -msgid "In %1$s minutes _plnom" -msgstr "" - -#. minutes — plural genitive -msgid "In %1$s minutes _plgen" -msgstr "" - -msgid "Update timetable" -msgstr "" - -msgid "Help" -msgstr "" - -msgid "Getting departures…" -msgstr "" - -msgid "Valid since %1$s" -msgstr "" - -msgid "Valid till %1$s" -msgstr "" - -msgid "No departures" -msgstr "" - -msgid "To" -msgstr "" - -msgid "Fro" -msgstr "" - -msgid "Timetable validity has ended. Connect to the Internet to download a new one in order to continue." -msgstr "" - -msgid "Timetable validity ends today." -msgstr "" - -msgid "Timetable validity ends tomorrow." -msgstr "" - -msgid "Just departed" -msgstr "" - -msgid "Offline timetable unavailable" -msgstr "" - -msgid "Timetable" -msgstr "" - -msgid "Timetable source" -msgstr "" - -msgid "Settings" -msgstr "" - -msgid "Automatic updates" -msgstr "" - -msgid "Mon" -msgstr "" - -msgid "Tue" -msgstr "" - -msgid "Wed" -msgstr "" - -msgid "Thu" -msgstr "" - -msgid "Fri" -msgstr "" - -msgid "Sat" -msgstr "" - -msgid "Sun" -msgstr "" - -msgid "Automatically check for and download timetable updates" -msgstr "" - -msgid "Server error" -msgstr "" diff --git a/i18n/po2xml.py b/i18n/po2xml.py deleted file mode 100644 index 6e63f1d3e3847fbd2bb7eef45fe3bcb1b16513a8..0000000000000000000000000000000000000000 --- a/i18n/po2xml.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/python3 - -import sys - -ids = {} -msgs = {} -last_id = '' - -with open('ids') as ids_file: - for line in ids_file.readlines(): - id, msg = line.split(' = ') - ids[msg.strip()] = id.strip() - -for line in sys.stdin: - line = line.split('"') - if line[0].strip() == 'msgid': - last_id = line[1] - if line[0].strip() == 'msgstr' and last_id != '': - msgs[last_id] = line[1] - -print("<resources>") -for id, msg in msgs.items(): - print(f' <string name="{ids[id]}">{msg}</string>') -print("</resources>") diff --git a/i18n/strings-de.xml b/i18n/strings-de.xml deleted file mode 100644 index 2aa35f26cd77104f979d8f986dd4469b12d46160..0000000000000000000000000000000000000000 --- a/i18n/strings-de.xml +++ /dev/null @@ -1,55 +0,0 @@ -<resources> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">Um %1$s</string> - <string name="now">Jetzt</string> - <string name="departure_in__singular_genitive">In %1$s Minute</string> - <string name="departure_in__plural_genitive">In %1$s Minuten</string> - <string name="departure_in__plural_nominative">In %1$s Minuten</string> - - <string name="timetable_downloaded">Neuer Fahrplan heruntergeladen</string> - <string name="action_change_type">Typ</string> - <string name="timetable_downloading">Fahrplan wird heruntergeladen</string> - <string name="search_placeholder">Haltestelle…</string> - <string name="no_connectivity_cant_update">Kein Verbindung – kann nicht den Fahrplan aktualisieren</string> - <string name="no_connectivity">Kein Verbindung</string> - <string name="timetable_up_to_date">Fahrplan ist aktuell</string> - <string name="error_try_later">Fehler. Versuch später noch einmal</string> - <string name="stop_already_fav">Diese Haltestelle ist bereits eine Lieblingshaltestelle</string> - <string name="action_edit">Bearbeiten</string> - <string name="action_delete">Löschen</string> - <string name="favourite_name">Lieblingshaltestelles Name</string> - <string name="edit_favourite_title">„%1$s“ bearbeiten</string> - <string name="no_next_departure">Keine nächste Abfahrt</string> - <string name="action_merge">Zusammenfügen</string> - <string name="merge_favourites">Lieblingshaltestellen zusammenfügen</string> - <string name="loading">Laden…</string> - <string name="refresh">Fahrplan aktualisieren</string> - <string name="title_activity_help">Hilfe</string> - <string name="valid_since">Gilt seit %1$s</string> - <string name="valid_till">Gilt bis %1$s</string> - <string name="departure_row_getting_departures">Abfahrten sammeln…</string> - <string name="no_departures">Keine Abfahrten</string> - <string name="tab_text_line_to">Hin</string> - <string name="tab_text_line_fro">Her</string> - <string name="timetable_validity_today">Fahrplan gilt nur bis heute.</string> - <string name="timetable_validity_finished">Die Gültigkeit des Zeitplans ist beendet. Verbind mit dem Internet, um eine neue herunterzuladen und um fortzufahren.</string> - <string name="timetable_validity_tomorrow">Fahrplan gilt nur bis morgen.</string> - <string name="just_departed">Gerade gegangen</string> - <string name="validity_offline_unavailable">Offline-Fahrplan ist nicht verfügbar</string> - <string name="pref_category_timetable">Fahrplan</string> - <string name="title_timetable_source_url">Quelle des Fahrplans</string> - <string name="title_activity_settings">Einstellungen</string> - <string name="settings">Einstellungen</string> - <string name="timetable_decompressing">Fahrplan wird entpackt</string> - <string name="Mon">Mo.</string> - <string name="Tue">Di.</string> - <string name="Wed">Mi.</string> - <string name="Thu">Do.</string> - <string name="Fri">Fr.</string> - <string name="Sat">Sa.</string> - <string name="Sun">So.</string> - <string name="title_timetable_automatic_update">Automatische Updates</string> - <string name="summary_timetable_automatic_update">Automatisch nach Fahrplanaktualisierungen suchen und diese herunterladen</string> - <string name="server_error">Serverfehler</string> -</resources> diff --git a/i18n/strings-it.xml b/i18n/strings-it.xml deleted file mode 100644 index 96a49332ee42d46b8a59b3170fcf498ed9af25f9..0000000000000000000000000000000000000000 --- a/i18n/strings-it.xml +++ /dev/null @@ -1,54 +0,0 @@ -<resources> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">Alle %1$s</string> - <string name="departure_in__singular_genitive">Tra %1$s minuto</string> - <string name="departure_in__plural_genitive">Tra %1$s minuti</string> - <string name="departure_in__plural_nominative">Tra %1$s minuti</string> - <string name="title_activity_help">Aiuto</string> - <string name="valid_since">Valido da %1$s</string> - <string name="valid_till">Valido a %1$s</string> - <string name="timetable_downloaded">Nuovo orario è stato scaricato</string> - <string name="action_change_type">Tipo</string> - <string name="timetable_downloading">Scaricando l’orario</string> - <string name="search_placeholder">Fermata…</string> - <string name="no_connectivity_cant_update">Nessuna connettività – non si riesce aggiornare l’orario</string> - <string name="no_connectivity">Nessuna connettività</string> - <string name="timetable_up_to_date">L’orario sta aggiornato</string> - <string name="error_try_later">Errore. Riprova più tardi</string> - <string name="now">Adesso</string> - <string name="stop_already_fav">Questa fermata è già un favorito</string> - <string name="action_edit">Modifica</string> - <string name="action_delete">Cancella</string> - <string name="favourite_name">Il nome del favorito</string> - <string name="edit_favourite_title">Modifica «%1$s»</string> - <string name="no_next_departure">Nessuna partenza successiva</string> - <string name="action_merge">Unisci</string> - <string name="merge_favourites">Unisci le favorite</string> - <string name="loading">Caricamento in corso…</string> - <string name="refresh">Aggiorna l’orario</string> - <string name="departure_row_getting_departures">Ottenere le partenze…</string> - <string name="no_departures">Nessune partenze</string> - <string name="tab_text_line_to">Avanti</string> - <string name="tab_text_line_fro">Indietro</string> - <string name="timetable_validity_today">L’orario è valido solo fino ad oggi.</string> - <string name="timetable_validity_finished">"La validità dell’orario è terminata. Connetti a Internet per scaricarne uno nuovo e continuare. "</string> - <string name="timetable_validity_tomorrow">L’orario è valido solo fino a domani.</string> - <string name="just_departed">Appena partito</string> - <string name="validity_offline_unavailable">L’orario offline non è disponibile</string> - <string name="pref_category_timetable">Orario</string> - <string name="title_timetable_source_url">Fonte dell’Orario</string> - <string name="title_activity_settings">Impostazioni</string> - <string name="settings">Impostazioni</string> - <string name="timetable_decompressing">Decomprimendo l’orario</string> - <string name="Mon">lun</string> - <string name="Tue">mar</string> - <string name="Wed">mer</string> - <string name="Thu">gio</string> - <string name="Fri">ven</string> - <string name="Sat">sab</string> - <string name="Sun">dom</string> - <string name="summary_timetable_automatic_update">Controlla e scarica automaticamente gli aggiornamenti dell’orario</string> - <string name="title_timetable_automatic_update">Aggiornamenti automatici</string> - <string name="server_error">Errore del server</string> -</resources> diff --git a/i18n/strings-nl.xml b/i18n/strings-nl.xml deleted file mode 100644 index afbe30f95d0afcd22d7b45bb8e25993b461c1f65..0000000000000000000000000000000000000000 --- a/i18n/strings-nl.xml +++ /dev/null @@ -1,56 +0,0 @@ -<resources> - <string name="timetable_downloaded">De nieuwe dienstregeling is gedownload</string> - <string name="action_change_type">Type</string> - <string name="departure_to">→ %1$s</string> - <string name="departure_to_line">%1$s → %2$s</string> - <string name="departure_at">Op %1$s</string> - <string name="timetable_downloading">Bezig met downloaden van dienstregeling</string> - <string name="search_placeholder">Halte…</string> - <string name="no_connectivity_cant_update">Geen internetverbinding – de dienstregeling kan niet worden bijgewerkt.</string> - <string name="no_connectivity">Geen internetverbinding</string> - <string name="timetable_up_to_date">De dienstregeling is volledig bijgewerkt.</string> - <string name="error_try_later">Fout; probeer het later opnieuw.</string> - <string name="now">Nu</string> - <string name="stop_already_fav">Deze halte staat al bij je favorieten</string> - <string name="action_edit">Bewerken</string> - <string name="action_delete">Verwijderen</string> - <string name="favourite_name">Naam van favoriet</string> - <string name="edit_favourite_title">‘%1$s’ bewerken</string> - <string name="no_next_departure">Geen vertrektijden</string> - <string name="action_merge">Samenvoegen</string> - <string name="merge_favourites">Favorieten samenvoegen</string> - <string name="loading">Bezig met laden…</string> - <string name="departure_in__singular_genitive">Over %1$s minuut</string> - <string name="departure_in__plural_genitive">Over %1$s minuten</string> - <string name="departure_in__plural_nominative">Over %1$s minuten</string> - - <string name="refresh">Dienstregeling bijwerken</string> - <string name="title_activity_help">Hulp</string> - <string name="departure_row_getting_departures">Bezig met ophalen van vertrektijden…</string> - <string name="valid_since">Ingegaan op %1$s</string> - <string name="valid_till">Verloopt op %1$s</string> - - <string name="no_departures">Geen vertrektijden</string> - <string name="tab_text_line_to">Naar</string> - <string name="tab_text_line_fro">Van</string> - <string name="timetable_validity_finished">De dienstregeling is verlopen. Maak verbinding met het internet om een nieuwe te downloaden.</string> - <string name="timetable_validity_today">De dienstregeling verloopt vandaag.</string> - <string name="timetable_validity_tomorrow">De dienstregeling verloopt morgen.</string> - <string name="just_departed">Zojuist vertrokken</string> - <string name="validity_offline_unavailable">Offline dienstregeling is niet beschikbaar</string> - <string name="pref_category_timetable">Dienstregeling</string> - <string name="title_timetable_source_url">Bron van de dienstregeling</string> - <string name="title_activity_settings">Instellingen</string> - <string name="settings">Instellingen</string> - <string name="timetable_decompressing">Bezig met uitpakken van dienstregeling</string> - <string name="Mon">ma</string> - <string name="Tue">di</string> - <string name="Wed">wo</string> - <string name="Thu">do</string> - <string name="Fri">vr</string> - <string name="Sat">za</string> - <string name="Sun">zo</string> - <string name="title_timetable_automatic_update">Automatische updates</string> - <string name="summary_timetable_automatic_update">Automatisch controleren en download dienstregeling updates</string> - <string name="server_error">Serverfout</string> -</resources> diff --git a/i18n/strings-pl.xml b/i18n/strings-pl.xml deleted file mode 100644 index 02ce0293314b34a070db9bff4bffac13496c51b9..0000000000000000000000000000000000000000 --- a/i18n/strings-pl.xml +++ /dev/null @@ -1,52 +0,0 @@ -timetable_downloaded = Pobrano nowy rozkład -action_change_type = Typ -departure_at = O %1$s -departure_to = → %1$s -timetable_downloading = Pobieranie rozkładu -search_placeholder = Przystanek… -timetable_up_to_date = Rozkład jest aktualny -no_connectivity_cant_update = Brak połączenia z Internetem – nie można zaktualizować rozkładu -no_connectivity = Brak połączenia z Internetem -error_try_later = Błąd. Spróbuj ponownie później -now = Teraz -stop_already_fav = Ten przystanek już jest pośród ulubionych -departure_to_line = %1$s → %2$s -action_delete = Usuń -action_edit = Edytuj -edit_favourite_title = Edytuj „%1$s” -favourite_name = Nazwa ulubionego -no_next_departure = Brak następnego odjazdu -action_merge = Połącz -merge_favourites = Połącz ulubione -loading = Ładowanie… -departure_in__singular_genitive = Za %1$s minutę -departure_in__plural_genitive = Za %1$s minut -departure_in__plural_nominative = Za %1$s minuty -refresh = Zaktualizuj rozkład -title_activity_help = Pomoc -departure_row_getting_departures = Zbieranie odjazdów… -valid_since = Ważny od %1$s -valid_till = Ważny do %1$s -no_departures = Brak odjazdów -tab_text_line_to = Tam -tab_text_line_fro = Z powrotem -timetable_validity_today = Rozkład obowiązuje tylko do dzisiaj. -timetable_validity_finished = Rozkład przestał obowiązywać. Połącz się z Internetem, aby pobrać nowy i kontynuować. -timetable_validity_tomorrow = Rozkład obowiązuje tylko do jutra. -just_departed = Właśnie odjechał -validity_offline_unavailable = Rozkład offline jest niedostępny -pref_category_timetable = Rozkład -title_timetable_source_url = Źródło rozkładu -title_activity_settings = Ustawienia -settings = Ustawienia -timetable_decompressing = Rozpakowywanie rozkładu -Mon = pon. -Tue = wt. -Wed = śr. -Thu = czw. -Fri = pt. -Sat = sob. -Sun = niedz. -summary_timetable_automatic_update = Automatycznie sprawdzaj i pobieraj aktualizacje rozkładu -title_timetable_automatic_update = Automatyczne aktualizacje -server_error = Błąd servera diff --git a/i18n/xml2po.py b/i18n/xml2po.py deleted file mode 100644 index 53a4ac73c4436121d509bf42f4e45052242e87c3..0000000000000000000000000000000000000000 --- a/i18n/xml2po.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/python3 - -import sys - -ids = {} -msgs = {} - -with open('ids') as ids_file: - for line in ids_file.readlines(): - id, msg = line.split(' = ') - ids[id] = msg.strip() - -for line in sys.stdin.readlines(): - id, msg = line.split(' = ') - msgs[id] = msg.strip() - -print('''#, fuzzy -msgid "" -msgstr "" -"MIME-Version: 1.0\\n" -"Content-Transfer-Encoding: 8bit\\n" -"Content-Type: text/plain; charset=UTF-8\\n" -''') - -for id, msg in msgs.items(): - print(f'msgid "{ids[id]}"') - print(f'msgstr "{msg}"') diff --git a/inari.svg b/inari.svg new file mode 100644 index 0000000000000000000000000000000000000000..33ef0449f475b445414c384d7050c0c552173d37 --- /dev/null +++ b/inari.svg @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + width="66.98246mm" + height="55.715553mm" + viewBox="0 0 66.98246 55.715553" + version="1.1" + id="svg5" + inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" + sodipodi:docname="drawing.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg"> + <sodipodi:namedview + id="namedview7" + pagecolor="#505050" + bordercolor="#eeeeee" + borderopacity="1" + inkscape:pageshadow="0" + inkscape:pageopacity="0" + inkscape:pagecheckerboard="0" + inkscape:document-units="mm" + showgrid="false" + inkscape:zoom="2.9362514" + inkscape:cx="109.66363" + inkscape:cy="116.30476" + inkscape:window-width="1920" + inkscape:window-height="1007" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:current-layer="layer1" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" /> + <defs + id="defs2" /> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-68.809603,-134.76337)"> + <g + id="g93742" + style="opacity:1"> + <ellipse + style="fill:#567ca0;fill-opacity:1;stroke-width:0.352122" + id="path76" + cx="74.383362" + cy="147.65054" + rx="5.5737591" + ry="5.313138" /> + <rect + style="fill:#b5c5c5;fill-opacity:1;stroke-width:0.264866" + id="rect180" + width="0.98591608" + height="33.420025" + x="73.769379" + y="152.92934" + ry="0" /> + <rect + style="fill:#798595;fill-opacity:1;stroke-width:0.264583" + id="rect284" + width="4.1957474" + height="7.8133383" + x="72.240288" + y="160.08839" /> + <path + id="rect286" + style="fill:#3f413c;fill-opacity:1;stroke-width:0.264583" + d="m 69.122551,186.42857 h 10.616875 v 3.85714 c -3.61761,0.26681 -7.1511,0.24826 -10.616875,0 z" + sodipodi:nodetypes="ccccc" /> + </g> + <g + id="g93748" + style="opacity:1"> + <path + style="fill:#53221b;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 85.111539,167.81735 5.761685,-3.25446 5.651425,-0.18282 6.146911,0.29303 4.65229,2.21507 -0.004,1.03917 -3.42174,2.39617 -13.590806,0.26858 z" + id="path573" /> + <path + id="rect995" + style="fill:#5d1c18;fill-opacity:1;stroke-width:0.999999" + d="m 364.35938,609.69922 v 47.28516 2.73046 h 1.83007 v -2.73046 -47.28516 z" + transform="scale(0.26458333)" /> + <path + style="fill:#da4e59;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 107.32381,166.88813 c 0.17887,-0.70857 -0.37741,-1.39599 -0.85581,-1.87043 -0.55448,-0.54375 -1.32405,-1.41023 -1.88439,-1.95734 -0.99251,-0.57802 -2.00332,-0.8984 -2.9239,-1.58632 -0.71176,-0.69646 -1.61272,-0.54635 -2.504459,-0.85685 -0.987749,-0.38335 -2.036605,-0.15004 -3.061415,-0.16444 -1.122642,0.12445 -2.25529,0.27454 -3.381729,0.40037 -0.863483,0.15571 -1.681674,0.48755 -2.422128,0.94552 -0.867217,0.26214 -1.547411,0.82582 -2.185826,1.44612 -0.789259,0.55813 -1.351825,1.34121 -2.036629,2.01205 -0.79524,0.5884 -0.879605,1.65158 -0.955985,2.56054 l 5.761685,-3.25446 5.651425,-0.18282 6.146911,0.29303 z" + id="path610" + sodipodi:nodetypes="ccccccccccc" /> + <path + id="rect1099" + style="fill:#743027;fill-opacity:1;stroke-width:0.264583" + d="m 96.403603,174.54978 h 1.29989 v 0 c 0,0 0.182881,2.34872 -0.629739,2.3552 -0.816203,0.007 -0.670151,-2.3552 -0.670151,-2.3552 z" + sodipodi:nodetypes="cccac" /> + </g> + <path + style="opacity:1;fill:#586c24;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" + d="m 124.288,137.28695 c 1.55667,0.0247 3.11335,0.0494 4.67002,0.0741 0.0656,-0.39103 0.14672,-0.81251 0.24808,-1.21017 0.22665,-0.37332 0.0954,-0.84353 0.26759,-1.20237 0.14774,-0.13672 0.64826,-0.36418 0.70598,0.0579 0.11517,0.41977 0.12391,0.92662 -0.058,1.3294 -0.10087,0.35297 -0.22333,0.72336 -0.38857,1.03184 1.59878,0.008 3.19756,0.0169 4.79634,0.0254 0.19706,0.32618 0.59875,0.21796 0.91466,0.39235 0.45633,0.0959 0.35374,0.5962 0.2949,1.00893 -0.32729,0.22892 -0.43162,0.6555 -0.8307,0.80451 -0.22902,0.28261 -0.57205,0.53644 -0.98158,0.35787 -0.51169,0.15718 -1.00745,-10e-4 -1.51752,-0.007 -0.38644,-0.0184 -0.68374,0.24067 -1.04592,0.36592 -0.39795,0.17617 -0.77318,0.43648 -1.05834,0.75772 -0.4346,0.48119 -0.95467,0.0349 -1.47961,0.0659 -0.41668,-0.1197 -0.69595,-0.41392 -1.07726,-0.616 -0.42922,-0.21433 -0.83971,-0.47247 -1.20031,-0.78722 -0.40077,-0.25153 -0.87849,-0.37984 -1.18117,-0.7678 -0.30003,-0.35635 -0.87962,-0.39383 -1.0307,-0.86207 -0.0807,-0.24907 -0.15484,-0.57474 -0.0479,-0.81961 z" + id="path2287" /> + <path + sodipodi:type="star" + style="opacity:1;fill:#ffe438;fill-opacity:1;stroke:none" + id="path96214" + inkscape:flatsided="false" + sodipodi:sides="5" + sodipodi:cx="268.70459" + sodipodi:cy="546.09521" + sodipodi:r1="27.938145" + sodipodi:r2="13.969073" + sodipodi:arg1="0.98751558" + sodipodi:arg2="1.6158341" + inkscape:rounded="0" + inkscape:randomized="0" + d="m 284.09195,569.41407 -16.01628,-9.36395 -16.79368,7.88527 3.95635,-18.12601 -12.68887,-13.53506 18.46144,-1.83853 8.95153,-16.25039 7.45345,16.98973 18.22121,3.49176 -13.85495,12.33877 z" + transform="matrix(0.13064095,0,0,0.13064095,39.153983,76.367755)" + inkscape:transform-center-x="-0.05077931" + inkscape:transform-center-y="-0.29988515" /> + </g> +</svg> diff --git a/metadata/en-US/changelogs/20.txt b/metadata/en-US/changelogs/20.txt new file mode 100644 index 0000000000000000000000000000000000000000..8976acc2147fe4e4d026f425de2915c6bed646a7 --- /dev/null +++ b/metadata/en-US/changelogs/20.txt @@ -0,0 +1,5 @@ +Version 3.0 is completely rewritten from scratch and features totally new architecture. + +* Favorites are removed +* Stops and vehicles are on map +* UI is now Material3 diff --git a/metadata/en-US/full_description.txt b/metadata/en-US/full_description.txt new file mode 100644 index 0000000000000000000000000000000000000000..54e327510dec975d7740b2c1d4ee297ae751647b --- /dev/null +++ b/metadata/en-US/full_description.txt @@ -0,0 +1,8 @@ +Bimba lets you check public transport timetable with realtime departures. Currently Poznań agglomeration (ZTM Poznań) is supported but more feeds will be added in the future. + +Current features: +* checking departures by stop, +* searching nearby stops, +* (ZTM Poznań only) searching stops by QR code +* vehicle attributes for departures +* vehicles and stops on map in real time diff --git a/metadata/en-US/images/featureGraphic.png b/metadata/en-US/images/featureGraphic.png new file mode 100644 index 0000000000000000000000000000000000000000..844a16c96d6c022afb07cdf727fa3230714650f9 Binary files /dev/null and b/metadata/en-US/images/featureGraphic.png differ diff --git a/metadata/en-US/images/icon.png b/metadata/en-US/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..51de732e44c246bac252b581c3bb1b3c9aa345c6 Binary files /dev/null and b/metadata/en-US/images/icon.png differ diff --git a/metadata/en-US/images/phoneScreenshots/Dash.png b/metadata/en-US/images/phoneScreenshots/Dash.png new file mode 100644 index 0000000000000000000000000000000000000000..146004687039135fbf1128f123d9fbb96cfcb92d Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/Dash.png differ diff --git a/metadata/en-US/images/phoneScreenshots/StopActivity.png b/metadata/en-US/images/phoneScreenshots/StopActivity.png new file mode 100644 index 0000000000000000000000000000000000000000..bd22a142e118239c447dd6a3f22f82b79f65f2c1 Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/StopActivity.png differ diff --git a/metadata/en-US/images/phoneScreenshots/map.png b/metadata/en-US/images/phoneScreenshots/map.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4c4ec3692bceb8a58ab7189f1182aa6393960a Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/map.png differ diff --git a/metadata/en-US/images/phoneScreenshots/mapBS.png b/metadata/en-US/images/phoneScreenshots/mapBS.png new file mode 100644 index 0000000000000000000000000000000000000000..47b86f8176f5710a9b88a60e9eb65ca2a6897f8f Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/mapBS.png differ diff --git a/metadata/en-US/images/phoneScreenshots/modification.png b/metadata/en-US/images/phoneScreenshots/modification.png new file mode 100644 index 0000000000000000000000000000000000000000..a838f5725c1cdcb0fe1328ab2815f62fc788b29d Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/modification.png differ diff --git a/metadata/en-US/images/phoneScreenshots/modification_more.png b/metadata/en-US/images/phoneScreenshots/modification_more.png new file mode 100644 index 0000000000000000000000000000000000000000..cfe8b805f78eb31aa4c8f6b777b0e41543cb6dad Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/modification_more.png differ diff --git a/metadata/en-US/images/phoneScreenshots/searchStop.png b/metadata/en-US/images/phoneScreenshots/searchStop.png new file mode 100644 index 0000000000000000000000000000000000000000..72028597f2ee1f7372327cd2adb8c2c9b3ec65b2 Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/searchStop.png differ diff --git a/metadata/en-US/images/phoneScreenshots/stopSpecify.png b/metadata/en-US/images/phoneScreenshots/stopSpecify.png new file mode 100644 index 0000000000000000000000000000000000000000..015d5e1fcd1d71dfb1f5fc56162e9bb5b75ca12a Binary files /dev/null and b/metadata/en-US/images/phoneScreenshots/stopSpecify.png differ diff --git a/metadata/en-US/short_description.txt b/metadata/en-US/short_description.txt new file mode 100644 index 0000000000000000000000000000000000000000..f9a5d1ebda7eb2bd14aeea0f93880337150b5563 --- /dev/null +++ b/metadata/en-US/short_description.txt @@ -0,0 +1 @@ +FLOSS public transport passenger companion; a timetable in your pocket. diff --git a/metadata/en-US/title.txt b/metadata/en-US/title.txt new file mode 100644 index 0000000000000000000000000000000000000000..038d5e6047bc863c8fd2210be761c396b834e447 --- /dev/null +++ b/metadata/en-US/title.txt @@ -0,0 +1 @@ +Bimba diff --git a/research/PDP b/research/PDP deleted file mode 100644 index 5ff738a2a11d6ca936d5d3002da3cc8fb3cf8266..0000000000000000000000000000000000000000 --- a/research/PDP +++ /dev/null @@ -1,26213 +0,0 @@ -function draw_clock() { - var n, r, t; - for (canvas = Raphael("analog", 100, 100), n = canvas.circle(25, 25, 23), n.attr({ - fill: "#F9F9F9", - stroke: "#003A7D", - "stroke-width": "2" - }), i = 0; i < 12; i++) { - var u = 25 + Math.round(18 * Math.cos(30 * i * Math.PI / 180)), - f = 25 + Math.round(18 * Math.sin(30 * i * Math.PI / 180)), - e = 25 + Math.round(22 * Math.cos(30 * i * Math.PI / 180)), - o = 25 + Math.round(22 * Math.sin(30 * i * Math.PI / 180)); - r = canvas.path("M" + u + " " + f + "L" + e + " " + o) - } - hour_hand = canvas.path("M 25 25 L 25 15"); - hour_hand.attr({ - stroke: "#003A7D", - "stroke-width": 2 - }); - minute_hand = canvas.path("M 25 25 L 25 10"); - minute_hand.attr({ - stroke: "#444444", - "stroke-width": 1 - }); - second_hand = canvas.path("M 25 30 L 25 8"); - second_hand.attr({ - stroke: "#003A7D", - "stroke-width": .5 - }); - t = canvas.circle(25, 25, 1); - t.attr("fill", "#003A7D"); - update_clock(); - setInterval("update_clock()", 1e3) -} - -function update_clock() { - var r = dateTimeFromServer - dateTimeFromClient, - u = (new Date).getTime(), - t = new Date; - t.setTime(u + r); - var n = t, - f = n.getHours(), - i = n.getMinutes(), - e = n.getSeconds(); - hour_hand.rotate(30 * f + i / 2.5, 25, 25); - minute_hand.rotate(6 * i, 25, 25); - second_hand.rotate(6 * e, 25, 25) -} - -function indirectStation() { - var i = $(".route ").find(".subRow").length, - n = $("#indirect"), - r = $("#newIndirect"), - u = '<div class="row btnRow"><button id="newIndirect" class="k-button k-button-get">' + C_DodajStacjePosrednia + "<\/button><\/div>", - t = $("#switchParamsMode").parent(); - i > 0 ? (n.attr("enable", "false").addClass("k-state-disabled"), n.text(C_PrzezStacjePosrednia), t.show(), r || $(".route .container").append(u)) : (n.removeAttr("enable").removeClass("k-state-disabled"), n.text(C_DodajStacjePosrednia), $("#newIndirect").parent(".btnRow").remove(), t.hide()) -} - -function countChecks(n) { - var r = n.closest(".layer").find("ul input:checkbox").length, - i = n.closest(".layer").find("ul input:checkbox:checked").length, - t = n.closest(".multiMenu").find(".num"); - t.html(""); - r === i ? (t.html(""), t.append("wszyscy")) : t.append("<span>wybrano " + i + "<\/span>") -} - -function null2empty(n, t, i) { - if (!t || t == "") return ""; - var r = i ? i : ""; - return n + " " + t + " " + r -} - -function minuty2MinGodz(n) { - n = Math.ceil(n); - var t = Math.floor(n / 60); - return t < 10 && (t = "0" + t), t += ":", n % 60 < 10 && (t += "0"), t + Math.round(n % 60) -} - -function minuty2HHmm(n) { - var t = Math.floor(n / 60), - i = n - t * 60; - return t < 10 && (t = "0" + t), i < 10 && (i = "0" + i), t + ":" + i -} - -function timeStamp2Tekst(n) { - return minuty2MinGodz(n.TotalMinutes) -} - -function jsonTime2Time(n, t) { - return n == "" ? "" : (t = typeof t != "undefined" ? t : "yyyy-MM-dd HH:mm", kendo.toString(new Date(parseInt(n.substr(6))), t)) -} - -function jsonTime2JsTime(n, t) { - return n == "" ? "" : (t = typeof t != "undefined" ? t : "yyyy-MM-dd HH:mm", new Date(parseInt(n.substr(6)))) -} - -function usunPolskieZnaki(n) { - return n = n.replace(/Ę/g, "E").replace(/ę/g, "e"), n = n.replace(/Ó/g, "O").replace(/o/g, "o"), n = n.replace(/Ą/g, "A").replace(/ą/g, "a"), n = n.replace(/Ś/g, "S").replace(/ś/g, "s"), n = n.replace(/Ł/g, "L").replace(/ł/g, "l"), n = n.replace(/Ż/g, "Z").replace(/ż/g, "z"), n = n.replace(/Ź/g, "Z").replace(/ź/g, "z"), n = n.replace(/Ć/g, "C").replace(/ć/g, "c"), n.replace(/Ń/g, "N").replace(/ń/g, "n") -} - -function generujHashDanych(n) { - var t = ""; - return t += n.StacjaPoczatkowaID.toString(), t += n.LiczbaPrzesiadek.toString(), t += Date.parse(n.Odjazd), t += Date.parse(n.Przyjazd), t + n.Pociagi[0].ZamowienieSKRJID.toString() -} -var dateTimeFromServer, dateTimeFromClient, mouse_is_inside; -(function(n, t) { - function dt(n) { - var t = n.length, - r = i.type(n); - return i.isWindow(n) ? !1 : 1 === n.nodeType && t ? !0 : "array" === r || "function" !== r && (0 === t || "number" == typeof t && t > 0 && t - 1 in n) - } - - function kf(n) { - var t = gt[n] = {}; - return i.each(n.match(s) || [], function(n, i) { - t[i] = !0 - }), t - } - - function ir(n, r, u, f) { - if (i.acceptData(n)) { - var s, h, c = i.expando, - a = "string" == typeof r, - l = n.nodeType, - o = l ? i.cache : n, - e = l ? n[c] : n[c] && c; - if (e && o[e] && (f || o[e].data) || !a || u !== t) return e || (l ? n[c] = e = b.pop() || i.guid++ : e = c), o[e] || (o[e] = {}, l || (o[e].toJSON = i.noop)), ("object" == typeof r || "function" == typeof r) && (f ? o[e] = i.extend(o[e], r) : o[e].data = i.extend(o[e].data, r)), s = o[e], f || (s.data || (s.data = {}), s = s.data), u !== t && (s[i.camelCase(r)] = u), a ? (h = s[r], null == h && (h = s[i.camelCase(r)])) : h = s, h - } - } - - function rr(n, t, r) { - if (i.acceptData(n)) { - var o, h, e, s = n.nodeType, - u = s ? i.cache : n, - f = s ? n[i.expando] : i.expando; - if (u[f]) { - if (t && (e = r ? u[f] : u[f].data)) { - for (i.isArray(t) ? t = t.concat(i.map(t, i.camelCase)) : (t in e) ? t = [t] : (t = i.camelCase(t), t = (t in e) ? [t] : t.split(" ")), o = 0, h = t.length; h > o; o++) delete e[t[o]]; - if (!(r ? ni : i.isEmptyObject)(e)) return - }(r || (delete u[f].data, ni(u[f]))) && (s ? i.cleanData([n], !0) : i.support.deleteExpando || u != u.window ? delete u[f] : u[f] = null) - } - } - } - - function ur(n, r, u) { - if (u === t && 1 === n.nodeType) { - var f = "data-" + r.replace(tr, "-$1").toLowerCase(); - if (u = n.getAttribute(f), "string" == typeof u) { - try { - u = "true" === u ? !0 : "false" === u ? !1 : "null" === u ? null : +u + "" === u ? +u : nr.test(u) ? i.parseJSON(u) : u - } catch (e) {} - i.data(n, r, u) - } else u = t - } - return u - } - - function ni(n) { - for (var t in n) - if (("data" !== t || !i.isEmptyObject(n[t])) && "toJSON" !== t) return !1; - return !0 - } - - function ht() { - return !0 - } - - function d() { - return !1 - } - - function cr(n, t) { - do n = n[t]; while (n && 1 !== n.nodeType); - return n - } - - function lr(n, t, r) { - if (t = t || 0, i.isFunction(t)) return i.grep(n, function(n, i) { - var u = !!t.call(n, i, n); - return u === r - }); - if (t.nodeType) return i.grep(n, function(n) { - return n === t === r - }); - if ("string" == typeof t) { - var u = i.grep(n, function(n) { - return 1 === n.nodeType - }); - if (fe.test(t)) return i.filter(t, u, !r); - t = i.filter(t, u) - } - return i.grep(n, function(n) { - return i.inArray(n, t) >= 0 === r - }) - } - - function ar(n) { - var i = vr.split("|"), - t = n.createDocumentFragment(); - if (t.createElement) - while (i.length) t.createElement(i.pop()); - return t - } - - function ye(n, t) { - return n.getElementsByTagName(t)[0] || n.appendChild(n.ownerDocument.createElement(t)) - } - - function dr(n) { - var t = n.getAttributeNode("type"); - return n.type = (t && t.specified) + "/" + n.type, n - } - - function gr(n) { - var t = le.exec(n.type); - return t ? n.type = t[1] : n.removeAttribute("type"), n - } - - function si(n, t) { - for (var u, r = 0; null != (u = n[r]); r++) i._data(u, "globalEval", !t || i._data(t[r], "globalEval")) - } - - function nu(n, t) { - if (1 === t.nodeType && i.hasData(n)) { - var u, f, o, s = i._data(n), - r = i._data(t, s), - e = s.events; - if (e) { - delete r.handle; - r.events = {}; - for (u in e) - for (f = 0, o = e[u].length; o > f; f++) i.event.add(t, u, e[u][f]) - } - r.data && (r.data = i.extend({}, r.data)) - } - } - - function pe(n, t) { - var r, f, u; - if (1 === t.nodeType) { - if (r = t.nodeName.toLowerCase(), !i.support.noCloneEvent && t[i.expando]) { - u = i._data(t); - for (f in u.events) i.removeEvent(t, f, u.handle); - t.removeAttribute(i.expando) - } - "script" === r && t.text !== n.text ? (dr(t).text = n.text, gr(t)) : "object" === r ? (t.parentNode && (t.outerHTML = n.outerHTML), i.support.html5Clone && n.innerHTML && !i.trim(t.innerHTML) && (t.innerHTML = n.innerHTML)) : "input" === r && ei.test(n.type) ? (t.defaultChecked = t.checked = n.checked, t.value !== n.value && (t.value = n.value)) : "option" === r ? t.defaultSelected = t.selected = n.defaultSelected : ("input" === r || "textarea" === r) && (t.defaultValue = n.defaultValue) - } - } - - function u(n, r) { - var s, e, h = 0, - f = typeof n.getElementsByTagName !== o ? n.getElementsByTagName(r || "*") : typeof n.querySelectorAll !== o ? n.querySelectorAll(r || "*") : t; - if (!f) - for (f = [], s = n.childNodes || n; null != (e = s[h]); h++) !r || i.nodeName(e, r) ? f.push(e) : i.merge(f, u(e, r)); - return r === t || r && i.nodeName(n, r) ? i.merge([n], f) : f - } - - function we(n) { - ei.test(n.type) && (n.defaultChecked = n.checked) - } - - function fu(n, t) { - if (t in n) return t; - for (var r = t.charAt(0).toUpperCase() + t.slice(1), u = t, i = uu.length; i--;) - if (t = uu[i] + r, t in n) return t; - return u - } - - function ut(n, t) { - return n = t || n, "none" === i.css(n, "display") || !i.contains(n.ownerDocument, n) - } - - function eu(n, t) { - for (var f, r, o, e = [], u = 0, s = n.length; s > u; u++) r = n[u], r.style && (e[u] = i._data(r, "olddisplay"), f = r.style.display, t ? (e[u] || "none" !== f || (r.style.display = ""), "" === r.style.display && ut(r) && (e[u] = i._data(r, "olddisplay", cu(r.nodeName)))) : e[u] || (o = ut(r), (f && "none" !== f || !o) && i._data(r, "olddisplay", o ? f : i.css(r, "display")))); - for (u = 0; s > u; u++) r = n[u], r.style && (t && "none" !== r.style.display && "" !== r.style.display || (r.style.display = t ? e[u] || "" : "none")); - return n - } - - function ou(n, t, i) { - var r = ge.exec(t); - return r ? Math.max(0, r[1] - (i || 0)) + (r[2] || "px") : t - } - - function su(n, t, r, u, f) { - for (var e = r === (u ? "border" : "content") ? 4 : "width" === t ? 1 : 0, o = 0; 4 > e; e += 2) "margin" === r && (o += i.css(n, r + p[e], !0, f)), u ? ("content" === r && (o -= i.css(n, "padding" + p[e], !0, f)), "margin" !== r && (o -= i.css(n, "border" + p[e] + "Width", !0, f))) : (o += i.css(n, "padding" + p[e], !0, f), "padding" !== r && (o += i.css(n, "border" + p[e] + "Width", !0, f))); - return o - } - - function hu(n, t, r) { - var e = !0, - u = "width" === t ? n.offsetWidth : n.offsetHeight, - f = v(n), - o = i.support.boxSizing && "border-box" === i.css(n, "boxSizing", !1, f); - if (0 >= u || null == u) { - if (u = y(n, t, f), (0 > u || null == u) && (u = n.style[t]), ct.test(u)) return u; - e = o && (i.support.boxSizingReliable || u === n.style[t]); - u = parseFloat(u) || 0 - } - return u + su(n, t, r || (o ? "border" : "content"), e, f) + "px" - } - - function cu(n) { - var u = r, - t = iu[n]; - return t || (t = lu(n, u), "none" !== t && t || (rt = (rt || i("<iframe frameborder='0' width='0' height='0'/>").css("cssText", "display:block !important")).appendTo(u.documentElement), u = (rt[0].contentWindow || rt[0].contentDocument).document, u.write("<!doctype html><html><body>"), u.close(), t = lu(n, u), rt.detach()), iu[n] = t), t - } - - function lu(n, t) { - var r = i(t.createElement(n)).appendTo(t.body), - u = i.css(r[0], "display"); - return r.remove(), u - } - - function ci(n, t, r, u) { - var f; - if (i.isArray(t)) i.each(t, function(t, i) { - r || ro.test(n) ? u(n, i) : ci(n + "[" + ("object" == typeof i ? t : "") + "]", i, r, u) - }); - else if (r || "object" !== i.type(t)) u(n, t); - else - for (f in t) ci(n + "[" + f + "]", t[f], r, u) - } - - function ku(n) { - return function(t, r) { - "string" != typeof t && (r = t, t = "*"); - var u, f = 0, - e = t.toLowerCase().match(s) || []; - if (i.isFunction(r)) - while (u = e[f++]) "+" === u[0] ? (u = u.slice(1) || "*", (n[u] = n[u] || []).unshift(r)) : (n[u] = n[u] || []).push(r) - } - } - - function du(n, r, u, f) { - function o(h) { - var c; - return e[h] = !0, i.each(n[h] || [], function(n, i) { - var h = i(r, u, f); - return "string" != typeof h || s || e[h] ? s ? !(c = h) : t : (r.dataTypes.unshift(h), o(h), !1) - }), c - } - var e = {}, - s = n === vi; - return o(r.dataTypes[0]) || !e["*"] && o("*") - } - - function yi(n, r) { - var f, u, e = i.ajaxSettings.flatOptions || {}; - for (u in r) r[u] !== t && ((e[u] ? n : f || (f = {}))[u] = r[u]); - return f && i.extend(!0, n, f), n - } - - function co(n, i, r) { - var s, o, e, u, h = n.contents, - f = n.dataTypes, - c = n.responseFields; - for (u in c) u in r && (i[c[u]] = r[u]); - while ("*" === f[0]) f.shift(), o === t && (o = n.mimeType || i.getResponseHeader("Content-Type")); - if (o) - for (u in h) - if (h[u] && h[u].test(o)) { - f.unshift(u); - break - } - if (f[0] in r) e = f[0]; - else { - for (u in r) { - if (!f[0] || n.converters[u + " " + f[0]]) { - e = u; - break - } - s || (s = u) - } - e = e || s - } - return e ? (e !== f[0] && f.unshift(e), r[e]) : t - } - - function lo(n, t) { - var o, r, i, e, u = {}, - h = 0, - s = n.dataTypes.slice(), - f = s[0]; - if (n.dataFilter && (t = n.dataFilter(t, n.dataType)), s[1]) - for (i in n.converters) u[i.toLowerCase()] = n.converters[i]; - for (; r = s[++h];) - if ("*" !== r) { - if ("*" !== f && f !== r) { - if (i = u[f + " " + r] || u["* " + r], !i) - for (o in u) - if (e = o.split(" "), e[1] === r && (i = u[f + " " + e[0]] || u["* " + e[0]])) { - i === !0 ? i = u[o] : u[o] !== !0 && (r = e[0], s.splice(h--, 0, r)); - break - } - if (i !== !0) - if (i && n.throws) t = i(t); - else try { - t = i(t) - } catch (c) { - return { - state: "parsererror", - error: i ? c : "No conversion from " + f + " to " + r - } - } - } - f = r - } - return { - state: "success", - data: t - } - } - - function nf() { - try { - return new n.XMLHttpRequest - } catch (t) {} - } - - function ao() { - try { - return new n.ActiveXObject("Microsoft.XMLHTTP") - } catch (t) {} - } - - function tf() { - return setTimeout(function() { - tt = t - }), tt = i.now() - } - - function wo(n, t) { - i.each(t, function(t, i) { - for (var u = (ft[t] || []).concat(ft["*"]), r = 0, f = u.length; f > r; r++) - if (u[r].call(n, t, i)) return - }) - } - - function rf(n, t, r) { - var h, e, o = 0, - l = yt.length, - f = i.Deferred().always(function() { - delete c.elem - }), - c = function() { - if (e) return !1; - for (var s = tt || tf(), t = Math.max(0, u.startTime + u.duration - s), h = t / u.duration || 0, i = 1 - h, r = 0, o = u.tweens.length; o > r; r++) u.tweens[r].run(i); - return f.notifyWith(n, [u, i, t]), 1 > i && o ? t : (f.resolveWith(n, [u]), !1) - }, - u = f.promise({ - elem: n, - props: i.extend({}, t), - opts: i.extend(!0, { - specialEasing: {} - }, r), - originalProperties: t, - originalOptions: r, - startTime: tt || tf(), - duration: r.duration, - tweens: [], - createTween: function(t, r) { - var f = i.Tween(n, u.opts, t, r, u.opts.specialEasing[t] || u.opts.easing); - return u.tweens.push(f), f - }, - stop: function(t) { - var i = 0, - r = t ? u.tweens.length : 0; - if (e) return this; - for (e = !0; r > i; i++) u.tweens[i].run(1); - return t ? f.resolveWith(n, [u, t]) : f.rejectWith(n, [u, t]), this - } - }), - s = u.props; - for (bo(s, u.opts.specialEasing); l > o; o++) - if (h = yt[o].call(u, n, s, u.opts)) return h; - return wo(u, s), i.isFunction(u.opts.start) && u.opts.start.call(n, u), i.fx.timer(i.extend(c, { - elem: n, - anim: u, - queue: u.opts.queue - })), u.progress(u.opts.progress).done(u.opts.done, u.opts.complete).fail(u.opts.fail).always(u.opts.always) - } - - function bo(n, t) { - var u, f, r, e, o; - for (r in n) - if (f = i.camelCase(r), e = t[f], u = n[r], i.isArray(u) && (e = u[1], u = n[r] = u[0]), r !== f && (n[f] = u, delete n[r]), o = i.cssHooks[f], o && "expand" in o) { - u = o.expand(u); - delete n[f]; - for (r in u) r in n || (n[r] = u[r], t[r] = e) - } else t[f] = e - } - - function ko(n, t, r) { - var u, o, w, a, s, v, l, f, b, h = this, - e = n.style, - y = {}, - p = [], - c = n.nodeType && ut(n); - r.queue || (f = i._queueHooks(n, "fx"), null == f.unqueued && (f.unqueued = 0, b = f.empty.fire, f.empty.fire = function() { - f.unqueued || b() - }), f.unqueued++, h.always(function() { - h.always(function() { - f.unqueued--; - i.queue(n, "fx").length || f.empty.fire() - }) - })); - 1 === n.nodeType && ("height" in t || "width" in t) && (r.overflow = [e.overflow, e.overflowX, e.overflowY], "inline" === i.css(n, "display") && "none" === i.css(n, "float") && (i.support.inlineBlockNeedsLayout && "inline" !== cu(n.nodeName) ? e.zoom = 1 : e.display = "inline-block")); - r.overflow && (e.overflow = "hidden", i.support.shrinkWrapBlocks || h.always(function() { - e.overflow = r.overflow[0]; - e.overflowX = r.overflow[1]; - e.overflowY = r.overflow[2] - })); - for (o in t) - if (a = t[o], vo.exec(a)) { - if (delete t[o], v = v || "toggle" === a, a === (c ? "hide" : "show")) continue; - p.push(o) - } - if (w = p.length) - for (s = i._data(n, "fxshow") || i._data(n, "fxshow", {}), ("hidden" in s) && (c = s.hidden), v && (s.hidden = !c), c ? i(n).show() : h.done(function() { - i(n).hide() - }), h.done(function() { - var t; - i._removeData(n, "fxshow"); - for (t in y) i.style(n, t, y[t]) - }), o = 0; w > o; o++) u = p[o], l = h.createTween(u, c ? s[u] : 0), y[u] = s[u] || i.style(n, u), u in s || (s[u] = l.start, c && (l.end = l.start, l.start = "width" === u || "height" === u ? 1 : 0)) - } - - function f(n, t, i, r, u) { - return new f.prototype.init(n, t, i, r, u) - } - - function pt(n, t) { - var r, i = { - height: n - }, - u = 0; - for (t = t ? 1 : 0; 4 > u; u += 2 - t) r = p[u], i["margin" + r] = i["padding" + r] = n; - return t && (i.opacity = i.width = n), i - } - - function uf(n) { - return i.isWindow(n) ? n : 9 === n.nodeType ? n.defaultView || n.parentWindow : !1 - } - var et, wi, o = typeof t, - r = n.document, - ff = n.location, - ef = n.jQuery, - of = n.$, - ot = {}, - b = [], - wt = "1.9.1", - bi = b.concat, - bt = b.push, - l = b.slice, - ki = b.indexOf, - sf = ot.toString, - it = ot.hasOwnProperty, - kt = wt.trim, - i = function(n, t) { - return new i.fn.init(n, t, wi) - }, - st = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, - s = /\S+/g, - hf = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - cf = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, - di = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, - lf = /^[\],:{}\s]*$/, - af = /(?:^|:|,)(?:\s*\[)+/g, - vf = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, - yf = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, - pf = /^-ms-/, - wf = /-([\da-z])/gi, - bf = function(n, t) { - return t.toUpperCase() - }, - h = function(n) { - (r.addEventListener || "load" === n.type || "complete" === r.readyState) && (gi(), i.ready()) - }, - gi = function() { - r.addEventListener ? (r.removeEventListener("DOMContentLoaded", h, !1), n.removeEventListener("load", h, !1)) : (r.detachEvent("onreadystatechange", h), n.detachEvent("onload", h)) - }, - gt, nr, tr, pi, lt, g, nt, gu, at; - i.fn = i.prototype = { - jquery: wt, - constructor: i, - init: function(n, u, f) { - var e, o; - if (!n) return this; - if ("string" == typeof n) { - if (e = "<" === n.charAt(0) && ">" === n.charAt(n.length - 1) && n.length >= 3 ? [null, n, null] : cf.exec(n), !e || !e[1] && u) return !u || u.jquery ? (u || f).find(n) : this.constructor(u).find(n); - if (e[1]) { - if (u = u instanceof i ? u[0] : u, i.merge(this, i.parseHTML(e[1], u && u.nodeType ? u.ownerDocument || u : r, !0)), di.test(e[1]) && i.isPlainObject(u)) - for (e in u) i.isFunction(this[e]) ? this[e](u[e]) : this.attr(e, u[e]); - return this - } - if (o = r.getElementById(e[2]), o && o.parentNode) { - if (o.id !== e[2]) return f.find(n); - this.length = 1; - this[0] = o - } - return this.context = r, this.selector = n, this - } - return n.nodeType ? (this.context = this[0] = n, this.length = 1, this) : i.isFunction(n) ? f.ready(n) : (n.selector !== t && (this.selector = n.selector, this.context = n.context), i.makeArray(n, this)) - }, - selector: "", - length: 0, - size: function() { - return this.length - }, - toArray: function() { - return l.call(this) - }, - get: function(n) { - return null == n ? this.toArray() : 0 > n ? this[this.length + n] : this[n] - }, - pushStack: function(n) { - var t = i.merge(this.constructor(), n); - return t.prevObject = this, t.context = this.context, t - }, - each: function(n, t) { - return i.each(this, n, t) - }, - ready: function(n) { - return i.ready.promise().done(n), this - }, - slice: function() { - return this.pushStack(l.apply(this, arguments)) - }, - first: function() { - return this.eq(0) - }, - last: function() { - return this.eq(-1) - }, - eq: function(n) { - var i = this.length, - t = +n + (0 > n ? i : 0); - return this.pushStack(t >= 0 && i > t ? [this[t]] : []) - }, - map: function(n) { - return this.pushStack(i.map(this, function(t, i) { - return n.call(t, i, t) - })) - }, - end: function() { - return this.prevObject || this.constructor(null) - }, - push: bt, - sort: [].sort, - splice: [].splice - }; - i.fn.init.prototype = i.fn; - i.extend = i.fn.extend = function() { - var u, o, r, e, s, h, n = arguments[0] || {}, - f = 1, - l = arguments.length, - c = !1; - for ("boolean" == typeof n && (c = n, n = arguments[1] || {}, f = 2), "object" == typeof n || i.isFunction(n) || (n = {}), l === f && (n = this, --f); l > f; f++) - if (null != (s = arguments[f])) - for (e in s) u = n[e], r = s[e], n !== r && (c && r && (i.isPlainObject(r) || (o = i.isArray(r))) ? (o ? (o = !1, h = u && i.isArray(u) ? u : []) : h = u && i.isPlainObject(u) ? u : {}, n[e] = i.extend(c, h, r)) : r !== t && (n[e] = r)); - return n - }; - i.extend({ - noConflict: function(t) { - return n.$ === i && (n.$ = of ), t && n.jQuery === i && (n.jQuery = ef), i - }, - isReady: !1, - readyWait: 1, - holdReady: function(n) { - n ? i.readyWait++ : i.ready(!0) - }, - ready: function(n) { - if (n === !0 ? !--i.readyWait : !i.isReady) { - if (!r.body) return setTimeout(i.ready); - i.isReady = !0; - n !== !0 && --i.readyWait > 0 || (et.resolveWith(r, [i]), i.fn.trigger && i(r).trigger("ready").off("ready")) - } - }, - isFunction: function(n) { - return "function" === i.type(n) - }, - isArray: Array.isArray || function(n) { - return "array" === i.type(n) - }, - isWindow: function(n) { - return null != n && n == n.window - }, - isNumeric: function(n) { - return !isNaN(parseFloat(n)) && isFinite(n) - }, - type: function(n) { - return null == n ? n + "" : "object" == typeof n || "function" == typeof n ? ot[sf.call(n)] || "object" : typeof n - }, - isPlainObject: function(n) { - if (!n || "object" !== i.type(n) || n.nodeType || i.isWindow(n)) return !1; - try { - if (n.constructor && !it.call(n, "constructor") && !it.call(n.constructor.prototype, "isPrototypeOf")) return !1 - } catch (u) { - return !1 - } - for (var r in n); - return r === t || it.call(n, r) - }, - isEmptyObject: function(n) { - for (var t in n) return !1; - return !0 - }, - error: function(n) { - throw Error(n); - }, - parseHTML: function(n, t, u) { - if (!n || "string" != typeof n) return null; - "boolean" == typeof t && (u = t, t = !1); - t = t || r; - var f = di.exec(n), - e = !u && []; - return f ? [t.createElement(f[1])] : (f = i.buildFragment([n], t, e), e && i(e).remove(), i.merge([], f.childNodes)) - }, - parseJSON: function(r) { - return n.JSON && n.JSON.parse ? n.JSON.parse(r) : null === r ? r : "string" == typeof r && (r = i.trim(r), r && lf.test(r.replace(vf, "@").replace(yf, "]").replace(af, ""))) ? Function("return " + r)() : (i.error("Invalid JSON: " + r), t) - }, - parseXML: function(r) { - var u, f; - if (!r || "string" != typeof r) return null; - try { - n.DOMParser ? (f = new DOMParser, u = f.parseFromString(r, "text/xml")) : (u = new ActiveXObject("Microsoft.XMLDOM"), u.async = "false", u.loadXML(r)) - } catch (e) { - u = t - } - return u && u.documentElement && !u.getElementsByTagName("parsererror").length || i.error("Invalid XML: " + r), u - }, - noop: function() {}, - globalEval: function(t) { - t && i.trim(t) && (n.execScript || function(t) { - n.eval.call(n, t) - })(t) - }, - camelCase: function(n) { - return n.replace(pf, "ms-").replace(wf, bf) - }, - nodeName: function(n, t) { - return n.nodeName && n.nodeName.toLowerCase() === t.toLowerCase() - }, - each: function(n, t, i) { - var u, r = 0, - f = n.length, - e = dt(n); - if (i) { - if (e) { - for (; f > r; r++) - if (u = t.apply(n[r], i), u === !1) break - } else - for (r in n) - if (u = t.apply(n[r], i), u === !1) break - } else if (e) { - for (; f > r; r++) - if (u = t.call(n[r], r, n[r]), u === !1) break - } else - for (r in n) - if (u = t.call(n[r], r, n[r]), u === !1) break; - return n - }, - trim: kt && !kt.call(" ") ? function(n) { - return null == n ? "" : kt.call(n) - } : function(n) { - return null == n ? "" : (n + "").replace(hf, "") - }, - makeArray: function(n, t) { - var r = t || []; - return null != n && (dt(Object(n)) ? i.merge(r, "string" == typeof n ? [n] : n) : bt.call(r, n)), r - }, - inArray: function(n, t, i) { - var r; - if (t) { - if (ki) return ki.call(t, n, i); - for (r = t.length, i = i ? 0 > i ? Math.max(0, r + i) : i : 0; r > i; i++) - if (i in t && t[i] === n) return i - } - return -1 - }, - merge: function(n, i) { - var f = i.length, - u = n.length, - r = 0; - if ("number" == typeof f) - for (; f > r; r++) n[u++] = i[r]; - else - while (i[r] !== t) n[u++] = i[r++]; - return n.length = u, n - }, - grep: function(n, t, i) { - var u, f = [], - r = 0, - e = n.length; - for (i = !!i; e > r; r++) u = !!t(n[r], r), i !== u && f.push(n[r]); - return f - }, - map: function(n, t, i) { - var u, r = 0, - e = n.length, - o = dt(n), - f = []; - if (o) - for (; e > r; r++) u = t(n[r], r, i), null != u && (f[f.length] = u); - else - for (r in n) u = t(n[r], r, i), null != u && (f[f.length] = u); - return bi.apply([], f) - }, - guid: 1, - proxy: function(n, r) { - var f, u, e; - return "string" == typeof r && (e = n[r], r = n, n = e), i.isFunction(n) ? (f = l.call(arguments, 2), u = function() { - return n.apply(r || this, f.concat(l.call(arguments))) - }, u.guid = n.guid = n.guid || i.guid++, u) : t - }, - access: function(n, r, u, f, e, o, s) { - var h = 0, - l = n.length, - c = null == u; - if ("object" === i.type(u)) { - e = !0; - for (h in u) i.access(n, r, h, u[h], !0, o, s) - } else if (f !== t && (e = !0, i.isFunction(f) || (s = !0), c && (s ? (r.call(n, f), r = null) : (c = r, r = function(n, t, r) { - return c.call(i(n), r) - })), r)) - for (; l > h; h++) r(n[h], u, s ? f : f.call(n[h], h, r(n[h], u))); - return e ? n : c ? r.call(n) : l ? r(n[0], u) : o - }, - now: function() { - return (new Date).getTime() - } - }); - i.ready.promise = function(t) { - if (!et) - if (et = i.Deferred(), "complete" === r.readyState) setTimeout(i.ready); - else if (r.addEventListener) r.addEventListener("DOMContentLoaded", h, !1), n.addEventListener("load", h, !1); - else { - r.attachEvent("onreadystatechange", h); - n.attachEvent("onload", h); - var u = !1; - try { - u = null == n.frameElement && r.documentElement - } catch (e) {} - u && u.doScroll && function f() { - if (!i.isReady) { - try { - u.doScroll("left") - } catch (n) { - return setTimeout(f, 50) - } - gi(); - i.ready() - } - }() - } - return et.promise(t) - }; - i.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(n, t) { - ot["[object " + t + "]"] = t.toLowerCase() - }); - wi = i(r); - gt = {}; - i.Callbacks = function(n) { - n = "string" == typeof n ? gt[n] || kf(n) : i.extend({}, n); - var o, f, c, s, e, l, r = [], - u = !n.once && [], - a = function(t) { - for (f = n.memory && t, c = !0, e = l || 0, l = 0, s = r.length, o = !0; r && s > e; e++) - if (r[e].apply(t[0], t[1]) === !1 && n.stopOnFalse) { - f = !1; - break - } - o = !1; - r && (u ? u.length && a(u.shift()) : f ? r = [] : h.disable()) - }, - h = { - add: function() { - if (r) { - var t = r.length; - (function u(t) { - i.each(t, function(t, f) { - var e = i.type(f); - "function" === e ? n.unique && h.has(f) || r.push(f) : f && f.length && "string" !== e && u(f) - }) - })(arguments); - o ? s = r.length : f && (l = t, a(f)) - } - return this - }, - remove: function() { - return r && i.each(arguments, function(n, t) { - for (var u; - (u = i.inArray(t, r, u)) > -1;) r.splice(u, 1), o && (s >= u && s--, e >= u && e--) - }), this - }, - has: function(n) { - return n ? i.inArray(n, r) > -1 : !(!r || !r.length) - }, - empty: function() { - return r = [], this - }, - disable: function() { - return r = u = f = t, this - }, - disabled: function() { - return !r - }, - lock: function() { - return u = t, f || h.disable(), this - }, - locked: function() { - return !u - }, - fireWith: function(n, t) { - return t = t || [], t = [n, t.slice ? t.slice() : t], !r || c && !u || (o ? u.push(t) : a(t)), this - }, - fire: function() { - return h.fireWith(this, arguments), this - }, - fired: function() { - return !!c - } - }; - return h - }; - i.extend({ - Deferred: function(n) { - var u = [ - ["resolve", "done", i.Callbacks("once memory"), "resolved"], - ["reject", "fail", i.Callbacks("once memory"), "rejected"], - ["notify", "progress", i.Callbacks("memory")] - ], - f = "pending", - r = { - state: function() { - return f - }, - always: function() { - return t.done(arguments).fail(arguments), this - }, - then: function() { - var n = arguments; - return i.Deferred(function(f) { - i.each(u, function(u, e) { - var s = e[0], - o = i.isFunction(n[u]) && n[u]; - t[e[1]](function() { - var n = o && o.apply(this, arguments); - n && i.isFunction(n.promise) ? n.promise().done(f.resolve).fail(f.reject).progress(f.notify) : f[s + "With"](this === r ? f.promise() : this, o ? [n] : arguments) - }) - }); - n = null - }).promise() - }, - promise: function(n) { - return null != n ? i.extend(n, r) : r - } - }, - t = {}; - return r.pipe = r.then, i.each(u, function(n, i) { - var e = i[2], - o = i[3]; - r[i[1]] = e.add; - o && e.add(function() { - f = o - }, u[1 ^ n][2].disable, u[2][2].lock); - t[i[0]] = function() { - return t[i[0] + "With"](this === t ? r : this, arguments), this - }; - t[i[0] + "With"] = e.fireWith - }), r.promise(t), n && n.call(t, t), t - }, - when: function(n) { - var t = 0, - u = l.call(arguments), - r = u.length, - e = 1 !== r || n && i.isFunction(n.promise) ? r : 0, - f = 1 === e ? n : i.Deferred(), - h = function(n, t, i) { - return function(r) { - t[n] = this; - i[n] = arguments.length > 1 ? l.call(arguments) : r; - i === o ? f.notifyWith(t, i) : --e || f.resolveWith(t, i) - } - }, - o, c, s; - if (r > 1) - for (o = Array(r), c = Array(r), s = Array(r); r > t; t++) u[t] && i.isFunction(u[t].promise) ? u[t].promise().done(h(t, s, u)).fail(f.reject).progress(h(t, c, o)) : --e; - return e || f.resolveWith(s, u), f.promise() - } - }); - i.support = function() { - var u, s, e, f, h, c, l, a, y, v, t = r.createElement("div"); - if (t.setAttribute("className", "t"), t.innerHTML = " <link/><table><\/table><a href='/a'>a<\/a><input type='checkbox'/>", s = t.getElementsByTagName("*"), e = t.getElementsByTagName("a")[0], !s || !e || !s.length) return {}; - h = r.createElement("select"); - l = h.appendChild(r.createElement("option")); - f = t.getElementsByTagName("input")[0]; - e.style.cssText = "top:1px;float:left;opacity:.5"; - u = { - getSetAttribute: "t" !== t.className, - leadingWhitespace: 3 === t.firstChild.nodeType, - tbody: !t.getElementsByTagName("tbody").length, - htmlSerialize: !!t.getElementsByTagName("link").length, - style: /top/.test(e.getAttribute("style")), - hrefNormalized: "/a" === e.getAttribute("href"), - opacity: /^0.5/.test(e.style.opacity), - cssFloat: !!e.style.cssFloat, - checkOn: !!f.value, - optSelected: l.selected, - enctype: !!r.createElement("form").enctype, - html5Clone: "<:nav><\/:nav>" !== r.createElement("nav").cloneNode(!0).outerHTML, - boxModel: "CSS1Compat" === r.compatMode, - deleteExpando: !0, - noCloneEvent: !0, - inlineBlockNeedsLayout: !1, - shrinkWrapBlocks: !1, - reliableMarginRight: !0, - boxSizingReliable: !0, - pixelPosition: !1 - }; - f.checked = !0; - u.noCloneChecked = f.cloneNode(!0).checked; - h.disabled = !0; - u.optDisabled = !l.disabled; - try { - delete t.test - } catch (p) { - u.deleteExpando = !1 - } - f = r.createElement("input"); - f.setAttribute("value", ""); - u.input = "" === f.getAttribute("value"); - f.value = "t"; - f.setAttribute("type", "radio"); - u.radioValue = "t" === f.value; - f.setAttribute("checked", "t"); - f.setAttribute("name", "t"); - c = r.createDocumentFragment(); - c.appendChild(f); - u.appendChecked = f.checked; - u.checkClone = c.cloneNode(!0).cloneNode(!0).lastChild.checked; - t.attachEvent && (t.attachEvent("onclick", function() { - u.noCloneEvent = !1 - }), t.cloneNode(!0).click()); - for (v in { - submit: !0, - change: !0, - focusin: !0 - }) t.setAttribute(a = "on" + v, "t"), u[v + "Bubbles"] = a in n || t.attributes[a].expando === !1; - return t.style.backgroundClip = "content-box", t.cloneNode(!0).style.backgroundClip = "", u.clearCloneStyle = "content-box" === t.style.backgroundClip, i(function() { - var e, f, i, h = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", - s = r.getElementsByTagName("body")[0]; - s && (e = r.createElement("div"), e.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px", s.appendChild(e).appendChild(t), t.innerHTML = "<table><tr><td><\/td><td>t<\/td><\/tr><\/table>", i = t.getElementsByTagName("td"), i[0].style.cssText = "padding:0;margin:0;border:0;display:none", y = 0 === i[0].offsetHeight, i[0].style.display = "", i[1].style.display = "none", u.reliableHiddenOffsets = y && 0 === i[0].offsetHeight, t.innerHTML = "", t.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;", u.boxSizing = 4 === t.offsetWidth, u.doesNotIncludeMarginInBodyOffset = 1 !== s.offsetTop, n.getComputedStyle && (u.pixelPosition = "1%" !== (n.getComputedStyle(t, null) || {}).top, u.boxSizingReliable = "4px" === (n.getComputedStyle(t, null) || { - width: "4px" - }).width, f = t.appendChild(r.createElement("div")), f.style.cssText = t.style.cssText = h, f.style.marginRight = f.style.width = "0", t.style.width = "1px", u.reliableMarginRight = !parseFloat((n.getComputedStyle(f, null) || {}).marginRight)), typeof t.style.zoom !== o && (t.innerHTML = "", t.style.cssText = h + "width:1px;padding:1px;display:inline;zoom:1", u.inlineBlockNeedsLayout = 3 === t.offsetWidth, t.style.display = "block", t.innerHTML = "<div><\/div>", t.firstChild.style.width = "5px", u.shrinkWrapBlocks = 3 !== t.offsetWidth, u.inlineBlockNeedsLayout && (s.style.zoom = 1)), s.removeChild(e), e = t = i = f = null) - }), s = h = c = l = e = f = null, u - }(); - nr = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/; - tr = /([A-Z])/g; - i.extend({ - cache: {}, - expando: "jQuery" + (wt + Math.random()).replace(/\D/g, ""), - noData: { - embed: !0, - object: "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", - applet: !0 - }, - hasData: function(n) { - return n = n.nodeType ? i.cache[n[i.expando]] : n[i.expando], !!n && !ni(n) - }, - data: function(n, t, i) { - return ir(n, t, i) - }, - removeData: function(n, t) { - return rr(n, t) - }, - _data: function(n, t, i) { - return ir(n, t, i, !0) - }, - _removeData: function(n, t) { - return rr(n, t, !0) - }, - acceptData: function(n) { - if (n.nodeType && 1 !== n.nodeType && 9 !== n.nodeType) return !1; - var t = n.nodeName && i.noData[n.nodeName.toLowerCase()]; - return !t || t !== !0 && n.getAttribute("classid") === t - } - }); - i.fn.extend({ - data: function(n, r) { - var e, f, u = this[0], - o = 0, - s = null; - if (n === t) { - if (this.length && (s = i.data(u), 1 === u.nodeType && !i._data(u, "parsedAttrs"))) { - for (e = u.attributes; e.length > o; o++) f = e[o].name, f.indexOf("data-") || (f = i.camelCase(f.slice(5)), ur(u, f, s[f])); - i._data(u, "parsedAttrs", !0) - } - return s - } - return "object" == typeof n ? this.each(function() { - i.data(this, n) - }) : i.access(this, function(r) { - return r === t ? u ? ur(u, n, i.data(u, n)) : null : (this.each(function() { - i.data(this, n, r) - }), t) - }, null, r, arguments.length > 1, null, !0) - }, - removeData: function(n) { - return this.each(function() { - i.removeData(this, n) - }) - } - }); - i.extend({ - queue: function(n, r, u) { - var f; - return n ? (r = (r || "fx") + "queue", f = i._data(n, r), u && (!f || i.isArray(u) ? f = i._data(n, r, i.makeArray(u)) : f.push(u)), f || []) : t - }, - dequeue: function(n, t) { - t = t || "fx"; - var f = i.queue(n, t), - e = f.length, - r = f.shift(), - u = i._queueHooks(n, t), - o = function() { - i.dequeue(n, t) - }; - "inprogress" === r && (r = f.shift(), e--); - u.cur = r; - r && ("fx" === t && f.unshift("inprogress"), delete u.stop, r.call(n, o, u)); - !e && u && u.empty.fire() - }, - _queueHooks: function(n, t) { - var r = t + "queueHooks"; - return i._data(n, r) || i._data(n, r, { - empty: i.Callbacks("once memory").add(function() { - i._removeData(n, t + "queue"); - i._removeData(n, r) - }) - }) - } - }); - i.fn.extend({ - queue: function(n, r) { - var u = 2; - return "string" != typeof n && (r = n, n = "fx", u--), u > arguments.length ? i.queue(this[0], n) : r === t ? this : this.each(function() { - var t = i.queue(this, n, r); - i._queueHooks(this, n); - "fx" === n && "inprogress" !== t[0] && i.dequeue(this, n) - }) - }, - dequeue: function(n) { - return this.each(function() { - i.dequeue(this, n) - }) - }, - delay: function(n, t) { - return n = i.fx ? i.fx.speeds[n] || n : n, t = t || "fx", this.queue(t, function(t, i) { - var r = setTimeout(t, n); - i.stop = function() { - clearTimeout(r) - } - }) - }, - clearQueue: function(n) { - return this.queue(n || "fx", []) - }, - promise: function(n, r) { - var u, e = 1, - o = i.Deferred(), - f = this, - s = this.length, - h = function() { - --e || o.resolveWith(f, [f]) - }; - for ("string" != typeof n && (r = n, n = t), n = n || "fx"; s--;) u = i._data(f[s], n + "queueHooks"), u && u.empty && (e++, u.empty.add(h)); - return h(), o.promise(r) - } - }); - var k, fr, ti = /[\t\r\n]/g, - df = /\r/g, - gf = /^(?:input|select|textarea|button|object)$/i, - ne = /^(?:a|area)$/i, - er = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i, - ii = /^(?:checked|selected)$/i, - a = i.support.getSetAttribute, - ri = i.support.input; - i.fn.extend({ - attr: function(n, t) { - return i.access(this, i.attr, n, t, arguments.length > 1) - }, - removeAttr: function(n) { - return this.each(function() { - i.removeAttr(this, n) - }) - }, - prop: function(n, t) { - return i.access(this, i.prop, n, t, arguments.length > 1) - }, - removeProp: function(n) { - return n = i.propFix[n] || n, this.each(function() { - try { - this[n] = t; - delete this[n] - } catch (i) {} - }) - }, - addClass: function(n) { - var e, t, r, u, o, f = 0, - h = this.length, - c = "string" == typeof n && n; - if (i.isFunction(n)) return this.each(function(t) { - i(this).addClass(n.call(this, t, this.className)) - }); - if (c) - for (e = (n || "").match(s) || []; h > f; f++) - if (t = this[f], r = 1 === t.nodeType && (t.className ? (" " + t.className + " ").replace(ti, " ") : " ")) { - for (o = 0; u = e[o++];) 0 > r.indexOf(" " + u + " ") && (r += u + " "); - t.className = i.trim(r) - } - return this - }, - removeClass: function(n) { - var e, t, r, u, o, f = 0, - h = this.length, - c = 0 === arguments.length || "string" == typeof n && n; - if (i.isFunction(n)) return this.each(function(t) { - i(this).removeClass(n.call(this, t, this.className)) - }); - if (c) - for (e = (n || "").match(s) || []; h > f; f++) - if (t = this[f], r = 1 === t.nodeType && (t.className ? (" " + t.className + " ").replace(ti, " ") : "")) { - for (o = 0; u = e[o++];) - while (r.indexOf(" " + u + " ") >= 0) r = r.replace(" " + u + " ", " "); - t.className = n ? i.trim(r) : "" - } - return this - }, - toggleClass: function(n, t) { - var r = typeof n, - u = "boolean" == typeof t; - return i.isFunction(n) ? this.each(function(r) { - i(this).toggleClass(n.call(this, r, this.className, t), t) - }) : this.each(function() { - if ("string" === r) - for (var f, c = 0, h = i(this), e = t, l = n.match(s) || []; f = l[c++];) e = u ? e : !h.hasClass(f), h[e ? "addClass" : "removeClass"](f); - else(r === o || "boolean" === r) && (this.className && i._data(this, "__className__", this.className), this.className = this.className || n === !1 ? "" : i._data(this, "__className__") || "") - }) - }, - hasClass: function(n) { - for (var i = " " + n + " ", t = 0, r = this.length; r > t; t++) - if (1 === this[t].nodeType && (" " + this[t].className + " ").replace(ti, " ").indexOf(i) >= 0) return !0; - return !1 - }, - val: function(n) { - var u, r, e, f = this[0]; - return arguments.length ? (e = i.isFunction(n), this.each(function(u) { - var f, o = i(this); - 1 === this.nodeType && (f = e ? n.call(this, u, o.val()) : n, null == f ? f = "" : "number" == typeof f ? f += "" : i.isArray(f) && (f = i.map(f, function(n) { - return null == n ? "" : n + "" - })), r = i.valHooks[this.type] || i.valHooks[this.nodeName.toLowerCase()], r && "set" in r && r.set(this, f, "value") !== t || (this.value = f)) - })) : f ? (r = i.valHooks[f.type] || i.valHooks[f.nodeName.toLowerCase()], r && "get" in r && (u = r.get(f, "value")) !== t ? u : (u = f.value, "string" == typeof u ? u.replace(df, "") : null == u ? "" : u)) : void 0 - } - }); - i.extend({ - valHooks: { - option: { - get: function(n) { - var t = n.attributes.value; - return !t || t.specified ? n.value : n.text - } - }, - select: { - get: function(n) { - for (var e, t, o = n.options, r = n.selectedIndex, u = "select-one" === n.type || 0 > r, s = u ? null : [], h = u ? r + 1 : o.length, f = 0 > r ? h : u ? r : 0; h > f; f++) - if (t = o[f], !(!t.selected && f !== r || (i.support.optDisabled ? t.disabled : null !== t.getAttribute("disabled")) || t.parentNode.disabled && i.nodeName(t.parentNode, "optgroup"))) { - if (e = i(t).val(), u) return e; - s.push(e) - } - return s - }, - set: function(n, t) { - var r = i.makeArray(t); - return i(n).find("option").each(function() { - this.selected = i.inArray(i(this).val(), r) >= 0 - }), r.length || (n.selectedIndex = -1), r - } - } - }, - attr: function(n, r, u) { - var f, s, e, h = n.nodeType; - if (n && 3 !== h && 8 !== h && 2 !== h) return typeof n.getAttribute === o ? i.prop(n, r, u) : (s = 1 !== h || !i.isXMLDoc(n), s && (r = r.toLowerCase(), f = i.attrHooks[r] || (er.test(r) ? fr : k)), u === t ? f && s && "get" in f && null !== (e = f.get(n, r)) ? e : (typeof n.getAttribute !== o && (e = n.getAttribute(r)), null == e ? t : e) : null !== u ? f && s && "set" in f && (e = f.set(n, u, r)) !== t ? e : (n.setAttribute(r, u + ""), u) : (i.removeAttr(n, r), t)) - }, - removeAttr: function(n, t) { - var r, u, e = 0, - f = t && t.match(s); - if (f && 1 === n.nodeType) - while (r = f[e++]) u = i.propFix[r] || r, er.test(r) ? !a && ii.test(r) ? n[i.camelCase("default-" + r)] = n[u] = !1 : n[u] = !1 : i.attr(n, r, ""), n.removeAttribute(a ? r : u) - }, - attrHooks: { - type: { - set: function(n, t) { - if (!i.support.radioValue && "radio" === t && i.nodeName(n, "input")) { - var r = n.value; - return n.setAttribute("type", t), r && (n.value = r), t - } - } - } - }, - propFix: { - tabindex: "tabIndex", - readonly: "readOnly", - "for": "htmlFor", - "class": "className", - maxlength: "maxLength", - cellspacing: "cellSpacing", - cellpadding: "cellPadding", - rowspan: "rowSpan", - colspan: "colSpan", - usemap: "useMap", - frameborder: "frameBorder", - contenteditable: "contentEditable" - }, - prop: function(n, r, u) { - var e, f, s, o = n.nodeType; - if (n && 3 !== o && 8 !== o && 2 !== o) return s = 1 !== o || !i.isXMLDoc(n), s && (r = i.propFix[r] || r, f = i.propHooks[r]), u !== t ? f && "set" in f && (e = f.set(n, u, r)) !== t ? e : n[r] = u : f && "get" in f && null !== (e = f.get(n, r)) ? e : n[r] - }, - propHooks: { - tabIndex: { - get: function(n) { - var i = n.getAttributeNode("tabindex"); - return i && i.specified ? parseInt(i.value, 10) : gf.test(n.nodeName) || ne.test(n.nodeName) && n.href ? 0 : t - } - } - } - }); - fr = { - get: function(n, r) { - var u = i.prop(n, r), - f = "boolean" == typeof u && n.getAttribute(r), - e = "boolean" == typeof u ? ri && a ? null != f : ii.test(r) ? n[i.camelCase("default-" + r)] : !!f : n.getAttributeNode(r); - return e && e.value !== !1 ? r.toLowerCase() : t - }, - set: function(n, t, r) { - return t === !1 ? i.removeAttr(n, r) : ri && a || !ii.test(r) ? n.setAttribute(!a && i.propFix[r] || r, r) : n[i.camelCase("default-" + r)] = n[r] = !0, r - } - }; - ri && a || (i.attrHooks.value = { - get: function(n, r) { - var u = n.getAttributeNode(r); - return i.nodeName(n, "input") ? n.defaultValue : u && u.specified ? u.value : t - }, - set: function(n, r, u) { - return i.nodeName(n, "input") ? (n.defaultValue = r, t) : k && k.set(n, r, u) - } - }); - a || (k = i.valHooks.button = { - get: function(n, i) { - var r = n.getAttributeNode(i); - return r && ("id" === i || "name" === i || "coords" === i ? "" !== r.value : r.specified) ? r.value : t - }, - set: function(n, i, r) { - var u = n.getAttributeNode(r); - return u || n.setAttributeNode(u = n.ownerDocument.createAttribute(r)), u.value = i += "", "value" === r || i === n.getAttribute(r) ? i : t - } - }, i.attrHooks.contenteditable = { - get: k.get, - set: function(n, t, i) { - k.set(n, "" === t ? !1 : t, i) - } - }, i.each(["width", "height"], function(n, r) { - i.attrHooks[r] = i.extend(i.attrHooks[r], { - set: function(n, i) { - return "" === i ? (n.setAttribute(r, "auto"), i) : t - } - }) - })); - i.support.hrefNormalized || (i.each(["href", "src", "width", "height"], function(n, r) { - i.attrHooks[r] = i.extend(i.attrHooks[r], { - get: function(n) { - var i = n.getAttribute(r, 2); - return null == i ? t : i - } - }) - }), i.each(["href", "src"], function(n, t) { - i.propHooks[t] = { - get: function(n) { - return n.getAttribute(t, 4) - } - } - })); - i.support.style || (i.attrHooks.style = { - get: function(n) { - return n.style.cssText || t - }, - set: function(n, t) { - return n.style.cssText = t + "" - } - }); - i.support.optSelected || (i.propHooks.selected = i.extend(i.propHooks.selected, { - get: function(n) { - var t = n.parentNode; - return t && (t.selectedIndex, t.parentNode && t.parentNode.selectedIndex), null - } - })); - i.support.enctype || (i.propFix.enctype = "encoding"); - i.support.checkOn || i.each(["radio", "checkbox"], function() { - i.valHooks[this] = { - get: function(n) { - return null === n.getAttribute("value") ? "on" : n.value - } - } - }); - i.each(["radio", "checkbox"], function() { - i.valHooks[this] = i.extend(i.valHooks[this], { - set: function(n, r) { - return i.isArray(r) ? n.checked = i.inArray(i(n).val(), r) >= 0 : t - } - }) - }); - var ui = /^(?:input|select|textarea)$/i, - te = /^key/, - ie = /^(?:mouse|contextmenu)|click/, - or = /^(?:focusinfocus|focusoutblur)$/, - sr = /^([^.]*)(?:\.(.+)|)$/; - i.event = { - global: {}, - add: function(n, r, u, f, e) { - var b, p, k, w, c, l, a, v, h, d, g, y = i._data(n); - if (y) { - for (u.handler && (w = u, u = w.handler, e = w.selector), u.guid || (u.guid = i.guid++), (p = y.events) || (p = y.events = {}), (l = y.handle) || (l = y.handle = function(n) { - return typeof i === o || n && i.event.triggered === n.type ? t : i.event.dispatch.apply(l.elem, arguments) - }, l.elem = n), r = (r || "").match(s) || [""], k = r.length; k--;) b = sr.exec(r[k]) || [], h = g = b[1], d = (b[2] || "").split(".").sort(), c = i.event.special[h] || {}, h = (e ? c.delegateType : c.bindType) || h, c = i.event.special[h] || {}, a = i.extend({ - type: h, - origType: g, - data: f, - handler: u, - guid: u.guid, - selector: e, - needsContext: e && i.expr.match.needsContext.test(e), - namespace: d.join(".") - }, w), (v = p[h]) || (v = p[h] = [], v.delegateCount = 0, c.setup && c.setup.call(n, f, d, l) !== !1 || (n.addEventListener ? n.addEventListener(h, l, !1) : n.attachEvent && n.attachEvent("on" + h, l))), c.add && (c.add.call(n, a), a.handler.guid || (a.handler.guid = u.guid)), e ? v.splice(v.delegateCount++, 0, a) : v.push(a), i.event.global[h] = !0; - n = null - } - }, - remove: function(n, t, r, u, f) { - var y, o, h, b, p, a, c, l, e, w, k, v = i.hasData(n) && i._data(n); - if (v && (a = v.events)) { - for (t = (t || "").match(s) || [""], p = t.length; p--;) - if (h = sr.exec(t[p]) || [], e = k = h[1], w = (h[2] || "").split(".").sort(), e) { - for (c = i.event.special[e] || {}, e = (u ? c.delegateType : c.bindType) || e, l = a[e] || [], h = h[2] && RegExp("(^|\\.)" + w.join("\\.(?:.*\\.|)") + "(\\.|$)"), b = y = l.length; y--;) o = l[y], !f && k !== o.origType || r && r.guid !== o.guid || h && !h.test(o.namespace) || u && u !== o.selector && ("**" !== u || !o.selector) || (l.splice(y, 1), o.selector && l.delegateCount--, c.remove && c.remove.call(n, o)); - b && !l.length && (c.teardown && c.teardown.call(n, w, v.handle) !== !1 || i.removeEvent(n, e, v.handle), delete a[e]) - } else - for (e in a) i.event.remove(n, e + t[p], r, u, !0); - i.isEmptyObject(a) && (delete v.handle, i._removeData(n, "events")) - } - }, - trigger: function(u, f, e, o) { - var a, v, h, p, l, c, w, b = [e || r], - s = it.call(u, "type") ? u.type : u, - y = it.call(u, "namespace") ? u.namespace.split(".") : []; - if (h = c = e = e || r, 3 !== e.nodeType && 8 !== e.nodeType && !or.test(s + i.event.triggered) && (s.indexOf(".") >= 0 && (y = s.split("."), s = y.shift(), y.sort()), v = 0 > s.indexOf(":") && "on" + s, u = u[i.expando] ? u : new i.Event(s, "object" == typeof u && u), u.isTrigger = !0, u.namespace = y.join("."), u.namespace_re = u.namespace ? RegExp("(^|\\.)" + y.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, u.result = t, u.target || (u.target = e), f = null == f ? [u] : i.makeArray(f, [u]), l = i.event.special[s] || {}, o || !l.trigger || l.trigger.apply(e, f) !== !1)) { - if (!o && !l.noBubble && !i.isWindow(e)) { - for (p = l.delegateType || s, or.test(p + s) || (h = h.parentNode); h; h = h.parentNode) b.push(h), c = h; - c === (e.ownerDocument || r) && b.push(c.defaultView || c.parentWindow || n) - } - for (w = 0; - (h = b[w++]) && !u.isPropagationStopped();) u.type = w > 1 ? p : l.bindType || s, a = (i._data(h, "events") || {})[u.type] && i._data(h, "handle"), a && a.apply(h, f), a = v && h[v], a && i.acceptData(h) && a.apply && a.apply(h, f) === !1 && u.preventDefault(); - if (u.type = s, !(o || u.isDefaultPrevented() || l._default && l._default.apply(e.ownerDocument, f) !== !1 || "click" === s && i.nodeName(e, "a") || !i.acceptData(e) || !v || !e[s] || i.isWindow(e))) { - c = e[v]; - c && (e[v] = null); - i.event.triggered = s; - try { - e[s]() - } catch (k) {} - i.event.triggered = t; - c && (e[v] = c) - } - return u.result - } - }, - dispatch: function(n) { - n = i.event.fix(n); - var o, e, r, u, s, h = [], - c = l.call(arguments), - a = (i._data(this, "events") || {})[n.type] || [], - f = i.event.special[n.type] || {}; - if (c[0] = n, n.delegateTarget = this, !f.preDispatch || f.preDispatch.call(this, n) !== !1) { - for (h = i.event.handlers.call(this, n, a), o = 0; - (u = h[o++]) && !n.isPropagationStopped();) - for (n.currentTarget = u.elem, s = 0; - (r = u.handlers[s++]) && !n.isImmediatePropagationStopped();)(!n.namespace_re || n.namespace_re.test(r.namespace)) && (n.handleObj = r, n.data = r.data, e = ((i.event.special[r.origType] || {}).handle || r.handler).apply(u.elem, c), e !== t && (n.result = e) === !1 && (n.preventDefault(), n.stopPropagation())); - return f.postDispatch && f.postDispatch.call(this, n), n.result - } - }, - handlers: function(n, r) { - var e, o, f, s, c = [], - h = r.delegateCount, - u = n.target; - if (h && u.nodeType && (!n.button || "click" !== n.type)) - for (; u != this; u = u.parentNode || this) - if (1 === u.nodeType && (u.disabled !== !0 || "click" !== n.type)) { - for (f = [], s = 0; h > s; s++) o = r[s], e = o.selector + " ", f[e] === t && (f[e] = o.needsContext ? i(e, this).index(u) >= 0 : i.find(e, this, null, [u]).length), f[e] && f.push(o); - f.length && c.push({ - elem: u, - handlers: f - }) - } - return r.length > h && c.push({ - elem: this, - handlers: r.slice(h) - }), c - }, - fix: function(n) { - if (n[i.expando]) return n; - var e, o, s, u = n.type, - f = n, - t = this.fixHooks[u]; - for (t || (this.fixHooks[u] = t = ie.test(u) ? this.mouseHooks : te.test(u) ? this.keyHooks : {}), s = t.props ? this.props.concat(t.props) : this.props, n = new i.Event(f), e = s.length; e--;) o = s[e], n[o] = f[o]; - return n.target || (n.target = f.srcElement || r), 3 === n.target.nodeType && (n.target = n.target.parentNode), n.metaKey = !!n.metaKey, t.filter ? t.filter(n, f) : n - }, - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - fixHooks: {}, - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function(n, t) { - return null == n.which && (n.which = null != t.charCode ? t.charCode : t.keyCode), n - } - }, - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function(n, i) { - var u, o, f, e = i.button, - s = i.fromElement; - return null == n.pageX && null != i.clientX && (o = n.target.ownerDocument || r, f = o.documentElement, u = o.body, n.pageX = i.clientX + (f && f.scrollLeft || u && u.scrollLeft || 0) - (f && f.clientLeft || u && u.clientLeft || 0), n.pageY = i.clientY + (f && f.scrollTop || u && u.scrollTop || 0) - (f && f.clientTop || u && u.clientTop || 0)), !n.relatedTarget && s && (n.relatedTarget = s === n.target ? i.toElement : s), n.which || e === t || (n.which = 1 & e ? 1 : 2 & e ? 3 : 4 & e ? 2 : 0), n - } - }, - special: { - load: { - noBubble: !0 - }, - click: { - trigger: function() { - return i.nodeName(this, "input") && "checkbox" === this.type && this.click ? (this.click(), !1) : t - } - }, - focus: { - trigger: function() { - if (this !== r.activeElement && this.focus) try { - return this.focus(), !1 - } catch (n) {} - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - return this === r.activeElement && this.blur ? (this.blur(), !1) : t - }, - delegateType: "focusout" - }, - beforeunload: { - postDispatch: function(n) { - n.result !== t && (n.originalEvent.returnValue = n.result) - } - } - }, - simulate: function(n, t, r, u) { - var f = i.extend(new i.Event, r, { - type: n, - isSimulated: !0, - originalEvent: {} - }); - u ? i.event.trigger(f, null, t) : i.event.dispatch.call(t, f); - f.isDefaultPrevented() && r.preventDefault() - } - }; - i.removeEvent = r.removeEventListener ? function(n, t, i) { - n.removeEventListener && n.removeEventListener(t, i, !1) - } : function(n, t, i) { - var r = "on" + t; - n.detachEvent && (typeof n[r] === o && (n[r] = null), n.detachEvent(r, i)) - }; - i.Event = function(n, r) { - return this instanceof i.Event ? (n && n.type ? (this.originalEvent = n, this.type = n.type, this.isDefaultPrevented = n.defaultPrevented || n.returnValue === !1 || n.getPreventDefault && n.getPreventDefault() ? ht : d) : this.type = n, r && i.extend(this, r), this.timeStamp = n && n.timeStamp || i.now(), this[i.expando] = !0, t) : new i.Event(n, r) - }; - i.Event.prototype = { - isDefaultPrevented: d, - isPropagationStopped: d, - isImmediatePropagationStopped: d, - preventDefault: function() { - var n = this.originalEvent; - this.isDefaultPrevented = ht; - n && (n.preventDefault ? n.preventDefault() : n.returnValue = !1) - }, - stopPropagation: function() { - var n = this.originalEvent; - this.isPropagationStopped = ht; - n && (n.stopPropagation && n.stopPropagation(), n.cancelBubble = !0) - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = ht; - this.stopPropagation() - } - }; - i.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" - }, function(n, t) { - i.event.special[n] = { - delegateType: t, - bindType: t, - handle: function(n) { - var u, f = this, - r = n.relatedTarget, - e = n.handleObj; - return (!r || r !== f && !i.contains(f, r)) && (n.type = e.origType, u = e.handler.apply(this, arguments), n.type = t), u - } - } - }); - i.support.submitBubbles || (i.event.special.submit = { - setup: function() { - return i.nodeName(this, "form") ? !1 : (i.event.add(this, "click._submit keypress._submit", function(n) { - var u = n.target, - r = i.nodeName(u, "input") || i.nodeName(u, "button") ? u.form : t; - r && !i._data(r, "submitBubbles") && (i.event.add(r, "submit._submit", function(n) { - n._submit_bubble = !0 - }), i._data(r, "submitBubbles", !0)) - }), t) - }, - postDispatch: function(n) { - n._submit_bubble && (delete n._submit_bubble, this.parentNode && !n.isTrigger && i.event.simulate("submit", this.parentNode, n, !0)) - }, - teardown: function() { - return i.nodeName(this, "form") ? !1 : (i.event.remove(this, "._submit"), t) - } - }); - i.support.changeBubbles || (i.event.special.change = { - setup: function() { - return ui.test(this.nodeName) ? (("checkbox" === this.type || "radio" === this.type) && (i.event.add(this, "propertychange._change", function(n) { - "checked" === n.originalEvent.propertyName && (this._just_changed = !0) - }), i.event.add(this, "click._change", function(n) { - this._just_changed && !n.isTrigger && (this._just_changed = !1); - i.event.simulate("change", this, n, !0) - })), !1) : (i.event.add(this, "beforeactivate._change", function(n) { - var t = n.target; - ui.test(t.nodeName) && !i._data(t, "changeBubbles") && (i.event.add(t, "change._change", function(n) { - !this.parentNode || n.isSimulated || n.isTrigger || i.event.simulate("change", this.parentNode, n, !0) - }), i._data(t, "changeBubbles", !0)) - }), t) - }, - handle: function(n) { - var i = n.target; - return this !== i || n.isSimulated || n.isTrigger || "radio" !== i.type && "checkbox" !== i.type ? n.handleObj.handler.apply(this, arguments) : t - }, - teardown: function() { - return i.event.remove(this, "._change"), !ui.test(this.nodeName) - } - }); - i.support.focusinBubbles || i.each({ - focus: "focusin", - blur: "focusout" - }, function(n, t) { - var u = 0, - f = function(n) { - i.event.simulate(t, n.target, i.event.fix(n), !0) - }; - i.event.special[t] = { - setup: function() { - 0 == u++ && r.addEventListener(n, f, !0) - }, - teardown: function() { - 0 == --u && r.removeEventListener(n, f, !0) - } - } - }); - i.fn.extend({ - on: function(n, r, u, f, e) { - var s, o; - if ("object" == typeof n) { - "string" != typeof r && (u = u || r, r = t); - for (s in n) this.on(s, r, u, n[s], e); - return this - } - if (null == u && null == f ? (f = r, u = r = t) : null == f && ("string" == typeof r ? (f = u, u = t) : (f = u, u = r, r = t)), f === !1) f = d; - else if (!f) return this; - return 1 === e && (o = f, f = function(n) { - return i().off(n), o.apply(this, arguments) - }, f.guid = o.guid || (o.guid = i.guid++)), this.each(function() { - i.event.add(this, n, f, u, r) - }) - }, - one: function(n, t, i, r) { - return this.on(n, t, i, r, 1) - }, - off: function(n, r, u) { - var f, e; - if (n && n.preventDefault && n.handleObj) return f = n.handleObj, i(n.delegateTarget).off(f.namespace ? f.origType + "." + f.namespace : f.origType, f.selector, f.handler), this; - if ("object" == typeof n) { - for (e in n) this.off(e, r, n[e]); - return this - } - return (r === !1 || "function" == typeof r) && (u = r, r = t), u === !1 && (u = d), this.each(function() { - i.event.remove(this, n, u, r) - }) - }, - bind: function(n, t, i) { - return this.on(n, null, t, i) - }, - unbind: function(n, t) { - return this.off(n, null, t) - }, - delegate: function(n, t, i, r) { - return this.on(t, n, i, r) - }, - undelegate: function(n, t, i) { - return 1 === arguments.length ? this.off(n, "**") : this.off(t, n || "**", i) - }, - trigger: function(n, t) { - return this.each(function() { - i.event.trigger(n, t, this) - }) - }, - triggerHandler: function(n, r) { - var u = this[0]; - return u ? i.event.trigger(n, r, u, !0) : t - } - }), - function(n, t) { - function ti(n) { - return tr.test(n + "") - } - - function ii() { - var n, t = []; - return n = function(i, u) { - return t.push(i += " ") > r.cacheLength && delete n[t.shift()], n[i] = u - } - } - - function l(n) { - return n[f] = !0, n - } - - function b(n) { - var t = s.createElement("div"); - try { - return n(t) - } catch (i) { - return !1 - } finally { - t = null - } - } - - function u(n, t, i, r) { - var y, u, e, l, p, v, w, h, d, b; - if ((t ? t.ownerDocument || t : k) !== s && it(t), t = t || s, i = i || [], !n || "string" != typeof n) return i; - if (1 !== (l = t.nodeType) && 9 !== l) return []; - if (!c && !r) { - if (y = ir.exec(n)) - if (e = y[1]) { - if (9 === l) { - if (u = t.getElementById(e), !u || !u.parentNode) return i; - if (u.id === e) return i.push(u), i - } else if (t.ownerDocument && (u = t.ownerDocument.getElementById(e)) && et(t, u) && u.id === e) return i.push(u), i - } else { - if (y[2]) return ut.apply(i, ft.call(t.getElementsByTagName(n), 0)), i; - if ((e = y[3]) && o.getByClassName && t.getElementsByClassName) return ut.apply(i, ft.call(t.getElementsByClassName(e), 0)), i - } - if (o.qsa && !a.test(n)) { - if (w = !0, h = f, d = t, b = 9 === l && n, 1 === l && "object" !== t.nodeName.toLowerCase()) { - for (v = yt(n), (w = t.getAttribute("id")) ? h = w.replace(fr, "\\$&") : t.setAttribute("id", h), h = "[id='" + h + "'] ", p = v.length; p--;) v[p] = h + pt(v[p]); - d = ni.test(n) && t.parentNode || t; - b = v.join(",") - } - if (b) try { - return ut.apply(i, ft.call(d.querySelectorAll(b), 0)), i - } catch (g) {} finally { - w || t.removeAttribute("id") - } - } - } - return lr(n.replace(at, "$1"), t, i, r) - } - - function yi(n, t) { - var i = t && n, - r = i && (~t.sourceIndex || li) - (~n.sourceIndex || li); - if (r) return r; - if (i) - while (i = i.nextSibling) - if (i === t) return -1; - return n ? 1 : -1 - } - - function or(n) { - return function(t) { - var i = t.nodeName.toLowerCase(); - return "input" === i && t.type === n - } - } - - function sr(n) { - return function(t) { - var i = t.nodeName.toLowerCase(); - return ("input" === i || "button" === i) && t.type === n - } - } - - function g(n) { - return l(function(t) { - return t = +t, l(function(i, r) { - for (var u, f = n([], i.length, t), e = f.length; e--;) i[u = f[e]] && (i[u] = !(r[u] = i[u])) - }) - }) - } - - function yt(n, t) { - var e, f, s, o, i, h, c, l = hi[n + " "]; - if (l) return t ? 0 : l.slice(0); - for (i = n, h = [], c = r.preFilter; i;) { - (!e || (f = ki.exec(i))) && (f && (i = i.slice(f[0].length) || i), h.push(s = [])); - e = !1; - (f = di.exec(i)) && (e = f.shift(), s.push({ - value: e, - type: f[0].replace(at, " ") - }), i = i.slice(e.length)); - for (o in r.filter)(f = vt[o].exec(i)) && (!c[o] || (f = c[o](f))) && (e = f.shift(), s.push({ - value: e, - type: o, - matches: f - }), i = i.slice(e.length)); - if (!e) break - } - return t ? i.length : i ? u.error(n) : hi(n, h).slice(0) - } - - function pt(n) { - for (var t = 0, r = n.length, i = ""; r > t; t++) i += n[t].value; - return i - } - - function ri(n, t, i) { - var r = t.dir, - u = i && "parentNode" === r, - e = wi++; - return t.first ? function(t, i, f) { - while (t = t[r]) - if (1 === t.nodeType || u) return n(t, i, f) - } : function(t, i, o) { - var h, s, c, l = v + " " + e; - if (o) { - while (t = t[r]) - if ((1 === t.nodeType || u) && n(t, i, o)) return !0 - } else - while (t = t[r]) - if (1 === t.nodeType || u) - if (c = t[f] || (t[f] = {}), (s = c[r]) && s[0] === l) { - if ((h = s[1]) === !0 || h === ot) return h === !0 - } else if (s = c[r] = [l], s[1] = n(t, i, o) || ot, s[1] === !0) return !0 - } - } - - function ui(n) { - return n.length > 1 ? function(t, i, r) { - for (var u = n.length; u--;) - if (!n[u](t, i, r)) return !1; - return !0 - } : n[0] - } - - function wt(n, t, i, r, u) { - for (var e, o = [], f = 0, s = n.length, h = null != t; s > f; f++)(e = n[f]) && (!i || i(e, r, u)) && (o.push(e), h && t.push(f)); - return o - } - - function fi(n, t, i, r, u, e) { - return r && !r[f] && (r = fi(r)), u && !u[f] && (u = fi(u, e)), l(function(f, e, o, s) { - var l, c, a, p = [], - y = [], - w = e.length, - b = f || cr(t || "*", o.nodeType ? [o] : o, []), - v = !n || !f && t ? b : wt(b, p, n, o, s), - h = i ? u || (f ? n : w || r) ? [] : e : v; - if (i && i(v, h, o, s), r) - for (l = wt(h, y), r(l, [], o, s), c = l.length; c--;)(a = l[c]) && (h[y[c]] = !(v[y[c]] = a)); - if (f) { - if (u || n) { - if (u) { - for (l = [], c = h.length; c--;)(a = h[c]) && l.push(v[c] = a); - u(null, h = [], l, s) - } - for (c = h.length; c--;)(a = h[c]) && (l = u ? dt.call(f, a) : p[c]) > -1 && (f[l] = !(e[l] = a)) - } - } else h = wt(h === e ? h.splice(w, h.length) : h), u ? u(null, e, h, s) : ut.apply(e, h) - }) - } - - function ei(n) { - for (var s, u, i, o = n.length, h = r.relative[n[0].type], c = h || r.relative[" "], t = h ? 1 : 0, l = ri(function(n) { - return n === s - }, c, !0), a = ri(function(n) { - return dt.call(s, n) > -1 - }, c, !0), e = [function(n, t, i) { - return !h && (i || t !== ht) || ((s = t).nodeType ? l(n, t, i) : a(n, t, i)) - }]; o > t; t++) - if (u = r.relative[n[t].type]) e = [ri(ui(e), u)]; - else { - if (u = r.filter[n[t].type].apply(null, n[t].matches), u[f]) { - for (i = ++t; o > i; i++) - if (r.relative[n[i].type]) break; - return fi(t > 1 && ui(e), t > 1 && pt(n.slice(0, t - 1)).replace(at, "$1"), u, i > t && ei(n.slice(t, i)), o > i && ei(n = n.slice(i)), o > i && pt(n)) - } - e.push(u) - } - return ui(e) - } - - function hr(n, t) { - var f = 0, - i = t.length > 0, - e = n.length > 0, - o = function(o, h, c, l, a) { - var p, d, b, w = [], - k = 0, - y = "0", - g = o && [], - nt = null != a, - tt = ht, - rt = o || e && r.find.TAG("*", a && h.parentNode || h), - it = v += null == tt ? 1 : Math.random() || .1; - for (nt && (ht = h !== s && h, ot = f); null != (p = rt[y]); y++) { - if (e && p) { - for (d = 0; b = n[d++];) - if (b(p, h, c)) { - l.push(p); - break - } - nt && (v = it, ot = ++f) - } - i && ((p = !b && p) && k--, o && g.push(p)) - } - if (k += y, i && y !== k) { - for (d = 0; b = t[d++];) b(g, w, h, c); - if (o) { - if (k > 0) - while (y--) g[y] || w[y] || (w[y] = bi.call(l)); - w = wt(w) - } - ut.apply(l, w); - nt && !o && w.length > 0 && k + t.length > 1 && u.uniqueSort(l) - } - return nt && (v = it, ht = tt), g - }; - return i ? l(o) : o - } - - function cr(n, t, i) { - for (var r = 0, f = t.length; f > r; r++) u(n, t[r], i); - return i - } - - function lr(n, t, i, u) { - var o, f, e, h, l, s = yt(n); - if (!u && 1 === s.length) { - if (f = s[0] = s[0].slice(0), f.length > 2 && "ID" === (e = f[0]).type && 9 === t.nodeType && !c && r.relative[f[1].type]) { - if (t = r.find.ID(e.matches[0].replace(p, w), t)[0], !t) return i; - n = n.slice(f.shift().value.length) - } - for (o = vt.needsContext.test(n) ? 0 : f.length; o--;) { - if (e = f[o], r.relative[h = e.type]) break; - if ((l = r.find[h]) && (u = l(e.matches[0].replace(p, w), ni.test(f[0].type) && t.parentNode || t))) { - if (f.splice(o, 1), n = u.length && pt(f), !n) return ut.apply(i, ft.call(u, 0)), i; - break - } - } - } - return bt(n, s)(u, t, c, i, ni.test(n)), i - } - - function pi() {} - var nt, ot, r, st, oi, bt, tt, ht, it, s, h, c, a, rt, ct, et, kt, f = "sizzle" + -new Date, - k = n.document, - o = {}, - v = 0, - wi = 0, - si = ii(), - hi = ii(), - ci = ii(), - y = typeof t, - li = -2147483648, - lt = [], - bi = lt.pop, - ut = lt.push, - ft = lt.slice, - dt = lt.indexOf || function(n) { - for (var t = 0, i = this.length; i > t; t++) - if (this[t] === n) return t; - return -1 - }, - e = "[\\x20\\t\\r\\n\\f]", - d = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - ai = d.replace("w", "w#"), - vi = "\\[" + e + "*(" + d + ")" + e + "*(?:([*^$|!~]?=)" + e + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + ai + ")|)|)" + e + "*\\]", - gt = ":(" + d + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + vi.replace(3, 8) + ")*)|.*)\\)|)", - at = RegExp("^" + e + "+|((?:^|[^\\\\])(?:\\\\.)*)" + e + "+$", "g"), - ki = RegExp("^" + e + "*," + e + "*"), - di = RegExp("^" + e + "*([\\x20\\t\\r\\n\\f>+~])" + e + "*"), - gi = RegExp(gt), - nr = RegExp("^" + ai + "$"), - vt = { - ID: RegExp("^#(" + d + ")"), - CLASS: RegExp("^\\.(" + d + ")"), - NAME: RegExp("^\\[name=['\"]?(" + d + ")['\"]?\\]"), - TAG: RegExp("^(" + d.replace("w", "w*") + ")"), - ATTR: RegExp("^" + vi), - PSEUDO: RegExp("^" + gt), - CHILD: RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + e + "*(even|odd|(([+-]|)(\\d*)n|)" + e + "*(?:([+-]|)" + e + "*(\\d+)|))" + e + "*\\)|)", "i"), - needsContext: RegExp("^" + e + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + e + "*((?:-\\d)?\\d*)" + e + "*\\)|)(?=[^-]|$)", "i") - }, - ni = /[\x20\t\r\n\f]*[+~]/, - tr = /^[^{]+\{\s*\[native code/, - ir = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - rr = /^(?:input|select|textarea|button)$/i, - ur = /^h\d$/i, - fr = /'|\\/g, - er = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, - p = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, - w = function(n, t) { - var i = "0x" + t - 65536; - return i !== i ? t : 0 > i ? String.fromCharCode(i + 65536) : String.fromCharCode(55296 | i >> 10, 56320 | 1023 & i) - }; - try { - ft.call(k.documentElement.childNodes, 0)[0].nodeType - } catch (ar) { - ft = function(n) { - for (var t, i = []; t = this[n++];) i.push(t); - return i - } - } - oi = u.isXML = function(n) { - var t = n && (n.ownerDocument || n).documentElement; - return t ? "HTML" !== t.nodeName : !1 - }; - it = u.setDocument = function(n) { - var i = n ? n.ownerDocument || n : k; - return i !== s && 9 === i.nodeType && i.documentElement ? (s = i, h = i.documentElement, c = oi(i), o.tagNameNoComments = b(function(n) { - return n.appendChild(i.createComment("")), !n.getElementsByTagName("*").length - }), o.attributes = b(function(n) { - n.innerHTML = "<select><\/select>"; - var t = typeof n.lastChild.getAttribute("multiple"); - return "boolean" !== t && "string" !== t - }), o.getByClassName = b(function(n) { - return n.innerHTML = "<div class='hidden e'><\/div><div class='hidden'><\/div>", n.getElementsByClassName && n.getElementsByClassName("e").length ? (n.lastChild.className = "e", 2 === n.getElementsByClassName("e").length) : !1 - }), o.getByName = b(function(n) { - n.id = f + 0; - n.innerHTML = "<a name='" + f + "'><\/a><div name='" + f + "'><\/div>"; - h.insertBefore(n, h.firstChild); - var t = i.getElementsByName && i.getElementsByName(f).length === 2 + i.getElementsByName(f + 0).length; - return o.getIdNotName = !i.getElementById(f), h.removeChild(n), t - }), r.attrHandle = b(function(n) { - return n.innerHTML = "<a href='#'><\/a>", n.firstChild && typeof n.firstChild.getAttribute !== y && "#" === n.firstChild.getAttribute("href") - }) ? {} : { - href: function(n) { - return n.getAttribute("href", 2) - }, - type: function(n) { - return n.getAttribute("type") - } - }, o.getIdNotName ? (r.find.ID = function(n, t) { - if (typeof t.getElementById !== y && !c) { - var i = t.getElementById(n); - return i && i.parentNode ? [i] : [] - } - }, r.filter.ID = function(n) { - var t = n.replace(p, w); - return function(n) { - return n.getAttribute("id") === t - } - }) : (r.find.ID = function(n, i) { - if (typeof i.getElementById !== y && !c) { - var r = i.getElementById(n); - return r ? r.id === n || typeof r.getAttributeNode !== y && r.getAttributeNode("id").value === n ? [r] : t : [] - } - }, r.filter.ID = function(n) { - var t = n.replace(p, w); - return function(n) { - var i = typeof n.getAttributeNode !== y && n.getAttributeNode("id"); - return i && i.value === t - } - }), r.find.TAG = o.tagNameNoComments ? function(n, i) { - return typeof i.getElementsByTagName !== y ? i.getElementsByTagName(n) : t - } : function(n, t) { - var i, r = [], - f = 0, - u = t.getElementsByTagName(n); - if ("*" === n) { - while (i = u[f++]) 1 === i.nodeType && r.push(i); - return r - } - return u - }, r.find.NAME = o.getByName && function(n, i) { - return typeof i.getElementsByName !== y ? i.getElementsByName(name) : t - }, r.find.CLASS = o.getByClassName && function(n, i) { - return typeof i.getElementsByClassName === y || c ? t : i.getElementsByClassName(n) - }, rt = [], a = [":focus"], (o.qsa = ti(i.querySelectorAll)) && (b(function(n) { - n.innerHTML = "<select><option selected=''><\/option><\/select>"; - n.querySelectorAll("[selected]").length || a.push("\\[" + e + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)"); - n.querySelectorAll(":checked").length || a.push(":checked") - }), b(function(n) { - n.innerHTML = "<input type='hidden' i=''/>"; - n.querySelectorAll("[i^='']").length && a.push("[*^$]=" + e + "*(?:\"\"|'')"); - n.querySelectorAll(":enabled").length || a.push(":enabled", ":disabled"); - n.querySelectorAll("*,:x"); - a.push(",.*:") - })), (o.matchesSelector = ti(ct = h.matchesSelector || h.mozMatchesSelector || h.webkitMatchesSelector || h.oMatchesSelector || h.msMatchesSelector)) && b(function(n) { - o.disconnectedMatch = ct.call(n, "div"); - ct.call(n, "[s!='']:x"); - rt.push("!=", gt) - }), a = RegExp(a.join("|")), rt = RegExp(rt.join("|")), et = ti(h.contains) || h.compareDocumentPosition ? function(n, t) { - var r = 9 === n.nodeType ? n.documentElement : n, - i = t && t.parentNode; - return n === i || !(!i || 1 !== i.nodeType || !(r.contains ? r.contains(i) : n.compareDocumentPosition && 16 & n.compareDocumentPosition(i))) - } : function(n, t) { - if (t) - while (t = t.parentNode) - if (t === n) return !0; - return !1 - }, kt = h.compareDocumentPosition ? function(n, t) { - var r; - return n === t ? (tt = !0, 0) : (r = t.compareDocumentPosition && n.compareDocumentPosition && n.compareDocumentPosition(t)) ? 1 & r || n.parentNode && 11 === n.parentNode.nodeType ? n === i || et(k, n) ? -1 : t === i || et(k, t) ? 1 : 0 : 4 & r ? -1 : 1 : n.compareDocumentPosition ? -1 : 1 - } : function(n, t) { - var r, u = 0, - o = n.parentNode, - s = t.parentNode, - f = [n], - e = [t]; - if (n === t) return tt = !0, 0; - if (!o || !s) return n === i ? -1 : t === i ? 1 : o ? -1 : s ? 1 : 0; - if (o === s) return yi(n, t); - for (r = n; r = r.parentNode;) f.unshift(r); - for (r = t; r = r.parentNode;) e.unshift(r); - while (f[u] === e[u]) u++; - return u ? yi(f[u], e[u]) : f[u] === k ? -1 : e[u] === k ? 1 : 0 - }, tt = !1, [0, 0].sort(kt), o.detectDuplicates = tt, s) : s - }; - u.matches = function(n, t) { - return u(n, null, null, t) - }; - u.matchesSelector = function(n, t) { - if ((n.ownerDocument || n) !== s && it(n), t = t.replace(er, "='$1']"), !(!o.matchesSelector || c || rt && rt.test(t) || a.test(t))) try { - var i = ct.call(n, t); - if (i || o.disconnectedMatch || n.document && 11 !== n.document.nodeType) return i - } catch (r) {} - return u(t, s, null, [n]).length > 0 - }; - u.contains = function(n, t) { - return (n.ownerDocument || n) !== s && it(n), et(n, t) - }; - u.attr = function(n, t) { - var i; - return (n.ownerDocument || n) !== s && it(n), c || (t = t.toLowerCase()), (i = r.attrHandle[t]) ? i(n) : c || o.attributes ? n.getAttribute(t) : ((i = n.getAttributeNode(t)) || n.getAttribute(t)) && n[t] === !0 ? t : i && i.specified ? i.value : null - }; - u.error = function(n) { - throw Error("Syntax error, unrecognized expression: " + n); - }; - u.uniqueSort = function(n) { - var r, u = [], - t = 1, - i = 0; - if (tt = !o.detectDuplicates, n.sort(kt), tt) { - for (; r = n[t]; t++) r === n[t - 1] && (i = u.push(t)); - while (i--) n.splice(u[i], 1) - } - return n - }; - st = u.getText = function(n) { - var r, i = "", - u = 0, - t = n.nodeType; - if (t) { - if (1 === t || 9 === t || 11 === t) { - if ("string" == typeof n.textContent) return n.textContent; - for (n = n.firstChild; n; n = n.nextSibling) i += st(n) - } else if (3 === t || 4 === t) return n.nodeValue - } else - for (; r = n[u]; u++) i += st(r); - return i - }; - r = u.selectors = { - cacheLength: 50, - createPseudo: l, - match: vt, - find: {}, - relative: { - ">": { - dir: "parentNode", - first: !0 - }, - " ": { - dir: "parentNode" - }, - "+": { - dir: "previousSibling", - first: !0 - }, - "~": { - dir: "previousSibling" - } - }, - preFilter: { - ATTR: function(n) { - return n[1] = n[1].replace(p, w), n[3] = (n[4] || n[5] || "").replace(p, w), "~=" === n[2] && (n[3] = " " + n[3] + " "), n.slice(0, 4) - }, - CHILD: function(n) { - return n[1] = n[1].toLowerCase(), "nth" === n[1].slice(0, 3) ? (n[3] || u.error(n[0]), n[4] = +(n[4] ? n[5] + (n[6] || 1) : 2 * ("even" === n[3] || "odd" === n[3])), n[5] = +(n[7] + n[8] || "odd" === n[3])) : n[3] && u.error(n[0]), n - }, - PSEUDO: function(n) { - var i, t = !n[5] && n[2]; - return vt.CHILD.test(n[0]) ? null : (n[4] ? n[2] = n[4] : t && gi.test(t) && (i = yt(t, !0)) && (i = t.indexOf(")", t.length - i) - t.length) && (n[0] = n[0].slice(0, i), n[2] = t.slice(0, i)), n.slice(0, 3)) - } - }, - filter: { - TAG: function(n) { - return "*" === n ? function() { - return !0 - } : (n = n.replace(p, w).toLowerCase(), function(t) { - return t.nodeName && t.nodeName.toLowerCase() === n - }) - }, - CLASS: function(n) { - var t = si[n + " "]; - return t || (t = RegExp("(^|" + e + ")" + n + "(" + e + "|$)")) && si(n, function(n) { - return t.test(n.className || typeof n.getAttribute !== y && n.getAttribute("class") || "") - }) - }, - ATTR: function(n, t, i) { - return function(r) { - var f = u.attr(r, n); - return null == f ? "!=" === t : t ? (f += "", "=" === t ? f === i : "!=" === t ? f !== i : "^=" === t ? i && 0 === f.indexOf(i) : "*=" === t ? i && f.indexOf(i) > -1 : "$=" === t ? i && f.slice(-i.length) === i : "~=" === t ? (" " + f + " ").indexOf(i) > -1 : "|=" === t ? f === i || f.slice(0, i.length + 1) === i + "-" : !1) : !0 - } - }, - CHILD: function(n, t, i, r, u) { - var s = "nth" !== n.slice(0, 3), - o = "last" !== n.slice(-4), - e = "of-type" === t; - return 1 === r && 0 === u ? function(n) { - return !!n.parentNode - } : function(t, i, h) { - var a, k, c, l, y, w, b = s !== o ? "nextSibling" : "previousSibling", - p = t.parentNode, - g = e && t.nodeName.toLowerCase(), - d = !h && !e; - if (p) { - if (s) { - while (b) { - for (c = t; c = c[b];) - if (e ? c.nodeName.toLowerCase() === g : 1 === c.nodeType) return !1; - w = b = "only" === n && !w && "nextSibling" - } - return !0 - } - if (w = [o ? p.firstChild : p.lastChild], o && d) { - for (k = p[f] || (p[f] = {}), a = k[n] || [], y = a[0] === v && a[1], l = a[0] === v && a[2], c = y && p.childNodes[y]; c = ++y && c && c[b] || (l = y = 0) || w.pop();) - if (1 === c.nodeType && ++l && c === t) { - k[n] = [v, y, l]; - break - } - } else if (d && (a = (t[f] || (t[f] = {}))[n]) && a[0] === v) l = a[1]; - else - while (c = ++y && c && c[b] || (l = y = 0) || w.pop()) - if ((e ? c.nodeName.toLowerCase() === g : 1 === c.nodeType) && ++l && (d && ((c[f] || (c[f] = {}))[n] = [v, l]), c === t)) break; - return l -= u, l === r || 0 == l % r && l / r >= 0 - } - } - }, - PSEUDO: function(n, t) { - var e, i = r.pseudos[n] || r.setFilters[n.toLowerCase()] || u.error("unsupported pseudo: " + n); - return i[f] ? i(t) : i.length > 1 ? (e = [n, n, "", t], r.setFilters.hasOwnProperty(n.toLowerCase()) ? l(function(n, r) { - for (var u, f = i(n, t), e = f.length; e--;) u = dt.call(n, f[e]), n[u] = !(r[u] = f[e]) - }) : function(n) { - return i(n, 0, e) - }) : i - } - }, - pseudos: { - not: l(function(n) { - var i = [], - r = [], - t = bt(n.replace(at, "$1")); - return t[f] ? l(function(n, i, r, u) { - for (var e, o = t(n, null, u, []), f = n.length; f--;)(e = o[f]) && (n[f] = !(i[f] = e)) - }) : function(n, u, f) { - return i[0] = n, t(i, null, f, r), !r.pop() - } - }), - has: l(function(n) { - return function(t) { - return u(n, t).length > 0 - } - }), - contains: l(function(n) { - return function(t) { - return (t.textContent || t.innerText || st(t)).indexOf(n) > -1 - } - }), - lang: l(function(n) { - return nr.test(n || "") || u.error("unsupported lang: " + n), n = n.replace(p, w).toLowerCase(), - function(t) { - var i; - do - if (i = c ? t.getAttribute("xml:lang") || t.getAttribute("lang") : t.lang) return i = i.toLowerCase(), i === n || 0 === i.indexOf(n + "-"); while ((t = t.parentNode) && 1 === t.nodeType); - return !1 - } - }), - target: function(t) { - var i = n.location && n.location.hash; - return i && i.slice(1) === t.id - }, - root: function(n) { - return n === h - }, - focus: function(n) { - return n === s.activeElement && (!s.hasFocus || s.hasFocus()) && !!(n.type || n.href || ~n.tabIndex) - }, - enabled: function(n) { - return n.disabled === !1 - }, - disabled: function(n) { - return n.disabled === !0 - }, - checked: function(n) { - var t = n.nodeName.toLowerCase(); - return "input" === t && !!n.checked || "option" === t && !!n.selected - }, - selected: function(n) { - return n.parentNode && n.parentNode.selectedIndex, n.selected === !0 - }, - empty: function(n) { - for (n = n.firstChild; n; n = n.nextSibling) - if (n.nodeName > "@" || 3 === n.nodeType || 4 === n.nodeType) return !1; - return !0 - }, - parent: function(n) { - return !r.pseudos.empty(n) - }, - header: function(n) { - return ur.test(n.nodeName) - }, - input: function(n) { - return rr.test(n.nodeName) - }, - button: function(n) { - var t = n.nodeName.toLowerCase(); - return "input" === t && "button" === n.type || "button" === t - }, - text: function(n) { - var t; - return "input" === n.nodeName.toLowerCase() && "text" === n.type && (null == (t = n.getAttribute("type")) || t.toLowerCase() === n.type) - }, - first: g(function() { - return [0] - }), - last: g(function(n, t) { - return [t - 1] - }), - eq: g(function(n, t, i) { - return [0 > i ? i + t : i] - }), - even: g(function(n, t) { - for (var i = 0; t > i; i += 2) n.push(i); - return n - }), - odd: g(function(n, t) { - for (var i = 1; t > i; i += 2) n.push(i); - return n - }), - lt: g(function(n, t, i) { - for (var r = 0 > i ? i + t : i; --r >= 0;) n.push(r); - return n - }), - gt: g(function(n, t, i) { - for (var r = 0 > i ? i + t : i; t > ++r;) n.push(r); - return n - }) - } - }; - for (nt in { - radio: !0, - checkbox: !0, - file: !0, - password: !0, - image: !0 - }) r.pseudos[nt] = or(nt); - for (nt in { - submit: !0, - reset: !0 - }) r.pseudos[nt] = sr(nt); - bt = u.compile = function(n, t) { - var r, u = [], - e = [], - i = ci[n + " "]; - if (!i) { - for (t || (t = yt(n)), r = t.length; r--;) i = ei(t[r]), i[f] ? u.push(i) : e.push(i); - i = ci(n, hr(e, u)) - } - return i - }; - r.pseudos.nth = r.pseudos.eq; - r.filters = pi.prototype = r.pseudos; - r.setFilters = new pi; - it(); - u.attr = i.attr; - i.find = u; - i.expr = u.selectors; - i.expr[":"] = i.expr.pseudos; - i.unique = u.uniqueSort; - i.text = u.getText; - i.isXMLDoc = u.isXML; - i.contains = u.contains - }(n); - var re = /Until$/, - ue = /^(?:parents|prev(?:Until|All))/, - fe = /^.[^:#\[\.,]*$/, - hr = i.expr.match.needsContext, - ee = { - children: !0, - contents: !0, - next: !0, - prev: !0 - }; - i.fn.extend({ - find: function(n) { - var t, r, f, u = this.length; - if ("string" != typeof n) return f = this, this.pushStack(i(n).filter(function() { - for (t = 0; u > t; t++) - if (i.contains(f[t], this)) return !0 - })); - for (r = [], t = 0; u > t; t++) i.find(n, this[t], r); - return r = this.pushStack(u > 1 ? i.unique(r) : r), r.selector = (this.selector ? this.selector + " " : "") + n, r - }, - has: function(n) { - var t, r = i(n, this), - u = r.length; - return this.filter(function() { - for (t = 0; u > t; t++) - if (i.contains(this, r[t])) return !0 - }) - }, - not: function(n) { - return this.pushStack(lr(this, n, !1)) - }, - filter: function(n) { - return this.pushStack(lr(this, n, !0)) - }, - is: function(n) { - return !!n && ("string" == typeof n ? hr.test(n) ? i(n, this.context).index(this[0]) >= 0 : i.filter(n, this).length > 0 : this.filter(n).length > 0) - }, - closest: function(n, t) { - for (var r, f = 0, o = this.length, u = [], e = hr.test(n) || "string" != typeof n ? i(n, t || this.context) : 0; o > f; f++) - for (r = this[f]; r && r.ownerDocument && r !== t && 11 !== r.nodeType;) { - if (e ? e.index(r) > -1 : i.find.matchesSelector(r, n)) { - u.push(r); - break - } - r = r.parentNode - } - return this.pushStack(u.length > 1 ? i.unique(u) : u) - }, - index: function(n) { - return n ? "string" == typeof n ? i.inArray(this[0], i(n)) : i.inArray(n.jquery ? n[0] : n, this) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 - }, - add: function(n, t) { - var r = "string" == typeof n ? i(n, t) : i.makeArray(n && n.nodeType ? [n] : n), - u = i.merge(this.get(), r); - return this.pushStack(i.unique(u)) - }, - addBack: function(n) { - return this.add(null == n ? this.prevObject : this.prevObject.filter(n)) - } - }); - i.fn.andSelf = i.fn.addBack; - i.each({ - parent: function(n) { - var t = n.parentNode; - return t && 11 !== t.nodeType ? t : null - }, - parents: function(n) { - return i.dir(n, "parentNode") - }, - parentsUntil: function(n, t, r) { - return i.dir(n, "parentNode", r) - }, - next: function(n) { - return cr(n, "nextSibling") - }, - prev: function(n) { - return cr(n, "previousSibling") - }, - nextAll: function(n) { - return i.dir(n, "nextSibling") - }, - prevAll: function(n) { - return i.dir(n, "previousSibling") - }, - nextUntil: function(n, t, r) { - return i.dir(n, "nextSibling", r) - }, - prevUntil: function(n, t, r) { - return i.dir(n, "previousSibling", r) - }, - siblings: function(n) { - return i.sibling((n.parentNode || {}).firstChild, n) - }, - children: function(n) { - return i.sibling(n.firstChild) - }, - contents: function(n) { - return i.nodeName(n, "iframe") ? n.contentDocument || n.contentWindow.document : i.merge([], n.childNodes) - } - }, function(n, t) { - i.fn[n] = function(r, u) { - var f = i.map(this, t, r); - return re.test(n) || (u = r), u && "string" == typeof u && (f = i.filter(u, f)), f = this.length > 1 && !ee[n] ? i.unique(f) : f, this.length > 1 && ue.test(n) && (f = f.reverse()), this.pushStack(f) - } - }); - i.extend({ - filter: function(n, t, r) { - return r && (n = ":not(" + n + ")"), 1 === t.length ? i.find.matchesSelector(t[0], n) ? [t[0]] : [] : i.find.matches(n, t) - }, - dir: function(n, r, u) { - for (var e = [], f = n[r]; f && 9 !== f.nodeType && (u === t || 1 !== f.nodeType || !i(f).is(u));) 1 === f.nodeType && e.push(f), f = f[r]; - return e - }, - sibling: function(n, t) { - for (var i = []; n; n = n.nextSibling) 1 === n.nodeType && n !== t && i.push(n); - return i - } - }); - var vr = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - oe = / jQuery\d+="(?:null|\d+)"/g, - yr = RegExp("<(?:" + vr + ")[\\s/>]", "i"), - fi = /^\s+/, - pr = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - wr = /<([\w:]+)/, - br = /<tbody/i, - se = /<|&#?\w+;/, - he = /<(?:script|style|link)/i, - ei = /^(?:checkbox|radio)$/i, - ce = /checked\s*(?:[^=]|=\s*.checked.)/i, - kr = /^$|\/(?:java|ecma)script/i, - le = /^true\/(.*)/, - ae = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, - e = { - option: [1, "<select multiple='multiple'>", "<\/select>"], - legend: [1, "<fieldset>", "<\/fieldset>"], - area: [1, "<map>", "<\/map>"], - param: [1, "<object>", "<\/object>"], - thead: [1, "<table>", "<\/table>"], - tr: [2, "<table><tbody>", "<\/tbody><\/table>"], - col: [2, "<table><tbody><\/tbody><colgroup>", "<\/colgroup><\/table>"], - td: [3, "<table><tbody><tr>", "<\/tr><\/tbody><\/table>"], - _default: i.support.htmlSerialize ? [0, "", ""] : [1, "X<div>", "<\/div>"] - }, - ve = ar(r), - oi = ve.appendChild(r.createElement("div")); - e.optgroup = e.option; - e.tbody = e.tfoot = e.colgroup = e.caption = e.thead; - e.th = e.td; - i.fn.extend({ - text: function(n) { - return i.access(this, function(n) { - return n === t ? i.text(this) : this.empty().append((this[0] && this[0].ownerDocument || r).createTextNode(n)) - }, null, n, arguments.length) - }, - wrapAll: function(n) { - if (i.isFunction(n)) return this.each(function(t) { - i(this).wrapAll(n.call(this, t)) - }); - if (this[0]) { - var t = i(n, this[0].ownerDocument).eq(0).clone(!0); - this[0].parentNode && t.insertBefore(this[0]); - t.map(function() { - for (var n = this; n.firstChild && 1 === n.firstChild.nodeType;) n = n.firstChild; - return n - }).append(this) - } - return this - }, - wrapInner: function(n) { - return i.isFunction(n) ? this.each(function(t) { - i(this).wrapInner(n.call(this, t)) - }) : this.each(function() { - var t = i(this), - r = t.contents(); - r.length ? r.wrapAll(n) : t.append(n) - }) - }, - wrap: function(n) { - var t = i.isFunction(n); - return this.each(function(r) { - i(this).wrapAll(t ? n.call(this, r) : n) - }) - }, - unwrap: function() { - return this.parent().each(function() { - i.nodeName(this, "body") || i(this).replaceWith(this.childNodes) - }).end() - }, - append: function() { - return this.domManip(arguments, !0, function(n) { - (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) && this.appendChild(n) - }) - }, - prepend: function() { - return this.domManip(arguments, !0, function(n) { - (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) && this.insertBefore(n, this.firstChild) - }) - }, - before: function() { - return this.domManip(arguments, !1, function(n) { - this.parentNode && this.parentNode.insertBefore(n, this) - }) - }, - after: function() { - return this.domManip(arguments, !1, function(n) { - this.parentNode && this.parentNode.insertBefore(n, this.nextSibling) - }) - }, - remove: function(n, t) { - for (var r, f = 0; null != (r = this[f]); f++)(!n || i.filter(n, [r]).length > 0) && (t || 1 !== r.nodeType || i.cleanData(u(r)), r.parentNode && (t && i.contains(r.ownerDocument, r) && si(u(r, "script")), r.parentNode.removeChild(r))); - return this - }, - empty: function() { - for (var n, t = 0; null != (n = this[t]); t++) { - for (1 === n.nodeType && i.cleanData(u(n, !1)); n.firstChild;) n.removeChild(n.firstChild); - n.options && i.nodeName(n, "select") && (n.options.length = 0) - } - return this - }, - clone: function(n, t) { - return n = null == n ? !1 : n, t = null == t ? n : t, this.map(function() { - return i.clone(this, n, t) - }) - }, - html: function(n) { - return i.access(this, function(n) { - var r = this[0] || {}, - f = 0, - o = this.length; - if (n === t) return 1 === r.nodeType ? r.innerHTML.replace(oe, "") : t; - if (!("string" != typeof n || he.test(n) || !i.support.htmlSerialize && yr.test(n) || !i.support.leadingWhitespace && fi.test(n) || e[(wr.exec(n) || ["", ""])[1].toLowerCase()])) { - n = n.replace(pr, "<$1><\/$2>"); - try { - for (; o > f; f++) r = this[f] || {}, 1 === r.nodeType && (i.cleanData(u(r, !1)), r.innerHTML = n); - r = 0 - } catch (s) {} - } - r && this.empty().append(n) - }, null, n, arguments.length) - }, - replaceWith: function(n) { - var t = i.isFunction(n); - return t || "string" == typeof n || (n = i(n).not(this).detach()), this.domManip([n], !0, function(n) { - var r = this.nextSibling, - t = this.parentNode; - t && (i(this).remove(), t.insertBefore(n, r)) - }) - }, - detach: function(n) { - return this.remove(n, !0) - }, - domManip: function(n, r, f) { - n = bi.apply([], n); - var c, e, l, s, y, h, o = 0, - a = this.length, - w = this, - b = a - 1, - v = n[0], - p = i.isFunction(v); - if (p || !(1 >= a || "string" != typeof v || i.support.checkClone) && ce.test(v)) return this.each(function(i) { - var u = w.eq(i); - p && (n[0] = v.call(this, i, r ? u.html() : t)); - u.domManip(n, r, f) - }); - if (a && (h = i.buildFragment(n, this[0].ownerDocument, !1, this), c = h.firstChild, 1 === h.childNodes.length && (h = c), c)) { - for (r = r && i.nodeName(c, "tr"), s = i.map(u(h, "script"), dr), l = s.length; a > o; o++) e = h, o !== b && (e = i.clone(e, !0, !0), l && i.merge(s, u(e, "script"))), f.call(r && i.nodeName(this[o], "table") ? ye(this[o], "tbody") : this[o], e, o); - if (l) - for (y = s[s.length - 1].ownerDocument, i.map(s, gr), o = 0; l > o; o++) e = s[o], kr.test(e.type || "") && !i._data(e, "globalEval") && i.contains(y, e) && (e.src ? i.ajax({ - url: e.src, - type: "GET", - dataType: "script", - async: !1, - global: !1, - throws: !0 - }) : i.globalEval((e.text || e.textContent || e.innerHTML || "").replace(ae, ""))); - h = c = null - } - return this - } - }); - i.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" - }, function(n, t) { - i.fn[n] = function(n) { - for (var u, r = 0, f = [], e = i(n), o = e.length - 1; o >= r; r++) u = r === o ? this : this.clone(!0), i(e[r])[t](u), bt.apply(f, u.get()); - return this.pushStack(f) - } - }); - i.extend({ - clone: function(n, t, r) { - var f, h, o, e, s, c = i.contains(n.ownerDocument, n); - if (i.support.html5Clone || i.isXMLDoc(n) || !yr.test("<" + n.nodeName + ">") ? o = n.cloneNode(!0) : (oi.innerHTML = n.outerHTML, oi.removeChild(o = oi.firstChild)), !(i.support.noCloneEvent && i.support.noCloneChecked || 1 !== n.nodeType && 11 !== n.nodeType || i.isXMLDoc(n))) - for (f = u(o), s = u(n), e = 0; null != (h = s[e]); ++e) f[e] && pe(h, f[e]); - if (t) - if (r) - for (s = s || u(n), f = f || u(o), e = 0; null != (h = s[e]); e++) nu(h, f[e]); - else nu(n, o); - return f = u(o, "script"), f.length > 0 && si(f, !c && u(n, "script")), f = s = h = null, o - }, - buildFragment: function(n, t, r, f) { - for (var h, o, w, s, y, p, l, b = n.length, a = ar(t), c = [], v = 0; b > v; v++) - if (o = n[v], o || 0 === o) - if ("object" === i.type(o)) i.merge(c, o.nodeType ? [o] : o); - else if (se.test(o)) { - for (s = s || a.appendChild(t.createElement("div")), y = (wr.exec(o) || ["", ""])[1].toLowerCase(), l = e[y] || e._default, s.innerHTML = l[1] + o.replace(pr, "<$1><\/$2>") + l[2], h = l[0]; h--;) s = s.lastChild; - if (!i.support.leadingWhitespace && fi.test(o) && c.push(t.createTextNode(fi.exec(o)[0])), !i.support.tbody) - for (o = "table" !== y || br.test(o) ? "<table>" !== l[1] || br.test(o) ? 0 : s : s.firstChild, h = o && o.childNodes.length; h--;) i.nodeName(p = o.childNodes[h], "tbody") && !p.childNodes.length && o.removeChild(p); - for (i.merge(c, s.childNodes), s.textContent = ""; s.firstChild;) s.removeChild(s.firstChild); - s = a.lastChild - } else c.push(t.createTextNode(o)); - for (s && a.removeChild(s), i.support.appendChecked || i.grep(u(c, "input"), we), v = 0; o = c[v++];) - if ((!f || -1 === i.inArray(o, f)) && (w = i.contains(o.ownerDocument, o), s = u(a.appendChild(o), "script"), w && si(s), r)) - for (h = 0; o = s[h++];) kr.test(o.type || "") && r.push(o); - return s = null, a - }, - cleanData: function(n, t) { - for (var r, f, u, e, c = 0, s = i.expando, h = i.cache, l = i.support.deleteExpando, a = i.event.special; null != (r = n[c]); c++) - if ((t || i.acceptData(r)) && (u = r[s], e = u && h[u])) { - if (e.events) - for (f in e.events) a[f] ? i.event.remove(r, f) : i.removeEvent(r, f, e.handle); - h[u] && (delete h[u], l ? delete r[s] : typeof r.removeAttribute !== o ? r.removeAttribute(s) : r[s] = null, b.push(u)) - } - } - }); - var rt, v, y, hi = /alpha\([^)]*\)/i, - be = /opacity\s*=\s*([^)]*)/, - ke = /^(top|right|bottom|left)$/, - de = /^(none|table(?!-c[ea]).+)/, - tu = /^margin/, - ge = RegExp("^(" + st + ")(.*)$", "i"), - ct = RegExp("^(" + st + ")(?!px)[a-z%]+$", "i"), - no = RegExp("^([+-])=(" + st + ")", "i"), - iu = { - BODY: "block" - }, - to = { - position: "absolute", - visibility: "hidden", - display: "block" - }, - ru = { - letterSpacing: 0, - fontWeight: 400 - }, - p = ["Top", "Right", "Bottom", "Left"], - uu = ["Webkit", "O", "Moz", "ms"]; - i.fn.extend({ - css: function(n, r) { - return i.access(this, function(n, r, u) { - var e, o, s = {}, - f = 0; - if (i.isArray(r)) { - for (o = v(n), e = r.length; e > f; f++) s[r[f]] = i.css(n, r[f], !1, o); - return s - } - return u !== t ? i.style(n, r, u) : i.css(n, r) - }, n, r, arguments.length > 1) - }, - show: function() { - return eu(this, !0) - }, - hide: function() { - return eu(this) - }, - toggle: function(n) { - var t = "boolean" == typeof n; - return this.each(function() { - (t ? n : ut(this)) ? i(this).show(): i(this).hide() - }) - } - }); - i.extend({ - cssHooks: { - opacity: { - get: function(n, t) { - if (t) { - var i = y(n, "opacity"); - return "" === i ? "1" : i - } - } - } - }, - cssNumber: { - columnCount: !0, - fillOpacity: !0, - fontWeight: !0, - lineHeight: !0, - opacity: !0, - orphans: !0, - widows: !0, - zIndex: !0, - zoom: !0 - }, - cssProps: { - float: i.support.cssFloat ? "cssFloat" : "styleFloat" - }, - style: function(n, r, u, f) { - if (n && 3 !== n.nodeType && 8 !== n.nodeType && n.style) { - var o, s, e, h = i.camelCase(r), - c = n.style; - if (r = i.cssProps[h] || (i.cssProps[h] = fu(c, h)), e = i.cssHooks[r] || i.cssHooks[h], u === t) return e && "get" in e && (o = e.get(n, !1, f)) !== t ? o : c[r]; - if (s = typeof u, "string" === s && (o = no.exec(u)) && (u = (o[1] + 1) * o[2] + parseFloat(i.css(n, r)), s = "number"), !(null == u || "number" === s && isNaN(u) || ("number" !== s || i.cssNumber[h] || (u += "px"), i.support.clearCloneStyle || "" !== u || 0 !== r.indexOf("background") || (c[r] = "inherit"), e && "set" in e && (u = e.set(n, u, f)) === t))) try { - c[r] = u - } catch (l) {} - } - }, - css: function(n, r, u, f) { - var h, e, o, s = i.camelCase(r); - return r = i.cssProps[s] || (i.cssProps[s] = fu(n.style, s)), o = i.cssHooks[r] || i.cssHooks[s], o && "get" in o && (e = o.get(n, !0, u)), e === t && (e = y(n, r, f)), "normal" === e && r in ru && (e = ru[r]), "" === u || u ? (h = parseFloat(e), u === !0 || i.isNumeric(h) ? h || 0 : e) : e - }, - swap: function(n, t, i, r) { - var f, u, e = {}; - for (u in t) e[u] = n.style[u], n.style[u] = t[u]; - f = i.apply(n, r || []); - for (u in t) n.style[u] = e[u]; - return f - } - }); - n.getComputedStyle ? (v = function(t) { - return n.getComputedStyle(t, null) - }, y = function(n, r, u) { - var s, h, c, o = u || v(n), - e = o ? o.getPropertyValue(r) || o[r] : t, - f = n.style; - return o && ("" !== e || i.contains(n.ownerDocument, n) || (e = i.style(n, r)), ct.test(e) && tu.test(r) && (s = f.width, h = f.minWidth, c = f.maxWidth, f.minWidth = f.maxWidth = f.width = e, e = o.width, f.width = s, f.minWidth = h, f.maxWidth = c)), e - }) : r.documentElement.currentStyle && (v = function(n) { - return n.currentStyle - }, y = function(n, i, r) { - var s, e, o, h = r || v(n), - u = h ? h[i] : t, - f = n.style; - return null == u && f && f[i] && (u = f[i]), ct.test(u) && !ke.test(i) && (s = f.left, e = n.runtimeStyle, o = e && e.left, o && (e.left = n.currentStyle.left), f.left = "fontSize" === i ? "1em" : u, u = f.pixelLeft + "px", f.left = s, o && (e.left = o)), "" === u ? "auto" : u - }); - i.each(["height", "width"], function(n, r) { - i.cssHooks[r] = { - get: function(n, u, f) { - return u ? 0 === n.offsetWidth && de.test(i.css(n, "display")) ? i.swap(n, to, function() { - return hu(n, r, f) - }) : hu(n, r, f) : t - }, - set: function(n, t, u) { - var f = u && v(n); - return ou(n, t, u ? su(n, r, u, i.support.boxSizing && "border-box" === i.css(n, "boxSizing", !1, f), f) : 0) - } - } - }); - i.support.opacity || (i.cssHooks.opacity = { - get: function(n, t) { - return be.test((t && n.currentStyle ? n.currentStyle.filter : n.style.filter) || "") ? .01 * parseFloat(RegExp.$1) + "" : t ? "1" : "" - }, - set: function(n, t) { - var r = n.style, - u = n.currentStyle, - e = i.isNumeric(t) ? "alpha(opacity=" + 100 * t + ")" : "", - f = u && u.filter || r.filter || ""; - r.zoom = 1; - (t >= 1 || "" === t) && "" === i.trim(f.replace(hi, "")) && r.removeAttribute && (r.removeAttribute("filter"), "" === t || u && !u.filter) || (r.filter = hi.test(f) ? f.replace(hi, e) : f + " " + e) - } - }); - i(function() { - i.support.reliableMarginRight || (i.cssHooks.marginRight = { - get: function(n, r) { - return r ? i.swap(n, { - display: "inline-block" - }, y, [n, "marginRight"]) : t - } - }); - !i.support.pixelPosition && i.fn.position && i.each(["top", "left"], function(n, r) { - i.cssHooks[r] = { - get: function(n, u) { - return u ? (u = y(n, r), ct.test(u) ? i(n).position()[r] + "px" : u) : t - } - } - }) - }); - i.expr && i.expr.filters && (i.expr.filters.hidden = function(n) { - return 0 >= n.offsetWidth && 0 >= n.offsetHeight || !i.support.reliableHiddenOffsets && "none" === (n.style && n.style.display || i.css(n, "display")) - }, i.expr.filters.visible = function(n) { - return !i.expr.filters.hidden(n) - }); - i.each({ - margin: "", - padding: "", - border: "Width" - }, function(n, t) { - i.cssHooks[n + t] = { - expand: function(i) { - for (var r = 0, f = {}, u = "string" == typeof i ? i.split(" ") : [i]; 4 > r; r++) f[n + p[r] + t] = u[r] || u[r - 2] || u[0]; - return f - } - }; - tu.test(n) || (i.cssHooks[n + t].set = ou) - }); - var io = /%20/g, - ro = /\[\]$/, - au = /\r?\n/g, - uo = /^(?:submit|button|image|reset|file)$/i, - fo = /^(?:input|select|textarea|keygen)/i; - i.fn.extend({ - serialize: function() { - return i.param(this.serializeArray()) - }, - serializeArray: function() { - return this.map(function() { - var n = i.prop(this, "elements"); - return n ? i.makeArray(n) : this - }).filter(function() { - var n = this.type; - return this.name && !i(this).is(":disabled") && fo.test(this.nodeName) && !uo.test(n) && (this.checked || !ei.test(n)) - }).map(function(n, t) { - var r = i(this).val(); - return null == r ? null : i.isArray(r) ? i.map(r, function(n) { - return { - name: t.name, - value: n.replace(au, "\r\n") - } - }) : { - name: t.name, - value: r.replace(au, "\r\n") - } - }).get() - } - }); - i.param = function(n, r) { - var u, f = [], - e = function(n, t) { - t = i.isFunction(t) ? t() : null == t ? "" : t; - f[f.length] = encodeURIComponent(n) + "=" + encodeURIComponent(t) - }; - if (r === t && (r = i.ajaxSettings && i.ajaxSettings.traditional), i.isArray(n) || n.jquery && !i.isPlainObject(n)) i.each(n, function() { - e(this.name, this.value) - }); - else - for (u in n) ci(u, n[u], r, e); - return f.join("&").replace(io, "+") - }; - i.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "), function(n, t) { - i.fn[t] = function(n, i) { - return arguments.length > 0 ? this.on(t, null, n, i) : this.trigger(t) - } - }); - i.fn.hover = function(n, t) { - return this.mouseenter(n).mouseleave(t || n) - }; - var w, c, li = i.now(), - ai = /\?/, - eo = /#.*$/, - vu = /([?&])_=[^&]*/, - oo = /^(.*?):[ \t]*([^\r\n]*)\r?$/gm, - so = /^(?:GET|HEAD)$/, - ho = /^\/\//, - yu = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, - pu = i.fn.load, - wu = {}, - vi = {}, - bu = "*/".concat("*"); - try { - c = ff.href - } catch (go) { - c = r.createElement("a"); - c.href = ""; - c = c.href - } - w = yu.exec(c.toLowerCase()) || []; - i.fn.load = function(n, r, u) { - if ("string" != typeof n && pu) return pu.apply(this, arguments); - var f, s, h, e = this, - o = n.indexOf(" "); - return o >= 0 && (f = n.slice(o, n.length), n = n.slice(0, o)), i.isFunction(r) ? (u = r, r = t) : r && "object" == typeof r && (h = "POST"), e.length > 0 && i.ajax({ - url: n, - type: h, - dataType: "html", - data: r - }).done(function(n) { - s = arguments; - e.html(f ? i("<div>").append(i.parseHTML(n)).find(f) : n) - }).complete(u && function(n, t) { - e.each(u, s || [n.responseText, t, n]) - }), this - }; - i.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function(n, t) { - i.fn[t] = function(n) { - return this.on(t, n) - } - }); - i.each(["get", "post"], function(n, r) { - i[r] = function(n, u, f, e) { - return i.isFunction(u) && (e = e || f, f = u, u = t), i.ajax({ - url: n, - type: r, - dataType: e, - data: u, - success: f - }) - } - }); - i.extend({ - active: 0, - lastModified: {}, - etag: {}, - ajaxSettings: { - url: c, - type: "GET", - isLocal: /^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(w[1]), - global: !0, - processData: !0, - async: !0, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - accepts: { - "*": bu, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - contents: { - xml: /xml/, - html: /html/, - json: /json/ - }, - responseFields: { - xml: "responseXML", - text: "responseText" - }, - converters: { - "* text": n.String, - "text html": !0, - "text json": i.parseJSON, - "text xml": i.parseXML - }, - flatOptions: { - url: !0, - context: !0 - } - }, - ajaxSetup: function(n, t) { - return t ? yi(yi(n, i.ajaxSettings), t) : yi(i.ajaxSettings, n) - }, - ajaxPrefilter: ku(wu), - ajaxTransport: ku(vi), - ajax: function(n, r) { - function k(n, r, s, c) { - var l, k, w, rt, p, a = r; - 2 !== o && (o = 2, g && clearTimeout(g), y = t, d = c || "", f.readyState = n > 0 ? 4 : 0, s && (rt = co(u, f, s)), n >= 200 && 300 > n || 304 === n ? (u.ifModified && (p = f.getResponseHeader("Last-Modified"), p && (i.lastModified[e] = p), p = f.getResponseHeader("etag"), p && (i.etag[e] = p)), 204 === n ? (l = !0, a = "nocontent") : 304 === n ? (l = !0, a = "notmodified") : (l = lo(u, rt), a = l.state, k = l.data, w = l.error, l = !w)) : (w = a, (n || !a) && (a = "error", 0 > n && (n = 0))), f.status = n, f.statusText = (r || a) + "", l ? tt.resolveWith(h, [k, a, f]) : tt.rejectWith(h, [f, a, w]), f.statusCode(b), b = t, v && nt.trigger(l ? "ajaxSuccess" : "ajaxError", [f, u, l ? k : w]), it.fireWith(h, [f, a]), v && (nt.trigger("ajaxComplete", [f, u]), --i.active || i.event.trigger("ajaxStop"))) - } - "object" == typeof n && (r = n, n = t); - r = r || {}; - var l, a, e, d, g, v, y, p, u = i.ajaxSetup({}, r), - h = u.context || u, - nt = u.context && (h.nodeType || h.jquery) ? i(h) : i.event, - tt = i.Deferred(), - it = i.Callbacks("once memory"), - b = u.statusCode || {}, - rt = {}, - ut = {}, - o = 0, - ft = "canceled", - f = { - readyState: 0, - getResponseHeader: function(n) { - var t; - if (2 === o) { - if (!p) - for (p = {}; t = oo.exec(d);) p[t[1].toLowerCase()] = t[2]; - t = p[n.toLowerCase()] - } - return null == t ? null : t - }, - getAllResponseHeaders: function() { - return 2 === o ? d : null - }, - setRequestHeader: function(n, t) { - var i = n.toLowerCase(); - return o || (n = ut[i] = ut[i] || n, rt[n] = t), this - }, - overrideMimeType: function(n) { - return o || (u.mimeType = n), this - }, - statusCode: function(n) { - var t; - if (n) - if (2 > o) - for (t in n) b[t] = [b[t], n[t]]; - else f.always(n[f.status]); - return this - }, - abort: function(n) { - var t = n || ft; - return y && y.abort(t), k(0, t), this - } - }; - if (tt.promise(f).complete = it.add, f.success = f.done, f.error = f.fail, u.url = ((n || u.url || c) + "").replace(eo, "").replace(ho, w[1] + "//"), u.type = r.method || r.type || u.method || u.type, u.dataTypes = i.trim(u.dataType || "*").toLowerCase().match(s) || [""], null == u.crossDomain && (l = yu.exec(u.url.toLowerCase()), u.crossDomain = !(!l || l[1] === w[1] && l[2] === w[2] && (l[3] || ("http:" === l[1] ? 80 : 443)) == (w[3] || ("http:" === w[1] ? 80 : 443)))), u.data && u.processData && "string" != typeof u.data && (u.data = i.param(u.data, u.traditional)), du(wu, u, r, f), 2 === o) return f; - v = u.global; - v && 0 == i.active++ && i.event.trigger("ajaxStart"); - u.type = u.type.toUpperCase(); - u.hasContent = !so.test(u.type); - e = u.url; - u.hasContent || (u.data && (e = u.url += (ai.test(e) ? "&" : "?") + u.data, delete u.data), u.cache === !1 && (u.url = vu.test(e) ? e.replace(vu, "$1_=" + li++) : e + (ai.test(e) ? "&" : "?") + "_=" + li++)); - u.ifModified && (i.lastModified[e] && f.setRequestHeader("If-Modified-Since", i.lastModified[e]), i.etag[e] && f.setRequestHeader("If-None-Match", i.etag[e])); - (u.data && u.hasContent && u.contentType !== !1 || r.contentType) && f.setRequestHeader("Content-Type", u.contentType); - f.setRequestHeader("Accept", u.dataTypes[0] && u.accepts[u.dataTypes[0]] ? u.accepts[u.dataTypes[0]] + ("*" !== u.dataTypes[0] ? ", " + bu + "; q=0.01" : "") : u.accepts["*"]); - for (a in u.headers) f.setRequestHeader(a, u.headers[a]); - if (u.beforeSend && (u.beforeSend.call(h, f, u) === !1 || 2 === o)) return f.abort(); - ft = "abort"; - for (a in { - success: 1, - error: 1, - complete: 1 - }) f[a](u[a]); - if (y = du(vi, u, r, f)) { - f.readyState = 1; - v && nt.trigger("ajaxSend", [f, u]); - u.async && u.timeout > 0 && (g = setTimeout(function() { - f.abort("timeout") - }, u.timeout)); - try { - o = 1; - y.send(rt, k) - } catch (et) { - if (!(2 > o)) throw et; - k(-1, et) - } - } else k(-1, "No Transport"); - return f - }, - getScript: function(n, r) { - return i.get(n, t, r, "script") - }, - getJSON: function(n, t, r) { - return i.get(n, t, r, "json") - } - }); - i.ajaxSetup({ - accepts: { - script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /(?:java|ecma)script/ - }, - converters: { - "text script": function(n) { - return i.globalEval(n), n - } - } - }); - i.ajaxPrefilter("script", function(n) { - n.cache === t && (n.cache = !1); - n.crossDomain && (n.type = "GET", n.global = !1) - }); - i.ajaxTransport("script", function(n) { - if (n.crossDomain) { - var u, f = r.head || i("head")[0] || r.documentElement; - return { - send: function(t, i) { - u = r.createElement("script"); - u.async = !0; - n.scriptCharset && (u.charset = n.scriptCharset); - u.src = n.url; - u.onload = u.onreadystatechange = function(n, t) { - (t || !u.readyState || /loaded|complete/.test(u.readyState)) && (u.onload = u.onreadystatechange = null, u.parentNode && u.parentNode.removeChild(u), u = null, t || i(200, "success")) - }; - f.insertBefore(u, f.firstChild) - }, - abort: function() { - u && u.onload(t, !0) - } - } - } - }); - pi = []; - lt = /(=)\?(?=&|$)|\?\?/; - i.ajaxSetup({ - jsonp: "callback", - jsonpCallback: function() { - var n = pi.pop() || i.expando + "_" + li++; - return this[n] = !0, n - } - }); - i.ajaxPrefilter("json jsonp", function(r, u, f) { - var e, s, o, h = r.jsonp !== !1 && (lt.test(r.url) ? "url" : "string" == typeof r.data && !(r.contentType || "").indexOf("application/x-www-form-urlencoded") && lt.test(r.data) && "data"); - return h || "jsonp" === r.dataTypes[0] ? (e = r.jsonpCallback = i.isFunction(r.jsonpCallback) ? r.jsonpCallback() : r.jsonpCallback, h ? r[h] = r[h].replace(lt, "$1" + e) : r.jsonp !== !1 && (r.url += (ai.test(r.url) ? "&" : "?") + r.jsonp + "=" + e), r.converters["script json"] = function() { - return o || i.error(e + " was not called"), o[0] - }, r.dataTypes[0] = "json", s = n[e], n[e] = function() { - o = arguments - }, f.always(function() { - n[e] = s; - r[e] && (r.jsonpCallback = u.jsonpCallback, pi.push(e)); - o && i.isFunction(s) && s(o[0]); - o = s = t - }), "script") : t - }); - gu = 0; - at = n.ActiveXObject && function() { - for (var n in g) g[n](t, !0) - }; - i.ajaxSettings.xhr = n.ActiveXObject ? function() { - return !this.isLocal && nf() || ao() - } : nf; - nt = i.ajaxSettings.xhr(); - i.support.cors = !!nt && "withCredentials" in nt; - nt = i.support.ajax = !!nt; - nt && i.ajaxTransport(function(r) { - if (!r.crossDomain || i.support.cors) { - var u; - return { - send: function(f, e) { - var h, s, o = r.xhr(); - if (r.username ? o.open(r.type, r.url, r.async, r.username, r.password) : o.open(r.type, r.url, r.async), r.xhrFields) - for (s in r.xhrFields) o[s] = r.xhrFields[s]; - r.mimeType && o.overrideMimeType && o.overrideMimeType(r.mimeType); - r.crossDomain || f["X-Requested-With"] || (f["X-Requested-With"] = "XMLHttpRequest"); - try { - for (s in f) o.setRequestHeader(s, f[s]) - } catch (c) {} - o.send(r.hasContent && r.data || null); - u = function(n, f) { - var s, a, l, c; - try { - if (u && (f || 4 === o.readyState)) - if (u = t, h && (o.onreadystatechange = i.noop, at && delete g[h]), f) 4 !== o.readyState && o.abort(); - else { - c = {}; - s = o.status; - a = o.getAllResponseHeaders(); - "string" == typeof o.responseText && (c.text = o.responseText); - try { - l = o.statusText - } catch (y) { - l = "" - } - s || !r.isLocal || r.crossDomain ? 1223 === s && (s = 204) : s = c.text ? 200 : 404 - } - } catch (v) { - f || e(-1, v) - } - c && e(s, l, c, a) - }; - r.async ? 4 === o.readyState ? setTimeout(u) : (h = ++gu, at && (g || (g = {}, i(n).unload(at)), g[h] = u), o.onreadystatechange = u) : u() - }, - abort: function() { - u && u(t, !0) - } - } - } - }); - var tt, vt, vo = /^(?:toggle|show|hide)$/, - yo = RegExp("^(?:([+-])=|)(" + st + ")([a-z%]*)$", "i"), - po = /queueHooks$/, - yt = [ko], - ft = { - "*": [function(n, t) { - var o, s, r = this.createTween(n, t), - e = yo.exec(t), - h = r.cur(), - u = +h || 0, - f = 1, - c = 20; - if (e) { - if (o = +e[2], s = e[3] || (i.cssNumber[n] ? "" : "px"), "px" !== s && u) { - u = i.css(r.elem, n, !0) || o || 1; - do f = f || ".5", u /= f, i.style(r.elem, n, u + s); while (f !== (f = r.cur() / h) && 1 !== f && --c) - } - r.unit = s; - r.start = u; - r.end = e[1] ? u + (e[1] + 1) * o : o - } - return r - }] - }; - i.Animation = i.extend(rf, { - tweener: function(n, t) { - i.isFunction(n) ? (t = n, n = ["*"]) : n = n.split(" "); - for (var r, u = 0, f = n.length; f > u; u++) r = n[u], ft[r] = ft[r] || [], ft[r].unshift(t) - }, - prefilter: function(n, t) { - t ? yt.unshift(n) : yt.push(n) - } - }); - i.Tween = f; - f.prototype = { - constructor: f, - init: function(n, t, r, u, f, e) { - this.elem = n; - this.prop = r; - this.easing = f || "swing"; - this.options = t; - this.start = this.now = this.cur(); - this.end = u; - this.unit = e || (i.cssNumber[r] ? "" : "px") - }, - cur: function() { - var n = f.propHooks[this.prop]; - return n && n.get ? n.get(this) : f.propHooks._default.get(this) - }, - run: function(n) { - var r, t = f.propHooks[this.prop]; - return this.pos = r = this.options.duration ? i.easing[this.easing](n, this.options.duration * n, 0, 1, this.options.duration) : n, this.now = (this.end - this.start) * r + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), t && t.set ? t.set(this) : f.propHooks._default.set(this), this - } - }; - f.prototype.init.prototype = f.prototype; - f.propHooks = { - _default: { - get: function(n) { - var t; - return null == n.elem[n.prop] || n.elem.style && null != n.elem.style[n.prop] ? (t = i.css(n.elem, n.prop, ""), t && "auto" !== t ? t : 0) : n.elem[n.prop] - }, - set: function(n) { - i.fx.step[n.prop] ? i.fx.step[n.prop](n) : n.elem.style && (null != n.elem.style[i.cssProps[n.prop]] || i.cssHooks[n.prop]) ? i.style(n.elem, n.prop, n.now + n.unit) : n.elem[n.prop] = n.now - } - } - }; - f.propHooks.scrollTop = f.propHooks.scrollLeft = { - set: function(n) { - n.elem.nodeType && n.elem.parentNode && (n.elem[n.prop] = n.now) - } - }; - i.each(["toggle", "show", "hide"], function(n, t) { - var r = i.fn[t]; - i.fn[t] = function(n, i, u) { - return null == n || "boolean" == typeof n ? r.apply(this, arguments) : this.animate(pt(t, !0), n, i, u) - } - }); - i.fn.extend({ - fadeTo: function(n, t, i, r) { - return this.filter(ut).css("opacity", 0).show().end().animate({ - opacity: t - }, n, i, r) - }, - animate: function(n, t, r, u) { - var o = i.isEmptyObject(n), - e = i.speed(t, r, u), - f = function() { - var t = rf(this, i.extend({}, n), e); - f.finish = function() { - t.stop(!0) - }; - (o || i._data(this, "finish")) && t.stop(!0) - }; - return f.finish = f, o || e.queue === !1 ? this.each(f) : this.queue(e.queue, f) - }, - stop: function(n, r, u) { - var f = function(n) { - var t = n.stop; - delete n.stop; - t(u) - }; - return "string" != typeof n && (u = r, r = n, n = t), r && n !== !1 && this.queue(n || "fx", []), this.each(function() { - var o = !0, - t = null != n && n + "queueHooks", - e = i.timers, - r = i._data(this); - if (t) r[t] && r[t].stop && f(r[t]); - else - for (t in r) r[t] && r[t].stop && po.test(t) && f(r[t]); - for (t = e.length; t--;) e[t].elem !== this || null != n && e[t].queue !== n || (e[t].anim.stop(u), o = !1, e.splice(t, 1)); - (o || !u) && i.dequeue(this, n) - }) - }, - finish: function(n) { - return n !== !1 && (n = n || "fx"), this.each(function() { - var t, f = i._data(this), - r = f[n + "queue"], - e = f[n + "queueHooks"], - u = i.timers, - o = r ? r.length : 0; - for (f.finish = !0, i.queue(this, n, []), e && e.cur && e.cur.finish && e.cur.finish.call(this), t = u.length; t--;) u[t].elem === this && u[t].queue === n && (u[t].anim.stop(!0), u.splice(t, 1)); - for (t = 0; o > t; t++) r[t] && r[t].finish && r[t].finish.call(this); - delete f.finish - }) - } - }); - i.each({ - slideDown: pt("show"), - slideUp: pt("hide"), - slideToggle: pt("toggle"), - fadeIn: { - opacity: "show" - }, - fadeOut: { - opacity: "hide" - }, - fadeToggle: { - opacity: "toggle" - } - }, function(n, t) { - i.fn[n] = function(n, i, r) { - return this.animate(t, n, i, r) - } - }); - i.speed = function(n, t, r) { - var u = n && "object" == typeof n ? i.extend({}, n) : { - complete: r || !r && t || i.isFunction(n) && n, - duration: n, - easing: r && t || t && !i.isFunction(t) && t - }; - return u.duration = i.fx.off ? 0 : "number" == typeof u.duration ? u.duration : u.duration in i.fx.speeds ? i.fx.speeds[u.duration] : i.fx.speeds._default, (null == u.queue || u.queue === !0) && (u.queue = "fx"), u.old = u.complete, u.complete = function() { - i.isFunction(u.old) && u.old.call(this); - u.queue && i.dequeue(this, u.queue) - }, u - }; - i.easing = { - linear: function(n) { - return n - }, - swing: function(n) { - return .5 - Math.cos(n * Math.PI) / 2 - } - }; - i.timers = []; - i.fx = f.prototype.init; - i.fx.tick = function() { - var u, n = i.timers, - r = 0; - for (tt = i.now(); n.length > r; r++) u = n[r], u() || n[r] !== u || n.splice(r--, 1); - n.length || i.fx.stop(); - tt = t - }; - i.fx.timer = function(n) { - n() && i.timers.push(n) && i.fx.start() - }; - i.fx.interval = 13; - i.fx.start = function() { - vt || (vt = setInterval(i.fx.tick, i.fx.interval)) - }; - i.fx.stop = function() { - clearInterval(vt); - vt = null - }; - i.fx.speeds = { - slow: 600, - fast: 200, - _default: 400 - }; - i.fx.step = {}; - i.expr && i.expr.filters && (i.expr.filters.animated = function(n) { - return i.grep(i.timers, function(t) { - return n === t.elem - }).length - }); - i.fn.offset = function(n) { - if (arguments.length) return n === t ? this : this.each(function(t) { - i.offset.setOffset(this, n, t) - }); - var r, e, f = { - top: 0, - left: 0 - }, - u = this[0], - s = u && u.ownerDocument; - if (s) return r = s.documentElement, i.contains(r, u) ? (typeof u.getBoundingClientRect !== o && (f = u.getBoundingClientRect()), e = uf(s), { - top: f.top + (e.pageYOffset || r.scrollTop) - (r.clientTop || 0), - left: f.left + (e.pageXOffset || r.scrollLeft) - (r.clientLeft || 0) - }) : f - }; - i.offset = { - setOffset: function(n, t, r) { - var f = i.css(n, "position"); - "static" === f && (n.style.position = "relative"); - var e = i(n), - o = e.offset(), - l = i.css(n, "top"), - a = i.css(n, "left"), - v = ("absolute" === f || "fixed" === f) && i.inArray("auto", [l, a]) > -1, - u = {}, - s = {}, - h, c; - v ? (s = e.position(), h = s.top, c = s.left) : (h = parseFloat(l) || 0, c = parseFloat(a) || 0); - i.isFunction(t) && (t = t.call(n, r, o)); - null != t.top && (u.top = t.top - o.top + h); - null != t.left && (u.left = t.left - o.left + c); - "using" in t ? t.using.call(n, u) : e.css(u) - } - }; - i.fn.extend({ - position: function() { - if (this[0]) { - var n, r, t = { - top: 0, - left: 0 - }, - u = this[0]; - return "fixed" === i.css(u, "position") ? r = u.getBoundingClientRect() : (n = this.offsetParent(), r = this.offset(), i.nodeName(n[0], "html") || (t = n.offset()), t.top += i.css(n[0], "borderTopWidth", !0), t.left += i.css(n[0], "borderLeftWidth", !0)), { - top: r.top - t.top - i.css(u, "marginTop", !0), - left: r.left - t.left - i.css(u, "marginLeft", !0) - } - } - }, - offsetParent: function() { - return this.map(function() { - for (var n = this.offsetParent || r.documentElement; n && !i.nodeName(n, "html") && "static" === i.css(n, "position");) n = n.offsetParent; - return n || r.documentElement - }) - } - }); - i.each({ - scrollLeft: "pageXOffset", - scrollTop: "pageYOffset" - }, function(n, r) { - var u = /Y/.test(r); - i.fn[n] = function(f) { - return i.access(this, function(n, f, e) { - var o = uf(n); - return e === t ? o ? r in o ? o[r] : o.document.documentElement[f] : n[f] : (o ? o.scrollTo(u ? i(o).scrollLeft() : e, u ? e : i(o).scrollTop()) : n[f] = e, t) - }, n, f, arguments.length, null) - } - }); - i.each({ - Height: "height", - Width: "width" - }, function(n, r) { - i.each({ - padding: "inner" + n, - content: r, - "": "outer" + n - }, function(u, f) { - i.fn[f] = function(f, e) { - var o = arguments.length && (u || "boolean" != typeof f), - s = u || (f === !0 || e === !0 ? "margin" : "border"); - return i.access(this, function(r, u, f) { - var e; - return i.isWindow(r) ? r.document.documentElement["client" + n] : 9 === r.nodeType ? (e = r.documentElement, Math.max(r.body["scroll" + n], e["scroll" + n], r.body["offset" + n], e["offset" + n], e["client" + n])) : f === t ? i.css(r, u, s) : i.style(r, u, f, s) - }, r, o ? f : t, o, null) - } - }) - }); - n.jQuery = n.$ = i; - "function" == typeof define && define.amd && define.amd.jQuery && define("jquery", [], function() { - return i - }) -})(window), -function(n) { - function i(n, t) { - for (var i = window, r = (n || "").split("."); i && r.length;) i = i[r.shift()]; - return typeof i == "function" ? i : (t.push(n), Function.constructor.apply(null, t)) - } - - function r(n) { - return n === "GET" || n === "POST" - } - - function e(n, t) { - r(t) || n.setRequestHeader("X-HTTP-Method-Override", t) - } - - function o(t, i, r) { - var u; - r.indexOf("application/x-javascript") === -1 && (u = (t.getAttribute("data-ajax-mode") || "").toUpperCase(), n(t.getAttribute("data-ajax-update")).each(function(t, r) { - var f; - switch (u) { - case "BEFORE": - f = r.firstChild; - n("<div />").html(i).contents().each(function() { - r.insertBefore(this, f) - }); - break; - case "AFTER": - n("<div />").html(i).contents().each(function() { - r.appendChild(this) - }); - break; - default: - n(r).html(i) - } - })) - } - - function u(t, u) { - var s, h, f, c; - (s = t.getAttribute("data-ajax-confirm"), !s || window.confirm(s)) && (h = n(t.getAttribute("data-ajax-loading")), c = t.getAttribute("data-ajax-loading-duration") || 0, n.extend(u, { - type: t.getAttribute("data-ajax-method") || undefined, - url: t.getAttribute("data-ajax-url") || undefined, - beforeSend: function(n) { - var r; - return e(n, f), r = i(t.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments), r !== !1 && h.show(c), r - }, - complete: function() { - h.hide(c); - i(t.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments) - }, - success: function(n, r, u) { - o(t, n, u.getResponseHeader("Content-Type") || "text/html"); - i(t.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments) - }, - error: i(t.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]) - }), u.data.push({ - name: "X-Requested-With", - value: "XMLHttpRequest" - }), f = u.type.toUpperCase(), r(f) || (u.type = "POST", u.data.push({ - name: "X-HTTP-Method-Override", - value: f - })), n.ajax(u)) - } - - function s(t) { - var i = n(t).data(f); - return !i || !i.validate || i.validate() - } - var t = "unobtrusiveAjaxClick", - f = "unobtrusiveValidation"; - n(document).on("click", "a[data-ajax=true]", function(n) { - n.preventDefault(); - u(this, { - url: this.href, - type: "GET", - data: [] - }) - }); - n(document).on("click", "form[data-ajax=true] input[type=image]", function(i) { - var r = i.target.name, - u = n(i.target), - f = u.parents("form")[0], - e = u.offset(); - n(f).data(t, [{ - name: r + ".x", - value: Math.round(i.pageX - e.left) - }, { - name: r + ".y", - value: Math.round(i.pageY - e.top) - }]); - setTimeout(function() { - n(f).removeData(t) - }, 0) - }); - n(document).on("click", "form[data-ajax=true] :submit", function(i) { - var r = i.target.name, - u = n(i.target).parents("form")[0]; - n(u).data(t, r ? [{ - name: r, - value: i.target.value - }] : []); - setTimeout(function() { - n(u).removeData(t) - }, 0) - }); - n(document).on("submit", "form[data-ajax=true]", function(i) { - var r = n(this).data(t) || []; - (i.preventDefault(), s(this)) && u(this, { - url: this.action, - type: this.method || "GET", - data: r.concat(n(this).serializeArray()) - }) - }) -}(jQuery), -function(n) { - n.extend(n.fn, { - validate: function(t) { - if (!this.length) return t && t.debug && window.console && console.warn("Nothing selected, can't validate, returning nothing."), void 0; - var i = n.data(this[0], "validator"); - return i ? i : (this.attr("novalidate", "novalidate"), i = new n.validator(t, this[0]), n.data(this[0], "validator", i), i.settings.onsubmit && (this.validateDelegate(":submit", "click", function(t) { - i.settings.submitHandler && (i.submitButton = t.target); - n(t.target).hasClass("cancel") && (i.cancelSubmit = !0); - void 0 !== n(t.target).attr("formnovalidate") && (i.cancelSubmit = !0) - }), this.submit(function(t) { - function r() { - var r; - return i.settings.submitHandler ? (i.submitButton && (r = n("<input type='hidden'/>").attr("name", i.submitButton.name).val(n(i.submitButton).val()).appendTo(i.currentForm)), i.settings.submitHandler.call(i, i.currentForm, t), i.submitButton && r.remove(), !1) : !0 - } - return i.settings.debug && t.preventDefault(), i.cancelSubmit ? (i.cancelSubmit = !1, r()) : i.form() ? i.pendingRequest ? (i.formSubmitted = !0, !1) : r() : (i.focusInvalid(), !1) - })), i) - }, - valid: function() { - if (n(this[0]).is("form")) return this.validate().form(); - var t = !0, - i = n(this[0].form).validate(); - return this.each(function() { - t = t && i.element(this) - }), t - }, - removeAttrs: function(t) { - var i = {}, - r = this; - return n.each(t.split(/\s/), function(n, t) { - i[t] = r.attr(t); - r.removeAttr(t) - }), i - }, - rules: function(t, i) { - var r = this[0], - o, u, h; - if (t) { - var e = n.data(r.form, "validator").settings, - s = e.rules, - f = n.validator.staticRules(r); - switch (t) { - case "add": - n.extend(f, n.validator.normalizeRule(i)); - delete f.messages; - s[r.name] = f; - i.messages && (e.messages[r.name] = n.extend(e.messages[r.name], i.messages)); - break; - case "remove": - return i ? (o = {}, n.each(i.split(/\s/), function(n, t) { - o[t] = f[t]; - delete f[t] - }), o) : (delete s[r.name], f) - } - } - return u = n.validator.normalizeRules(n.extend({}, n.validator.classRules(r), n.validator.attributeRules(r), n.validator.dataRules(r), n.validator.staticRules(r)), r), u.required && (h = u.required, delete u.required, u = n.extend({ - required: h - }, u)), u - } - }); - n.extend(n.expr[":"], { - blank: function(t) { - return !n.trim("" + n(t).val()) - }, - filled: function(t) { - return !!n.trim("" + n(t).val()) - }, - unchecked: function(t) { - return !n(t).prop("checked") - } - }); - n.validator = function(t, i) { - this.settings = n.extend(!0, {}, n.validator.defaults, t); - this.currentForm = i; - this.init() - }; - n.validator.format = function(t, i) { - return 1 === arguments.length ? function() { - var i = n.makeArray(arguments); - return i.unshift(t), n.validator.format.apply(this, i) - } : (arguments.length > 2 && i.constructor !== Array && (i = n.makeArray(arguments).slice(1)), i.constructor !== Array && (i = [i]), n.each(i, function(n, i) { - t = t.replace(RegExp("\\{" + n + "\\}", "g"), function() { - return i - }) - }), t) - }; - n.extend(n.validator, { - defaults: { - messages: {}, - groups: {}, - rules: {}, - errorClass: "error", - validClass: "valid", - errorElement: "label", - focusInvalid: !0, - errorContainer: n([]), - errorLabelContainer: n([]), - onsubmit: !0, - ignore: ":hidden", - ignoreTitle: !1, - onfocusin: function(n) { - this.lastActive = n; - this.settings.focusCleanup && !this.blockFocusCleanup && (this.settings.unhighlight && this.settings.unhighlight.call(this, n, this.settings.errorClass, this.settings.validClass), this.addWrapper(this.errorsFor(n)).hide()) - }, - onfocusout: function(n) { - !this.checkable(n) && (n.name in this.submitted || !this.optional(n)) && this.element(n) - }, - onkeyup: function(n, t) { - (9 !== t.which || "" !== this.elementValue(n)) && (n.name in this.submitted || n === this.lastElement) && this.element(n) - }, - onclick: function(n) { - n.name in this.submitted ? this.element(n) : n.parentNode.name in this.submitted && this.element(n.parentNode) - }, - highlight: function(t, i, r) { - "radio" === t.type ? this.findByName(t.name).addClass(i).removeClass(r) : n(t).addClass(i).removeClass(r) - }, - unhighlight: function(t, i, r) { - "radio" === t.type ? this.findByName(t.name).removeClass(i).addClass(r) : n(t).removeClass(i).addClass(r) - } - }, - setDefaults: function(t) { - n.extend(n.validator.defaults, t) - }, - messages: { - required: "This field is required.", - remote: "Please fix this field.", - email: "Please enter a valid email address.", - url: "Please enter a valid URL.", - date: "Please enter a valid date.", - dateISO: "Please enter a valid date (ISO).", - number: "Please enter a valid number.", - digits: "Please enter only digits.", - creditcard: "Please enter a valid credit card number.", - equalTo: "Please enter the same value again.", - maxlength: n.validator.format("Please enter no more than {0} characters."), - minlength: n.validator.format("Please enter at least {0} characters."), - rangelength: n.validator.format("Please enter a value between {0} and {1} characters long."), - range: n.validator.format("Please enter a value between {0} and {1}."), - max: n.validator.format("Please enter a value less than or equal to {0}."), - min: n.validator.format("Please enter a value greater than or equal to {0}.") - }, - autoCreateRanges: !1, - prototype: { - init: function() { - function i(t) { - var i = n.data(this[0].form, "validator"), - r = "on" + t.type.replace(/^validate/, ""); - i.settings[r] && i.settings[r].call(i, this[0], t) - } - var r, t; - this.labelContainer = n(this.settings.errorLabelContainer); - this.errorContext = this.labelContainer.length && this.labelContainer || n(this.currentForm); - this.containers = n(this.settings.errorContainer).add(this.settings.errorLabelContainer); - this.submitted = {}; - this.valueCache = {}; - this.pendingRequest = 0; - this.pending = {}; - this.invalid = {}; - this.reset(); - r = this.groups = {}; - n.each(this.settings.groups, function(t, i) { - "string" == typeof i && (i = i.split(/\s/)); - n.each(i, function(n, i) { - r[i] = t - }) - }); - t = this.settings.rules; - n.each(t, function(i, r) { - t[i] = n.validator.normalizeRule(r) - }); - n(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'] ", "focusin focusout keyup", i).validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", i); - this.settings.invalidHandler && n(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler) - }, - form: function() { - return this.checkForm(), n.extend(this.submitted, this.errorMap), this.invalid = n.extend({}, this.errorMap), this.valid() || n(this.currentForm).triggerHandler("invalid-form", [this]), this.showErrors(), this.valid() - }, - checkForm: function() { - this.prepareForm(); - for (var n = 0, t = this.currentElements = this.elements(); t[n]; n++) this.check(t[n]); - return this.valid() - }, - element: function(t) { - t = this.validationTargetFor(this.clean(t)); - this.lastElement = t; - this.prepareElement(t); - this.currentElements = n(t); - var i = this.check(t) !== !1; - return i ? delete this.invalid[t.name] : this.invalid[t.name] = !0, this.numberOfInvalids() || (this.toHide = this.toHide.add(this.containers)), this.showErrors(), i - }, - showErrors: function(t) { - if (t) { - n.extend(this.errorMap, t); - this.errorList = []; - for (var i in t) this.errorList.push({ - message: t[i], - element: this.findByName(i)[0] - }); - this.successList = n.grep(this.successList, function(n) { - return !(n.name in t) - }) - } - this.settings.showErrors ? this.settings.showErrors.call(this, this.errorMap, this.errorList) : this.defaultShowErrors() - }, - resetForm: function() { - n.fn.resetForm && n(this.currentForm).resetForm(); - this.submitted = {}; - this.lastElement = null; - this.prepareForm(); - this.hideErrors(); - this.elements().removeClass(this.settings.errorClass).removeData("previousValue") - }, - numberOfInvalids: function() { - return this.objectLength(this.invalid) - }, - objectLength: function(n) { - var t = 0; - for (var i in n) t++; - return t - }, - hideErrors: function() { - this.addWrapper(this.toHide).hide() - }, - valid: function() { - return 0 === this.size() - }, - size: function() { - return this.errorList.length - }, - focusInvalid: function() { - if (this.settings.focusInvalid) try { - n(this.findLastActive() || this.errorList.length && this.errorList[0].element || []).filter(":visible").focus().trigger("focusin") - } catch (t) {} - }, - findLastActive: function() { - var t = this.lastActive; - return t && 1 === n.grep(this.errorList, function(n) { - return n.element.name === t.name - }).length && t - }, - elements: function() { - var t = this, - i = {}; - return n(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function() { - return !this.name && t.settings.debug && window.console && console.error("%o has no name assigned", this), this.name in i || !t.objectLength(n(this).rules()) ? !1 : (i[this.name] = !0, !0) - }) - }, - clean: function(t) { - return n(t)[0] - }, - errors: function() { - var t = this.settings.errorClass.replace(" ", "."); - return n(this.settings.errorElement + "." + t, this.errorContext) - }, - reset: function() { - this.successList = []; - this.errorList = []; - this.errorMap = {}; - this.toShow = n([]); - this.toHide = n([]); - this.currentElements = n([]) - }, - prepareForm: function() { - this.reset(); - this.toHide = this.errors().add(this.containers) - }, - prepareElement: function(n) { - this.reset(); - this.toHide = this.errorsFor(n) - }, - elementValue: function(t) { - var r = n(t).attr("type"), - i = n(t).val(); - return "radio" === r || "checkbox" === r ? n("input[name='" + n(t).attr("name") + "']:checked").val() : "string" == typeof i ? i.replace(/\r/g, "") : i - }, - check: function(t) { - var r, u; - t = this.validationTargetFor(this.clean(t)); - var i, f = n(t).rules(), - e = !1, - s = this.elementValue(t); - for (r in f) { - u = { - method: r, - parameters: f[r] - }; - try { - if (i = n.validator.methods[r].call(this, s, t, u.parameters), "dependency-mismatch" === i) { - e = !0; - continue - } - if (e = !1, "pending" === i) return this.toHide = this.toHide.not(this.errorsFor(t)), void 0; - if (!i) return this.formatAndAdd(t, u), !1 - } catch (o) { - throw this.settings.debug && window.console && console.log("Exception occurred when checking element " + t.id + ", check the '" + u.method + "' method.", o), o; - } - } - if (!e) return (this.objectLength(f) && this.successList.push(t), !0) - }, - customDataMessage: function(t, i) { - return n(t).data("msg-" + i.toLowerCase()) || t.attributes && n(t).attr("data-msg-" + i.toLowerCase()) - }, - customMessage: function(n, t) { - var i = this.settings.messages[n]; - return i && (i.constructor === String ? i : i[t]) - }, - findDefined: function() { - for (var n = 0; arguments.length > n; n++) - if (void 0 !== arguments[n]) return arguments[n]; - return void 0 - }, - defaultMessage: function(t, i) { - return this.findDefined(this.customMessage(t.name, i), this.customDataMessage(t, i), !this.settings.ignoreTitle && t.title || void 0, n.validator.messages[i], "<strong>Warning: No message defined for " + t.name + "<\/strong>") - }, - formatAndAdd: function(t, i) { - var r = this.defaultMessage(t, i.method), - u = /\$?\{(\d+)\}/g; - "function" == typeof r ? r = r.call(this, i.parameters, t) : u.test(r) && (r = n.validator.format(r.replace(u, "{$1}"), i.parameters)); - this.errorList.push({ - message: r, - element: t - }); - this.errorMap[t.name] = r; - this.submitted[t.name] = r - }, - addWrapper: function(n) { - return this.settings.wrapper && (n = n.add(n.parent(this.settings.wrapper))), n - }, - defaultShowErrors: function() { - for (var i, t, n = 0; this.errorList[n]; n++) t = this.errorList[n], this.settings.highlight && this.settings.highlight.call(this, t.element, this.settings.errorClass, this.settings.validClass), this.showLabel(t.element, t.message); - if (this.errorList.length && (this.toShow = this.toShow.add(this.containers)), this.settings.success) - for (n = 0; this.successList[n]; n++) this.showLabel(this.successList[n]); - if (this.settings.unhighlight) - for (n = 0, i = this.validElements(); i[n]; n++) this.settings.unhighlight.call(this, i[n], this.settings.errorClass, this.settings.validClass); - this.toHide = this.toHide.not(this.toShow); - this.hideErrors(); - this.addWrapper(this.toShow).show() - }, - validElements: function() { - return this.currentElements.not(this.invalidElements()) - }, - invalidElements: function() { - return n(this.errorList).map(function() { - return this.element - }) - }, - showLabel: function(t, i) { - var r = this.errorsFor(t); - r.length ? (r.removeClass(this.settings.validClass).addClass(this.settings.errorClass), r.html(i)) : (r = n("<" + this.settings.errorElement + ">").attr("for", this.idOrName(t)).addClass(this.settings.errorClass).html(i || ""), this.settings.wrapper && (r = r.hide().show().wrap("<" + this.settings.wrapper + "/>").parent()), this.labelContainer.append(r).length || (this.settings.errorPlacement ? this.settings.errorPlacement(r, n(t)) : r.insertAfter(t))); - !i && this.settings.success && (r.text(""), "string" == typeof this.settings.success ? r.addClass(this.settings.success) : this.settings.success(r, t)); - this.toShow = this.toShow.add(r) - }, - errorsFor: function(t) { - var i = this.idOrName(t); - return this.errors().filter(function() { - return n(this).attr("for") === i - }) - }, - idOrName: function(n) { - return this.groups[n.name] || (this.checkable(n) ? n.name : n.id || n.name) - }, - validationTargetFor: function(n) { - return this.checkable(n) && (n = this.findByName(n.name).not(this.settings.ignore)[0]), n - }, - checkable: function(n) { - return /radio|checkbox/i.test(n.type) - }, - findByName: function(t) { - return n(this.currentForm).find("[name='" + t + "']") - }, - getLength: function(t, i) { - switch (i.nodeName.toLowerCase()) { - case "select": - return n("option:selected", i).length; - case "input": - if (this.checkable(i)) return this.findByName(i.name).filter(":checked").length - } - return t.length - }, - depend: function(n, t) { - return this.dependTypes[typeof n] ? this.dependTypes[typeof n](n, t) : !0 - }, - dependTypes: { - boolean: function(n) { - return n - }, - string: function(t, i) { - return !!n(t, i.form).length - }, - "function": function(n, t) { - return n(t) - } - }, - optional: function(t) { - var i = this.elementValue(t); - return !n.validator.methods.required.call(this, i, t) && "dependency-mismatch" - }, - startRequest: function(n) { - this.pending[n.name] || (this.pendingRequest++, this.pending[n.name] = !0) - }, - stopRequest: function(t, i) { - this.pendingRequest--; - 0 > this.pendingRequest && (this.pendingRequest = 0); - delete this.pending[t.name]; - i && 0 === this.pendingRequest && this.formSubmitted && this.form() ? (n(this.currentForm).submit(), this.formSubmitted = !1) : !i && 0 === this.pendingRequest && this.formSubmitted && (n(this.currentForm).triggerHandler("invalid-form", [this]), this.formSubmitted = !1) - }, - previousValue: function(t) { - return n.data(t, "previousValue") || n.data(t, "previousValue", { - old: null, - valid: !0, - message: this.defaultMessage(t, "remote") - }) - } - }, - classRuleSettings: { - required: { - required: !0 - }, - email: { - email: !0 - }, - url: { - url: !0 - }, - date: { - date: !0 - }, - dateISO: { - dateISO: !0 - }, - number: { - number: !0 - }, - digits: { - digits: !0 - }, - creditcard: { - creditcard: !0 - } - }, - addClassRules: function(t, i) { - t.constructor === String ? this.classRuleSettings[t] = i : n.extend(this.classRuleSettings, t) - }, - classRules: function(t) { - var i = {}, - r = n(t).attr("class"); - return r && n.each(r.split(" "), function() { - this in n.validator.classRuleSettings && n.extend(i, n.validator.classRuleSettings[this]) - }), i - }, - attributeRules: function(t) { - var u = {}, - e = n(t), - f = e[0].getAttribute("type"), - r, i; - for (r in n.validator.methods) "required" === r ? (i = e.get(0).getAttribute(r), "" === i && (i = !0), i = !!i) : i = e.attr(r), /min|max/.test(r) && (null === f || /number|range|text/.test(f)) && (i = Number(i)), i ? u[r] = i : f === r && "range" !== f && (u[r] = !0); - return u.maxlength && /-1|2147483647|524288/.test(u.maxlength) && delete u.maxlength, u - }, - dataRules: function(t) { - var i, r, u = {}, - f = n(t); - for (i in n.validator.methods) r = f.data("rule-" + i.toLowerCase()), void 0 !== r && (u[i] = r); - return u - }, - staticRules: function(t) { - var i = {}, - r = n.data(t.form, "validator"); - return r.settings.rules && (i = n.validator.normalizeRule(r.settings.rules[t.name]) || {}), i - }, - normalizeRules: function(t, i) { - return n.each(t, function(r, u) { - if (u === !1) return delete t[r], void 0; - if (u.param || u.depends) { - var f = !0; - switch (typeof u.depends) { - case "string": - f = !!n(u.depends, i.form).length; - break; - case "function": - f = u.depends.call(i, i) - } - f ? t[r] = void 0 !== u.param ? u.param : !0 : delete t[r] - } - }), n.each(t, function(r, u) { - t[r] = n.isFunction(u) ? u(i) : u - }), n.each(["minlength", "maxlength"], function() { - t[this] && (t[this] = Number(t[this])) - }), n.each(["rangelength", "range"], function() { - var i; - t[this] && (n.isArray(t[this]) ? t[this] = [Number(t[this][0]), Number(t[this][1])] : "string" == typeof t[this] && (i = t[this].split(/[\s,]+/), t[this] = [Number(i[0]), Number(i[1])])) - }), n.validator.autoCreateRanges && (t.min && t.max && (t.range = [t.min, t.max], delete t.min, delete t.max), t.minlength && t.maxlength && (t.rangelength = [t.minlength, t.maxlength], delete t.minlength, delete t.maxlength)), t - }, - normalizeRule: function(t) { - if ("string" == typeof t) { - var i = {}; - n.each(t.split(/\s/), function() { - i[this] = !0 - }); - t = i - } - return t - }, - addMethod: function(t, i, r) { - n.validator.methods[t] = i; - n.validator.messages[t] = void 0 !== r ? r : n.validator.messages[t]; - 3 > i.length && n.validator.addClassRules(t, n.validator.normalizeRule(t)) - }, - methods: { - required: function(t, i, r) { - if (!this.depend(r, i)) return "dependency-mismatch"; - if ("select" === i.nodeName.toLowerCase()) { - var u = n(i).val(); - return u && u.length > 0 - } - return this.checkable(i) ? this.getLength(t, i) > 0 : n.trim(t).length > 0 - }, - email: function(n, t) { - return this.optional(t) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(n) - }, - url: function(n, t) { - return this.optional(t) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(n) - }, - date: function(n, t) { - return this.optional(t) || !/Invalid|NaN/.test("" + new Date(n)) - }, - dateISO: function(n, t) { - return this.optional(t) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(n) - }, - number: function(n, t) { - return this.optional(t) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(n) - }, - digits: function(n, t) { - return this.optional(t) || /^\d+$/.test(n) - }, - creditcard: function(n, t) { - var r, e; - if (this.optional(t)) return "dependency-mismatch"; - if (/[^0-9 \-]+/.test(n)) return !1; - var f = 0, - i = 0, - u = !1; - for (n = n.replace(/\D/g, ""), r = n.length - 1; r >= 0; r--) e = n.charAt(r), i = parseInt(e, 10), u && (i *= 2) > 9 && (i -= 9), f += i, u = !u; - return 0 == f % 10 - }, - minlength: function(t, i, r) { - var u = n.isArray(t) ? t.length : this.getLength(n.trim(t), i); - return this.optional(i) || u >= r - }, - maxlength: function(t, i, r) { - var u = n.isArray(t) ? t.length : this.getLength(n.trim(t), i); - return this.optional(i) || r >= u - }, - rangelength: function(t, i, r) { - var u = n.isArray(t) ? t.length : this.getLength(n.trim(t), i); - return this.optional(i) || u >= r[0] && r[1] >= u - }, - min: function(n, t, i) { - return this.optional(t) || n >= i - }, - max: function(n, t, i) { - return this.optional(t) || i >= n - }, - range: function(n, t, i) { - return this.optional(t) || n >= i[0] && i[1] >= n - }, - equalTo: function(t, i, r) { - var u = n(r); - return this.settings.onfocusout && u.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { - n(i).valid() - }), t === u.val() - }, - remote: function(t, i, r) { - var f, u, e; - return this.optional(i) ? "dependency-mismatch" : (f = this.previousValue(i), this.settings.messages[i.name] || (this.settings.messages[i.name] = {}), f.originalMessage = this.settings.messages[i.name].remote, this.settings.messages[i.name].remote = f.message, r = "string" == typeof r && { - url: r - } || r, f.old === t) ? f.valid : (f.old = t, u = this, this.startRequest(i), e = {}, e[i.name] = t, n.ajax(n.extend(!0, { - url: r, - mode: "abort", - port: "validate" + i.name, - dataType: "json", - data: e, - success: function(r) { - var e, h, s, o; - u.settings.messages[i.name].remote = f.originalMessage; - e = r === !0 || "true" === r; - e ? (h = u.formSubmitted, u.prepareElement(i), u.formSubmitted = h, u.successList.push(i), delete u.invalid[i.name], u.showErrors()) : (s = {}, o = r || u.defaultMessage(i, "remote"), s[i.name] = f.message = n.isFunction(o) ? o(t) : o, u.invalid[i.name] = !0, u.showErrors(s)); - f.valid = e; - u.stopRequest(i, e) - } - }, r)), "pending") - } - } - }); - n.format = n.validator.format -}(jQuery), -function(n) { - var t = {}, - i; - n.ajaxPrefilter ? n.ajaxPrefilter(function(n, i, r) { - var u = n.port; - "abort" === n.mode && (t[u] && t[u].abort(), t[u] = r) - }) : (i = n.ajax, n.ajax = function(r) { - var f = ("mode" in r ? r : n.ajaxSettings).mode, - u = ("port" in r ? r : n.ajaxSettings).port; - return "abort" === f ? (t[u] && t[u].abort(), t[u] = i.apply(this, arguments), t[u]) : i.apply(this, arguments) - }) -}(jQuery), -function(n) { - n.extend(n.fn, { - validateDelegate: function(t, i, r) { - return this.bind(i, function(i) { - var u = n(i.target); - if (u.is(t)) return r.apply(u, arguments) - }) - } - }) -}(jQuery), -function(n) { - function i(n, t, i) { - n.rules[t] = i; - n.message && (n.messages[t] = n.message) - } - - function h(n) { - return n.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g) - } - - function f(n) { - return n.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1") - } - - function e(n) { - return n.substr(0, n.lastIndexOf(".") + 1) - } - - function o(n, t) { - return n.indexOf("*.") === 0 && (n = n.replace("*.", t)), n - } - - function c(t, i) { - var r = n(this).find("[data-valmsg-for='" + f(i[0].name) + "']"), - u = r.attr("data-valmsg-replace"), - e = u ? n.parseJSON(u) !== !1 : null; - r.removeClass("field-validation-valid").addClass("field-validation-error"); - t.data("unobtrusiveContainer", r); - e ? (r.empty(), t.removeClass("input-validation-error").appendTo(r)) : t.hide() - } - - function l(t, i) { - var u = n(this).find("[data-valmsg-summary=true]"), - r = u.find("ul"); - r && r.length && i.errorList.length && (r.empty(), u.addClass("validation-summary-errors").removeClass("validation-summary-valid"), n.each(i.errorList, function() { - n("<li />").html(this.message).appendTo(r) - })) - } - - function a(t) { - var i = t.data("unobtrusiveContainer"), - r = i.attr("data-valmsg-replace"), - u = r ? n.parseJSON(r) : null; - i && (i.addClass("field-validation-valid").removeClass("field-validation-error"), t.removeData("unobtrusiveContainer"), u && i.empty()) - } - - function v() { - var t = n(this); - t.data("validator").resetForm(); - t.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"); - t.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer") - } - - function s(t) { - var i = n(t), - r = i.data(u), - f = n.proxy(v, t); - return r || (r = { - options: { - errorClass: "input-validation-error", - errorElement: "span", - errorPlacement: n.proxy(c, t), - invalidHandler: n.proxy(l, t), - messages: {}, - rules: {}, - success: n.proxy(a, t) - }, - attachValidation: function() { - i.unbind("reset." + u, f).bind("reset." + u, f).validate(this.options) - }, - validate: function() { - return i.validate(), i.valid() - } - }, i.data(u, r)), r - } - var r = n.validator, - t, u = "unobtrusiveValidation"; - r.unobtrusive = { - adapters: [], - parseElement: function(t, i) { - var u = n(t), - f = u.parents("form")[0], - r, e, o; - f && (r = s(f), r.options.rules[t.name] = e = {}, r.options.messages[t.name] = o = {}, n.each(this.adapters, function() { - var i = "data-val-" + this.name, - r = u.attr(i), - s = {}; - r !== undefined && (i += "-", n.each(this.params, function() { - s[this] = u.attr(i + this) - }), this.adapt({ - element: t, - form: f, - message: r, - params: s, - rules: e, - messages: o - })) - }), n.extend(e, { - __dummy__: !0 - }), i || r.attachValidation()) - }, - parse: function(t) { - var i = n(t).parents("form").andSelf().add(n(t).find("form")).filter("form"); - n(t).find(":input[data-val=true]").each(function() { - r.unobtrusive.parseElement(this, !0) - }); - i.each(function() { - var n = s(this); - n && n.attachValidation() - }) - } - }; - t = r.unobtrusive.adapters; - t.add = function(n, t, i) { - return i || (i = t, t = []), this.push({ - name: n, - params: t, - adapt: i - }), this - }; - t.addBool = function(n, t) { - return this.add(n, function(r) { - i(r, t || n, !0) - }) - }; - t.addMinMax = function(n, t, r, u, f, e) { - return this.add(n, [f || "min", e || "max"], function(n) { - var f = n.params.min, - e = n.params.max; - f && e ? i(n, u, [f, e]) : f ? i(n, t, f) : e && i(n, r, e) - }) - }; - t.addSingleVal = function(n, t, r) { - return this.add(n, [t || "val"], function(u) { - i(u, r || n, u.params[t]) - }) - }; - r.addMethod("__dummy__", function() { - return !0 - }); - r.addMethod("regex", function(n, t, i) { - var r; - return this.optional(t) ? !0 : (r = new RegExp(i).exec(n), r && r.index === 0 && r[0].length === n.length) - }); - r.addMethod("nonalphamin", function(n, t, i) { - var r; - return i && (r = n.match(/\W/g), r = r && r.length >= i), r - }); - t.addSingleVal("accept", "exts").addSingleVal("regex", "pattern"); - t.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); - t.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); - t.add("equalto", ["other"], function(t) { - var r = e(t.element.name), - u = t.params.other, - s = o(u, r), - h = n(t.form).find(":input[name='" + f(s) + "']")[0]; - i(t, "equalTo", h) - }); - t.add("required", function(n) { - (n.element.tagName.toUpperCase() !== "INPUT" || n.element.type.toUpperCase() !== "CHECKBOX") && i(n, "required", !0) - }); - t.add("remote", ["url", "type", "additionalfields"], function(t) { - var r = { - url: t.params.url, - type: t.params.type || "GET", - data: {} - }, - u = e(t.element.name); - n.each(h(t.params.additionalfields || t.element.name), function(i, e) { - var s = o(e, u); - r.data[s] = function() { - return n(t.form).find(":input[name='" + f(s) + "']").val() - } - }); - i(t, "remote", r) - }); - t.add("password", ["min", "nonalphamin", "regex"], function(n) { - n.params.min && i(n, "minlength", n.params.min); - n.params.nonalphamin && i(n, "nonalphamin", n.params.nonalphamin); - n.params.regex && i(n, "regex", n.params.regex) - }); - n(function() { - r.unobtrusive.parse(document) - }) -}(jQuery); -window.Modernizr = function(n, t, i) { - function a(n) { - c.cssText = n - } - - function vt(n, t) { - return a(y.join(n + ";") + (t || "")) - } - - function h(n, t) { - return typeof n === t - } - - function v(n, t) { - return !!~("" + n).indexOf(t) - } - - function lt(n, t) { - var u, r; - for (u in n) - if (r = n[u], !v(r, "-") && c[r] !== i) return t == "pfx" ? r : !0; - return !1 - } - - function yt(n, t, r) { - var f, u; - for (f in n) - if (u = t[n[f]], u !== i) return r === !1 ? n[f] : h(u, "function") ? u.bind(r || t) : u; - return !1 - } - - function f(n, t, i) { - var r = n.charAt(0).toUpperCase() + n.slice(1), - u = (n + " " + ot.join(r + " ") + r).split(" "); - return h(t, "string") || h(t, "undefined") ? lt(u, t) : (u = (n + " " + st.join(r + " ") + r).split(" "), yt(u, t, i)) - } - - function pt() { - u.input = function(i) { - for (var r = 0, u = i.length; r < u; r++) w[i[r]] = !!(i[r] in o); - return w.list && (w.list = !!(t.createElement("datalist") && n.HTMLDataListElement)), w - }("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")); - u.inputtypes = function(n) { - for (var u = 0, r, f, e, h = n.length; u < h; u++) o.setAttribute("type", f = n[u]), r = o.type !== "text", r && (o.value = g, o.style.cssText = "position:absolute;visibility:hidden;", /^range$/.test(f) && o.style.WebkitAppearance !== i ? (s.appendChild(o), e = t.defaultView, r = e.getComputedStyle && e.getComputedStyle(o, null).WebkitAppearance !== "textfield" && o.offsetHeight !== 0, s.removeChild(o)) : /^(search|tel)$/.test(f) || (r = /^(url|email)$/.test(f) ? o.checkValidity && o.checkValidity() === !1 : o.value != g)), ht[n[u]] = !!r; - return ht - }("search tel url email datetime date month week time datetime-local number range color".split(" ")) - } - var u = {}, - d = !0, - s = t.documentElement, - e = "modernizr", - ut = t.createElement(e), - c = ut.style, - o = t.createElement("input"), - g = ":)", - ft = {}.toString, - y = " -webkit- -moz- -o- -ms- ".split(" "), - et = "Webkit Moz O ms", - ot = et.split(" "), - st = et.toLowerCase().split(" "), - p = { - svg: "http://www.w3.org/2000/svg" - }, - r = {}, - ht = {}, - w = {}, - nt = [], - tt = nt.slice, - b, l = function(n, i, r, u) { - var l, a, c, v, f = t.createElement("div"), - h = t.body, - o = h || t.createElement("body"); - if (parseInt(r, 10)) - while (r--) c = t.createElement("div"), c.id = u ? u[r] : e + (r + 1), f.appendChild(c); - return l = ["­", '<style id="s', e, '">', n, "<\/style>"].join(""), f.id = e, (h ? f : o).innerHTML += l, o.appendChild(f), h || (o.style.background = "", o.style.overflow = "hidden", v = s.style.overflow, s.style.overflow = "hidden", s.appendChild(o)), a = i(f, n), h ? f.parentNode.removeChild(f) : (o.parentNode.removeChild(o), s.style.overflow = v), !!a - }, - at = function(t) { - var i = n.matchMedia || n.msMatchMedia, - r; - return i ? i(t).matches : (l("@media " + t + " { #" + e + " { position: absolute; } }", function(t) { - r = (n.getComputedStyle ? getComputedStyle(t, null) : t.currentStyle).position == "absolute" - }), r) - }, - ct = function() { - function r(r, u) { - u = u || t.createElement(n[r] || "div"); - r = "on" + r; - var f = r in u; - return f || (u.setAttribute || (u = t.createElement("div")), u.setAttribute && u.removeAttribute && (u.setAttribute(r, ""), f = h(u[r], "function"), h(u[r], "undefined") || (u[r] = i), u.removeAttribute(r))), u = null, f - } - var n = { - select: "input", - change: "input", - submit: "form", - reset: "form", - error: "img", - load: "img", - abort: "img" - }; - return r - }(), - it = {}.hasOwnProperty, - rt, k; - rt = h(it, "undefined") || h(it.call, "undefined") ? function(n, t) { - return t in n && h(n.constructor.prototype[t], "undefined") - } : function(n, t) { - return it.call(n, t) - }; - Function.prototype.bind || (Function.prototype.bind = function(n) { - var t = this, - i, r; - if (typeof t != "function") throw new TypeError; - return i = tt.call(arguments, 1), r = function() { - var f, e, u; - return this instanceof r ? (f = function() {}, f.prototype = t.prototype, e = new f, u = t.apply(e, i.concat(tt.call(arguments))), Object(u) === u) ? u : e : t.apply(n, i.concat(tt.call(arguments))) - }, r - }); - r.flexbox = function() { - return f("flexWrap") - }; - r.flexboxlegacy = function() { - return f("boxDirection") - }; - r.canvas = function() { - var n = t.createElement("canvas"); - return !!(n.getContext && n.getContext("2d")) - }; - r.canvastext = function() { - return !!(u.canvas && h(t.createElement("canvas").getContext("2d").fillText, "function")) - }; - r.webgl = function() { - return !!n.WebGLRenderingContext - }; - r.touch = function() { - var i; - return "ontouchstart" in n || n.DocumentTouch && t instanceof DocumentTouch ? i = !0 : l(["@media (", y.join("touch-enabled),("), e, ")", "{#modernizr{top:9px;position:absolute}}"].join(""), function(n) { - i = n.offsetTop === 9 - }), i - }; - r.geolocation = function() { - return "geolocation" in navigator - }; - r.postmessage = function() { - return !!n.postMessage - }; - r.websqldatabase = function() { - return !!n.openDatabase - }; - r.indexedDB = function() { - return !!f("indexedDB", n) - }; - r.hashchange = function() { - return ct("hashchange", n) && (t.documentMode === i || t.documentMode > 7) - }; - r.history = function() { - return !!(n.history && history.pushState) - }; - r.draganddrop = function() { - var n = t.createElement("div"); - return "draggable" in n || "ondragstart" in n && "ondrop" in n - }; - r.websockets = function() { - return "WebSocket" in n || "MozWebSocket" in n - }; - r.rgba = function() { - return a("background-color:rgba(150,255,150,.5)"), v(c.backgroundColor, "rgba") - }; - r.hsla = function() { - return a("background-color:hsla(120,40%,100%,.5)"), v(c.backgroundColor, "rgba") || v(c.backgroundColor, "hsla") - }; - r.multiplebgs = function() { - return a("background:url(https://),url(https://),red url(https://)"), /(url\s*\(.*?){3}/.test(c.background) - }; - r.backgroundsize = function() { - return f("backgroundSize") - }; - r.borderimage = function() { - return f("borderImage") - }; - r.borderradius = function() { - return f("borderRadius") - }; - r.boxshadow = function() { - return f("boxShadow") - }; - r.textshadow = function() { - return t.createElement("div").style.textShadow === "" - }; - r.opacity = function() { - return vt("opacity:.55"), /^0.55$/.test(c.opacity) - }; - r.cssanimations = function() { - return f("animationName") - }; - r.csscolumns = function() { - return f("columnCount") - }; - r.cssgradients = function() { - var n = "background-image:"; - return a((n + "-webkit- ".split(" ").join("gradient(linear,left top,right bottom,from(#9f9),to(white));" + n) + y.join("linear-gradient(left top,#9f9, white);" + n)).slice(0, -n.length)), v(c.backgroundImage, "gradient") - }; - r.cssreflections = function() { - return f("boxReflect") - }; - r.csstransforms = function() { - return !!f("transform") - }; - r.csstransforms3d = function() { - var n = !!f("perspective"); - return n && "webkitPerspective" in s.style && l("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}", function(t) { - n = t.offsetLeft === 9 && t.offsetHeight === 3 - }), n - }; - r.csstransitions = function() { - return f("transition") - }; - r.fontface = function() { - var n; - return l('@font-face {font-family:"font";src:url("https://")}', function(i, r) { - var f = t.getElementById("smodernizr"), - u = f.sheet || f.styleSheet, - e = u ? u.cssRules && u.cssRules[0] ? u.cssRules[0].cssText : u.cssText || "" : ""; - n = /src/i.test(e) && e.indexOf(r.split(" ")[0]) === 0 - }), n - }; - r.generatedcontent = function() { - var n; - return l(["#", e, "{font:0/0 a}#", e, ':after{content:"', g, '";visibility:hidden;font:3px/1 a}'].join(""), function(t) { - n = t.offsetHeight >= 3 - }), n - }; - r.video = function() { - var i = t.createElement("video"), - n = !1; - try { - (n = !!i.canPlayType) && (n = new Boolean(n), n.ogg = i.canPlayType('video/ogg; codecs="theora"').replace(/^no$/, ""), n.h264 = i.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/, ""), n.webm = i.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/, "")) - } catch (r) {} - return n - }; - r.audio = function() { - var i = t.createElement("audio"), - n = !1; - try { - (n = !!i.canPlayType) && (n = new Boolean(n), n.ogg = i.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/, ""), n.mp3 = i.canPlayType("audio/mpeg;").replace(/^no$/, ""), n.wav = i.canPlayType('audio/wav; codecs="1"').replace(/^no$/, ""), n.m4a = (i.canPlayType("audio/x-m4a;") || i.canPlayType("audio/aac;")).replace(/^no$/, "")) - } catch (r) {} - return n - }; - r.localstorage = function() { - try { - return localStorage.setItem(e, e), localStorage.removeItem(e), !0 - } catch (n) { - return !1 - } - }; - r.sessionstorage = function() { - try { - return sessionStorage.setItem(e, e), sessionStorage.removeItem(e), !0 - } catch (n) { - return !1 - } - }; - r.webworkers = function() { - return !!n.Worker - }; - r.applicationcache = function() { - return !!n.applicationCache - }; - r.svg = function() { - return !!t.createElementNS && !!t.createElementNS(p.svg, "svg").createSVGRect - }; - r.inlinesvg = function() { - var n = t.createElement("div"); - return n.innerHTML = "<svg/>", (n.firstChild && n.firstChild.namespaceURI) == p.svg - }; - r.smil = function() { - return !!t.createElementNS && /SVGAnimate/.test(ft.call(t.createElementNS(p.svg, "animate"))) - }; - r.svgclippaths = function() { - return !!t.createElementNS && /SVGClipPath/.test(ft.call(t.createElementNS(p.svg, "clipPath"))) - }; - for (k in r) rt(r, k) && (b = k.toLowerCase(), u[b] = r[k](), nt.push((u[b] ? "" : "no-") + b)); - return u.input || pt(), u.addTest = function(n, t) { - if (typeof n == "object") - for (var r in n) rt(n, r) && u.addTest(r, n[r]); - else { - if (n = n.toLowerCase(), u[n] !== i) return u; - t = typeof t == "function" ? t() : t; - typeof d != "undefined" && d && (s.className += " " + (t ? "" : "no-") + n); - u[n] = t - } - return u - }, a(""), ut = o = null, - function(n, t) { - function p(n, t) { - var i = n.createElement("p"), - r = n.getElementsByTagName("head")[0] || n.documentElement; - return i.innerHTML = "x<style>" + t + "<\/style>", r.insertBefore(i.lastChild, r.firstChild) - } - - function c() { - var n = r.elements; - return typeof n == "string" ? n.split(" ") : n - } - - function o(n) { - var t = h[n[s]]; - return t || (t = {}, e++, n[s] = e, h[e] = t), t - } - - function l(n, r, u) { - if (r || (r = t), i) return r.createElement(n); - u || (u = o(r)); - var f; - return f = u.cache[n] ? u.cache[n].cloneNode() : y.test(n) ? (u.cache[n] = u.createElem(n)).cloneNode() : u.createElem(n), f.canHaveChildren && !v.test(n) ? u.frag.appendChild(f) : f - } - - function w(n, r) { - if (n || (n = t), i) return n.createDocumentFragment(); - r = r || o(n); - for (var f = r.frag.cloneNode(), u = 0, e = c(), s = e.length; u < s; u++) f.createElement(e[u]); - return f - } - - function b(n, t) { - t.cache || (t.cache = {}, t.createElem = n.createElement, t.createFrag = n.createDocumentFragment, t.frag = t.createFrag()); - n.createElement = function(i) { - return r.shivMethods ? l(i, n, t) : t.createElem(i) - }; - n.createDocumentFragment = Function("h,f", "return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(" + c().join().replace(/\w+/g, function(n) { - return t.createElem(n), t.frag.createElement(n), 'c("' + n + '")' - }) + ");return n}")(r, t.frag) - } - - function a(n) { - n || (n = t); - var u = o(n); - return !r.shivCSS || f || u.hasCSS || (u.hasCSS = !!p(n, "article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")), i || b(n, u), n - } - var u = n.html5 || {}, - v = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i, - y = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i, - f, s = "_html5shiv", - e = 0, - h = {}, - i, r; - (function() { - try { - var n = t.createElement("a"); - n.innerHTML = "<xyz><\/xyz>"; - f = "hidden" in n; - i = n.childNodes.length == 1 || function() { - t.createElement("a"); - var n = t.createDocumentFragment(); - return typeof n.cloneNode == "undefined" || typeof n.createDocumentFragment == "undefined" || typeof n.createElement == "undefined" - }() - } catch (r) { - f = !0; - i = !0 - } - })(); - r = { - elements: u.elements || "abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video", - shivCSS: u.shivCSS !== !1, - supportsUnknownElements: i, - shivMethods: u.shivMethods !== !1, - type: "default", - shivDocument: a, - createElement: l, - createDocumentFragment: w - }; - n.html5 = r; - a(t) - }(this, t), u._version = "2.6.2", u._prefixes = y, u._domPrefixes = st, u._cssomPrefixes = ot, u.mq = at, u.hasEvent = ct, u.testProp = function(n) { - return lt([n]) - }, u.testAllProps = f, u.testStyles = l, u.prefixed = function(n, t, i) { - return t ? f(n, t, i) : f(n, "pfx") - }, s.className = s.className.replace(/(^|\s)no-js(\s|$)/, "$1$2") + (d ? " js " + nt.join(" ") : ""), u - }(this, this.document), - function(n, t, i) { - function l(n) { - var t = {}, - r = /^jQuery\d+$/; - return i.each(n.attributes, function(n, i) { - i.specified && !r.test(i.name) && (t[i.name] = i.value) - }), t - } - - function f(n, r) { - var f = this, - u = i(f); - if (f.value == u.attr("placeholder") && u.hasClass("placeholder")) - if (u.data("placeholder-password")) { - if (u = u.hide().next().show().attr("id", u.removeAttr("id").data("placeholder-id")), n === !0) return u[0].value = r; - u.focus() - } else f.value = "", u.removeClass("placeholder"), f == t.activeElement && f.select() - } - - function s() { - var t, r = this, - n = i(r), - e = n, - u = this.id; - if (r.value == "") { - if (r.type == "password") { - if (!n.data("placeholder-textinput")) { - try { - t = n.clone().attr({ - type: "text" - }) - } catch (o) { - t = i("<input>").attr(i.extend(l(this), { - type: "text" - })) - } - t.removeAttr("name").data({ - "placeholder-password": !0, - "placeholder-id": u - }).bind("focus.placeholder", f); - n.data({ - "placeholder-textinput": t, - "placeholder-id": u - }).before(t) - } - n = n.removeAttr("id").hide().prev().attr("id", u).show() - } - n.addClass("placeholder"); - n[0].value = n.attr("placeholder") - } else n.removeClass("placeholder") - } - var u = "placeholder" in t.createElement("input"), - e = "placeholder" in t.createElement("textarea"), - h = i.fn, - c = i.valHooks, - o, r; - u && e ? (r = h.placeholder = function() { - return this - }, r.input = r.textarea = !0) : (r = h.placeholder = function() { - var n = this; - return n.filter((u ? "textarea" : ":input") + "[placeholder]").not(".placeholder").bind({ - "focus.placeholder": f, - "blur.placeholder": s - }).data("placeholder-enabled", !0).trigger("blur.placeholder"), n - }, r.input = u, r.textarea = e, o = { - get: function(n) { - var t = i(n); - return t.data("placeholder-enabled") && t.hasClass("placeholder") ? "" : n.value - }, - set: function(n, r) { - var u = i(n); - return u.data("placeholder-enabled") ? (r == "" ? (n.value = r, n != t.activeElement && s.call(n)) : u.hasClass("placeholder") ? f.call(n, !0, r) || (n.value = r) : n.value = r, u) : n.value = r - } - }, u || (c.input = o), e || (c.textarea = o), i(function() { - i(t).delegate("form", "submit.placeholder", function() { - var n = i(".placeholder", this).each(f); - setTimeout(function() { - n.each(s) - }, 10) - }) - }), i(n).bind("beforeunload.placeholder", function() { - i(".placeholder").each(function() { - this.value = "" - }) - })) - }(this, document, jQuery), - function(n) { - "function" == typeof define && define.amd ? define(["jquery"], n) : n(jQuery) - }(function(n) { - function r(n) { - return n - } - - function u(n) { - return decodeURIComponent(n.replace(f, " ")) - } - - function i(n) { - 0 === n.indexOf('"') && (n = n.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, "\\")); - try { - return t.json ? JSON.parse(n) : n - } catch (i) {} - } - var f = /\+/g, - t = n.cookie = function(f, e, o) { - var l, s; - if (void 0 !== e) return (o = n.extend({}, t.defaults, o), "number" == typeof o.expires) && (l = o.expires, s = o.expires = new Date, s.setDate(s.getDate() + l)), e = t.json ? JSON.stringify(e) : e + "", document.cookie = [t.raw ? f : encodeURIComponent(f), "=", t.raw ? e : encodeURIComponent(e), o.expires ? "; expires=" + o.expires.toUTCString() : "", o.path ? "; path=" + o.path : "", o.domain ? "; domain=" + o.domain : "", o.secure ? "; secure" : ""].join(""); - for (var a = t.raw ? r : u, v = document.cookie.split("; "), h = f ? void 0 : {}, c = 0, b = v.length; b > c; c++) { - var y = v[c].split("="), - p = a(y.shift()), - w = a(y.join("=")); - if (f && f === p) { - h = i(w); - break - } - f || (h[p] = i(w)) - } - return h - }; - t.defaults = {}; - n.removeCookie = function(t, i) { - return void 0 !== n.cookie(t) ? (n.cookie(t, "", n.extend(i, { - expires: -1 - })), !0) : !1 - } - }); -typeof JSON != "object" && (JSON = {}), - function() { - "use strict"; - - function i(n) { - return n < 10 ? "0" + n : n - } - - function o(n) { - return e.lastIndex = 0, e.test(n) ? '"' + n.replace(e, function(n) { - var t = s[n]; - return typeof t == "string" ? t : "\\u" + ("0000" + n.charCodeAt(0).toString(16)).slice(-4) - }) + '"' : '"' + n + '"' - } - - function u(i, f) { - var s, l, h, a, v = n, - c, e = f[i]; - e && typeof e == "object" && typeof e.toJSON == "function" && (e = e.toJSON(i)); - typeof t == "function" && (e = t.call(f, i, e)); - switch (typeof e) { - case "string": - return o(e); - case "number": - return isFinite(e) ? String(e) : "null"; - case "boolean": - case "null": - return String(e); - case "object": - if (!e) return "null"; - if (n += r, c = [], Object.prototype.toString.apply(e) === "[object Array]") { - for (a = e.length, s = 0; s < a; s += 1) c[s] = u(s, e) || "null"; - return h = c.length === 0 ? "[]" : n ? "[\n" + n + c.join(",\n" + n) + "\n" + v + "]" : "[" + c.join(",") + "]", n = v, h - } - if (t && typeof t == "object") - for (a = t.length, s = 0; s < a; s += 1) typeof t[s] == "string" && (l = t[s], h = u(l, e), h && c.push(o(l) + (n ? ": " : ":") + h)); - else - for (l in e) Object.prototype.hasOwnProperty.call(e, l) && (h = u(l, e), h && c.push(o(l) + (n ? ": " : ":") + h)); - return h = c.length === 0 ? "{}" : n ? "{\n" + n + c.join(",\n" + n) + "\n" + v + "}" : "{" + c.join(",") + "}", n = v, h - } - } - typeof Date.prototype.toJSON != "function" && (Date.prototype.toJSON = function() { - return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + i(this.getUTCMonth() + 1) + "-" + i(this.getUTCDate()) + "T" + i(this.getUTCHours()) + ":" + i(this.getUTCMinutes()) + ":" + i(this.getUTCSeconds()) + "Z" : null - }, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function() { - return this.valueOf() - }); - var f = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - e = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - n, r, s = { - "\b": "\\b", - "\t": "\\t", - "\n": "\\n", - "\f": "\\f", - "\r": "\\r", - '"': '\\"', - "\\": "\\\\" - }, - t; - typeof JSON.stringify != "function" && (JSON.stringify = function(i, f, e) { - var o; - if (n = "", r = "", typeof e == "number") - for (o = 0; o < e; o += 1) r += " "; - else typeof e == "string" && (r = e); - if (t = f, f && typeof f != "function" && (typeof f != "object" || typeof f.length != "number")) throw new Error("JSON.stringify"); - return u("", { - "": i - }) - }); - typeof JSON.parse != "function" && (JSON.parse = function(text, reviver) { - function walk(n, t) { - var r, u, i = n[t]; - if (i && typeof i == "object") - for (r in i) Object.prototype.hasOwnProperty.call(i, r) && (u = walk(i, r), u !== undefined ? i[r] = u : delete i[r]); - return reviver.call(n, t, i) - } - var j; - if (text = String(text), f.lastIndex = 0, f.test(text) && (text = text.replace(f, function(n) { - return "\\u" + ("0000" + n.charCodeAt(0).toString(16)).slice(-4) - })), /^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) return j = eval("(" + text + ")"), typeof reviver == "function" ? walk({ - "": j - }, "") : j; - throw new SyntaxError("JSON.parse"); - }) - }(), - function() { - function ut() { - var u = !1, - n; - if ("localStorage" in window) try { - window.localStorage.setItem("_tmptest", "tmpval"); - u = !0; - window.localStorage.removeItem("_tmptest") - } catch (f) {} - if (u) try { - window.localStorage && (i = window.localStorage, r = "localStorage", s = i.jStorage_update) - } catch (e) {} else if ("globalStorage" in window) try { - window.globalStorage && (i = window.globalStorage[window.location.hostname], r = "globalStorage", s = i.jStorage_update) - } catch (o) {} else if (t = document.createElement("link"), t.addBehavior) { - t.style.behavior = "url(#default#userData)"; - document.getElementsByTagName("head")[0].appendChild(t); - try { - t.load("jStorage") - } catch (h) { - t.setAttribute("jStorage", "{}"); - t.save("jStorage"); - t.load("jStorage") - } - n = "{}"; - try { - n = t.getAttribute("jStorage") - } catch (c) {} - try { - s = t.getAttribute("jStorage_update") - } catch (a) {} - i.jStorage = n; - r = "userDataBehavior" - } else { - t = null; - return - } - it(); - p(); - y("local"); - y("session"); - ft(); - rt(); - "addEventListener" in window && window.addEventListener("pageshow", function(n) { - n.persisted && l() - }, !1) - } - - function y(t, i) { - function l() { - if (t == "session") try { - o = u.parse(window.name || "{}") - } catch (n) { - o = {} - } - } - - function a() { - t == "session" && (window.name = u.stringify(o)) - } - var c = !1, - s = 0, - h, f, o = {}, - v = Math.random(); - if (i || typeof window[t + "Storage"] == "undefined") { - if (t == "local" && window.globalStorage) { - localStorage = window.globalStorage[window.location.hostname]; - return - } - if (r == "userDataBehavior") { - i && window[t + "Storage"] && window[t + "Storage"].parentNode && window[t + "Storage"].parentNode.removeChild(window[t + "Storage"]); - f = document.createElement("button"); - document.getElementsByTagName("head")[0].appendChild(f); - t == "local" ? o = n : t == "session" && l(); - for (h in o) o.hasOwnProperty(h) && h != "__jstorage_meta" && h != "length" && typeof o[h] != "undefined" && (h in f || s++, f[h] = o[h]); - f.length = s; - f.key = function(n) { - var i = 0, - t; - l(); - for (t in o) - if (o.hasOwnProperty(t) && t != "__jstorage_meta" && t != "length" && typeof o[t] != "undefined") { - if (i == n) return t; - i++ - } - }; - f.getItem = function(n) { - return (l(), t == "session") ? o[n] : e.jStorage.get(n) - }; - f.setItem = function(n, t) { - typeof t != "undefined" && (f[n] = (t || "").toString()) - }; - f.removeItem = function(n) { - if (t == "local") return e.jStorage.deleteKey(n); - f[n] = undefined; - c = !0; - n in f && f.removeAttribute(n); - c = !1 - }; - f.clear = function() { - if (t == "session") { - window.name = ""; - y("session", !0); - return - } - e.jStorage.flush() - }; - t == "local" && (d = function(n, t) { - n != "length" && (c = !0, typeof t == "undefined" ? n in f && (s--, f.removeAttribute(n)) : (n in f || s++, f[n] = (t || "").toString()), f.length = s, c = !1) - }); - f.attachEvent("onpropertychange", function(n) { - if (n.propertyName != "length" && !c && n.propertyName != "length") { - if (t == "local") n.propertyName in o || typeof f[n.propertyName] == "undefined" || s++; - else if (t == "session") { - l(); - typeof f[n.propertyName] == "undefined" || n.propertyName in o ? typeof f[n.propertyName] == "undefined" && n.propertyName in o ? (delete o[n.propertyName], s--) : o[n.propertyName] = f[n.propertyName] : (o[n.propertyName] = f[n.propertyName], s++); - a(); - f.length = s; - return - } - e.jStorage.set(n.propertyName, f[n.propertyName]); - f.length = s - } - }); - window[t + "Storage"] = f - } - } - } - - function tt() { - var n = "{}"; - if (r == "userDataBehavior") { - t.load("jStorage"); - try { - n = t.getAttribute("jStorage") - } catch (u) {} - try { - s = t.getAttribute("jStorage_update") - } catch (f) {} - i.jStorage = n - } - it(); - p(); - rt() - } - - function ft() { - r == "localStorage" || r == "globalStorage" ? "addEventListener" in window ? window.addEventListener("storage", l, !1) : document.attachEvent("onstorage", l) : r == "userDataBehavior" && setInterval(l, 1e3) - } - - function l() { - var n; - clearTimeout(g); - g = setTimeout(function() { - if (r == "localStorage" || r == "globalStorage") n = i.jStorage_update; - else if (r == "userDataBehavior") { - t.load("jStorage"); - try { - n = t.getAttribute("jStorage_update") - } catch (u) {} - } - n && n != s && (s = n, et()) - }, 25) - } - - function et() { - var i = u.parse(u.stringify(n.__jstorage_meta.CRC32)), - r, t, f, e; - tt(); - r = u.parse(u.stringify(n.__jstorage_meta.CRC32)); - f = []; - e = []; - for (t in i) - if (i.hasOwnProperty(t)) { - if (!r[t]) { - e.push(t); - continue - } - i[t] != r[t] && String(i[t]).substr(0, 2) == "2." && f.push(t) - } - for (t in r) r.hasOwnProperty(t) && (i[t] || f.push(t)); - c(f, "updated"); - c(e, "deleted") - } - - function c(n, t) { - var u, i, e, r, o; - if (n = [].concat(n || []), t == "flushed") { - n = []; - for (u in f) f.hasOwnProperty(u) && n.push(u); - t = "deleted" - } - for (i = 0, e = n.length; i < e; i++) - if (f[n[i]]) - for (r = 0, o = f[n[i]].length; r < o; r++) f[n[i]][r](n[i], t) - } - - function a() { - var n = (+new Date).toString(); - r == "localStorage" || r == "globalStorage" ? i.jStorage_update = n : r == "userDataBehavior" && (t.setAttribute("jStorage_update", n), t.save("jStorage")); - l() - } - - function it() { - if (i.jStorage) try { - n = u.parse(String(i.jStorage)) - } catch (t) { - i.jStorage = "{}" - } else i.jStorage = "{}"; - w = i.jStorage ? String(i.jStorage).length : 0; - n.__jstorage_meta || (n.__jstorage_meta = {}); - n.__jstorage_meta.CRC32 || (n.__jstorage_meta.CRC32 = {}) - } - - function v() { - st(); - try { - i.jStorage = u.stringify(n); - t && (t.setAttribute("jStorage", i.jStorage), t.save("jStorage")); - w = i.jStorage ? String(i.jStorage).length : 0 - } catch (r) {} - } - - function o(n) { - if (!n || typeof n != "string" && typeof n != "number") throw new TypeError("Key name must be string or numeric"); - if (n == "__jstorage_meta") throw new TypeError("Reserved key name"); - return !0 - } - - function p() { - var u, t, i, f, r = Infinity, - e = !1, - o = []; - if (clearTimeout(nt), n.__jstorage_meta && typeof n.__jstorage_meta.TTL == "object") { - u = +new Date; - i = n.__jstorage_meta.TTL; - f = n.__jstorage_meta.CRC32; - for (t in i) i.hasOwnProperty(t) && (i[t] <= u ? (delete i[t], delete f[t], delete n[t], e = !0, o.push(t)) : i[t] < r && (r = i[t])); - r != Infinity && (nt = setTimeout(p, r - u)); - e && (v(), a(), c(o, "deleted")) - } - } - - function rt() { - var t, r, i; - if (n.__jstorage_meta.PubSub) { - for (r = b, i = len = n.__jstorage_meta.PubSub.length - 1; i >= 0; i--) t = n.__jstorage_meta.PubSub[i], t[0] > b && (r = t[0], ot(t[1], t[2])); - b = r - } - } - - function ot(n, t) { - if (h[n]) - for (var i = 0, r = h[n].length; i < r; i++) h[n][i](n, u.parse(u.stringify(t))) - } - - function st() { - var i, t, r; - if (n.__jstorage_meta.PubSub) { - for (i = +new Date - 2e3, t = 0, r = n.__jstorage_meta.PubSub.length; t < r; t++) - if (n.__jstorage_meta.PubSub[t][0] <= i) { - n.__jstorage_meta.PubSub.splice(t, n.__jstorage_meta.PubSub.length - t); - break - } - n.__jstorage_meta.PubSub.length || delete n.__jstorage_meta.PubSub - } - } - - function ht(t, i) { - n.__jstorage_meta || (n.__jstorage_meta = {}); - n.__jstorage_meta.PubSub || (n.__jstorage_meta.PubSub = []); - n.__jstorage_meta.PubSub.unshift([+new Date, t, i]); - v(); - a() - } - - function ct(n, t) { - for (var f = n.length, i = t ^ f, u = 0, r; f >= 4;) r = n.charCodeAt(u) & 255 | (n.charCodeAt(++u) & 255) << 8 | (n.charCodeAt(++u) & 255) << 16 | (n.charCodeAt(++u) & 255) << 24, r = (r & 65535) * 1540483477 + (((r >>> 16) * 1540483477 & 65535) << 16), r ^= r >>> 24, r = (r & 65535) * 1540483477 + (((r >>> 16) * 1540483477 & 65535) << 16), i = (i & 65535) * 1540483477 + (((i >>> 16) * 1540483477 & 65535) << 16) ^ r, f -= 4, ++u; - switch (f) { - case 3: - i ^= (n.charCodeAt(u + 2) & 255) << 16; - case 2: - i ^= (n.charCodeAt(u + 1) & 255) << 8; - case 1: - i ^= n.charCodeAt(u) & 255; - i = (i & 65535) * 1540483477 + (((i >>> 16) * 1540483477 & 65535) << 16) - } - return i ^= i >>> 13, i = (i & 65535) * 1540483477 + (((i >>> 16) * 1540483477 & 65535) << 16), i ^= i >>> 15, i >>> 0 - } - var e = window.jQuery || window.$ || (window.$ = {}), - u = { - parse: window.JSON && (window.JSON.parse || window.JSON.decode) || String.prototype.evalJSON && function(n) { - return String(n).evalJSON() - } || e.parseJSON || e.evalJSON, - stringify: Object.toJSON || window.JSON && (window.JSON.stringify || window.JSON.encode) || e.toJSON - }; - if (!u.parse || !u.stringify) throw new Error("No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page"); - var n = {}, - i = { - jStorage: "{}" - }, - t = null, - w = 0, - r = !1, - f = {}, - g = !1, - s = 0, - h = {}, - b = +new Date, - nt, k = { - isXML: function(n) { - var t = (n ? n.ownerDocument || n : 0).documentElement; - return t ? t.nodeName !== "HTML" : !1 - }, - encode: function(n) { - if (!this.isXML(n)) return !1; - try { - return (new XMLSerializer).serializeToString(n) - } catch (t) { - try { - return n.xml - } catch (i) {} - } - return !1 - }, - decode: function(n) { - var i = "DOMParser" in window && (new DOMParser).parseFromString || window.ActiveXObject && function(n) { - var t = new ActiveXObject("Microsoft.XMLDOM"); - return t.async = "false", t.loadXML(n), t - }, - t; - return i ? (t = i.call("DOMParser" in window && new DOMParser || window, n, "text/xml"), this.isXML(t) ? t : !1) : !1 - } - }, - d = function() {}; - e.jStorage = { - version: "0.3.1", - set: function(t, i, r) { - if (o(t), r = r || {}, typeof i == "undefined") return this.deleteKey(t), i; - if (k.isXML(i)) i = { - _is_xml: !0, - xml: k.encode(i) - }; - else { - if (typeof i == "function") return undefined; - i && typeof i == "object" && (i = u.parse(u.stringify(i))) - } - return n[t] = i, n.__jstorage_meta.CRC32[t] = "2." + ct(u.stringify(i)), this.setTTL(t, r.TTL || 0), d(t, i), c(t, "updated"), i - }, - get: function(t, i) { - return (o(t), t in n) ? n[t] && typeof n[t] == "object" && n[t]._is_xml ? k.decode(n[t].xml) : n[t] : typeof i == "undefined" ? null : i - }, - deleteKey: function(t) { - return (o(t), t in n) ? (delete n[t], typeof n.__jstorage_meta.TTL == "object" && t in n.__jstorage_meta.TTL && delete n.__jstorage_meta.TTL[t], delete n.__jstorage_meta.CRC32[t], d(t, undefined), v(), a(), c(t, "deleted"), !0) : !1 - }, - setTTL: function(t, i) { - var r = +new Date; - return (o(t), i = Number(i) || 0, t in n) ? (n.__jstorage_meta.TTL || (n.__jstorage_meta.TTL = {}), i > 0 ? n.__jstorage_meta.TTL[t] = r + i : delete n.__jstorage_meta.TTL[t], v(), p(), a(), !0) : !1 - }, - getTTL: function(t) { - var r = +new Date, - i; - return (o(t), t in n && n.__jstorage_meta.TTL && n.__jstorage_meta.TTL[t]) ? (i = n.__jstorage_meta.TTL[t] - r, i || 0) : 0 - }, - flush: function() { - return n = { - __jstorage_meta: { - CRC32: {} - } - }, y("local", !0), v(), a(), c(null, "flushed"), !0 - }, - storageObj: function() { - function t() {} - return t.prototype = n, new t - }, - index: function() { - var i = []; - for (var t in n) n.hasOwnProperty(t) && t != "__jstorage_meta" && i.push(t); - return i - }, - storageSize: function() { - return w - }, - currentBackend: function() { - return r - }, - storageAvailable: function() { - return !!r - }, - listenKeyChange: function(n, t) { - o(n); - f[n] || (f[n] = []); - f[n].push(t) - }, - stopListening: function(n, t) { - if (o(n), f[n]) { - if (!t) { - delete f[n]; - return - } - for (var i = f[n].length - 1; i >= 0; i--) f[n][i] == t && f[n].splice(i, 1) - } - }, - subscribe: function(n, t) { - if (n = (n || "").toString(), !n) throw new TypeError("Channel not defined"); - h[n] || (h[n] = []); - h[n].push(t) - }, - publish: function(n, t) { - if (n = (n || "").toString(), !n) throw new TypeError("Channel not defined"); - ht(n, t) - }, - reInit: function() { - tt() - } - }; - ut() - }(), - function(n, t) { - function ut() {} - - function bi(n, t) { - if (t) return "'" + n.split("'").join("\\'").split('\\"').join('\\\\\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t") + "'"; - var i = n.charAt(0), - r = n.substring(1); - return i === "=" ? "+(" + r + ")+" : i === ":" ? "+e(" + r + ")+" : ";" + n + ";o+=" - } - - function e(n, t, i) { - return (n = n + "", t = t || 2, i = t - n.length, i) ? rr[t].substring(0, i) + n : n - } - - function ur(t, u) { - var c = r.browser, - o, g = t.css("direction") == "rtl", - e, v; - if (t.parent().hasClass("k-animation-container")) e = t.parent(".k-animation-container"), v = e[0].style, e.is(":hidden") && e.show(), o = tt.test(v.width) || tt.test(v.height), o || e.css({ - width: t.outerWidth(), - height: t.outerHeight(), - boxSizing: "content-box", - mozBoxSizing: "content-box", - webkitBoxSizing: "content-box" - }); - else { - var y = t.css(i.support.transitions.css + "box-shadow") || t.css("box-shadow"), - f = y ? y.match(vi) || [0, 0, 0, 0, 0] : [0, 0, 0, 0, 0], - l = p.max(+f[3], +(f[4] || 0)), - a = -f[1] + l, - w = +f[1] + l, - b = +f[2] + l, - s = t[0].style.width, - h = t[0].style.height, - k = tt.test(s), - d = tt.test(h); - c.opera && (a = w = b = 5); - o = k || d; - !k && (!u || u && s) && (s = t.outerWidth()); - !d && (!u || u && h) && (h = t.outerHeight()); - t.wrap(n("<div/>").addClass("k-animation-container").css({ - width: s, - height: h, - marginLeft: a * (g ? 1 : -1), - paddingLeft: a, - paddingRight: w, - paddingBottom: b - })); - o && t.css({ - width: "100%", - height: "100%", - boxSizing: "border-box", - mozBoxSizing: "border-box", - webkitBoxSizing: "border-box" - }) - } - return c.msie && p.floor(c.version) <= 7 && (t.css({ - zoom: 1 - }), t.children(".k-menu").width(t.width())), t.parent() - } - - function kt(n) { - for (var t = 1, i = arguments.length, t = 1; t < i; t++) dt(n, arguments[t]); - return n - } - - function dt(n, t) { - var o = i.data.ObservableArray, - s = i.data.DataSource, - u, r, f, e; - for (u in t) r = t[u], f = typeof r, f === a && r !== null && r.constructor !== Array && r.constructor !== o && r.constructor !== s ? r instanceof Date ? n[u] = new Date(r.getTime()) : ft(r.clone) ? n[u] = r.clone() : (e = n[u], n[u] = typeof e === a ? e || {} : {}, dt(n[u], r)) : f !== rt && (n[u] = r); - return n - } - - function ct(n, i, r) { - for (var u in i) - if (i.hasOwnProperty(u) && i[u].test(n)) return u; - return r !== t ? r : n - } - - function fr(n) { - return n.replace(/([a-z][A-Z])/g, function(n) { - return n.charAt(0) + "-" + n.charAt(1).toLowerCase() - }) - } - - function gt(n) { - return n.replace(/\-(\w)/g, function(n, t) { - return t.toUpperCase() - }) - } - - function er(t, r) { - var u = {}, - f; - return document.defaultView && document.defaultView.getComputedStyle ? (f = document.defaultView.getComputedStyle(t, ""), r && n.each(r, function(n, t) { - u[t] = f.getPropertyValue(t) - })) : (f = t.currentStyle, r && n.each(r, function(n, t) { - u[t] = f[gt(t)] - })), i.size(u) || (u = f), u - } - - function or(n) { - var t = 0; - for (var i in n) n.hasOwnProperty(i) && i != "toJSON" && t++; - return t - } - - function sr(n, t, i) { - var u, f, e, o; - return (t || (t = "offset"), u = n[t](), f = r.mobileOS, r.touch && f.ios && f.flatVersion < 410 && (e = t == "offset" ? u : n.offset(), o = u.left == e.left && u.top == e.top, o)) ? { - top: u.top - window.scrollY, - left: u.left - window.scrollX - } : (r.browser.msie && (r.pointers || r.msPointers) && !i && (u.top -= window.pageYOffset - document.documentElement.scrollTop, u.left -= window.pageXOffset - document.documentElement.scrollLeft), u) - } - - function hr(n) { - var t = {}; - return d(typeof n == "string" ? n.split(" ") : n, function(n) { - t[n] = this - }), t - } - - function cr(n) { - return new i.effects.Element(n) - } - - function ti(n, t, i, r) { - return typeof n === u && (ft(t) && (r = t, t = 400, i = !1), ft(i) && (r = i, i = !1), typeof t === pt && (i = t, t = 400), n = { - effects: n, - duration: t, - reverse: i, - complete: r - }), s({ - effects: {}, - duration: 400, - reverse: !1, - init: g, - teardown: g, - hide: !1 - }, n, { - completeCallback: n.complete, - complete: g - }) - } - - function ii(t, i, r, u, f) { - for (var e = 0, s = t.length, o; e < s; e++) o = n(t[e]), o.queue(function() { - h.promise(o, ti(i, r, u, f)) - }); - return t - } - - function lr(n, t, i, r, u, f) { - return h.transitionPromise(n, t, ti(i, r, u, f)) - } - - function ar(n, t, i, r) { - return t && (t = t.split(" "), d(t, function(t, i) { - n.toggleClass(i, r) - })), n - } - - function wr(n) { - return ("" + n).replace(vr, "&").replace(yr, "<").replace(pr, ">") - } - - function at(n, r) { - var u; - return r.indexOf("data") === 0 && (r = r.substring(4), r = r.charAt(0).toLowerCase() + r.substring(1)), r = r.replace(gr, "-$1"), u = n.getAttribute("data-" + i.ns + r), u === null ? u = t : u === "null" ? u = null : u === "true" ? u = !0 : u === "false" ? u = !1 : yi.test(u) ? u = parseFloat(u) : kr.test(u) && !dr.test(u) && (u = new Function("return (" + u + ")")()), u - } - - function fi(r, u) { - var o = {}, - e, f; - for (e in u) f = at(r, e), f !== t && (br.test(e) && (f = i.template(n("#" + f).html())), o[e] = f); - return o - } - - function nu(t, i) { - return n.contains(t, i) ? -1 : 1 - } - - function tu() { - var t = n(this); - return n.inArray(t.attr("data-role"), ["slider", "rangeslider"]) > 0 || t.is(":visible") - } - - function iu(n, t) { - var i = n.nodeName.toLowerCase(); - return (/input|select|textarea|button|object/.test(i) ? !n.disabled : "a" === i ? n.href || t : t) && ru(n) - } - - function ru(t) { - return !n(t).parents().addBack().filter(function() { - return n.css(this, "visibility") === "hidden" || n.expr.filters.hidden(this) - }).length - } - - function o(n, t) { - return new o.fn.init(n, t) - } - var i = window.kendo = window.kendo || { - cultures: {} - }, - s = n.extend, - d = n.each, - li = n.isArray, - ot = n.proxy, - g = n.noop, - p = Math, - v, nt = window.JSON || {}, - r = {}, - tt = /%/, - ai = /\{(\d+)(:[^\}]+)?\}/g, - vi = /(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+(?:\.?)\d*)px\s*(\d+)?/i, - yi = /^(\+|-?)\d+(\.?)\d*$/, - c = "function", - u = "string", - l = "number", - a = "object", - it = "null", - pt = "boolean", - rt = "undefined", - wt = {}, - bt = {}, - st = [].slice, - y = window.Globalize, - ni, h, lt, ri, ui, w, ei, oi, hi, vt, et, ci, yt, k; - i.version = "2013.3.1324"; - ut.extend = function(n) { - var r = function() {}, - t, u = this, - i = n && n.init ? n.init : function() { - u.apply(this, arguments) - }, - f; - r.prototype = u.prototype; - f = i.fn = i.prototype = new r; - for (t in n) f[t] = typeof n[t] !== a || n[t] instanceof Array || n[t] === null ? n[t] : s(!0, {}, r.prototype[t], n[t]); - return f.constructor = i, i.extend = u.extend, i - }; - ut.prototype._initOptions = function(n) { - this.options = kt({}, this.options, n) - }; - var ft = i.isFunction = function(n) { - return typeof n == "function" - }, - pi = function() { - this._defaultPrevented = !0 - }, - wi = function() { - return this._defaultPrevented === !0 - }, - ht = ut.extend({ - init: function() { - this._events = {} - }, - bind: function(n, i, r) { - var f = this, - e, s = typeof n === u ? [n] : n, - h, l, o, v = typeof i === c, - a; - if (i === t) { - for (e in n) f.bind(e, n[e]); - return f - } - for (e = 0, h = s.length; e < h; e++) n = s[e], o = v ? i : i[n], o && (r && (l = o, o = function() { - f.unbind(n, o); - l.apply(f, arguments) - }), a = f._events[n] = f._events[n] || [], a.push(o)); - return f - }, - one: function(n, t) { - return this.bind(n, t, !0) - }, - first: function(n, t) { - for (var r = this, e = typeof n === u ? [n] : n, f, h = typeof t === c, s, i = 0, o = e.length; i < o; i++) n = e[i], f = h ? t : t[n], f && (s = r._events[n] = r._events[n] || [], s.unshift(f)); - return r - }, - trigger: function(n, t) { - var u = this, - i = u._events[n], - r, f; - if (i) { - for (t = t || {}, t.sender = u, t._defaultPrevented = !1, t.preventDefault = pi, t.isDefaultPrevented = wi, i = i.slice(), r = 0, f = i.length; r < f; r++) i[r].call(u, t); - return t._defaultPrevented === !0 - } - return !1 - }, - unbind: function(n, i) { - var u = this, - f = u._events[n], - r; - if (n === t) u._events = {}; - else if (f) - if (i) - for (r = f.length - 1; r >= 0; r--) f[r] === i && f.splice(r, 1); - else u._events[n] = []; - return u - } - }); - var ki = /^\w+/, - di = /\$\{([^}]*)\}/g, - gi = /\\\}/g, - nr = /__CURLY__/g, - tr = /\\#/g, - ir = /__SHARP__/g, - rr = ["", "0", "00", "000", "0000"]; - v = { - paramName: "data", - useWithBlock: !0, - render: function(n, t) { - for (var u = "", i = 0, r = t.length; i < r; i++) u += n(t[i]); - return u - }, - compile: function(t, r) { - var h = s({}, this, r), - c = h.paramName, - a = c.match(ki)[0], - l = h.useWithBlock, - u = "var o,e=kendo.htmlEncode;", - o, e, f; - if (ft(t)) return t.length === 2 ? function(i) { - return t(n, { - data: i - }).join("") - } : t; - for (u += l ? "with(" + c + "){" : "", u += "o=", e = t.replace(gi, "__CURLY__").replace(di, "#=e($1)#").replace(nr, "}").replace(tr, "__SHARP__").split("#"), f = 0; f < e.length; f++) u += bi(e[f], f % 2 == 0); - u += l ? ";}" : ";"; - u += "return o;"; - u = u.replace(ir, "#"); - try { - return o = new Function(a, u), o._slotCount = Math.floor(e.length / 2), o - } catch (v) { - throw new Error(i.format("Invalid template:'{0}' Generated code:'{1}'", t, u)); - } - } - }, - function() { - function o(n) { - return f.lastIndex = 0, f.test(n) ? '"' + n.replace(f, function(n) { - var t = s[n]; - return typeof t === u ? t : "\\u" + ("0000" + n.charCodeAt(0).toString(16)).slice(-4) - }) + '"' : '"' + n + '"' - } - - function r(f, e) { - var v, w, y, k, d = n, - p, s = e[f], - b; - if (s && typeof s === a && typeof s.toJSON === c && (s = s.toJSON(f)), typeof t === c && (s = t.call(e, f, s)), b = typeof s, b === u) return o(s); - if (b === l) return isFinite(s) ? String(s) : it; - if (b === pt || b === it) return String(s); - if (b === a) { - if (!s) return it; - if (n += i, p = [], h.apply(s) === "[object Array]") { - for (k = s.length, v = 0; v < k; v++) p[v] = r(v, s) || it; - return y = p.length === 0 ? "[]" : n ? "[\n" + n + p.join(",\n" + n) + "\n" + d + "]" : "[" + p.join(",") + "]", n = d, y - } - if (t && typeof t === a) - for (k = t.length, v = 0; v < k; v++) typeof t[v] === u && (w = t[v], y = r(w, s), y && p.push(o(w) + (n ? ": " : ":") + y)); - else - for (w in s) Object.hasOwnProperty.call(s, w) && (y = r(w, s), y && p.push(o(w) + (n ? ": " : ":") + y)); - return y = p.length === 0 ? "{}" : n ? "{\n" + n + p.join(",\n" + n) + "\n" + d + "}" : "{" + p.join(",") + "}", n = d, y - } - } - var f = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - n, i, s = { - "\b": "\\b", - "\t": "\\t", - "\n": "\\n", - "\f": "\\f", - "\r": "\\r", - '"': '\\"', - "\\": "\\\\" - }, - t, h = {}.toString; - typeof Date.prototype.toJSON !== c && (Date.prototype.toJSON = function() { - var n = this; - return isFinite(n.valueOf()) ? e(n.getUTCFullYear(), 4) + "-" + e(n.getUTCMonth() + 1) + "-" + e(n.getUTCDate()) + "T" + e(n.getUTCHours()) + ":" + e(n.getUTCMinutes()) + ":" + e(n.getUTCSeconds()) + "Z" : null - }, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function() { - return this.valueOf() - }); - typeof nt.stringify !== c && (nt.stringify = function(f, e, o) { - var s; - if (n = "", i = "", typeof o === l) - for (s = 0; s < o; s += 1) i += " "; - else typeof o === u && (i = o); - if (t = e, e && typeof e !== c && (typeof e !== a || typeof e.length !== l)) throw new Error("JSON.stringify"); - return r("", { - "": f - }) - }) - }(), - function() { - function v(n) { - if (n) { - if (n.numberFormat) return n; - if (typeof n === u) { - var t = i.cultures; - return t[n] || t[n.split("-")[0]] || null - } - return null - } - return null - } - - function w(n) { - return n && (n = v(n)), n || i.cultures.current - } - - function rt(n) { - n.groupSizes = n.groupSize; - n.percent.groupSizes = n.percent.groupSize; - n.currency.groupSizes = n.currency.groupSize - } - - function ut(n, i, r) { - r = w(r); - var u = r.calendars.standard, - f = u.days, - o = u.months; - return i = u.patterns[i] || i, i.replace(d, function(i) { - var r; - return i === "d" ? r = n.getDate() : i === "dd" ? r = e(n.getDate()) : i === "ddd" ? r = f.namesAbbr[n.getDay()] : i === "dddd" ? r = f.names[n.getDay()] : i === "M" ? r = n.getMonth() + 1 : i === "MM" ? r = e(n.getMonth() + 1) : i === "MMM" ? r = o.namesAbbr[n.getMonth()] : i === "MMMM" ? r = o.names[n.getMonth()] : i === "yy" ? r = e(n.getFullYear() % 100) : i === "yyyy" ? r = e(n.getFullYear(), 4) : i === "h" ? r = n.getHours() % 12 || 12 : i === "hh" ? r = e(n.getHours() % 12 || 12) : i === "H" ? r = n.getHours() : i === "HH" ? r = e(n.getHours()) : i === "m" ? r = n.getMinutes() : i === "mm" ? r = e(n.getMinutes()) : i === "s" ? r = n.getSeconds() : i === "ss" ? r = e(n.getSeconds()) : i === "f" ? r = p.floor(n.getMilliseconds() / 100) : i === "ff" ? r = p.floor(n.getMilliseconds() / 10) : i === "fff" ? r = n.getMilliseconds() : i === "tt" && (r = n.getHours() < 12 ? u.AM[0] : u.PM[0]), r !== t ? r : i.slice(1, i.length - 1) - }) - } - - function ft(n, i, u) { - u = w(u); - var l = u.numberFormat, - ot = l.groupSize[0], - lt = l[c], - vt = l[f], - at = l.decimals, - kt = l.pattern[0], - dt = [], - yt, ft, st, pt, wt, et = n < 0, - b, p, rt, ei, gt = r, - y = r, - e, ut, d, ni, ri, it, v, a, bt, ti, ui, ii, fi, ht = -1, - ct; - if (n === t) return r; - if (!isFinite(n)) return n; - if (!i) return u.name.length ? n.toLocaleString() : n.toString(); - if (wt = g.exec(i), wt) { - if (i = wt[1].toLowerCase(), ft = i === "c", st = i === "p", (ft || st) && (l = ft ? l.currency : l.percent, ot = l.groupSize[0], lt = l[c], vt = l[f], at = l.decimals, yt = l.symbol, kt = l.pattern[et ? 0 : 1]), pt = wt[2], pt && (at = +pt), i === "e") return pt ? n.toExponential(at) : n.toExponential(); - if (st && (n *= 100), n = h(n, at), et = n < 0, n = n.split(f), b = n[0], p = n[1], et && (b = b.substring(1)), y = b, rt = b.length, rt >= ot) - for (y = r, e = 0; e < rt; e++) e > 0 && (rt - e) % ot == 0 && (y += lt), y += b.charAt(e); - if (p && (y += vt + p), i === "n" && !et) return y; - for (n = r, e = 0, ut = kt.length; e < ut; e++) d = kt.charAt(e), n += d === "n" ? y : d === "$" || d === "%" ? yt : d; - return n - } - if (et && (n = -n), (i.indexOf("'") > -1 || i.indexOf('"') > -1 || i.indexOf("\\") > -1) && (i = i.replace(nt, function(n) { - var t = n.charAt(0).replace("\\", ""), - i = n.slice(1).replace(t, ""); - return dt.push(i), k - })), i = i.split(";"), et && i[1]) i = i[1], ri = !0; - else if (n === 0) { - if (i = i[2] || i[0], i.indexOf(o) == -1 && i.indexOf(s) == -1) return i - } else i = i[0]; - if (ui = i.indexOf("%"), ii = i.indexOf("$"), st = ui != -1, ft = ii != -1, st && (n *= 100), ft && i[ii - 1] === "\\" && (i = i.split("\\").join(""), ft = !1), (ft || st) && (l = ft ? l.currency : l.percent, ot = l.groupSize[0], lt = l[c], vt = l[f], at = l.decimals, yt = l.symbol), ni = i.indexOf(c) > -1, ni && (i = i.replace(tt, r)), it = i.indexOf(f), ut = i.length, it != -1 ? (p = n.toString().split("e"), p = p[1] ? h(n, Math.abs(p[1])) : p[0], p = p.split(f)[1] || r, a = i.lastIndexOf(s) - it, v = i.lastIndexOf(o) - it, bt = a > -1, ti = v > -1, e = p.length, bt || ti || (i = i.substring(0, it) + i.substring(it + 1), ut = i.length, it = -1, e = 0), bt && a > v ? e = a : v > a && (ti && e > v ? e = v : bt && e < a && (e = a)), e > -1 && (n = h(n, e))) : n = h(n), v = i.indexOf(o), fi = a = i.indexOf(s), ht = v == -1 && a != -1 ? a : v != -1 && a == -1 ? v : v > a ? a : v, v = i.lastIndexOf(o), a = i.lastIndexOf(s), ct = v == -1 && a != -1 ? a : v != -1 && a == -1 ? v : v > a ? v : a, ht == ut && (ct = ht), ht != -1) { - if (y = n.toString().split(f), b = y[0], p = y[1] || r, rt = b.length, ei = p.length, et && n * -1 >= 0 && (et = !1), ni) - if (rt === ot && rt < it - fi) b = lt + b; - else if (rt > ot) { - for (y = r, e = 0; e < rt; e++) e > 0 && (rt - e) % ot == 0 && (y += lt), y += b.charAt(e); - b = y - } - for (n = i.substring(0, ht), et && !ri && (n += "-"), e = ht; e < ut; e++) { - if (d = i.charAt(e), it == -1) { - if (ct - e < rt) { - n += b; - break - } - } else if (a != -1 && a < e && (gt = r), it - e <= rt && it - e > -1 && (n += b, e = it), it === e) { - n += (p ? vt : r) + p; - e += ct - it + 1; - continue - } - d === s ? (n += d, gt = d) : d === o && (n += gt) - } - if (ct >= ht && (n += i.substring(ct + 1)), ft || st) { - for (y = r, e = 0, ut = n.length; e < ut; e++) d = n.charAt(e), y += d === "$" || d === "%" ? yt : d; - n = y - } - if (ut = dt.length, ut) - for (e = 0; e < ut; e++) n = n.replace(k, dt[e]) - } - return n - } - var d = /dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|HH|H|hh|h|mm|m|fff|ff|f|tt|ss|s|"[^"]*"|'[^']*'/g, - g = /^(n|c|p|e)(\d*)$/i, - nt = /(\\.)|(['][^']*[']?)|(["][^"]*["]?)/g, - tt = /\,/g, - r = "", - f = ".", - c = ",", - o = "#", - s = "0", - k = "??", - a = "en-US", - it = {}.toString; - i.cultures["en-US"] = { - name: a, - numberFormat: { - pattern: ["-n"], - decimals: 2, - ",": ",", - ".": ".", - groupSize: [3], - percent: { - pattern: ["-n %", "n %"], - decimals: 2, - ",": ",", - ".": ".", - groupSize: [3], - symbol: "%" - }, - currency: { - pattern: ["($n)", "$n"], - decimals: 2, - ",": ",", - ".": ".", - groupSize: [3], - symbol: "$" - } - }, - calendars: { - standard: { - days: { - names: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], - namesAbbr: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], - namesShort: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"] - }, - months: { - names: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - namesAbbr: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] - }, - AM: ["AM", "am", "AM"], - PM: ["PM", "pm", "PM"], - patterns: { - d: "M/d/yyyy", - D: "dddd, MMMM dd, yyyy", - F: "dddd, MMMM dd, yyyy h:mm:ss tt", - g: "M/d/yyyy h:mm tt", - G: "M/d/yyyy h:mm:ss tt", - m: "MMMM dd", - M: "MMMM dd", - s: "yyyy'-'MM'-'ddTHH':'mm':'ss", - t: "h:mm tt", - T: "h:mm:ss tt", - u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", - y: "MMMM, yyyy", - Y: "MMMM, yyyy" - }, - "/": "/", - ":": ":", - firstDay: 0, - twoDigitYearMax: 2029 - } - } - }; - i.culture = function(n) { - var u = i.cultures, - r; - if (n !== t) r = v(n) || u[a], r.calendar = r.calendars.standard, u.current = r, y && rt(r.numberFormat); - else return u.current - }; - i.findCulture = v; - i.getCulture = w; - i.culture(a); - var et = 9e15, - h = function(n, t) { - var i = Math.pow(10, t || 0), - r = Math.round(n * i); - return r > et ? n.toFixed(t) : (r / i).toFixed(t) - }, - b = function(n, i, r) { - if (i) { - if (it.call(n) === "[object Date]") return ut(n, i, r); - if (typeof n === l) return ft(n, i, r) - } - return n !== t ? n : "" - }; - y && (b = function(t, i, r) { - return n.isPlainObject(r) && (r = r.name), y.format(t, i, r) - }); - i.format = function(n) { - var t = arguments; - return n.replace(ai, function(n, i, r) { - var u = t[parseInt(i, 10) + 1]; - return b(u, r ? r.substring(1) : "") - }) - }; - i._extractFormat = function(n) { - return n.slice(0, 3) === "{0:" && (n = n.slice(3, n.length - 1)), n - }; - i._activeElement = function() { - try { - return document.activeElement - } catch (n) { - return document.documentElement.activeElement - } - }; - i._round = h; - i.toString = b - }(), - function() { - function r(n, t, i) { - return !(n >= t && n <= i) - } - - function b(n) { - return n.charAt(0) - } - - function s(t) { - return n.map(t, b) - } - - function k(n, t) { - t || n.getHours() !== 23 || n.setHours(n.getHours() + 2) - } - - function d(n) { - for (var t = 0, r = n.length, i = []; t < r; t++) i[t] = (n[t] + "").toLowerCase(); - return i - } - - function h(n) { - var t = {}; - for (var i in n) t[i] = d(n[i]); - return t - } - - function g(n, i, u) { - if (!n) return null; - var p = function(n) { - for (var t = 0; i[rt] === n;) t++, rt++; - return t > 0 && (rt -= 1), t - }, - nt = function(t) { - var r = e[t] || new RegExp("^\\d{1," + t + "}"), - i = n.substr(b, t).match(r); - return i ? (i = i[0], b += i.length, parseInt(i, 10)) : null - }, - ht = function(t, i) { - for (var r = 0, o = t.length, f, e, u; r < o; r++) - if (f = t[r], e = f.length, u = n.substr(b, e), i && (u = u.toLowerCase()), u == f) return b += e, r + 1; - return null - }, - ft = function() { - var t = !1; - return n.charAt(b) === i[rt] && (b++, t = !0), t - }, - y = u.calendars.standard, - c = null, - tt = null, - w = null, - o = null, - it = null, - ut = null, - d = null, - rt = 0, - b = 0, - yt = !1, - pt = new Date, - ct = y.twoDigitYearMax || 2029, - et = pt.getFullYear(), - l, f, dt, wt, bt, kt, gt, g, lt, at, vt, ot, ni, st; - for (i || (i = "d"), wt = y.patterns[i], wt && (i = wt), i = i.split(""), dt = i.length; rt < dt; rt++) - if (l = i[rt], yt) l === "'" ? yt = !1 : ft(); - else if (l === "d") { - if (f = p("d"), y._lowerDays || (y._lowerDays = h(y.days)), w = f < 3 ? nt(2) : ht(y._lowerDays[f == 3 ? "namesAbbr" : "names"], !0), w === null || r(w, 1, 31)) return null - } else if (l === "M") { - if (f = p("M"), y._lowerMonths || (y._lowerMonths = h(y.months)), tt = f < 3 ? nt(2) : ht(y._lowerMonths[f == 3 ? "namesAbbr" : "names"], !0), tt === null || r(tt, 1, 12)) return null; - tt -= 1 - } else if (l === "y") { - if (f = p("y"), c = nt(f), c === null) return null; - f == 2 && (typeof ct == "string" && (ct = et + parseInt(ct, 10)), c = et - et % 100 + c, c > ct && (c -= 100)) - } else if (l === "h") { - if (p("h"), o = nt(2), o == 12 && (o = 0), o === null || r(o, 0, 11)) return null - } else if (l === "H") { - if (p("H"), o = nt(2), o === null || r(o, 0, 23)) return null - } else if (l === "m") { - if (p("m"), it = nt(2), it === null || r(it, 0, 59)) return null - } else if (l === "s") { - if (p("s"), ut = nt(2), ut === null || r(ut, 0, 59)) return null - } else if (l === "f") { - if (f = p("f"), st = n.substr(b, f).match(e[3]), d = nt(f), d !== null && (st = st[0].length, st < 3 && (d *= Math.pow(10, 3 - st)), f > 3 && (d = parseInt(d.toString().substring(0, 3), 10))), d === null || r(d, 0, 999)) return null - } else if (l === "t") { - if (f = p("t"), lt = y.AM, at = y.PM, f === 1 && (lt = s(lt), at = s(at)), bt = ht(at), !bt && !ht(lt)) return null - } else if (l === "z") { - if (kt = !0, f = p("z"), n.substr(b, 1) === "Z") { - if (!gt) return null; - ft(); - continue - } - if ((g = n.substr(b, 6).match(f > 2 ? v : a), !g) || (g = g[0], b = g.length, g = g.split(":"), vt = parseInt(g[0], 10), r(vt, -12, 13)) || f > 2 && (ot = parseInt(g[1], 10), isNaN(ot) || r(ot, 0, 59))) return null - } else if (l === "T") gt = ft(); - else if (l === "'") yt = !0, ft(); - else if (!ft()) return null; - return (ni = o !== null || it !== null || ut || null, c === null && tt === null && w === null && ni ? (c = et, tt = pt.getMonth(), w = pt.getDate()) : (c === null && (c = et), w === null && (w = 1)), bt && o < 12 && (o += 12), kt ? (vt && (o += -vt), ot && (it += -ot), n = new Date(Date.UTC(c, tt, w, o, it, ut, d))) : (n = new Date(c, tt, w, o, it, ut, d), k(n, o)), c < 100 && n.setFullYear(c), n.getDate() !== w && kt === t) ? null : n - } - var u = /\u00A0/g, - c = /[eE][\-+]?[0-9]+/, - a = /[+|\-]\d{1,2}/, - v = /[+|\-]\d{1,2}:\d{2}/, - p = /^\/Date\((.*?)\)\/$/, - w = /[+-]{1}\d+/, - f = ["G", "g", "d", "F", "D", "y", "m", "T", "t"], - e = { - 2: /^\d{1,2}/, - 3: /^\d{1,3}/, - 4: /^\d{4}/ - }, - o = {}.toString; - i.parseDate = function(n, t, r) { - if (o.call(n) === "[object Date]") return n; - var e = 0, - u = null, - s, c, h; - if (n && n.indexOf("/D") === 0 && (u = p.exec(n), u)) return u = u[1], h = w.exec(u), u = parseInt(u, 10), h && (u -= parseInt(h[0], 10) * i.date.MS_PER_MINUTE), new Date(u); - if (r = i.getCulture(r), !t) { - for (t = [], c = r.calendar.patterns, s = f.length; e < s; e++) t[e] = c[f[e]]; - e = 0; - t = ["yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM/dd", "ddd MMM dd yyyy HH:mm:ss", "yyyy-MM-ddTHH:mm:ss.fffffffzzz", "yyyy-MM-ddTHH:mm:ss.fffzzz", "yyyy-MM-ddTHH:mm:sszzz", "yyyy-MM-ddTHH:mmzzz", "yyyy-MM-ddTHH:mmzz", "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd"].concat(t) - } - for (t = li(t) ? t : [t], s = t.length; e < s; e++) - if (u = g(n, t[e], r), u) return u; - return u - }; - i.parseInt = function(n, t) { - var r = i.parseFloat(n, t); - return r && (r = r | 0), r - }; - i.parseFloat = function(n, t, r) { - if (!n && n !== 0) return null; - if (typeof n === l) return n; - n = n.toString(); - t = i.getCulture(t); - var f = t.numberFormat, - h = f.percent, - a = f.currency, - s = a.symbol, - v = h.symbol, - e = n.indexOf("-"), - o, y; - return c.test(n) ? (n = parseFloat(n.replace(f["."], ".")), isNaN(n) && (n = null), n) : e > 0 ? null : (e = e > -1, n.indexOf(s) > -1 || r && r.toLowerCase().indexOf("c") > -1 ? (f = a, o = f.pattern[0].replace("$", s).split("n"), n.indexOf(o[0]) > -1 && n.indexOf(o[1]) > -1 && (n = n.replace(o[0], "").replace(o[1], ""), e = !0)) : n.indexOf(v) > -1 && (y = !0, f = h, s = v), n = n.replace("-", "").replace(s, "").replace(u, " ").split(f[","].replace(u, " ")).join("").replace(f["."], "."), n = parseFloat(n), isNaN(n) ? n = null : e && (n *= -1), n && y && (n /= 100), n) - }; - y && (i.parseDate = function(n, t, i) { - return o.call(n) === "[object Date]" ? n : y.parseDate(n, t, i) - }, i.parseFloat = function(i, r) { - return typeof i === l ? i : i === t || i === null ? null : (n.isPlainObject(r) && (r = r.name), i = y.parseFloat(i, r), isNaN(i) ? null : i) - }) - }(), - function() { - var e, i, f, c; - r.scrollbar = function() { - var n = document.createElement("div"), - t; - return n.style.cssText = "overflow:scroll;overflow-x:hidden;zoom:1;clear:both", n.innerHTML = " ", document.body.appendChild(n), t = n.offsetWidth - n.scrollWidth, document.body.removeChild(n), t - }; - r.isRtl = function(t) { - return n(t).closest(".k-rtl").length > 0 - }; - e = document.createElement("table"); - try { - e.innerHTML = "<tr><td><\/td><\/tr>"; - r.tbodyInnerHtml = !0 - } catch (l) { - r.tbodyInnerHtml = !1 - } - r.touch = "ontouchstart" in window; - r.msPointers = window.MSPointerEvent; - r.pointers = window.PointerEvent; - var o = r.transitions = !1, - h = r.transforms = !1, - s = "HTMLElement" in window ? HTMLElement.prototype : []; - r.hasHW3D = "WebKitCSSMatrix" in window && "m11" in new window.WebKitCSSMatrix || "MozPerspective" in document.documentElement.style || "msPerspective" in document.documentElement.style; - d(["Moz", "webkit", "O", "ms"], function() { - var t = this.toString(), - i = typeof e.style[t + "Transition"] === u, - n; - if (i || typeof e.style[t + "Transform"] === u) return n = t.toLowerCase(), h = { - css: n != "ms" ? "-" + n + "-" : "", - prefix: t, - event: n === "o" || n === "webkit" ? n : "" - }, i && (o = h, o.event = o.event ? o.event + "TransitionEnd" : "transitionend"), !1 - }); - e = null; - r.transforms = h; - r.transitions = o; - r.devicePixelRatio = window.devicePixelRatio === t ? 1 : window.devicePixelRatio; - try { - r.screenWidth = window.outerWidth || window.screen ? window.screen.availWidth : window.innerWidth; - r.screenHeight = window.outerHeight || window.screen ? window.screen.availHeight : window.innerHeight - } catch (l) { - r.screenWidth = window.screen.availWidth; - r.screenHeight = window.screen.availHeight - } - r.detectOS = function(n) { - var t = !1, - u, f = [], - o = !/mobile safari/i.test(n), - e = { - fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/, - android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.(\d+(\.\d+)?)/, - iphone: /(iPhone|iPod).*OS\s+(\d+)[\._]([\d\._]+)/, - ipad: /(iPad).*OS\s+(\d+)[\._]([\d_]+)/, - meego: /(MeeGo).+NokiaBrowser\/(\d+)\.([\d\._]+)/, - webos: /(webOS)\/(\d+)\.(\d+(\.\d+)?)/, - blackberry: /(BlackBerry|BB10).*?Version\/(\d+)\.(\d+(\.\d+)?)/, - playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/, - wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/, - windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/, - tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i, - sailfish: /(sailfish).*rv:(\d+)\.(\d+(\.\d+)?).*firefox/i, - ffos: /(Mobile).*rv:(\d+)\.(\d+(\.\d+)?).*Firefox/ - }, - s = { - ios: /^i(phone|pad|pod)$/i, - android: /^android|fire$/i, - blackberry: /^blackberry|playbook/i, - windows: /windows/, - wp: /wp/, - flat: /sailfish|ffos|tizen/i, - meego: /meego/ - }, - h = { - tablet: /playbook|ipad|fire/i - }, - c = { - omini: /Opera\sMini/i, - omobile: /Opera\sMobi/i, - firefox: /Firefox|Fennec/i, - mobilesafari: /version\/.*safari/i, - chrome: /chrome/i, - webkit: /webkit/i, - ie: /MSIE|Windows\sPhone/i - }; - for (var i in e) - if (e.hasOwnProperty(i) && (f = n.match(e[i]), f)) { - if (i == "windows" && "plugins" in navigator) return !1; - t = {}; - t.device = i; - t.tablet = ct(i, h, !1); - t.browser = ct(n, c, "default"); - t.name = ct(i, s); - t[t.name] = !0; - t.majorVersion = f[2]; - t.minorVersion = f[3].replace("_", "."); - u = t.minorVersion.replace(".", "").substr(0, 2); - t.flatVersion = t.majorVersion + u + new Array(3 - (u.length < 3 ? u.length : 2)).join("0"); - t.appMode = window.navigator.standalone || /file|local|wmapp/.test(window.location.protocol) || typeof PhoneGap !== rt || typeof cordova !== rt; - t.android && (r.devicePixelRatio < 1.5 && t.flatVersion < 400 || o) && (r.screenWidth > 800 || r.screenHeight > 800) && (t.tablet = i); - break - } - return t - }; - i = r.mobileOS = r.detectOS(navigator.userAgent); - r.wpDevicePixelRatio = i.wp ? screen.width / 320 : 0; - r.kineticScrollNeeded = i && (r.touch || r.msPointers || r.pointers); - r.hasNativeScrolling = !1; - (i.ios && i.majorVersion > 4 || i.android && i.majorVersion > 2 || i.wp) && (r.hasNativeScrolling = i); - r.mouseAndTouchPresent = r.touch && !(r.mobileOS.ios || r.mobileOS.android); - r.detectBrowser = function(n) { - var t = !1, - i = [], - r = { - webkit: /(chrome)[ \/]([\w.]+)/i, - safari: /(webkit)[ \/]([\w.]+)/i, - opera: /(opera)(?:.*version|)[ \/]([\w.]+)/i, - msie: /(msie\s|trident.*? rv:)([\w.]+)/i, - mozilla: /(mozilla)(?:.*? rv:([\w.]+)|)/i - }; - for (var u in r) - if (r.hasOwnProperty(u) && (i = n.match(r[u]), i)) { - t = {}; - t[u] = !0; - t[i[1].toLowerCase()] = !0; - t.version = parseInt(document.documentMode || i[2], 10); - break - } - return t - }; - r.browser = r.detectBrowser(navigator.userAgent); - r.zoomLevel = function() { - try { - return r.touch ? document.documentElement.clientWidth / window.innerWidth : r.browser.msie && r.browser.version >= 10 ? (top || window).document.documentElement.offsetWidth / (top || window).innerWidth : 1 - } catch (n) { - return 1 - } - }; - r.cssBorderSpacing = typeof document.documentElement.style.borderSpacing != "undefined" && !(r.browser.msie && r.browser.version < 8), - function(t) { - var i, r = parseInt(t.version, 10); - t.msie ? i = "ie" : t.mozilla ? i = "ff" : t.safari ? i = "safari" : t.webkit ? i = "webkit" : t.opera && (i = "opera"); - i && n(document.documentElement).addClass("k-" + i + " k-" + i + r) - }(r.browser); - r.eventCapture = document.documentElement.addEventListener; - f = document.createElement("input"); - r.placeholder = "placeholder" in f; - r.input = function() { - for (var i = ["number", "date", "time", "month", "week", "datetime", "datetime-local"], e = i.length, r = "test", u = {}, n = 0, t; n < e; n++) t = i[n], f.setAttribute("type", t), f.value = r, u[t.replace("-", "")] = f.type !== "text" && f.value !== r; - return u - }(); - f.style.cssText = "float:left;"; - r.cssFloat = !!f.style.cssFloat; - f = null; - r.stableSort = function() { - var n = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].sort(function() { - return 0 - }); - return n[0] === 0 && n[1] === 1 && n[2] === 2 && n[3] === 3 && n[4] === 4 && n[5] === 5 && n[6] === 6 && n[7] === 7 && n[8] === 8 && n[9] === 9 && n[10] === 10 && n[11] === 11 && n[12] === 12 - }(); - r.matchesSelector = s.webkitMatchesSelector || s.mozMatchesSelector || s.msMatchesSelector || s.oMatchesSelector || s.matchesSelector || function(t) { - for (var i = document.querySelectorAll ? (this.parentNode || document).querySelectorAll(t) || [] : n(t), r = i.length; r--;) - if (i[r] == this) return !0; - return !1 - }; - r.pushState = window.history && window.history.pushState; - c = document.documentMode; - r.hashChange = "onhashchange" in window && !(r.browser.msie && (!c || c <= 8)) - }(); - ni = { - left: { - reverse: "right" - }, - right: { - reverse: "left" - }, - down: { - reverse: "up" - }, - up: { - reverse: "down" - }, - top: { - reverse: "bottom" - }, - bottom: { - reverse: "top" - }, - "in": { - reverse: "out" - }, - out: { - reverse: "in" - } - }; - h = {}; - n.extend(h, { - Element: function(t) { - this.element = n(t) - }, - promise: function(n, t) { - n.is(":visible") || n.css({ - display: n.data("olddisplay") || "block" - }).css("display"); - t.hide && n.data("olddisplay", n.css("display")).hide(); - t.init && t.init(); - t.completeCallback && t.completeCallback(n); - n.dequeue() - }, - transitionPromise: function(n, t, r) { - var u = i.wrap(n); - return u.append(t), n.hide(), t.show(), r.completeCallback && r.completeCallback(n), n - }, - disable: function() { - this.promise = this.promiseShim; - this.transitionPromise = this.transitionPromiseShim - }, - enable: function() { - this.promise = this.animatedPromise; - this.transitionPromise = this.animatedTransitionPromise - } - }); - h.promiseShim = h.promise; - h.transitionPromiseShim = h.transitionPromise; - "kendoAnimate" in n.fn || s(n.fn, { - kendoStop: function(n, t) { - return this.stop(n, t) - }, - kendoAnimate: function(n, t, i, r) { - return ii(this, n, t, i, r) - }, - kendoAnimateTo: function(n, t, i, r, u) { - return lr(this, n, t, i, r, u) - }, - kendoAddClass: function(n, t) { - return i.toggleClass(this, n, t, !0) - }, - kendoRemoveClass: function(n, t) { - return i.toggleClass(this, n, t, !1) - }, - kendoToggleClass: function(n, t, r) { - return i.toggleClass(this, n, t, r) - } - }); - var vr = /&/g, - yr = /</g, - pr = />/g; - lt = function(n) { - return n.target - }; - r.touch && (lt = function(n) { - var t = "originalEvent" in n ? n.originalEvent.changedTouches : "changedTouches" in n ? n.changedTouches : null; - return t ? document.elementFromPoint(t[0].clientX, t[0].clientY) : n.target - }, d(["swipe", "swipeLeft", "swipeRight", "swipeUp", "swipeDown", "doubleTap", "tap"], function(t, i) { - n.fn[i] = function(n) { - return this.bind(i, n) - } - })); - r.touch ? r.mobileOS ? (r.mousedown = "touchstart", r.mouseup = "touchend", r.mousemove = "touchmove", r.mousecancel = "touchcancel", r.click = "touchend", r.resize = "orientationchange") : (r.mousedown = "mousedown touchstart", r.mouseup = "mouseup touchend", r.mousemove = "mousemove touchmove", r.mousecancel = "mouseleave touchcancel", r.click = "click", r.resize = "resize") : r.pointers ? (r.mousemove = "pointermove", r.mousedown = "pointerdown", r.mouseup = "pointerup", r.mousecancel = "pointercancel", r.click = "pointerup", r.resize = "orientationchange resize") : r.msPointers ? (r.mousemove = "MSPointerMove", r.mousedown = "MSPointerDown", r.mouseup = "MSPointerUp", r.mousecancel = "MSPointerCancel", r.click = "MSPointerUp", r.resize = "orientationchange resize") : (r.mousemove = "mousemove", r.mousedown = "mousedown", r.mouseup = "mouseup", r.mousecancel = "mouseleave", r.click = "click", r.resize = "resize"); - ri = function(n, t) { - for (var o = t || "d", r, i, e = 1, u = 0, f = n.length; u < f; u++) i = n[u], i !== "" && (r = i.indexOf("["), r !== 0 && (r == -1 ? i = "." + i : (e++, i = "." + i.substring(0, r) + " || {})" + i.substring(r))), e++, o += i + (u < f - 1 ? " || {})" : ")")); - return new Array(e).join("(") + o - }; - ui = /^([a-z]+:)?\/\//i; - s(i, { - ui: i.ui || {}, - fx: i.fx || cr, - effects: i.effects || h, - mobile: i.mobile || {}, - data: i.data || {}, - dataviz: i.dataviz || { - ui: { - roles: {} - } - }, - keys: { - INSERT: 45, - DELETE: 46, - BACKSPACE: 8, - TAB: 9, - ENTER: 13, - ESC: 27, - LEFT: 37, - UP: 38, - RIGHT: 39, - DOWN: 40, - END: 35, - HOME: 36, - SPACEBAR: 32, - PAGEUP: 33, - PAGEDOWN: 34, - F2: 113, - F10: 121, - F12: 123 - }, - support: i.support || r, - animate: i.animate || ii, - ns: "", - attr: function(n) { - return "data-" + i.ns + n - }, - wrap: ur, - deepExtend: kt, - getComputedStyles: er, - size: or, - toCamelCase: gt, - toHyphens: fr, - getOffset: i.getOffset || sr, - parseEffects: i.parseEffects || hr, - toggleClass: i.toggleClass || ar, - directions: i.directions || ni, - Observable: ht, - Class: ut, - Template: v, - template: ot(v.compile, v), - render: ot(v.render, v), - stringify: ot(nt.stringify, nt), - eventTarget: lt, - htmlEncode: wr, - isLocalUrl: function(n) { - return n && !ui.test(n) - }, - expr: function(n, t, i) { - return n = n || "", typeof t == u && (i = t, t = !1), i = i || "d", n && n.charAt(0) !== "[" && (n = "." + n), t ? ri(n.split("."), i) : i + n - }, - getter: function(n, t) { - return wt[n] = wt[n] || new Function("d", "return " + i.expr(n, t)) - }, - setter: function(n) { - return bt[n] = bt[n] || new Function("d,value", i.expr(n) + "=value") - }, - accessor: function(n) { - return { - get: i.getter(n), - set: i.setter(n) - } - }, - guid: function() { - for (var t = "", i, n = 0; n < 32; n++) i = p.random() * 16 | 0, (n == 8 || n == 12 || n == 16 || n == 20) && (t += "-"), t += (n == 12 ? 4 : n == 16 ? i & 3 | 8 : i).toString(16); - return t - }, - roleSelector: function(n) { - return n.replace(/(\S+)/g, "[" + i.attr("role") + "=$1],").slice(0, -1) - }, - triggeredByInput: function(n) { - return /^(label|input|textarea|select)$/i.test(n.target.tagName) - }, - logToConsole: function(n) { - var t = window.console; - typeof t != "undefined" && t.log && t.log(n) - } - }); - w = ht.extend({ - init: function(n, t) { - var r = this; - r.element = i.jQuery(n).handler(r); - ht.fn.init.call(r); - t = r.options = s(!0, {}, r.options, t); - r.element.attr(i.attr("role")) || r.element.attr(i.attr("role"), (t.name || "").toLowerCase()); - r.element.data("kendo" + t.prefix + t.name, r); - r.bind(r.events, t) - }, - events: [], - options: { - prefix: "" - }, - _hasBindingTarget: function() { - return !!this.element[0].kendoBindingTarget - }, - _tabindex: function(n) { - n = n || this.wrapper; - var i = this.element, - t = "tabindex", - r = n.attr(t) || i.attr(t); - i.removeAttr(t); - n.attr(t, isNaN(r) ? 0 : r) - }, - setOptions: function(t) { - for (var i = this, u = 0, f = i.events.length, r; u < f; u++) r = i.events[u], i.options[r] && t[r] && i.unbind(r, i.options[r]); - n.extend(i.options, t); - i.bind(i.events, t) - }, - resize: function(n) { - var t = this.getSize(), - i = this._size; - (n || !i || t.width !== i.width || t.height !== i.height) && (this._resize(t), this.trigger("resize", t), this._size = t) - }, - getSize: function() { - return i.dimensions(this.element) - }, - size: function(n) { - if (n) this.setSize(n); - else return this.getSize() - }, - setSize: n.noop, - _resize: n.noop, - destroy: function() { - var n = this; - n.element.removeData("kendo" + n.options.prefix + n.options.name); - n.element.removeData("handler"); - n.unbind() - } - }); - i.dimensions = function(n, t) { - var i = n[0]; - return t && n.css(t), { - width: i.offsetWidth, - height: i.offsetHeight - } - }; - i.notify = g; - var br = /template$/i, - kr = /^\s*(?:\{(?:.|\r\n|\n)*\}|\[(?:.|\r\n|\n)*\])\s*$/, - dr = /^\{(\d+)(:[^\}]+)?\}/, - gr = /([A-Z])/g; - i.initWidget = function(r, f, e) { - var s, a, o, l, y, h, v, c; - if ((e ? e.roles && (e = e.roles) : e = i.ui.roles, r = r.nodeType ? r : r[0], h = r.getAttribute("data-" + i.ns + "role"), h) && (o = h.indexOf(".") === -1 ? e[h] : i.getter(h)(window), o)) { - for (c = at(r, "dataSource"), f = n.extend({}, fi(r, o.fn.options), f), c && (f.dataSource = typeof c === u ? i.getter(c)(window) : c), l = 0, y = o.fn.events.length; l < y; l++) a = o.fn.events[l], v = at(r, a), v !== t && (f[a] = i.getter(v)(window)); - return s = n(r).data("kendo" + o.fn.options.prefix + o.fn.options.name), s ? s.setOptions(f) : s = new o(r, f), s - } - }; - i.rolesFromNamespaces = function(n) { - var r = [], - t, u; - for (n[0] || (n = [i.ui, i.dataviz.ui]), t = 0, u = n.length; t < u; t++) r[t] = n[t].roles; - return s.apply(null, [{}].concat(r.reverse())) - }; - i.init = function(t) { - var r = i.rolesFromNamespaces(st.call(arguments, 1)); - n(t).find("[data-" + i.ns + "role]").addBack().each(function() { - i.initWidget(this, {}, r) - }) - }; - i.destroy = function(t) { - n(t).find("[data-" + i.ns + "role]").addBack().each(function() { - var t = i.widgetInstance(n(this)); - t && t.destroy() - }) - }; - i.resize = function(t) { - var u = n(t).find("[data-" + i.ns + "role]").addBack().filter(tu), - r; - u.length && (r = n.makeArray(u), r.sort(nu), n.each(r, function() { - var t = i.widgetInstance(n(this)); - t && t.resize() - })) - }; - i.parseOptions = fi; - s(i.ui, { - Widget: w, - roles: {}, - progress: function(t, r) { - var u = t.find(".k-loading-mask"), - o = i.support, - c = o.browser, - f, s, h, e; - r ? u.length || (f = o.isRtl(t), s = f ? "right" : "left", e = t.scrollLeft(), h = c.webkit ? f ? t[0].scrollWidth - t.width() - 2 * e : 0 : 0, u = n("<div class='k-loading-mask'><span class='k-loading-text'>Loading...<\/span><div class='k-loading-image'/><div class='k-loading-color'/><\/div>").width("100%").height("100%").css("top", t.scrollTop()).css(s, Math.abs(e) + h).prependTo(t)) : u && u.remove() - }, - plugin: function(r, f, e) { - var o = r.fn.options.name, - s; - f = f || i.ui; - e = e || ""; - f[o] = r; - f.roles[o.toLowerCase()] = r; - s = "getKendo" + e + o; - o = "kendo" + e + o; - n.fn[o] = function(f) { - var e = this, - s; - return typeof f === u ? (s = st.call(arguments, 1), this.each(function() { - var r = n.data(this, o), - u, h; - if (!r) throw new Error(i.format("Cannot call method '{0}' of {1} before it is initialized", f, o)); - if (u = r[f], typeof u !== c) throw new Error(i.format("Cannot find method '{0}' of {1}", f, o)); - return h = u.apply(r, s), h !== t ? (e = h, !1) : void 0 - })) : this.each(function() { - new r(this, f) - }), e - }; - n.fn[s] = function() { - return this.data(o) - } - } - }); - ei = { - bind: function() { - return this - } - }; - oi = w.extend({ - init: function(n, t) { - w.fn.init.call(this, n, t); - this.element.autoApplyNS(); - this.wrapper = this.element; - this.element.addClass("km-widget") - }, - destroy: function() { - w.fn.destroy.call(this); - this.element.kendoDestroy() - }, - options: { - prefix: "Mobile" - }, - events: [], - view: function() { - var n = this.element.closest(i.roleSelector("view splitview modalview drawer")); - return i.widgetInstance(n, i.mobile.ui) - }, - container: function() { - var n = this.element.closest(i.roleSelector("view layout modalview drawer")); - return i.widgetInstance(n, i.mobile.ui) || ei - } - }); - s(i.mobile, { - init: function(n) { - i.init(n, i.mobile.ui, i.ui, i.dataviz.ui) - }, - ui: { - Widget: oi, - roles: {}, - plugin: function(n) { - i.ui.plugin(n, i.mobile.ui, "Mobile") - } - } - }); - i.touchScroller = function(t, u) { - return n(t).map(function(t, f) { - return f = n(f), r.kineticScrollNeeded && i.mobile.ui.Scroller && !f.data("kendoMobileScroller") ? (f.kendoMobileScroller(u), f.data("kendoMobileScroller")) : !1 - })[0] - }; - i.preventDefault = function(n) { - n.preventDefault() - }; - i.widgetInstance = function(n, t) { - var r = n.data(i.ns + "role"), - u, f, s, e, o; - if (r) - for (r === "content" && (r = "scroller"), u = t ? [t.roles[r]] : [i.ui.roles[r], i.dataviz.ui.roles[r], i.mobile.ui.roles[r]], r.indexOf(".") >= 0 && (u = [i.getter(r)(window)]), f = 0, s = u.length; f < s; f++) - if (e = u[f], e && (o = n.data("kendo" + e.fn.options.prefix + e.fn.options.name), o)) return o - }; - i.onResize = function(t) { - var i = t; - r.mobileOS.android && (i = function() { - setTimeout(t, 600) - }); - n(window).on(r.resize, i); - return i - }; - i.unbindResize = function(t) { - n(window).off(r.resize, t) - }; - i.attrValue = function(n, t) { - return n.data(i.ns + t) - }; - i.days = { - Sunday: 0, - Monday: 1, - Tuesday: 2, - Wednesday: 3, - Thursday: 4, - Friday: 5, - Saturday: 6 - }; - n.extend(n.expr[":"], { - kendoFocusable: function(t) { - var i = n.attr(t, "tabindex"); - return iu(t, !isNaN(i) && i > -1) - } - }); - var si = ["mousedown", "mousemove", "mouseenter", "mouseleave", "mouseover", "mouseout", "mouseup", "click"], - uu = "label, input, [data-rel=external]", - f = { - setupMouseMute: function() { - var t = 0, - u = si.length, - e = document.documentElement, - i; - if (!f.mouseTrap && r.eventCapture) - for (f.mouseTrap = !0, f.bustClick = !1, f.captureMouse = !1, i = function(t) { - f.captureMouse && (t.type === "click" ? f.bustClick && !n(t.target).is(uu) && (t.preventDefault(), t.stopPropagation()) : t.stopPropagation()) - }; t < u; t++) e.addEventListener(si[t], i, !0) - }, - muteMouse: function(n) { - f.captureMouse = !0; - n.data.bustClick && (f.bustClick = !0); - clearTimeout(f.mouseTrapTimeoutID) - }, - unMuteMouse: function() { - clearTimeout(f.mouseTrapTimeoutID); - f.mouseTrapTimeoutID = setTimeout(function() { - f.captureMouse = !1; - f.bustClick = !1 - }, 400) - } - }, - b = { - down: "touchstart mousedown", - move: "mousemove touchmove", - up: "mouseup touchend touchcancel", - cancel: "mouseleave touchcancel" - }; - r.touch && (r.mobileOS.ios || r.mobileOS.android) ? b = { - down: "touchstart", - move: "touchmove", - up: "touchend touchcancel", - cancel: "touchcancel" - } : r.pointers ? b = { - down: "pointerdown", - move: "pointermove", - up: "pointerup", - cancel: "pointercancel pointerleave" - } : r.msPointers && (b = { - down: "MSPointerDown", - move: "MSPointerMove", - up: "MSPointerUp", - cancel: "MSPointerCancel MSPointerLeave" - }); - !r.msPointers || "onmspointerenter" in window || n.each({ - MSPointerEnter: "MSPointerOver", - MSPointerLeave: "MSPointerOut" - }, function(t, i) { - n.event.special[t] = { - delegateType: i, - bindType: i, - handle: function(t) { - var u, f = this, - r = t.relatedTarget, - e = t.handleObj; - return r && (r === f || n.contains(f, r)) || (t.type = e.origType, u = e.handler.apply(this, arguments), t.type = i), u - } - } - }); - hi = function(n) { - return b[n] || n - }; - vt = /([^ ]+)/g; - i.applyEventMap = function(n, t) { - return n = n.replace(vt, hi), t && (n = n.replace(vt, "$1." + t)), n - }; - et = n.fn.on; - s(!0, o, n); - o.fn = o.prototype = new n; - o.fn.constructor = o; - o.fn.init = function(t, i) { - return i && i instanceof n && !(i instanceof o) && (i = o(i)), n.fn.init.call(this, t, i, ci) - }; - o.fn.init.prototype = o.fn; - ci = o(document); - s(o.fn, { - handler: function(n) { - return this.data("handler", n), this - }, - autoApplyNS: function(n) { - return this.data("kendoNS", n || i.guid()), this - }, - on: function() { - var t = this, - l = t.data("kendoNS"), - s, n, e, o, h, c; - return arguments.length === 1 ? et.call(t, arguments[0]) : (s = t, n = st.call(arguments), typeof n[n.length - 1] === rt && n.pop(), e = n[n.length - 1], o = i.applyEventMap(n[0], l), r.mouseAndTouchPresent && o.search(/mouse|click/) > -1 && this[0] !== document.documentElement && (f.setupMouseMute(), h = n.length === 2 ? null : n[1], c = o.indexOf("click") > -1 && o.indexOf("touchend") > -1, et.call(this, { - touchstart: f.muteMouse, - touchend: f.unMuteMouse - }, h, { - bustClick: c - })), typeof e === u && (s = t.data("handler"), e = s[e], n[n.length - 1] = function(n) { - e.call(s, n) - }), n[0] = o, et.apply(t, n), t) - }, - kendoDestroy: function(n) { - return n = n || this.data("kendoNS"), n && this.off("." + n), this - } - }); - i.jQuery = o; - i.eventMap = b; - i.timezone = function() { - function i(i, r) { - var u, o, s, c = r[3], - e = r[4], - f = r[5], - h = r[8]; - return (h || (r[8] = h = {}), h[i]) ? h[i] : (isNaN(e) ? e.indexOf("last") === 0 ? (u = new Date(Date.UTC(i, n[c] + 1, 1, f[0] - 24, f[1], f[2], 0)), o = t[e.substr(4, 3)], s = u.getUTCDay(), u.setUTCDate(u.getUTCDate() + o - s - (o > s ? 7 : 0))) : e.indexOf(">=") >= 0 && (u = new Date(Date.UTC(i, n[c], e.substr(5), f[0], f[1], f[2], 0)), o = t[e.substr(0, 3)], s = u.getUTCDay(), u.setUTCDate(u.getUTCDate() + o - s + (o < s ? 7 : 0))) : u = new Date(Date.UTC(i, n[c], e, f[0], f[1], f[2], 0)), h[i] = u) - } - - function f(n, t, r) { - var f, e, u; - return (t = t[r], !t) ? (f = r.split(":"), e = 0, f.length > 1 && (e = f[0] * 60 + Number(f[1])), [-1e6, "max", "-", "Jan", 1, [0, 0, 0], e, "-"]) : (u = new Date(n).getUTCFullYear(), t = jQuery.grep(t, function(n) { - var i = n[0], - t = n[1]; - return i <= u && (t >= u || i == u && t == "only" || t == "max") - }), t.push(n), t.sort(function(n, t) { - return typeof n != "number" && (n = Number(i(u, n))), typeof t != "number" && (t = Number(i(u, t))), n - t - }), t[jQuery.inArray(n, t) - 1]) - } - - function e(n, t, i) { - var r = t[i], - u, f, e; - if (typeof r == "string" && (r = t[r]), !r) throw new Error('Timezone "' + i + '" is either incorrect, or kendo.timezones.min.js is not included.'); - for (u = r.length - 1; u >= 0; u--) - if (f = r[u][3], f && n > f) break; - if (e = r[u + 1], !e) throw new Error('Timezone "' + i + '" not found on ' + n + "."); - return e - } - - function r(n, t, i, r) { - typeof n != l && (n = Date.UTC(n.getFullYear(), n.getMonth(), n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds())); - var u = e(n, t, r); - return { - zone: u, - rule: f(n, i, u[1]) - } - } - - function o(n, t) { - if (t == "Etc/UTC" || t == "Etc/GMT") return 0; - var i = r(n, this.zones, this.rules, t), - u = i.zone, - f = i.rule; - return f ? u[0] - f[6] : u[0] - } - - function s(n, t) { - var f = r(n, this.zones, this.rules, t), - e = f.zone, - i = f.rule, - u = e[2]; - return u.indexOf("/") >= 0 ? u.split("/")[i && i[6] ? 1 : 0] : u.indexOf("%s") >= 0 ? u.replace("%s", !i || i[7] == "-" ? "" : i[7]) : u - } - - function h(n, t, i) { - var r, f; - return typeof t == u && (t = this.offset(n, t)), typeof i == u && (i = this.offset(n, i)), r = n.getTimezoneOffset(), n = new Date(n.getTime() + (t - i) * 6e4), f = n.getTimezoneOffset(), new Date(n.getTime() + (f - r) * 6e4) - } - - function c(n, t) { - return this.convert(n, n.getTimezoneOffset(), t) - } - - function a(n, t) { - return this.convert(n, t, n.getTimezoneOffset()) - } - - function v(n) { - return this.apply(new Date(n), "Etc/UTC") - } - var n = { - Jan: 0, - Feb: 1, - Mar: 2, - Apr: 3, - May: 4, - Jun: 5, - Jul: 6, - Aug: 7, - Sep: 8, - Oct: 9, - Nov: 10, - Dec: 11 - }, - t = { - Sun: 0, - Mon: 1, - Tue: 2, - Wed: 3, - Thu: 4, - Fri: 5, - Sat: 6 - }; - return { - zones: {}, - rules: {}, - offset: o, - convert: h, - apply: c, - remove: a, - abbr: s, - toLocalDate: v - } - }(); - i.date = function() { - function t(n, t) { - return t === 0 && n.getHours() === 23 ? (n.setHours(n.getHours() + 2), !0) : !1 - } - - function e(n, i, r) { - var u = n.getHours(); - r = r || 1; - i = (i - n.getDay() + 7 * r) % 7; - n.setDate(n.getDate() + i); - t(n, u) - } - - function c(n, t, i) { - return n = new Date(n), e(n, t, i), n - } - - function o(n) { - return new Date(n.getFullYear(), n.getMonth(), 1) - } - - function l(n) { - var t = new Date(n.getFullYear(), n.getMonth() + 1, 0), - i = o(n), - r = Math.abs(t.getTimezoneOffset() - i.getTimezoneOffset()); - return r && t.setHours(i.getHours() + r / 60), t - } - - function i(n) { - return n = new Date(n.getFullYear(), n.getMonth(), n.getDate(), 0, 0, 0), t(n, 0), n - } - - function a(n) { - return Date.UTC(n.getFullYear(), n.getMonth(), n.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds()) - } - - function r(n) { - return n.getTime() - i(n) - } - - function v(t, i, u) { - var e = r(i), - o = r(u), - f; - return !t || e == o ? !0 : (i >= u && (u += n), f = r(t), e > f && (f += n), o < e && (o += n), f >= e && f <= o) - } - - function y(t, i, r) { - var e = i.getTime(), - u = r.getTime(), - f; - return e >= u && (u += n), f = t.getTime(), f >= e && f <= u - } - - function u(i, r) { - var u = i.getHours(); - return i = new Date(i), s(i, r * n), t(i, u), i - } - - function s(n, t, i) { - var u = n.getTimezoneOffset(), - r; - n.setTime(n.getTime() + t); - i || (r = n.getTimezoneOffset() - u, n.setTime(n.getTime() + r * f)) - } - - function h() { - return i(new Date) - } - - function p(n) { - return i(n).getTime() == h().getTime() - } - - function w(n) { - var t = new Date(1980, 1, 1, 0, 0, 0); - return n && t.setHours(n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds()), t - } - var f = 6e4, - n = 864e5; - return { - adjustDST: t, - dayOfWeek: c, - setDayOfWeek: e, - getDate: i, - isInDateRange: y, - isInTimeRange: v, - isToday: p, - nextDay: function(n) { - return u(n, 1) - }, - previousDay: function(n) { - return u(n, -1) - }, - toUtcTime: a, - MS_PER_DAY: n, - MS_PER_MINUTE: f, - setTime: s, - addDays: u, - today: h, - toInvariantTime: w, - firstDayOfMonth: o, - lastDayOfMonth: l, - getMilliseconds: r - } - }(); - i.stripWhitespace = function(n) { - for (var t = document.createNodeIterator(n, NodeFilter.SHOW_TEXT, function(t) { - return t.parentNode == n ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT - }, !1); t.nextNode();) t.referenceNode && !t.referenceNode.textContent.trim() && t.referenceNode.parentNode.removeChild(t.referenceNode) - }; - yt = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(n) { - setTimeout(n, 1e3 / 60) - }; - i.animationFrame = function(n) { - yt.call(window, n) - }; - k = []; - i.queueAnimation = function(n) { - k[k.length] = n; - k.length === 1 && i.runNextAnimation() - }; - i.runNextAnimation = function() { - var n = k.shift(); - i.animationFrame(function() { - n(); - yt[0] && i.runNextAnimation() - }) - }; - i.parseQueryStringParams = function(n) { - for (var u = n.split("?")[1] || "", r = {}, i = u.split(/&|=/), f = i.length, t = 0; t < f; t += 2) i[t] !== "" && (r[decodeURIComponent(i[t])] = decodeURIComponent(i[t + 1])); - return r - } - }(jQuery); -typeof kendo_module == "undefined" && (kendo_module = function() {}); -kendo_module({ - id: "core", - name: "Core", - category: "framework", - description: "The core of the Kendo framework." -}); -kendo_module({ - id: "fx", - name: "Effects", - category: "framework", - description: "Required for animation effects in all Kendo UI widgets.", - depends: ["core"] - }), - function(n, t) { - function ii(n) { - return parseInt(n, 10) - } - - function p(n, t) { - return ii(n.css(t)) - } - - function ir(n) { - var t = n.effects; - return t === "zoom" && (t = "zoom:in fade:in"), t === "fade" && (t = "fade:in"), t === "slide" && (t = "tile:left"), /^slide:(.+)$/.test(t) && (t = "tile:" + RegExp.$1), t === "overlay" && (t = "slideIn:left"), /^overlay:(.+)$/.test(t) && (t = "slideIn:" + RegExp.$1), n.effects = i.parseEffects(t), tr && t == "tile:left" && (n.previousDivisor = 3), n - } - - function rr(n) { - var t = []; - for (var i in n) t.push(i); - return t - } - - function st(n) { - for (var t in n) rt.indexOf(t) != -1 && d.indexOf(t) == -1 && delete n[t]; - return n - } - - function ht(n, t) { - var r = [], - u = {}, - o, i, s, c; - for (i in t) o = i.toLowerCase(), c = f && rt.indexOf(o) != -1, !h.hasHW3D && c && d.indexOf(o) == -1 ? delete t[i] : (s = t[i], c ? r.push(i + "(" + s + ")") : u[i] = s); - return r.length && (u[e] = r.join(" ")), u - } - - function ri(n, t) { - var u, i, r; - return f ? (u = n.css(e), u == gi) ? t == "scale" ? 1 : 0 : (i = u.match(new RegExp(t + "\\s*\\(([\\d\\w\\.]+)")), r = 0, i ? r = ii(i[1]) : (i = u.match(vi) || [0, 0, 0, 0, 0], t = t.toLowerCase(), yi.test(t) ? r = parseFloat(i[3] / i[2]) : t == "translatey" ? r = parseFloat(i[4] / i[2]) : t == "scale" ? r = parseFloat(i[2]) : t == "rotate" && (r = parseFloat(Math.atan2(i[2], i[1])))), r) : parseFloat(n.css(t)) - } - - function lt(n) { - return n.charAt(0).toUpperCase() + n.substring(1) - } - - function o(n, t) { - var i = l.extend(t), - r = i.prototype.directions; - u[lt(n)] = i; - u.Element.prototype[n] = function(n, t, r, u) { - return new i(this.element, n, t, r, u) - }; - a(r, function(t, r) { - u.Element.prototype[n + lt(r)] = function(n, t, u) { - return new i(this.element, r, n, t, u) - } - }) - } - - function fi(n, t, i, r) { - o(n, { - directions: ui, - startValue: function(n) { - return this._startValue = n, this - }, - endValue: function(n) { - return this._endValue = n, this - }, - shouldHide: function() { - return this._shouldHide - }, - prepare: function(n, u) { - var s = this, - f, e, h = this._direction === "out", - o = s.element.data(t), - c = !(isNaN(o) || o == i); - f = c ? o : typeof this._startValue != "undefined" ? this._startValue : h ? i : r; - e = typeof this._endValue != "undefined" ? this._endValue : h ? r : i; - this._reverse ? (n[t] = e, u[t] = f) : (n[t] = f, u[t] = e); - s._shouldHide = u[t] === r - } - }) - } - - function hi(n, t) { - var r = i.directions[t].vertical, - u = n[r ? nt : ft]() / 2 + "px"; - return oi[t].replace("$size", u) - } - var i = window.kendo, - u = i.effects, - a = n.each, - r = n.extend, - ci = n.proxy, - h = i.support, - vt = h.browser, - f = h.transforms, - s = h.transitions, - li = { - scale: 0, - scalex: 0, - scaley: 0, - scale3d: 0 - }, - ai = { - translate: 0, - translatex: 0, - translatey: 0, - translate3d: 0 - }, - yt = typeof document.documentElement.style.zoom != "undefined" && !f, - vi = /matrix3?d?\s*\(.*,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?/i, - pt = /^(-?[\d\.\-]+)?[\w\s]*,?\s*(-?[\d\.\-]+)?[\w\s]*/i, - yi = /translatex?$/i, - pi = /(zoom|fade|expand)(\w+)/, - wt = /(zoom|fade|expand)/, - wi = /[xy]$/i, - rt = ["perspective", "rotate", "rotatex", "rotatey", "rotatez", "rotate3d", "scale", "scalex", "scaley", "scalez", "scale3d", "skew", "skewx", "skewy", "translate", "translatex", "translatey", "translatez", "translate3d", "matrix", "matrix3d"], - d = ["rotate", "scale", "scalex", "scaley", "skew", "skewx", "skewy", "translate", "translatex", "translatey", "matrix"], - bi = { - rotate: "deg", - scale: "", - skew: "px", - translate: "px" - }, - g = f.css, - ki = Math.round, - di = "", - w = "px", - gi = "none", - ut = "auto", - ft = "width", - nt = "height", - bt = "hidden", - et = "origin", - kt = "abortId", - tt = "overflow", - v = "translate", - b = "position", - dt = "completeCallback", - y = g + "transition", - e = g + "transform", - nr = g + "backface-visibility", - gt = g + "perspective", - ot = "1500px", - ni = "perspective(" + ot + ")", - tr = h.mobileOS && h.mobileOS.majorVersion == 7, - c = { - left: { - reverse: "right", - property: "left", - transition: "translatex", - vertical: !1, - modifier: -1 - }, - right: { - reverse: "left", - property: "left", - transition: "translatex", - vertical: !1, - modifier: 1 - }, - down: { - reverse: "up", - property: "top", - transition: "translatey", - vertical: !0, - modifier: 1 - }, - up: { - reverse: "down", - property: "top", - transition: "translatey", - vertical: !0, - modifier: -1 - }, - top: { - reverse: "bottom" - }, - bottom: { - reverse: "top" - }, - "in": { - reverse: "out", - modifier: -1 - }, - out: { - reverse: "in", - modifier: 1 - }, - vertical: { - reverse: "vertical" - }, - horizontal: { - reverse: "horizontal" - } - }, - ti, ct, l, k, ui, ei, oi, si, it, at; - i.directions = c; - r(n.fn, { - kendoStop: function(n, t) { - return s ? u.stopQueue(this, n || !1, t || !1) : this.stop(n, t) - } - }); - f && !s && (a(d, function(t, i) { - n.fn[i] = function(t) { - if (typeof t == "undefined") return ri(this, i); - var r = n(this)[0], - u = i + "(" + t + bi[i.replace(wi, "")] + ")"; - return r.style.cssText.indexOf(e) == -1 ? n(this).css(e, u) : r.style.cssText = r.style.cssText.replace(new RegExp(i + "\\(.*?\\)", "i"), u), this - }; - n.fx.step[i] = function(t) { - n(t.elem)[i](t.now) - } - }), ti = n.fx.prototype.cur, n.fx.prototype.cur = function() { - return d.indexOf(this.prop) != -1 ? parseFloat(n(this.elem)[this.prop]()) : ti.apply(this, arguments) - }); - i.toggleClass = function(n, t, i, u) { - return t && (t = t.split(" "), s && (i = r({ - exclusive: "all", - duration: 400, - ease: "ease-out" - }, i), n.css(y, i.exclusive + " " + i.duration + "ms " + i.ease), setTimeout(function() { - n.css(y, "").css(nt) - }, i.duration)), a(t, function(t, i) { - n.toggleClass(i, u) - })), n - }; - i.parseEffects = function(n, t) { - var i = {}; - return typeof n == "string" ? a(n.split(" "), function(n, r) { - var o = !wt.test(r), - s = r.replace(pi, function(n, t, i) { - return t + ":" + i.toLowerCase() - }), - u = s.split(":"), - f = u[1], - e = {}; - u.length > 1 && (e.direction = t && o ? c[f].reverse : f); - i[u[0]] = e - }) : a(n, function(n) { - var r = this.direction; - r && t && !wt.test(n) && (this.direction = c[r].reverse); - i[n] = this - }), i - }; - s && r(u, { - transition: function(t, i, u) { - var h, l = 0, - a = t.data("keys") || [], - f, c, o; - if (u = r({ - duration: 200, - ease: "ease-out", - complete: null, - exclusive: "all" - }, u), c = !1, o = function() { - c || (c = !0, f && (clearTimeout(f), f = null), t.removeData(kt).dequeue().css(y, "").css(y), u.complete.call(t)) - }, u.duration = n.fx ? n.fx.speeds[u.duration] || u.duration : u.duration, h = ht(t, i), n.merge(a, rr(h)), t.data("keys", n.unique(a)).height(), t.css(y, u.exclusive + " " + u.duration + "ms " + u.ease).css(y), t.css(h).css(e), s.event) { - t.one(s.event, o); - u.duration !== 0 && (l = 500) - } - f = setTimeout(o, u.duration + l); - t.data(kt, f); - t.data(dt, o) - }, - stopQueue: function(n, t, r) { - var u, f = n.data("keys"), - e = !r && f, - o = n.data(dt); - return e && (u = i.getComputedStyles(n[0], f)), o && o(), e && n.css(u), n.removeData("keys").stop(t) - } - }); - ct = i.Class.extend({ - init: function(n, t) { - var i = this; - i.element = n; - i.effects = []; - i.options = t; - i.restore = [] - }, - run: function(t) { - var a = this, - l, h, v, k = t.length, - c = a.element, - i = a.options, - p = n.Deferred(), - o = {}, - y = {}, - w, b, d, g; - for (a.effects = t, p.then(n.proxy(a, "complete")), c.data("animating", !0), h = 0; h < k; h++) - for (l = t[h], l.setReverse(i.reverse), l.setOptions(i), a.addRestoreProperties(l.restore), l.prepare(o, y), b = l.children(), v = 0, d = b.length; v < d; v++) b[v].duration(i.duration).run(); - for (g in i.effects) r(y, i.effects[g].properties); - for (c.is(":visible") || r(o, { - display: c.data("olddisplay") || "block" - }), f && !i.reset && (w = c.data("targetTransform"), w && (o = r(w, o))), o = ht(c, o), f && !s && (o = st(o)), c.css(o).css(e), h = 0; h < k; h++) t[h].setup(); - return i.init && i.init(), c.data("targetTransform", y), u.animate(c, y, r({}, i, { - complete: p.resolve - })), p.promise() - }, - stop: function() { - n(this.element).kendoStop(!0, !0) - }, - addRestoreProperties: function(n) { - for (var i = this.element, t, r = 0, u = n.length; r < u; r++) t = n[r], this.restore.push(t), i.data(t) || i.data(t, i.css(t)) - }, - restoreCallback: function() { - for (var t, i = this.element, n = 0, r = this.restore.length; n < r; n++) t = this.restore[n], i.css(t, i.data(t)) - }, - complete: function() { - var i = this, - r = 0, - t = i.element, - u = i.options, - e = i.effects, - o = e.length; - for (t.removeData("animating").dequeue(), u.hide && t.data("olddisplay", t.css("display")).hide(), this.restoreCallback(), yt && !f && setTimeout(n.proxy(this, "restoreCallback"), 0); r < o; r++) e[r].teardown(); - u.completeCallback && u.completeCallback(t) - } - }); - u.promise = function(n, t) { - var r = [], - f, s = new ct(n, t), - e = i.parseEffects(t.effects), - h, o; - t.effects = e; - for (o in e) f = u[lt(o)], f && (h = new f(n, e[o].direction), r.push(h)); - r[0] ? s.run(r) : (n.is(":visible") || n.css({ - display: n.data("olddisplay") || "block" - }).css("display"), t.init && t.init(), n.dequeue(), s.complete()) - }; - u.transitionPromise = function(n, t, i) { - return u.animateTo(n, t, i), n - }; - r(u, { - animate: function(i, e, o) { - var h = o.transition !== !1; - delete o.transition; - s && "transition" in u && h ? u.transition(i, e, o) : f ? i.animate(st(e), { - queue: !1, - show: !1, - hide: !1, - duration: o.duration, - complete: o.complete - }) : i.each(function() { - var i = n(this), - u = {}; - a(rt, function(n, o) { - var c, y = e ? e[o] + " " : null, - s, w, k, h, l, a; - y && (s = e, o in li && e[o] !== t ? (c = y.match(pt), f && r(s, { - scale: +c[0] - })) : o in ai && e[o] !== t && (w = i.css(b), k = w == "absolute" || w == "fixed", i.data(v) || (k ? i.data(v, { - top: p(i, "top") || 0, - left: p(i, "left") || 0, - bottom: p(i, "bottom"), - right: p(i, "right") - }) : i.data(v, { - top: p(i, "marginTop") || 0, - left: p(i, "marginLeft") || 0 - })), h = i.data(v), c = y.match(pt), c && (l = o == v + "y" ? 0 : +c[1], a = o == v + "y" ? +c[1] : +c[2], k ? (isNaN(h.right) ? isNaN(l) || r(s, { - left: h.left + l - }) : isNaN(l) || r(s, { - right: h.right - l - }), isNaN(h.bottom) ? isNaN(a) || r(s, { - top: h.top + a - }) : isNaN(a) || r(s, { - bottom: h.bottom - a - })) : (isNaN(l) || r(s, { - marginLeft: h.left + l - }), isNaN(a) || r(s, { - marginTop: h.top + a - })))), !f && o != "scale" && o in s && delete s[o], s && r(u, s)) - }); - vt.msie && delete u.scale; - i.animate(u, { - queue: !1, - show: !1, - hide: !1, - duration: o.duration, - complete: o.complete - }) - }) - }, - animateTo: function(t, i, u) { - function a(n) { - i[0].style.cssText = ""; - t.each(function() { - this.style.cssText = "" - }); - h.mobileOS.android || f.css(tt, c); - s || e.css(b, l); - u.completeCallback && u.completeCallback.call(t, n) - } - var o, f = t.parents().filter(i.parents()).first(), - e = n().add(t.parent()).add(i.parent()), - s = t.css(b) == "absolute", - c, l; - s || (l = e.css(b), e.css(b, "absolute")); - u = ir(u); - h.mobileOS.android || (c = f.css(tt), f.css(tt, "hidden")); - n.each(u.effects, function(n, t) { - o = o || t.direction - }); - u.complete = vt.msie ? function() { - setTimeout(a, 0) - } : a; - u.previous = u.reverse ? i : t; - u.reset = !0; - (u.reverse ? t : i).each(function() { - n(this).kendoAnimate(r(!0, {}, u)); - u.complete = null; - u.previous = null - }) - } - }); - u.animatedPromise = u.promise; - u.animatedTransitionPromise = u.transitionPromise; - l = i.Class.extend({ - init: function(n, t) { - var i = this; - i.element = n; - i._direction = t; - i.options = {}; - i._additionalEffects = []; - i.restore || (i.restore = []) - }, - reverse: function() { - return this._reverse = !0, this.run() - }, - play: function() { - return this._reverse = !1, this.run() - }, - add: function(n) { - return this._additionalEffects.push(n), this - }, - direction: function(n) { - return this._direction = n, this - }, - duration: function(n) { - return this._duration = n, this - }, - compositeRun: function() { - var n = this, - t = new ct(n.element, { - reverse: n._reverse, - duration: n._duration - }), - i = n._additionalEffects.concat([n]); - return t.run(i) - }, - run: function() { - if (this._additionalEffects && this._additionalEffects[0]) return this.compositeRun(); - var o = this, - t = o.element, - h = 0, - y = o.restore, - w = y.length, - c, l = n.Deferred(), - i = {}, - a = {}, - v, p = o.children(), - b = p.length; - for (l.then(n.proxy(o, "_complete")), t.data("animating", !0), h = 0; h < w; h++) c = y[h], t.data(c) || t.data(c, t.css(c)); - for (h = 0; h < b; h++) p[h].duration(o._duration).run(); - return o.prepare(i, a), t.is(":visible") || r(i, { - display: t.data("olddisplay") || "block" - }), f && (v = t.data("targetTransform"), v && (i = r(v, i))), i = ht(t, i), f && !s && (i = st(i)), t.css(i).css(e), o.setup(), t.data("targetTransform", a), u.animate(t, a, { - duration: o._duration, - complete: l.resolve - }), l.promise() - }, - stop: function() { - for (var t = 0, i = this.children(), r = i.length, t = 0; t < r; t++) i[t].stop(); - return n(this.element).kendoStop(!0, !0), this - }, - restoreCallback: function() { - for (var t, i = this.element, n = 0, r = this.restore.length; n < r; n++) t = this.restore[n], i.css(t, i.data(t)) - }, - _complete: function() { - var t = this, - i = t.element; - i.removeData("animating").dequeue(); - t.restoreCallback(); - t.shouldHide() && i.data("olddisplay", i.css("display")).hide(); - yt && !f && setTimeout(n.proxy(t, "restoreCallback"), 0); - t.teardown() - }, - setOptions: function(n) { - r(!0, this.options, n) - }, - children: function() { - return [] - }, - shouldHide: n.noop, - setup: n.noop, - prepare: n.noop, - teardown: n.noop, - directions: [], - setReverse: function(n) { - return this._reverse = n, this - } - }); - k = ["left", "right", "up", "down"]; - ui = ["in", "out"]; - o("slideIn", { - directions: k, - divisor: function(n) { - return this.options.divisor = n, this - }, - prepare: function(n, t) { - var r = this, - u, e = r.element, - i = c[r._direction], - h = -i.modifier * (i.vertical ? e.outerHeight() : e.outerWidth()), - o = h / (r.options && r.options.divisor || 1) + w, - s = "0px"; - r._reverse && (u = n, n = t, t = u); - f ? (n[i.transition] = o, t[i.transition] = s) : (n[i.property] = o, t[i.property] = s) - } - }); - o("tile", { - directions: k, - init: function(n, t, i) { - l.prototype.init.call(this, n, t); - this.options = { - previous: i - } - }, - previousDivisor: function(n) { - return this.options.previousDivisor = n, this - }, - children: function() { - var n = this, - t = n._reverse, - r = n.options.previous, - e = n.options.previousDivisor || 1, - u = n._direction, - f = [i.fx(n.element).slideIn(u).setReverse(t)]; - return r && f.push(i.fx(r).slideIn(c[u].reverse).divisor(e).setReverse(!t)), f - } - }); - fi("fade", "opacity", 1, 0); - fi("zoom", "scale", 1, .01); - o("slideMargin", { - prepare: function(n, t) { - var r = this, - i = r.element, - u = r.options, - o = i.data(et), - s = u.offset, - f, e = r._reverse; - e || o !== null || i.data(et, parseFloat(i.css("margin-" + u.axis))); - f = i.data(et) || 0; - t["margin-" + u.axis] = e ? f : f + s - } - }); - o("slideTo", { - prepare: function(n, t) { - var u = this, - e = u.element, - o = u.options, - i = o.offset.split(","), - r = u._reverse; - f ? (t.translatex = r ? 0 : i[0], t.translatey = r ? 0 : i[1]) : (t.left = r ? 0 : i[0], t.top = r ? 0 : i[1]); - e.css("left") - } - }); - o("expand", { - directions: ["horizontal", "vertical"], - restore: [tt], - prepare: function(n, i) { - var f = this, - e = f.element, - o = f.options, - s = f._reverse, - r = f._direction === "vertical" ? nt : ft, - h = e[0].style[r], - c = e.data(r), - u = parseFloat(c || h), - l = ki(e.css(r, ut)[r]()); - n.overflow = bt; - u = o && o.reset ? l || u : u || l; - i[r] = (s ? 0 : u) + w; - n[r] = (s ? u : 0) + w; - c === t && e.data(r, h) - }, - shouldHide: function() { - return this._reverse - }, - teardown: function() { - var t = this, - i = t.element, - n = t._direction === "vertical" ? nt : ft, - r = i.data(n); - (r == ut || r === di) && setTimeout(function() { - i.css(n, ut).css(n) - }, 0) - } - }); - ei = { - position: "absolute", - marginLeft: 0, - marginTop: 0, - scale: 1 - }; - o("transfer", { - init: function(n, t) { - this.element = n; - this.options = { - target: t - }; - this.restore = [] - }, - setup: function() { - this.element.appendTo(document.body) - }, - prepare: function(n, t) { - var s = this, - i = s.element, - g = s.options, - nt = s._reverse, - h = g.target, - u, tt = ri(i, "scale"), - l = h.offset(), - a = h.outerHeight() / i.outerHeight(); - r(n, ei); - t.scale = 1; - i.css(e, "scale(1)").css(e); - u = i.offset(); - i.css(e, "scale(" + tt + ")"); - var f = 0, - o = 0, - v = l.left - u.left, - y = l.top - u.top, - p = f + i.outerWidth(), - b = o, - it = v + h.outerWidth(), - rt = y, - c = (y - o) / (v - f), - k = (rt - b) / (it - p), - d = (o - b - c * f + k * p) / (k - c), - ut = o + c * (d - f); - n.top = u.top; - n.left = u.left; - n.transformOrigin = d + w + " " + ut + w; - nt ? n.scale = a : t.scale = a - } - }); - oi = { - top: "rect(auto auto $size auto)", - bottom: "rect($size auto auto auto)", - left: "rect(auto $size auto auto)", - right: "rect(auto auto auto $size)" - }; - si = { - top: { - start: "rotatex(0deg)", - end: "rotatex(180deg)" - }, - bottom: { - start: "rotatex(-180deg)", - end: "rotatex(0deg)" - }, - left: { - start: "rotatey(0deg)", - end: "rotatey(-180deg)" - }, - right: { - start: "rotatey(180deg)", - end: "rotatey(0deg)" - } - }; - o("turningPage", { - directions: k, - init: function(n, t, i) { - l.prototype.init.call(this, n, t); - this._container = i - }, - prepare: function(n, t) { - var r = this, - f = r._reverse, - o = f ? c[r._direction].reverse : r._direction, - u = si[o]; - n.zIndex = 1; - r._clipInHalf && (n.clip = hi(r._container, i.directions[o].reverse)); - n[nr] = bt; - t[e] = ni + (f ? u.start : u.end); - n[e] = ni + (f ? u.end : u.start) - }, - setup: function() { - this._container.append(this.element) - }, - face: function(n) { - return this._face = n, this - }, - shouldHide: function() { - var n = this, - t = n._reverse, - i = n._face; - return t && !i || !t && i - }, - clipInHalf: function(n) { - return this._clipInHalf = n, this - }, - temporary: function() { - return this.element.addClass("temp-page"), this - } - }); - o("staticPage", { - directions: k, - init: function(n, t, i) { - l.prototype.init.call(this, n, t); - this._container = i - }, - restore: ["clip"], - prepare: function(n, t) { - var i = this, - r = i._reverse ? c[i._direction].reverse : i._direction; - n.clip = hi(i._container, r); - n.opacity = .999; - t.opacity = 1 - }, - shouldHide: function() { - var n = this, - t = n._reverse, - i = n._face; - return t && !i || !t && i - }, - face: function(n) { - return this._face = n, this - } - }); - o("pageturn", { - directions: ["horizontal", "vertical"], - init: function(n, t, i, r) { - l.prototype.init.call(this, n, t); - this.options = {}; - this.options.face = i; - this.options.back = r - }, - children: function() { - var r = this, - u = r.options, - n = r._direction === "horizontal" ? "left" : "top", - f = i.directions[n].reverse, - t = r._reverse, - o, s = u.face.clone(!0).removeAttr("id"), - h = u.back.clone(!0).removeAttr("id"), - e = r.element; - return t && (o = n, n = f, f = o), [i.fx(u.face).staticPage(n, e).face(!0).setReverse(t), i.fx(u.back).staticPage(f, e).setReverse(t), i.fx(s).turningPage(n, e).face(!0).clipInHalf(!0).temporary().setReverse(t), i.fx(h).turningPage(f, e).clipInHalf(!0).temporary().setReverse(t)] - }, - prepare: function(n, t) { - n[gt] = ot; - n.transformStyle = "preserve-3d"; - n.opacity = .999; - t.opacity = 1 - }, - teardown: function() { - this.element.find(".temp-page").remove() - } - }); - o("flip", { - directions: ["horizontal", "vertical"], - init: function(n, t, i, r) { - l.prototype.init.call(this, n, t); - this.options = {}; - this.options.face = i; - this.options.back = r - }, - children: function() { - var n = this, - f = n.options, - t = n._direction === "horizontal" ? "left" : "top", - r = i.directions[t].reverse, - u = n._reverse, - e, o = n.element; - return u && (e = t, t = r, r = e), [i.fx(f.face).turningPage(t, o).face(!0).setReverse(u), i.fx(f.back).turningPage(r, o).setReverse(u)] - }, - prepare: function(n) { - n[gt] = ot; - n.transformStyle = "preserve-3d" - } - }); - it = i.Class.extend({ - init: function() { - var n = this; - n._tickProxy = ci(n._tick, n); - n._started = !1 - }, - tick: n.noop, - done: n.noop, - onEnd: n.noop, - onCancel: n.noop, - start: function() { - this.done() || (this._started = !0, i.animationFrame(this._tickProxy)) - }, - cancel: function() { - this._started = !1; - this.onCancel() - }, - _tick: function() { - var n = this; - n._started && (n.tick(), n.done() ? (n._started = !1, n.onEnd()) : i.queueAnimation(n._tickProxy)) - } - }); - at = it.extend({ - init: function(n) { - var t = this; - r(t, n); - it.fn.init.call(t) - }, - done: function() { - return this.timePassed() >= this.duration - }, - timePassed: function() { - return Math.min(this.duration, new Date - this.startDate) - }, - moveTo: function(n) { - var t = this, - i = t.movable; - t.initial = i[t.axis]; - t.delta = n.location - t.initial; - t.duration = typeof n.duration == "number" ? n.duration : 300; - t.tick = t._easeProxy(n.ease); - t.startDate = new Date; - t.start() - }, - _easeProxy: function(n) { - var t = this; - return function() { - t.movable.moveAxis(t.axis, n(t.timePassed(), t.initial, t.delta, t.duration)) - } - } - }); - r(at, { - easeOutExpo: function(n, t, i, r) { - return n == r ? t + i : i * (-Math.pow(2, -10 * n / r) + 1) + t - }, - easeOutBack: function(n, t, i, r, u) { - return u = 1.70158, i * ((n = n / r - 1) * n * ((u + 1) * n + u) + 1) + t - } - }); - u.Animation = it; - u.Transition = at; - u.createEffect = o - }(window.kendo.jQuery); -kendo_module({ - id: "data", - name: "Data source", - category: "framework", - description: "Powerful component for using local and remote data.Fully supports CRUD, Sorting, Paging, Filtering, Grouping, and Aggregates.", - depends: ["core"], - features: [{ - id: "data-odata", - name: "OData", - description: "Support for accessing Open Data Protocol (OData) services.", - depends: ["data.odata"] - }, { - id: "data-XML", - name: "XML", - description: "Support for binding to XML.", - depends: ["data.xml"] - }] - }), - function(n, t) { - function gt(n, t, i, u) { - return function(f) { - var e = {}; - for (var o in f) e[o] = f[o]; - e.field = u ? i + "." + f.field : i; - t == r && n._notifyChange && n._notifyChange(e); - n.trigger(t, e) - } - } - - function li(t, i) { - if (t === i) return !0; - var r = n.type(t), - f = n.type(i), - u; - if (r !== f) return !1; - if (r === "date") return t.getTime() === i.getTime(); - if (r !== "object" && r !== "array") return !1; - for (u in t) - if (!li(t[u], i[u])) return !1; - return !0 - } - - function ou(n, t) { - var i; - for (var r in n) - if ((i = n[r], l(i) && i.field && i.field === t) || i === t) return i; - return null - } - - function u(n) { - this.data = n || [] - } - - function it(n, i) { - if (n) { - var r = typeof n === o ? { - field: n, - dir: i - } : n, - u = d(r) ? r : r !== t ? [r] : []; - return pr(u, function(n) { - return !!n.dir - }) - } - } - - function wi(n) { - var i, f, r, t, u = n.filters; - if (u) - for (i = 0, f = u.length; i < f; i++) r = u[i], t = r.operator, t && typeof t === o && (r.operator = pi[t.toLowerCase()] || t), wi(r) - } - - function ct(n) { - if (n && !k(n)) return (d(n) || !n.filters) && (n = { - logic: "and", - filters: d(n) ? n : [n] - }), wi(n), n - } - - function su(n) { - return d(n) ? n : [n] - } - - function rt(n, i) { - var r = typeof n === o ? { - field: n, - dir: i - } : n, - u = d(r) ? r : r !== t ? [r] : []; - return vt(u, function(n) { - return { - field: n.field, - dir: n.dir || "asc", - aggregates: n.aggregates - } - }) - } - - function hu(n, t) { - return n && n.getTime && t && t.getTime ? n.getTime() === t.getTime() : n === t - } - - function cu(n, t, r, u, f) { - var o, h, s, c, e; - for (t = t || [], c = t.length, o = 0; o < c; o++) h = t[o], s = h.aggregate, e = h.field, n[e] = n[e] || {}, n[e][s] = bi[s.toLowerCase()](n[e][s], r, i.accessor(e), u, f) - } - - function ki(n) { - return typeof n == "number" && !isNaN(n) - } - - function lu(n) { - for (var i = n.length, r = new Array(i), t = 0; t < i; t++) r[t] = n[t].toJSON(); - return r - } - - function di(n, t) { - t = t || {}; - var i = new u(n), - f = t.aggregate, - r = t.filter; - return r && (i = i.filter(r)), i.aggregate(f) - } - - function au(n, t, i, r, u) { - for (var e, f, o, s = 0, h = n.length; s < h; s++) { - e = n[s]; - for (f in t) o = u[f], o && o !== f && (e[o] = t[f](e), delete e[f]) - } - } - - function tr(n, t, i, r, u) { - for (var e, f, o, s = 0, h = n.length; s < h; s++) { - e = n[s]; - for (f in t) e[f] = i._parse(f, t[f](e)), o = u[f], o && o !== f && delete e[o] - } - } - - function ir(n, t, i, r, u) { - for (var f, o, e = 0, s = n.length; e < s; e++) f = n[e], o = r[f.field], o && o != f.field && (f.field = o), f.value = i._parse(f.field, f.value), f.hasSubgroups ? ir(f.items, t, i, r, u) : tr(f.items, t, i, r, u) - } - - function ni(n, t, i, r, u, f) { - return function(e) { - return e = n(e), e && !k(r) && (st.call(e) === "[object Array]" || e instanceof p || (e = [e]), i(e, r, new t, u, f)), e || [] - } - } - - function ii(n, t, i, r) { - for (var f, e = 0, u, o; t.length && r;) - if (f = t[e], u = f.items, o = u.length, n && n.field === f.field && n.value === f.value ? (n.hasSubgroups && n.items.length ? ii(n.items[n.items.length - 1], f.items, i, r) : (u = u.slice(i, i + r), n.items = n.items.concat(u)), t.splice(e--, 1)) : f.hasSubgroups && u.length ? ii(f, u, i, r) : (u = u.slice(i, i + r), f.items = u, f.items.length || t.splice(e--, 1)), u.length === 0 ? i -= o : (i = 0, r -= u.length), ++e >= t.length) break; - e < t.length && t.splice(e, t.length - e) - } - - function rr(n) { - for (var i = [], t = 0, r = n.length; t < r; t++) i = n[t].hasSubgroups ? i.concat(rr(n[t].items)) : i.concat(n[t].items.slice()); - return i - } - - function ur(n, t) { - var r, f, u, i; - if (t) - for (r = 0, f = n.length; r < f; r++) u = n[r], i = u.items, u.hasSubgroups ? ur(i, t) : !i.length || i[0] instanceof t || (i.type = t, i.wrapAll(i, i)) - } - - function fr(n, t) { - for (var i = 0, r = n.length; i < r; i++) - if (n[i].hasSubgroups) { - if (fr(n[i].items, t)) return !0 - } else if (t(n[i].items, n[i])) return !0 - } - - function vu(n, t) { - for (var i = 0, r = n.length; i < r; i++) - if (n[i].uid == t.uid) return t = n[i], n.splice(i, 1), t - } - - function er(n, t) { - for (var i, u, r = n.length - 1, f = 0; r >= f; r--) u = n[r], i = { - value: t.get(u.field), - field: u.field, - items: i ? [i] : [t], - hasSubgroups: !!i, - aggregates: {} - }; - return i - } - - function or(n, t) { - return t ? hr(n, function(n) { - return n[t.idField] === t.id - }) : -1 - } - - function sr(n, t) { - return t ? hr(n, function(n) { - return n.uid == t.uid - }) : -1 - } - - function hr(n, t) { - for (var i = 0, r = n.length; i < r; i++) - if (t(n[i])) return i; - return -1 - } - - function cr(n, t) { - if (n && !k(n)) { - var i = n[t], - r; - return (r = l(i) ? i.from || i.field || t : n[t] || t, y(r)) ? t : r - } - return t - } - - function lr(n, t) { - var r, f, i = {}; - for (var u in n) u !== "filters" && (i[u] = n[u]); - if (n.filters) - for (i.filters = [], r = 0, f = n.filters.length; r < f; r++) i.filters[r] = lr(n.filters[r], t); - else i.field = cr(t.fields, i.field); - return i - } - - function lt(n, t) { - for (var o = [], i, u, f, r = 0, e = n.length; r < e; r++) { - i = {}; - u = n[r]; - for (f in u) i[f] = u[f]; - i.field = cr(t.fields, i.field); - i.aggregates && d(i.aggregates) && (i.aggregates = lt(i.aggregates, t)); - o.push(i) - } - return o - } - - function yu(t, i) { - for (var o = n(t)[0].children, h = [], e, c = i[0], l = i[1], u, r, f = 0, s = o.length; f < s; f++)(e = {}, r = o[f], r.disabled) || (e[c.field] = r.text, u = r.attributes.value, u = u && u.specified ? r.value : r.text, e[l.field] = u, h.push(e)); - return h - } - - function pu(t, i) { - for (var s = n(t)[0].tBodies[0], h = s ? s.rows : [], r, v = i.length, l = [], a, f, e, o, u = 0, c = h.length; u < c; u++) { - for (f = {}, o = !0, a = h[u].cells, r = 0; r < v; r++) e = a[r], e.nodeName.toLowerCase() !== "th" && (o = !1, f[i[r].field] = e.innerHTML); - o || l.push(f) - } - return l - } - - function ar(n) { - return function() { - var t = this._data, - i = h.fn[n].apply(this, dt.call(arguments)); - return this._data != t && this._attachBubbleHandlers(), i - } - } - - function vr(t, i) { - function c(n, t) { - return n.filter(t).add(n.find(t)) - } - for (var l = n(t).children(), v = [], r, b = i[0].field, y = i[1] && i[1].field, p = i[2] && i[2].field, w = i[3] && i[3].field, f, s, o, h, u, e = 0, a = l.length; e < a; e++) r = { - _loaded: !0 - }, f = l.eq(e), o = f[0].firstChild, u = f.children(), t = u.filter("ul"), u = u.filter(":not(ul)"), s = f.attr("data-id"), s && (r.id = s), o && (r[b] = o.nodeType == 3 ? o.nodeValue : u.text()), y && (r[y] = c(u, "a").attr("href")), w && (r[w] = c(u, "img").attr("src")), p && (h = c(u, ".k-sprite").prop("className"), r[p] = h && n.trim(h.replace("k-sprite", ""))), t.length && (r.items = vr(t.eq(0), i)), f.attr("data-hasChildren") == "true" && (r.hasChildren = !0), v.push(r); - return v - } - var e = n.extend, - v = n.proxy, - l = n.isPlainObject, - k = n.isEmptyObject, - d = n.isArray, - pr = n.grep, - at = n.ajax, - vt, yt = n.each, - b = n.noop, - i = window.kendo, - y = i.isFunction, - g = i.Observable, - ft = i.Class, - o = "string", - pt = "function", - ei = "create", - oi = "read", - si = "update", - hi = "destroy", - r = "change", - ci = "sync", - wt = "get", - a = "error", - tt = "requestStart", - bt = "progress", - nt = "requestEnd", - wr = [ei, oi, si, hi], - et = function(n) { - return n - }, - ot = i.getter, - kt = i.stringify, - f = Math, - br = [].push, - kr = [].join, - dr = [].pop, - gr = [].splice, - nu = [].shift, - dt = [].slice, - tu = [].unshift, - st = {}.toString, - iu = i.support.stableSort, - ru = /^\/Date\((.*?)\)\/$/, - uu = /(\r+|\n+)/g, - fu = /(?=['\\])/g, - p = g.extend({ - init: function(n, t) { - var i = this; - i.type = t || s; - g.fn.init.call(i); - i.length = n.length; - i.wrapAll(n, i) - }, - toJSON: function() { - for (var i = this.length, t, r = new Array(i), n = 0; n < i; n++) t = this[n], t instanceof s && (t = t.toJSON()), r[n] = t; - return r - }, - parent: b, - wrapAll: function(n, t) { - var r = this, - i, u, f = function() { - return r - }; - for (t = t || [], i = 0, u = n.length; i < u; i++) t[i] = r.wrap(n[i], f); - return t - }, - wrap: function(n, t) { - var i = this, - u; - return n !== null && st.call(n) === "[object Object]" && (u = n instanceof i.type || n instanceof c, u || (n = n instanceof s ? n.toJSON() : n, n = new i.type(n)), n.parent = t, n.bind(r, function(n) { - i.trigger(r, { - field: n.field, - node: n.node, - index: n.index, - items: n.items || [this], - action: n.node ? n.action || "itemchange" : "itemchange" - }) - })), n - }, - push: function() { - var i = this.length, - n = this.wrapAll(arguments), - t; - return t = br.apply(this, n), this.trigger(r, { - action: "add", - index: i, - items: n - }), t - }, - slice: dt, - join: kr, - pop: function() { - var n = this.length, - t = dr.apply(this); - return n && this.trigger(r, { - action: "remove", - index: n - 1, - items: [t] - }), t - }, - splice: function(n, t, i) { - var e = this.wrapAll(dt.call(arguments, 2)), - u, f, o; - if (u = gr.apply(this, [n, t].concat(e)), u.length) - for (this.trigger(r, { - action: "remove", - index: n, - items: u - }), f = 0, o = u.length; f < o; f++) u[f].children && u[f].unbind(r); - return i && this.trigger(r, { - action: "add", - index: n, - items: e - }), u - }, - shift: function() { - var t = this.length, - n = nu.apply(this); - return t && this.trigger(r, { - action: "remove", - index: 0, - items: [n] - }), n - }, - unshift: function() { - var n = this.wrapAll(arguments), - t; - return t = tu.apply(this, n), this.trigger(r, { - action: "add", - index: 0, - items: n - }), t - }, - indexOf: function(n) { - for (var i = this, t = 0, r = i.length; t < r; t++) - if (i[t] === n) return t; - return -1 - }, - forEach: function(n) { - for (var t = 0, i = this.length; t < i; t++) n(this[t], t, this) - }, - map: function(n) { - for (var t = 0, i = [], r = this.length; t < r; t++) i[t] = n(this[t], t, this); - return i - }, - filter: function(n) { - for (var t = 0, i = [], r, u = this.length; t < u; t++) r = this[t], n(r, t, this) && (i[i.length] = r); - return i - }, - find: function(n) { - for (var t = 0, i, r = this.length; t < r; t++) - if (i = this[t], n(i, t, this)) return i - }, - every: function(n) { - for (var t = 0, i, r = this.length; t < r; t++) - if (i = this[t], !n(i, t, this)) return !1; - return !0 - }, - some: function(n) { - for (var t = 0, i, r = this.length; t < r; t++) - if (i = this[t], n(i, t, this)) return !0; - return !1 - }, - remove: function(n) { - this.splice(this.indexOf(n), 1) - }, - empty: function() { - this.splice(0, this.length) - } - }), - s = g.extend({ - init: function(n) { - var r = this, - u, t, f = function() { - return r - }; - g.fn.init.call(this); - for (t in n) u = n[t], t.charAt(0) != "_" && (u = r.wrap(u, t, f)), r[t] = u; - r.uid = i.guid() - }, - shouldSerialize: function(n) { - return this.hasOwnProperty(n) && n !== "_events" && typeof this[n] !== pt && n !== "uid" - }, - forEach: function(n) { - for (var t in this) this.shouldSerialize(t) && n(this[t], t) - }, - toJSON: function() { - var i = {}, - n; - for (var t in this) this.shouldSerialize(t) && (n = this[t], (n instanceof s || n instanceof p) && (n = n.toJSON()), i[t] = n); - return i - }, - get: function(n) { - var t = this; - return t.trigger(wt, { - field: n - }), n === "this" ? t : i.getter(n, !0)(t) - }, - _set: function(n, t) { - var o = this, - f = n.indexOf(".") >= 0, - r, u, e; - if (f) - for (r = n.split("."), u = ""; r.length > 1;) { - if (u += r.shift(), e = i.getter(u, !0)(o), e instanceof s) return e.set(r.join("."), t), f; - u += "." - } - return i.setter(n)(o, t), f - }, - set: function(n, t) { - var u = this, - f = i.getter(n, !0)(u); - f !== t && (u.trigger("set", { - field: n, - value: t - }) || (!u._set(n, u.wrap(t, n, function() { - return u - })) || n.indexOf("(") >= 0 || n.indexOf("[") >= 0) && u.trigger(r, { - field: n - })) - }, - parent: b, - wrap: function(n, t, i) { - var o = this, - u = st.call(n), - f, e; - return n != null && (u === "[object Object]" || u === "[object Array]") && (f = n instanceof p, e = n instanceof h, u !== "[object Object]" || e || f ? (u === "[object Array]" || f || e) && (f || e || (n = new p(n)), n.parent() != i() && n.bind(r, gt(o, r, t, !1))) : (n instanceof s || (n = new s(n)), n.parent() != i() && (n.bind(wt, gt(o, wt, t, !0)), n.bind(r, gt(o, r, t, !0)))), n.parent = i), n - } - }), - ai = { - number: function(n) { - return i.parseFloat(n) - }, - date: function(n) { - return i.parseDate(n) - }, - boolean: function(n) { - return typeof n === o ? n.toLowerCase() === "true" : n != null ? !!n : n - }, - string: function(n) { - return n != null ? n + "" : n - }, - "default": function(n) { - return n - } - }, - eu = { - string: "", - number: 0, - date: new Date, - boolean: !1, - "default": "" - }, - c = s.extend({ - init: function(i) { - var r = this; - (!i || n.isEmptyObject(i)) && (i = n.extend({}, r.defaults, i)); - s.fn.init.call(r, i); - r.dirty = !1; - r.idField && (r.id = r.get(r.idField), r.id === t && (r.id = r._defaultId)) - }, - shouldSerialize: function(n) { - return s.fn.shouldSerialize.call(this, n) && n !== "uid" && !(this.idField !== "id" && n === "id") && n !== "dirty" && n !== "_accessors" - }, - _parse: function(n, t) { - var u = this, - f = n, - r = u.fields || {}, - i; - return n = r[n], n || (n = ou(r, f)), n && (i = n.parse, !i && n.type && (i = ai[n.type.toLowerCase()])), i ? i(t) : t - }, - _notifyChange: function(n) { - var t = n.action; - (t == "add" || t == "remove") && (this.dirty = !0) - }, - editable: function(n) { - return n = (this.fields || {})[n], n ? n.editable !== !1 : !0 - }, - set: function(n, t, i) { - var r = this; - r.editable(n) && (t = r._parse(n, t), li(t, r.get(n)) || (r.dirty = !0, s.fn.set.call(r, n, t, i))) - }, - accept: function(n) { - var t = this, - u = function() { - return t - }, - i, r; - for (i in n) r = n[i], i.charAt(0) != "_" && (r = t.wrap(n[i], i, u)), t._set(i, r); - t.idField && (t.id = t.get(t.idField)); - t.dirty = !1 - }, - isNew: function() { - return this.id === this._defaultId - } - }), - ht, vi, yi, pi, bi, ti, h, ri, ui, w, fi, yr; - c.define = function(n, i) { - i === t && (i = n, n = c); - var s, r = e({ - defaults: {} - }, i), - f, u, y, l, a, w, p = {}, - h, v = r.id; - if (v && (r.idField = v), r.id && delete r.id, v && (r.defaults[v] = r._defaultId = ""), st.call(r.fields) === "[object Array]") { - for (a = 0, w = r.fields.length; a < w; a++) u = r.fields[a], typeof u === o ? p[u] = {} : u.field && (p[u.field] = u); - r.fields = p - } - for (f in r.fields) u = r.fields[f], y = u.type || "default", l = null, h = f, f = typeof u.field === o ? u.field : f, u.nullable || (l = r.defaults[h !== f ? h : f] = u.defaultValue !== t ? u.defaultValue : eu[y.toLowerCase()]), i.id === f && (r._defaultId = l), r.defaults[h !== f ? h : f] = l, u.parse = u.parse || ai[y]; - return s = n.extend(r), s.define = function(n) { - return c.define(s, n) - }, r.fields && (s.fields = r.fields, s.idField = r.idField), s - }; - ht = { - selector: function(n) { - return y(n) ? n : ot(n) - }, - compare: function(n) { - var t = this.selector(n); - return function(n, i) { - return (n = t(n), i = t(i), n == null && i == null) ? 0 : n == null ? -1 : i == null ? 1 : n.localeCompare ? n.localeCompare(i) : n > i ? 1 : n < i ? -1 : 0 - } - }, - create: function(n) { - var t = n.compare || this.compare(n.field); - return n.dir == "desc" ? function(n, i) { - return t(i, n, !0) - } : t - }, - combine: function(n) { - return function(t, i) { - for (var u = n[0](t, i), r = 1, f = n.length; r < f; r++) u = u || n[r](t, i); - return u - } - } - }; - vi = e({}, ht, { - asc: function(n) { - var t = this.selector(n); - return function(n, i) { - var r = t(n), - u = t(i); - return (r && r.getTime && u && u.getTime && (r = r.getTime(), u = u.getTime()), r === u) ? n.__position - i.__position : r == null ? -1 : u == null ? 1 : r.localeCompare ? r.localeCompare(u) : r > u ? 1 : -1 - } - }, - desc: function(n) { - var t = this.selector(n); - return function(n, i) { - var u = t(n), - r = t(i); - return (u && u.getTime && r && r.getTime && (u = u.getTime(), r = r.getTime()), u === r) ? n.__position - i.__position : u == null ? 1 : r == null ? -1 : r.localeCompare ? r.localeCompare(u) : u < r ? 1 : -1 - } - }, - create: function(n) { - return this[n.dir](n.field) - } - }); - vt = function(n, t) { - for (var r = n.length, u = new Array(r), i = 0; i < r; i++) u[i] = t(n[i], i, n); - return u - }; - yi = function() { - function t(n) { - return n.replace(fu, "\\").replace(uu, "") - } - - function n(n, i, r, u) { - var f; - return r != null && (typeof r === o && (r = t(r), f = ru.exec(r), f ? r = new Date(+f[1]) : u ? (r = "'" + r.toLowerCase() + "'", i = "(" + i + " || '').toLowerCase()") : r = "'" + r + "'"), r.getTime && (i = "(" + i + "?" + i + ".getTime():" + i + ")", r = r.getTime())), i + " " + n + " " + r - } - return { - eq: function(t, i, r) { - return n("==", t, i, r) - }, - neq: function(t, i, r) { - return n("!=", t, i, r) - }, - gt: function(t, i, r) { - return n(">", t, i, r) - }, - gte: function(t, i, r) { - return n(">=", t, i, r) - }, - lt: function(t, i, r) { - return n("<", t, i, r) - }, - lte: function(t, i, r) { - return n("<=", t, i, r) - }, - startswith: function(n, i, r) { - return r && (n = "(" + n + " || '').toLowerCase()", i && (i = i.toLowerCase())), i && (i = t(i)), n + ".lastIndexOf('" + i + "', 0) == 0" - }, - endswith: function(n, i, r) { - return r && (n = "(" + n + " || '').toLowerCase()", i && (i = i.toLowerCase())), i && (i = t(i)), n + ".indexOf('" + i + "', " + n + ".length - " + (i || "").length + ") >= 0" - }, - contains: function(n, i, r) { - return r && (n = "(" + n + " || '').toLowerCase()", i && (i = i.toLowerCase())), i && (i = t(i)), n + ".indexOf('" + i + "') >= 0" - }, - doesnotcontain: function(n, i, r) { - return r && (n = "(" + n + " || '').toLowerCase()", i && (i = i.toLowerCase())), i && (i = t(i)), n + ".indexOf('" + i + "') == -1" - } - } - }(); - u.filterExpr = function(n) { - for (var l = [], r, f, e = [], o = [], h, c, v = n.filters, s = 0, a = v.length; s < a; s++) r = v[s], h = r.field, c = r.operator, r.filters ? (f = u.filterExpr(r), r = f.expression.replace(/__o\[(\d+)\]/g, function(n, t) { - return t = +t, "__o[" + (o.length + t) + "]" - }).replace(/__f\[(\d+)\]/g, function(n, t) { - return t = +t, "__f[" + (e.length + t) + "]" - }), o.push.apply(o, f.operators), e.push.apply(e, f.fields)) : (typeof h === pt ? (f = "__f[" + e.length + "](d)", e.push(h)) : f = i.expr(h), typeof c === pt ? (r = "__o[" + o.length + "](" + f + ", " + r.value + ")", o.push(c)) : r = yi[(c || "eq").toLowerCase()](f, r.value, r.ignoreCase !== t ? r.ignoreCase : !0)), l.push(r); - return { - expression: "(" + l.join({ - and: " && ", - or: " || " - }[n.logic]) + ")", - fields: e, - operators: o - } - }; - pi = { - "==": "eq", - equals: "eq", - isequalto: "eq", - equalto: "eq", - equal: "eq", - "!=": "neq", - ne: "neq", - notequals: "neq", - isnotequalto: "neq", - notequalto: "neq", - notequal: "neq", - "<": "lt", - islessthan: "lt", - lessthan: "lt", - less: "lt", - "<=": "lte", - le: "lte", - islessthanorequalto: "lte", - lessthanequal: "lte", - ">": "gt", - isgreaterthan: "gt", - greaterthan: "gt", - greater: "gt", - ">=": "gte", - isgreaterthanorequalto: "gte", - greaterthanequal: "gte", - ge: "gte", - notsubstringof: "doesnotcontain" - }; - u.normalizeFilter = ct; - u.prototype = { - toArray: function() { - return this.data - }, - range: function(n, t) { - return new u(this.data.slice(n, n + t)) - }, - skip: function(n) { - return new u(this.data.slice(n)) - }, - take: function(n) { - return new u(this.data.slice(0, n)) - }, - select: function(n) { - return new u(vt(this.data, n)) - }, - order: function(n, t) { - var i = { - dir: t - }; - return n && (n.compare ? i.compare = n.compare : i.field = n), new u(this.data.slice(0).sort(ht.create(i))) - }, - orderBy: function(n) { - return this.order(n, "asc") - }, - orderByDescending: function(n) { - return this.order(n, "desc") - }, - sort: function(n, t, i) { - var r, f, u = it(n, t), - e = []; - if (i = i || ht, u.length) { - for (r = 0, f = u.length; r < f; r++) e.push(i.create(u[r])); - return this.orderBy({ - compare: i.combine(e) - }) - } - return this - }, - filter: function(n) { - var t, r, s, i, h, c = this.data, - f, e, l = [], - o; - if (n = ct(n), !n || n.filters.length === 0) return this; - for (i = u.filterExpr(n), f = i.fields, e = i.operators, h = o = new Function("d, __f, __o", "return " + i.expression), (f.length || e.length) && (o = function(n) { - return h(n, f, e) - }), t = 0, s = c.length; t < s; t++) r = c[t], o(r) && l.push(r); - return new u(l) - }, - group: function(n, t) { - n = rt(n || []); - t = t || this.data; - var f = this, - i = new u(f.data), - r; - return n.length > 0 && (r = n[0], i = i.groupBy(r).select(function(i) { - var f = new u(t).filter([{ - field: i.field, - operator: "eq", - value: i.value, - ignoreCase: !1 - }]); - return { - field: i.field, - value: i.value, - items: n.length > 1 ? new u(i.items).group(n.slice(1), f.toArray()).toArray() : i.items, - hasSubgroups: n.length > 1, - aggregates: f.aggregate(r.aggregates) - } - })), i - }, - groupBy: function(n) { - if (k(n) || !this.data.length) return new u([]); - for (var t = n.field, o = this._sortForGrouping(t, n.dir || "asc"), c = i.accessor(t), s, r = c.get(o[0], t), f = { - field: t, - value: r, - items: [] - }, h, a = [f], e = 0, l = o.length; e < l; e++) s = o[e], h = c.get(s, t), hu(r, h) || (r = h, f = { - field: t, - value: r, - items: [] - }, a.push(f)), f.items.push(s); - return new u(a) - }, - _sortForGrouping: function(n, t) { - var i, f, r = this.data; - if (!iu) { - for (i = 0, f = r.length; i < f; i++) r[i].__position = i; - for (r = new u(r).sort(n, t, vi).toArray(), i = 0, f = r.length; i < f; i++) delete r[i].__position; - return r - } - return this.sort(n, t).toArray() - }, - aggregate: function(n) { - var t, i, r = {}; - if (n && n.length) - for (t = 0, i = this.data.length; t < i; t++) cu(r, n, this.data[t], t, i); - return r - } - }; - bi = { - sum: function(n, t, i) { - return (n || 0) + i.get(t) - }, - count: function(n) { - return (n || 0) + 1 - }, - average: function(n, t, i, r, u) { - return n = (n || 0) + i.get(t), r == u - 1 && (n = n / u), n - }, - max: function(n, t, i) { - var r = i.get(t); - return n = n || 0, n < r && (n = r), n - }, - min: function(n, t, i) { - var r = i.get(t); - return ki(n) || (n = r), n > r && ki(r) && (n = r), n - } - }; - u.process = function(n, i) { - i = i || {}; - var r = new u(n), - f = i.group, - e = rt(f || []).concat(it(i.sort || [])), - o, s = i.filter, - h = i.skip, - c = i.take; - return s && (r = r.filter(s), o = r.toArray().length), e && (r = r.sort(e), f && (n = r.toArray())), h !== t && c !== t && (r = r.range(h, c)), f && (r = r.group(f, n)), { - total: o, - data: r.toArray() - } - }; - var gi = ft.extend({ - init: function(n) { - this.data = n.data - }, - read: function(n) { - n.success(this.data) - }, - update: function(n) { - n.success(n.data) - }, - create: function(n) { - n.success(n.data) - }, - destroy: function(n) { - n.success(n.data) - } - }), - nr = ft.extend({ - init: function(n) { - var i = this, - t; - n = i.options = e({}, i.options, n); - yt(wr, function(t, i) { - typeof n[i] === o && (n[i] = { - url: n[i] - }) - }); - i.cache = n.cache ? ut.create(n.cache) : { - find: b, - add: b - }; - t = n.parameterMap; - i.parameterMap = y(t) ? t : function(n) { - var i = {}; - return yt(n, function(n, r) { - n in t && (n = t[n], l(n) && (r = n.value(r), n = n.key)); - i[n] = r - }), i - } - }, - options: { - parameterMap: et - }, - create: function(n) { - return at(this.setup(n, ei)) - }, - read: function(i) { - var f = this, - r, o, u, e = f.cache; - i = f.setup(i, oi); - r = i.success || b; - o = i.error || b; - u = e.find(i.data); - u !== t ? r(u) : (i.success = function(n) { - e.add(i.data, n); - r(n) - }, n.ajax(i)) - }, - update: function(n) { - return at(this.setup(n, si)) - }, - destroy: function(n) { - return at(this.setup(n, hi)) - }, - setup: function(n, t) { - n = n || {}; - var u = this, - r, i = u.options[t], - f = y(i.data) ? i.data(n.data) : i.data; - return n = e(!0, {}, i, n), r = e(!0, {}, f, n.data), n.data = u.parameterMap(r, t), y(n.url) && (n.url = n.url(r)), n - } - }), - ut = ft.extend({ - init: function() { - this._store = {} - }, - add: function(n, i) { - n !== t && (this._store[kt(n)] = i) - }, - find: function(n) { - return this._store[kt(n)] - }, - clear: function() { - this._store = {} - }, - remove: function(n) { - delete this._store[kt(n)] - } - }); - ut.create = function(n) { - var t = { - inmemory: function() { - return new ut - } - }; - return l(n) && y(n.find) ? n : n === !0 ? new ut : t[n]() - }; - ti = ft.extend({ - init: function(n) { - var t = this, - s, u, i, y; - n = n || {}; - for (s in n) u = n[s], t[s] = typeof u === o ? ot(u) : u; - if (y = n.modelBase || c, l(t.model) && (t.model = i = y.define(t.model)), t.model) { - var w = v(t.data, t), - b = v(t.groups, t), - k = v(t.serialize, t), - f = {}, - h = {}, - p = {}, - e = {}, - a = !1, - r; - i = t.model; - i.fields && (yt(i.fields, function(n, t) { - var i; - r = n; - l(t) && t.field ? r = t.field : typeof t === o && (r = t); - l(t) && t.from && (i = t.from); - a = a || i && i !== n || r !== n; - h[n] = ot(i || r); - p[n] = ot(n); - f[i || r] = n; - e[n] = i || r - }), !n.serialize && a && (t.serialize = ni(k, i, au, p, f, e))); - t.data = ni(w, i, tr, h, f, e); - t.groups = ni(b, i, ir, h, f, e) - } - }, - errors: function(n) { - return n ? n.errors : null - }, - parse: et, - data: et, - total: function(n) { - return n.length - }, - groups: et, - aggregates: function() { - return {} - }, - serialize: function(n) { - return n - } - }); - h = g.extend({ - init: function(n) { - var u = this, - o, f; - n && (f = n.data); - n = u.options = e({}, u.options, n); - u._map = {}; - u._prefetch = {}; - u._data = []; - u._pristineData = []; - u._ranges = []; - u._view = []; - u._pristine = []; - u._destroyed = []; - u._pageSize = n.pageSize; - u._page = n.page || (n.pageSize ? 1 : t); - u._sort = it(n.sort); - u._filter = ct(n.filter); - u._group = rt(n.group); - u._aggregate = n.aggregate; - u._total = n.total; - g.fn.init.call(u); - u.transport = ri.create(n, f); - u.reader = new i.data.readers[n.schema.type || "json"](n.schema); - o = u.reader.model || {}; - u._data = u._observe(u._data); - u.bind([a, r, tt, ci, nt, bt], n) - }, - options: { - data: [], - schema: { - modelBase: c - }, - serverSorting: !1, - serverPaging: !1, - serverFiltering: !1, - serverGrouping: !1, - serverAggregates: !1, - batch: !1 - }, - _isServerGrouped: function() { - var n = this.group() || []; - return this.options.serverGrouping && n.length - }, - _flatData: function(n) { - return this._isServerGrouped() ? rr(n) : n - }, - parent: b, - get: function(n) { - for (var i = this._flatData(this._data), t = 0, r = i.length; t < r; t++) - if (i[t].id == n) return i[t] - }, - getByUid: function(n) { - var t, r, i = this._flatData(this._data); - if (i) - for (t = 0, r = i.length; t < r; t++) - if (i[t].uid == n) return i[t] - }, - indexOf: function(n) { - return sr(this._data, n) - }, - at: function(n) { - return this._data[n] - }, - data: function(n) { - var i = this; - if (n !== t) i._data = this._observe(n), i._ranges = [], i._addRange(i._data), i._total = i._data.length, i._process(i._data); - else return i._data - }, - view: function() { - return this._view - }, - add: function(n) { - return this.insert(this._data.length, n) - }, - _createNewModel: function(n) { - return this.reader.model ? new this.reader.model(n) : new s(n) - }, - insert: function(n, t) { - return t || (t = n, n = 0), t instanceof c || (t = this._createNewModel(t)), this._isServerGrouped() ? this._data.splice(n, 0, er(this.group(), t)) : this._data.splice(n, 0, t), t - }, - remove: function(n) { - var t, i = this, - r = i._isServerGrouped(); - return this._eachItem(i._data, function(u) { - return t = vu(u, n), t && r ? (t.isNew && t.isNew() || i._destroyed.push(t), !0) : void 0 - }), n - }, - sync: function() { - var t = this, - i, f, e = [], - o = [], - s = t._destroyed, - u = t._flatData(t._data), - r; - if (t.reader.model) { - for (i = 0, f = u.length; i < f; i++) u[i].isNew() ? e.push(u[i]) : u[i].dirty && o.push(u[i]); - r = t._send("create", e); - r.push.apply(r, t._send("update", o)); - r.push.apply(r, t._send("destroy", s)); - n.when.apply(null, r).then(function() { - for (var n = 0, i = arguments.length; n < i; n++) t._accept(arguments[n]); - t._change({ - action: "sync" - }); - t.trigger(ci) - }) - } - }, - cancelChanges: function(n) { - var t = this; - n instanceof i.data.Model ? t._cancelModel(n) : (t._destroyed = [], t._data = t._observe(t._pristineData), t.options.serverPaging && (t._total = t.reader.total(t._pristine)), t._change()) - }, - hasChanges: function() { - var n, i, t = this._data; - if (this._destroyed.length) return !0; - for (n = 0, i = t.length; n < i; n++) - if (t[n].isNew() || t[n].dirty) return !0; - return !1 - }, - _accept: function(t) { - var r = this, - f = t.models, - i = t.response, - u = 0, - s = r._isServerGrouped(), - h = r._pristineData, - e = t.type, - o; - if (r.trigger(nt, { - response: i, - type: e - }), i && !k(i)) { - if (i = r.reader.parse(i), r._handleCustomErrors(i)) return; - i = r.reader.data(i); - n.isArray(i) || (i = [i]) - } else i = n.map(f, function(n) { - return n.toJSON() - }); - for (e === "destroy" && (r._destroyed = []), u = 0, o = f.length; u < o; u++) e !== "destroy" ? (f[u].accept(i[u]), e === "create" ? h.push(s ? er(r.group(), f[u]) : i[u]) : e === "update" && r._updatePristineForModel(f[u], i[u])) : r._removePristineForModel(f[u]) - }, - _updatePristineForModel: function(n, t) { - this._executeOnPristineForModel(n, function(n, r) { - i.deepExtend(r[n], t) - }) - }, - _executeOnPristineForModel: function(n, t) { - this._eachPristineItem(function(i) { - var r = or(i, n); - if (r > -1) return t(r, i), !0 - }) - }, - _removePristineForModel: function(n) { - this._executeOnPristineForModel(n, function(n, t) { - t.splice(n, 1) - }) - }, - _readData: function(n) { - var t = this._isServerGrouped() ? this.reader.groups : this.reader.data; - return t(n) - }, - _eachPristineItem: function(n) { - this._eachItem(this._pristineData, n) - }, - _eachItem: function(n, t) { - n && n.length && (this._isServerGrouped() ? fr(n, t) : t(n)) - }, - _pristineForModel: function(n) { - var i, t, r = function(r) { - return t = or(r, n), t > -1 ? (i = r[t], !0) : void 0 - }; - return this._eachPristineItem(r), i - }, - _cancelModel: function(n) { - var i = this._pristineForModel(n), - t; - this._eachItem(this._data, function(r) { - t = sr(r, n); - t != -1 && (!n.isNew() && i ? r[t].accept(i) : r.splice(t, 1)) - }) - }, - _promise: function(t, i, r) { - var u = this, - f = u.transport; - return n.Deferred(function(n) { - u.trigger(tt, { - type: r - }); - f[r].call(f, e({ - success: function(t) { - n.resolve({ - response: t, - models: i, - type: r - }) - }, - error: function(t, i, r) { - n.reject(t); - u.error(t, i, r) - } - }, t)) - }).promise() - }, - _send: function(n, t) { - var r = this, - i, f, u = [], - e = r.reader.serialize(lu(t)); - if (r.options.batch) t.length && u.push(r._promise({ - data: { - models: e - } - }, t, n)); - else - for (i = 0, f = t.length; i < f; i++) u.push(r._promise({ - data: e[i] - }, [t[i]], n)); - return u - }, - read: function(n) { - var t = this, - i = t._params(n); - t._queueRequest(i, function() { - t.trigger(tt, { - type: "read" - }) ? t._dequeueRequest() : (t.trigger(bt), t._ranges = [], t.transport.read({ - data: i, - success: v(t.success, t), - error: v(t.error, t) - })) - }) - }, - success: function(t) { - var i = this, - r = i.options; - if (i.trigger(nt, { - response: t, - type: "read" - }), t = i.reader.parse(t), i._handleCustomErrors(t)) { - i._dequeueRequest(); - return - } - i._pristine = l(t) ? n.extend(!0, {}, t) : t.slice ? t.slice(0) : t; - i._total = i.reader.total(t); - i._aggregate && r.serverAggregates && (i._aggregateResult = i.reader.aggregates(t)); - t = i._readData(t); - i._pristineData = t.slice(0); - i._data = i._observe(t); - i._addRange(i._data); - i._process(i._data); - i._dequeueRequest() - }, - _addRange: function(n) { - var t = this, - i = t._skip || 0, - r = i + t._flatData(n).length; - t._ranges.push({ - start: i, - end: r, - data: n - }); - t._ranges.sort(function(n, t) { - return n.start - t.start - }) - }, - error: function(n, t, i) { - this._dequeueRequest(); - this.trigger(nt, {}); - this.trigger(a, { - xhr: n, - status: t, - errorThrown: i - }) - }, - _params: function(n) { - var t = this, - i = e({ - take: t.take(), - skip: t.skip(), - page: t.page(), - pageSize: t.pageSize(), - sort: t._sort, - filter: t._filter, - group: t._group, - aggregate: t._aggregate - }, n); - return t.options.serverPaging || (delete i.take, delete i.skip, delete i.page, delete i.pageSize), t.options.serverGrouping ? t.reader.model && i.group && (i.group = lt(i.group, t.reader.model)) : delete i.group, t.options.serverFiltering ? t.reader.model && i.filter && (i.filter = lr(i.filter, t.reader.model)) : delete i.filter, t.options.serverSorting ? t.reader.model && i.sort && (i.sort = lt(i.sort, t.reader.model)) : delete i.sort, t.options.serverAggregates ? t.reader.model && i.aggregate && (i.aggregate = lt(i.aggregate, t.reader.model)) : delete i.aggregate, i - }, - _queueRequest: function(n, i) { - var r = this; - r._requestInProgress ? r._pending = { - callback: v(i, r), - options: n - } : (r._requestInProgress = !0, r._pending = t, i()) - }, - _dequeueRequest: function() { - var n = this; - n._requestInProgress = !1; - n._pending && n._queueRequest(n._pending.options, n._pending.callback) - }, - _handleCustomErrors: function(n) { - if (this.reader.errors) { - var t = this.reader.errors(n); - if (t) return this.trigger(a, { - xhr: null, - status: "customerror", - errorThrown: "custom error", - errors: t - }), !0 - } - return !1 - }, - _observe: function(n) { - var t = this, - i = t.reader.model, - u = !1; - return i && n.length && (u = !(n[0] instanceof i)), n instanceof p ? u && (n.type = t.reader.model, n.wrapAll(n, n)) : (n = new p(n, t.reader.model), n.parent = function() { - return t.parent() - }), t._isServerGrouped() && ur(n, i), t._changeHandler && t._data && t._data instanceof p ? t._data.unbind(r, t._changeHandler) : t._changeHandler = v(t._change, t), n.bind(r, t._changeHandler) - }, - _change: function(n) { - var t = this, - r, f, i = n ? n.action : "", - u; - if (i === "remove") - for (r = 0, f = n.items.length; r < f; r++) n.items[r].isNew && n.items[r].isNew() || t._destroyed.push(n.items[r]); - t.options.autoSync && (i === "add" || i === "remove" || i === "itemchange") ? t.sync() : (u = parseInt(t._total || t.reader.total(t._pristine), 10), i === "add" ? u += n.items.length : i === "remove" ? u -= n.items.length : i === "itemchange" || i === "sync" || t.options.serverPaging || (u = t.reader.total(t._pristine)), t._total = u, t._process(t._data, n)) - }, - _process: function(n, i) { - var f = this, - e = {}, - o; - f.options.serverPaging !== !0 && (e.skip = f._skip, e.take = f._take || f._pageSize, e.skip === t && f._page !== t && f._pageSize !== t && (e.skip = (f._page - 1) * f._pageSize)); - f.options.serverSorting !== !0 && (e.sort = f._sort); - f.options.serverFiltering !== !0 && (e.filter = f._filter); - f.options.serverGrouping !== !0 && (e.group = f._group); - f.options.serverAggregates !== !0 && (e.aggregate = f._aggregate, f._aggregateResult = di(n, e)); - o = u.process(n, e); - f._view = o.data; - o.total === t || f.options.serverFiltering || (f._total = o.total); - i = i || {}; - i.items = i.items || f._view; - f.trigger(r, i) - }, - _mergeState: function(n) { - var i = this; - return n !== t && (i._pageSize = n.pageSize, i._page = n.page, i._sort = n.sort, i._filter = n.filter, i._group = n.group, i._aggregate = n.aggregate, i._skip = n.skip, i._take = n.take, i._skip === t && (i._skip = i.skip(), n.skip = i.skip()), i._take === t && i._pageSize !== t && (i._take = i._pageSize, n.take = i._take), n.sort && (i._sort = n.sort = it(n.sort)), n.filter && (i._filter = n.filter = ct(n.filter)), n.group && (i._group = n.group = rt(n.group)), n.aggregate && (i._aggregate = n.aggregate = su(n.aggregate))), n - }, - query: function(n) { - var i = this, - f, e = i.options.serverSorting || i.options.serverPaging || i.options.serverFiltering || i.options.serverGrouping || i.options.serverAggregates; - e || (i._data === t || i._data.length === 0) && !i._destroyed.length ? i.read(i._mergeState(n)) : i.trigger(tt, { - type: "read" - }) || (i.trigger(bt), f = u.process(i._data, i._mergeState(n)), i.options.serverFiltering || (i._total = f.total !== t ? f.total : i._data.length), i._view = f.data, i._aggregateResult = di(i._data, n), i.trigger(nt, {}), i.trigger(r, { - items: f.data - })) - }, - fetch: function(t) { - var i = this; - return n.Deferred(function(n) { - var f = function(r) { - i.unbind(a, u); - n.resolve(); - t && t.call(i, r) - }, - u = function(t) { - n.reject(t) - }; - i.one(r, f); - i.one(a, u); - i._query() - }).promise() - }, - _query: function(n) { - var t = this; - t.query(e({}, { - page: t.page(), - pageSize: t.pageSize(), - sort: t.sort(), - filter: t.filter(), - group: t.group(), - aggregate: t.aggregate() - }, n)) - }, - next: function(n) { - var t = this, - i = t.page(), - r = t.total(); - if (n = n || {}, i && (!r || !(i + 1 > t.totalPages()))) return t._skip = i * t.take(), i += 1, n.page = i, t._query(n), i - }, - prev: function(n) { - var t = this, - i = t.page(); - if (n = n || {}, i && i !== 1) return t._skip = t._skip - t.take(), i -= 1, n.page = i, t._query(n), i - }, - page: function(n) { - var i = this, - r; - if (n !== t) { - n = f.max(f.min(f.max(n, 1), i.totalPages()), 1); - i._query({ - page: n - }); - return - } - return r = i.skip(), r !== t ? f.round((r || 0) / (i.take() || 1)) + 1 : t - }, - pageSize: function(n) { - var i = this; - if (n !== t) { - i._query({ - pageSize: n, - page: 1 - }); - return - } - return i.take() - }, - sort: function(n) { - var i = this; - if (n !== t) { - i._query({ - sort: n - }); - return - } - return i._sort - }, - filter: function(n) { - var i = this; - if (n === t) return i._filter; - i._query({ - filter: n, - page: 1 - }) - }, - group: function(n) { - var i = this; - if (n !== t) { - i._query({ - group: n - }); - return - } - return i._group - }, - total: function() { - return parseInt(this._total || 0, 10) - }, - aggregate: function(n) { - var i = this; - if (n !== t) { - i._query({ - aggregate: n - }); - return - } - return i._aggregate - }, - aggregates: function() { - return this._aggregateResult - }, - totalPages: function() { - var n = this, - t = n.pageSize() || n.total(); - return f.ceil((n.total() || 0) / t) - }, - inRange: function(n, t) { - var i = this, - r = f.min(n + t, i.total()); - return !i.options.serverPaging && i.data.length > 0 ? !0 : i._findRange(n, r).length > 0 - }, - lastRange: function() { - var n = this._ranges; - return n[n.length - 1] || { - start: 0, - end: 0, - data: [] - } - }, - firstItemUid: function() { - var n = this._ranges; - return n.length && n[0].data.length && n[0].data[0].uid - }, - range: function(n, i) { - n = f.min(n || 0, this.total()); - var r = this, - e = f.max(f.floor(n / i), 0) * i, - u = f.min(e + i, r.total()), - o; - if (o = r._findRange(n, f.min(n + i, r.total())), o.length) { - r._skip = n > r.skip() ? f.min(u, (r.totalPages() - 1) * r.take()) : e; - r._take = i; - var s = r.options.serverPaging, - h = r.options.serverSorting, - c = r.options.serverFiltering; - try { - r.options.serverPaging = !0; - r._isServerGrouped() || r.group() && r.group().length || (r.options.serverSorting = !0); - r.options.serverFiltering = !0; - s && (r._data = o = r._observe(o)); - r._process(o) - } finally { - r.options.serverPaging = s; - r.options.serverSorting = h; - r.options.serverFiltering = c - } - return - } - i !== t && (r._rangeExists(e, u) ? e < n && r.prefetch(u, i, function() { - r.range(n, i) - }) : r.prefetch(e, i, function() { - n > e && u < r.total() && !r._rangeExists(u, f.min(u + i, r.total())) ? r.prefetch(u, i, function() { - r.range(n, i) - }) : r.range(n, i) - })) - }, - _findRange: function(n, i) { - for (var f = this, p = f._ranges, r, w = [], c, l, s, b, a, v, h = f.options, g = h.serverSorting || h.serverPaging || h.serverFiltering || h.serverGrouping || h.serverAggregates, y, e, d, o = 0, k = p.length; o < k; o++) - if (r = p[o], n >= r.start && n <= r.end) { - for (e = 0, c = o; c < k; c++) - if (r = p[c], y = f._flatData(r.data), y.length && n + e >= r.start && (b = r.data, a = r.end, g || (d = rt(f.group() || []).concat(it(f.sort() || [])), v = u.process(r.data, { - sort: d, - filter: f.filter() - }), y = b = v.data, v.total !== t && (a = v.total)), l = 0, n + e > r.start && (l = n + e - r.start), s = y.length, a > i && (s = s - (a - i)), e += s - l, w = f._mergeGroups(w, b, l, s), i <= r.end && e == i - n)) return w; - break - } - return [] - }, - _mergeGroups: function(n, t, i, r) { - if (this._isServerGrouped()) { - var u = t.toJSON(), - f; - return n.length && (f = n[n.length - 1]), ii(f, u, i, r), n.concat(u) - } - return n.concat(t.slice(i, r)) - }, - skip: function() { - var n = this; - return n._skip === t ? n._page !== t ? (n._page - 1) * (n.take() || 1) : t : n._skip - }, - take: function() { - return this._take || this._pageSize - }, - _prefetchSuccessHandler: function(n, t, i) { - var u = this; - return function(f) { - var h = !1, - e = { - start: n, - end: t, - data: [] - }, - o, c, s; - if (u._dequeueRequest(), u.trigger(nt, { - response: f, - type: "read" - }), f = u.reader.parse(f), s = u._readData(f), s.length) { - for (o = 0, c = u._ranges.length; o < c; o++) - if (u._ranges[o].start === n) { - h = !0; - e = u._ranges[o]; - break - } - h || u._ranges.push(e) - } - e.data = u._observe(s); - e.end = e.start + u._flatData(e.data).length; - u._ranges.sort(function(n, t) { - return n.start - t.start - }); - u._total = u.reader.total(f); - i && s.length ? i() : u.trigger(r, {}) - } - }, - prefetch: function(n, t, i) { - var r = this, - u = f.min(n + t, r.total()), - e = { - take: t, - skip: n, - page: n / t + 1, - pageSize: t, - sort: r._sort, - filter: r._filter, - group: r._group, - aggregate: r._aggregate - }; - r._rangeExists(n, u) ? i && i() : (clearTimeout(r._timeout), r._timeout = setTimeout(function() { - r._queueRequest(e, function() { - r.trigger(tt, { - type: "read" - }) ? r._dequeueRequest() : r.transport.read({ - data: r._params(e), - success: r._prefetchSuccessHandler(n, u, i) - }) - }) - }, 100)) - }, - _rangeExists: function(n, t) { - for (var f = this, r = f._ranges, i = 0, u = r.length; i < u; i++) - if (r[i].start <= n && r[i].end >= t) return !0; - return !1 - } - }); - ri = {}; - ri.create = function(n, t) { - var u, r = n.transport; - return r ? (r.read = typeof r.read === o ? { - url: r.read - } : r.read, n.type && (i.data.transports[n.type] && !l(i.data.transports[n.type]) ? u = new i.data.transports[n.type](e(r, { - data: t - })) : r = e(!0, {}, i.data.transports[n.type], r), n.schema = e(!0, {}, i.data.schemas[n.type], n.schema)), u || (u = y(r.read) ? r : new nr(r))) : u = new gi({ - data: n.data - }), u - }; - h.create = function(n) { - n = n && n.push ? { - data: n - } : n; - var t = n || {}, - u = t.data, - r = t.fields, - c = t.table, - l = t.select, - f, a, s = {}, - o; - if (u || !r || t.transport || (c ? u = pu(c, r) : l && (u = yu(l, r))), i.data.Model && r && (!t.schema || !t.schema.model)) { - for (f = 0, a = r.length; f < a; f++) o = r[f], o.type && (s[o.field] = o); - k(s) || (t.schema = e(!0, t.schema, { - model: { - fields: s - } - })) - } - return t.data = u, t instanceof h ? t : new h(t) - }; - ui = c.define({ - init: function(n) { - var t = this, - r = t.hasChildren || n && n.hasChildren, - f = "items", - u = {}; - i.data.Model.fn.init.call(t, n); - typeof t.children === o && (f = t.children); - u = { - schema: { - data: f, - model: { - hasChildren: r, - id: t.idField - } - } - }; - typeof t.children !== o && e(u, t.children); - u.data = n; - r || (r = u.schema.data); - typeof r === o && (r = i.getter(r)); - y(r) && (t.hasChildren = !!r.call(t, t)); - t._childrenOptions = u; - t.hasChildren && t._initChildren(); - t._loaded = !!(n && (n[f] || n._loaded)) - }, - _initChildren: function() { - var n = this, - t, i, u; - n.children instanceof w || (t = n.children = new w(n._childrenOptions), i = t.transport, u = i.parameterMap, i.parameterMap = function(t) { - return t[n.idField || "id"] = n.id, u && (t = u(t)), t - }, t.parent = function() { - return n - }, t.bind(r, function(t) { - t.node = t.node || n; - n.trigger(r, t) - }), t.bind(a, function(t) { - var i = n.parent(); - i && (t.node = t.node || n, i.trigger(a, t)) - }), n._updateChildrenField()) - }, - append: function(n) { - this._initChildren(); - this.loaded(!0); - this.children.add(n) - }, - hasChildren: !1, - level: function() { - for (var n = this.parentNode(), t = 0; n && n.parentNode;) t++, n = n.parentNode ? n.parentNode() : null; - return t - }, - _updateChildrenField: function() { - var n = this._childrenOptions.schema.data; - this[n || "items"] = this.children.data() - }, - _childrenLoaded: function() { - this._loaded = !0; - this._updateChildrenField() - }, - load: function() { - var i = {}, - u = "_query", - n; - if (this.hasChildren) { - this._initChildren(); - n = this.children; - i[this.idField || "id"] = this.id; - this._loaded || (n._data = t, u = "read"); - n.one(r, v(this._childrenLoaded, this)); - n[u](i) - } else this.loaded(!0) - }, - parentNode: function() { - var n = this.parent(); - return n.parent() - }, - loaded: function(n) { - if (n !== t) this._loaded = n; - else return this._loaded - }, - shouldSerialize: function(n) { - return c.fn.shouldSerialize.call(this, n) && n !== "children" && n !== "_loaded" && n !== "hasChildren" && n !== "_childrenOptions" - } - }); - w = h.extend({ - init: function(n) { - var t = ui.define({ - children: n - }); - h.fn.init.call(this, e(!0, {}, { - schema: { - modelBase: t, - model: t - } - }, n)); - this._attachBubbleHandlers() - }, - _attachBubbleHandlers: function() { - var n = this; - n._data.bind(a, function(t) { - n.trigger(a, t) - }) - }, - remove: function(n) { - var t = n.parentNode(), - i = this, - r; - return t && t._initChildren && (i = t.children), r = h.fn.remove.call(i, n), t && !i.data().length && (t.hasChildren = !1), r - }, - success: ar("success"), - data: ar("data"), - insert: function(n, t) { - var i = this.parent(); - return i && i._initChildren && (i.hasChildren = !0, i._initChildren()), h.fn.insert.call(this, n, t) - }, - _find: function(n, t) { - var r, e, i, u, f; - if (i = h.fn[n].call(this, t), i) return i; - if (u = this._flatData(this.data()), u) - for (r = 0, e = u.length; r < e; r++) - if ((f = u[r].children, f instanceof w) && (i = f[n](t), i)) return i - }, - get: function(n) { - return this._find("get", n) - }, - getByUid: function(n) { - return this._find("getByUid", n) - } - }); - w.create = function(n) { - n = n && n.push ? { - data: n - } : n; - var t = n || {}, - i = t.data, - r = t.fields, - u = t.list; - return i && i._dataSource ? i._dataSource : (i || !r || t.transport || u && (i = vr(u, r)), t.data = i, t instanceof w ? t : new w(t)) - }; - fi = i.Observable.extend({ - init: function(n, t, r) { - i.Observable.fn.init.call(this); - this._prefetching = !1; - this.dataSource = n; - this.prefetch = !r; - var u = this; - n.bind("change", function() { - u._change() - }); - this._syncWithDataSource(); - this.setViewSize(t) - }, - setViewSize: function(n) { - this.viewSize = n; - this._recalculate() - }, - at: function(n) { - var i = this.pageSize, - r, u; - if (n >= this.total()) { - this.trigger("endreached", { - index: n - }); - return - } - return this.useRanges ? (this.useRanges && ((n < this.dataOffset || n > this.skip + i) && (u = Math.floor(n / i) * i, this.range(u)), n === this.prefetchThreshold && this._prefetch(), n === this.midPageThreshold ? this.range(this.nextMidRange) : n === this.nextPageThreshold ? this.range(this.nextFullRange) : n === this.pullBackThreshold && (this.offset === this.skip ? this.range(this.previousMidRange) : this.range(this.previousFullRange)), r = this.dataSource.at(n - this.dataOffset)), r === t && this.trigger("endreached", { - index: n - }), r) : this.dataSource.view()[n] - }, - indexOf: function(n) { - return this.dataSource.data().indexOf(n) + this.dataOffset - }, - total: function() { - return parseInt(this.dataSource.total(), 10) - }, - next: function() { - var n = this, - t = n.pageSize, - i = n.skip - n.viewSize, - r = f.max(f.floor(i / t), 0) * t + t; - this.offset = i; - this.dataSource.prefetch(r, t, function() { - n._goToRange(i, !0) - }) - }, - range: function(n) { - if (this.offset !== n) { - var r = this, - t = this.pageSize, - u = f.max(f.floor(n / t), 0) * t + t, - i = this.dataSource; - this.offset = n; - this._recalculate(); - i.inRange(n, t) ? this._goToRange(n) : this.prefetch && i.prefetch(u, t, function() { - r._goToRange(n, !0) - }) - } - }, - syncDataSource: function() { - var n = this.offset; - this.offset = null; - this.range(n) - }, - destroy: function() { - this.unbind() - }, - _prefetch: function() { - var i = this, - n = this.pageSize, - t = this.skip + n, - r = this.dataSource; - r.inRange(t, n) || this._prefetching || !this.prefetch || (this._prefetching = !0, this.trigger("prefetching", { - skip: t, - take: n - }), r.prefetch(t, n, function() { - i._prefetching = !1; - i.trigger("prefetched", { - skip: t, - take: n - }) - })) - }, - _goToRange: function(n, t) { - this.offset === n && (this.dataOffset = n, this._expanding = t, this.dataSource.range(n, this.pageSize)) - }, - _change: function() { - var n = this.dataSource, - t = n.firstItemUid(); - this.length = this.useRanges ? n.lastRange().end : n.view().length; - this._firstItemUid === t && this.useRanges || (this._syncWithDataSource(), this._recalculate(), this.trigger("reset", { - offset: this.offset - })); - this.trigger("resize"); - this._expanding && this.trigger("expand"); - delete this._expanding - }, - _syncWithDataSource: function() { - var n = this.dataSource; - this._firstItemUid = n.firstItemUid(); - this.dataOffset = this.offset = n.skip() || 0; - this.pageSize = n.pageSize(); - this.useRanges = n.options.serverPaging - }, - _recalculate: function() { - var t = this.pageSize, - r = this.offset, - i = this.viewSize, - n = Math.ceil(r / t) * t; - this.skip = n; - this.midPageThreshold = n + t - 1; - this.nextPageThreshold = n + i - 1; - this.prefetchThreshold = n + Math.floor(t / 3 * 2); - this.pullBackThreshold = this.offset - 1; - this.nextMidRange = n + t - i; - this.nextFullRange = n; - this.previousMidRange = r - i; - this.previousFullRange = n - t - } - }); - yr = i.Observable.extend({ - init: function(n, t) { - var r = this; - i.Observable.fn.init.call(r); - this.dataSource = n; - this.batchSize = t; - this._total = 0; - this.buffer = new fi(n, t * 3); - this.buffer.bind({ - endreached: function(n) { - r.trigger("endreached", { - index: n.index - }) - }, - prefetching: function(n) { - r.trigger("prefetching", { - skip: n.skip, - take: n.take - }) - }, - prefetched: function(n) { - r.trigger("prefetched", { - skip: n.skip, - take: n.take - }) - }, - reset: function() { - r._total = 0; - r.trigger("reset") - }, - resize: function() { - r._total = Math.ceil(this.length / r.batchSize); - r.trigger("resize", { - total: r.total(), - offset: this.offset - }) - } - }) - }, - syncDataSource: function() { - this.buffer.syncDataSource() - }, - at: function(n) { - var i = this.buffer, - f = n * this.batchSize, - o = this.batchSize, - e = [], - u, r; - for (i.offset > f && i.at(i.offset - 1), r = 0; r < o; r++) { - if (u = i.at(f + r), u === t) break; - e.push(u) - } - return e - }, - total: function() { - return this._total - }, - destroy: function() { - this.buffer.destroy(); - this.unbind() - } - }); - e(!0, i.data, { - readers: { - json: ti - }, - Query: u, - DataSource: h, - HierarchicalDataSource: w, - Node: ui, - ObservableObject: s, - ObservableArray: p, - LocalTransport: gi, - RemoteTransport: nr, - Cache: ut, - DataReader: ti, - Model: c, - Buffer: fi, - BatchBuffer: yr - }) - }(window.kendo.jQuery); -kendo_module({ - id: "validator", - name: "Validator", - category: "web", - description: "The Validator offers an easy way to do a client-side form validation.", - depends: ["core"] - }), - function(n) { - function nt(i) { - var r = t.ui.validator.ruleResolvers || {}, - u = {}; - for (var f in r) n.extend(!0, u, r[f].resolve(i)); - return u - } - - function tt(n) { - return n.replace(/&/g, "&").replace(/"/g, '"').replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">") - } - - function it(n) { - return (n = (n + "").split("."), n.length > 1) ? n[1].length : 0 - } - - function rt(t) { - return n.parseHTML ? n(n.parseHTML(t)) : n(t) - } - var t = window.kendo, - f = t.ui.Widget, - i = ".kendoValidator", - u = "k-invalid-msg", - p = new RegExp(u, "i"), - w = "k-invalid", - b = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i, - k = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i, - r = ":input:not(:button,[type=submit],[type=reset],[disabled],[readonly])", - o = ":checkbox:not([disabled],[readonly])", - e = "[type=number],[type=range]", - s = "blur", - h = "name", - c = "form", - l = "novalidate", - d = n.proxy, - a = function(n, t) { - return typeof t == "string" && (t = new RegExp("^(?:" + t + ")$")), t.test(n) - }, - v = function(n, t, i) { - var r = n.val(); - return n.filter(t).length && r !== "" ? a(r, i) : !0 - }, - g = function(n, t) { - return n.length ? n[0].attributes[t] != null : !1 - }, - y; - t.ui.validator || (t.ui.validator = { - rules: {}, - messages: {} - }); - y = f.extend({ - init: function(i, r) { - var u = this, - e = nt(i); - r = r || {}; - r.rules = n.extend({}, t.ui.validator.rules, e.rules, r.rules); - r.messages = n.extend({}, t.ui.validator.messages, e.messages, r.messages); - f.fn.init.call(u, i, r); - u._errorTemplate = t.template(u.options.errorTemplate); - u.element.is(c) && u.element.attr(l, l); - u._errors = {}; - u._attachEvents() - }, - events: ["validate"], - options: { - name: "Validator", - errorTemplate: '<span class="k-widget k-tooltip k-tooltip-validation"><span class="k-icon k-warning"> <\/span> #=message#<\/span>', - messages: { - required: "{0} is required", - pattern: "{0} is not valid", - min: "{0} should be greater than or equal to {1}", - max: "{0} should be smaller than or equal to {1}", - step: "{0} is not valid", - email: "{0} is not valid email", - url: "{0} is not valid URL", - date: "{0} is not valid date" - }, - rules: { - required: function(n) { - var i = n.filter("[type=checkbox]").length && !n.is(":checked"), - t = n.val(); - return !(g(n, "required") && (t === "" || !t || i)) - }, - pattern: function(n) { - return n.filter("[type=text],[type=email],[type=url],[type=tel],[type=search],[type=password]").filter("[pattern]").length && n.val() !== "" ? a(n.val(), n.attr("pattern")) : !0 - }, - min: function(n) { - if (n.filter(e + ",[" + t.attr("type") + "=number]").filter("[min]").length && n.val() !== "") { - var i = parseFloat(n.attr("min")) || 0, - r = t.parseFloat(n.val()); - return i <= r - } - return !0 - }, - max: function(n) { - if (n.filter(e + ",[" + t.attr("type") + "=number]").filter("[max]").length && n.val() !== "") { - var i = parseFloat(n.attr("max")) || 0, - r = t.parseFloat(n.val()); - return i >= r - } - return !0 - }, - step: function(n) { - if (n.filter(e + ",[" + t.attr("type") + "=number]").filter("[step]").length && n.val() !== "") { - var f = parseFloat(n.attr("min")) || 0, - i = parseFloat(n.attr("step")) || 1, - o = parseFloat(n.val()), - r = it(i), - u; - return r ? (u = Math.pow(10, r), (o - f) * u % (i * u) / Math.pow(100, r) == 0) : (o - f) % i == 0 - } - return !0 - }, - email: function(n) { - return v(n, "[type=email],[" + t.attr("type") + "=email]", b) - }, - url: function(n) { - return v(n, "[type=url],[" + t.attr("type") + "=url]", k) - }, - date: function(n) { - return n.filter("[type^=date],[" + t.attr("type") + "=date]").length && n.val() !== "" ? t.parseDate(n.val(), n.attr(t.attr("format"))) !== null : !0 - } - }, - validateOnBlur: !0 - }, - destroy: function() { - f.fn.destroy.call(this); - this.element.off(i) - }, - _submit: function(n) { - return this.validate() ? !0 : (n.stopPropagation(), n.stopImmediatePropagation(), n.preventDefault(), !1) - }, - _attachEvents: function() { - var t = this; - if (t.element.is(c)) t.element.on("submit" + i, d(t._submit, t)); - if (t.options.validateOnBlur) - if (t.element.is(r)) { - t.element.on(s + i, function() { - t.validateInput(t.element) - }); - if (t.element.is(o)) t.element.on("click" + i, function() { - t.validateInput(t.element) - }) - } else { - t.element.on(s + i, r, function() { - t.validateInput(n(this)) - }); - t.element.on("click" + i, o, function() { - t.validateInput(n(this)) - }) - } - }, - validate: function() { - var i, n, t = !1, - f, u; - if (this._errors = {}, this.element.is(r)) t = this.validateInput(this.element); - else { - for (u = !1, i = this.element.find(r), n = 0, f = i.length; n < f; n++) this.validateInput(i.eq(n)) || (u = !0); - t = !u - } - return this.trigger("validate", { - valid: t - }), t - }, - validateInput: function(t) { - var r; - t = n(t); - var i = this, - c = i._errorTemplate, - s = i._checkValidity(t), - f = s.valid, - l = "." + u, - e = t.attr(h) || "", - a = i._findMessageContainer(e).add(t.next(l)).hide(), - o; - return t.removeAttr("aria-invalid"), f || (o = i._extractMessage(t, s.key), i._errors[e] = o, r = rt(c({ - message: tt(o) - })), i._decorateMessageContainer(r, e), a.replaceWith(r).length || r.insertAfter(t), r.show(), t.attr("aria-invalid", !0)), t.toggleClass(w, !f), f - }, - hideMessages: function() { - var i = this, - t = "." + u, - n = i.element; - n.is(r) ? n.next(t).hide() : n.find(t).hide() - }, - _findMessageContainer: function(i) { - for (var u, h, e = t.ui.validator.messageLocators, o, r = n(), s = this.element[0].getElementsByTagName("*"), f = 0, c = s.length; f < c; f++) u = s[f], p.test(u.className) && (h = u.getAttribute(t.attr("for")), h === i && (r = r.add(u))); - for (o in e) r = r.add(e[o].locate(this.element, i)); - return r - }, - _decorateMessageContainer: function(n, i) { - var r = t.ui.validator.messageLocators, - f; - n.addClass(u).attr(t.attr("for"), i || ""); - for (f in r) r[f].decorate(n, i); - n.attr("role", "alert") - }, - _extractMessage: function(n, i) { - var u = this, - r = u.options.messages[i], - f = n.attr(h); - return r = t.isFunction(r) ? r(n) : r, t.format(n.attr(t.attr(i + "-msg")) || n.attr("validationMessage") || n.attr("title") || r || "", f, n.attr(i)) - }, - _checkValidity: function(n) { - var t = this.options.rules; - for (var i in t) - if (!t[i](n)) return { - valid: !1, - key: i - }; - return { - valid: !0 - } - }, - errors: function() { - var n = [], - t = this._errors; - for (var i in t) n.push(t[i]); - return n - } - }); - t.ui.plugin(y) - }(window.kendo.jQuery); -kendo_module({ - id: "userevents", - name: "User Events", - category: "framework", - depends: ["core"], - hidden: !0 - }), - function(n) { - function it(n, t) { - var i = n.x.location, - r = n.y.location, - u = t.x.location, - f = t.y.location, - e = i - u, - o = r - f; - return { - center: { - x: (i + u) / 2, - y: (r + f) / 2 - }, - distance: Math.sqrt(e * e + o * o) - } - } - - function h(n) { - var t = [], - r = n.originalEvent, - f = n.currentTarget, - e = 0, - s, o, u; - if (n.api) t.push({ - id: 2, - event: n, - target: n.target, - currentTarget: n.target, - location: n - }); - else if (n.type.match(/touch/)) - for (o = r ? r.changedTouches : [], s = o.length; e < s; e++) u = o[e], t.push({ - location: u, - event: n, - target: u.target, - currentTarget: f, - id: u.identifier - }); - else i.pointers || i.msPointers ? t.push({ - location: r, - event: n, - target: n.target, - currentTarget: f, - id: r.pointerId - }) : t.push({ - id: 1, - event: n, - target: n.target, - currentTarget: f, - location: n - }); - return t - } - - function ct(t) { - var i, r, u; - t.preventDefault(); - i = n(t.data.root); - r = i.closest(".k-widget").parent(); - r[0] || (r = i.parent()); - u = n.extend(!0, {}, t, { - target: i[0] - }); - r.trigger(n.Event(t.type, u)) - } - - function ut(n) { - for (var r = t.eventMap.up.split(" "), i = 0, u = r.length; i < u; i++) n(r[i]) - } - var t = window.kendo, - i = t.support, - ft = window.document, - c = t.Class, - l = t.Observable, - u = n.now, - f = n.extend, - a = i.mobileOS, - et = a && a.android, - v = 800, - ot = i.browser.msie ? 5 : 0, - y = "press", - p = "hold", - w = "select", - b = "start", - e = "move", - o = "end", - k = "cancel", - s = "tap", - d = "release", - st = "gesturestart", - g = "gesturechange", - nt = "gestureend", - tt = "gesturetap", - rt = c.extend({ - init: function(n, t) { - var i = this; - i.axis = n; - i._updateLocationData(t); - i.startLocation = i.location; - i.velocity = i.delta = 0; - i.timeStamp = u() - }, - move: function(n) { - var t = this, - i = n["page" + t.axis], - r = u(), - f = r - t.timeStamp || 1; - (i || !et) && (t.delta = i - t.location, t._updateLocationData(n), t.initialDelta = i - t.startLocation, t.velocity = t.delta / f, t.timeStamp = r) - }, - _updateLocationData: function(n) { - var t = this, - i = t.axis; - t.location = n["page" + i]; - t.client = n["client" + i]; - t.screen = n["screen" + i] - } - }), - ht = c.extend({ - init: function(n, t, i) { - var r = this; - f(r, { - x: new rt("X", i.location), - y: new rt("Y", i.location), - userEvents: n, - target: t, - currentTarget: i.currentTarget, - initialTouch: i.target, - id: i.id, - _moved: !1, - _finished: !1 - }); - r.press = function() { - r._trigger(y, i); - r._holdTimeout = setTimeout(function() { - r._trigger(p, i) - }, n.minHold) - } - }, - move: function(n) { - var t = this; - if (!t._finished) { - if (t.x.move(n.location), t.y.move(n.location), !t._moved) { - if (t._withinIgnoreThreshold()) return; - if (r.current && r.current !== t.userEvents) return t.dispose(); - t._start(n) - } - t._finished || t._trigger(e, n) - } - }, - end: function(n) { - var t = this; - (t.endTime = u(), t._finished) || (t._finished = !0, t._moved ? t._trigger(o, n) : t._trigger(s, n), clearTimeout(t._holdTimeout), t._trigger(d, n), t.dispose()) - }, - dispose: function() { - var t = this, - r = t.userEvents, - i = r.touches; - t._finished = !0; - i.splice(n.inArray(t, i), 1) - }, - skip: function() { - this.dispose() - }, - cancel: function() { - this.dispose() - }, - isMoved: function() { - return this._moved - }, - _start: function(n) { - clearTimeout(this._holdTimeout); - this.startTime = u(); - this._moved = !0; - this._trigger(b, n) - }, - _trigger: function(n, t) { - var i = this, - r = t.event, - u = { - touch: i, - x: i.x, - y: i.y, - target: i.target, - event: r - }; - i.userEvents.notify(n, u) && r.preventDefault() - }, - _withinIgnoreThreshold: function() { - var n = this.x.initialDelta, - t = this.y.initialDelta; - return Math.sqrt(n * n + t * t) <= this.userEvents.threshold - } - }), - r = l.extend({ - init: function(r, u) { - var h = this, - a, c = t.guid(), - it, rt; - u = u || {}; - a = h.filter = u.filter; - h.threshold = u.threshold || ot; - h.minHold = u.minHold || v; - h.touches = []; - h._maxTouches = u.multiTouch ? 2 : 1; - h.allowSelection = u.allowSelection; - h.captureUpIfMoved = u.captureUpIfMoved; - h.eventNS = c; - r = n(r).handler(h); - l.fn.init.call(h); - f(h, { - element: r, - surface: u.global ? n(ft.documentElement) : n(u.surface || r), - stopPropagation: u.stopPropagation, - pressed: !1 - }); - h.surface.handler(h).on(t.applyEventMap("move", c), "_move").on(t.applyEventMap("up cancel", c), "_end"); - r.on(t.applyEventMap("down", c), a, "_start"); - if ((i.pointers || i.msPointers) && r.css("-ms-touch-action", "pinch-zoom double-tap-zoom"), u.preventDragEvent) r.on(t.applyEventMap("dragstart", c), t.preventDefault); - r.on(t.applyEventMap("mousedown selectstart", c), a, { - root: r - }, "_select"); - h.captureUpIfMoved && i.eventCapture && (it = h.surface[0], rt = n.proxy(h.preventIfMoving, h), ut(function(n) { - it.addEventListener(n, rt, !0) - })); - h.bind([y, p, s, b, e, o, d, k, st, g, nt, tt, w], u) - }, - preventIfMoving: function(n) { - this._isMoved() && n.preventDefault() - }, - destroy: function() { - var n = this, - t; - n._destroyed || (n._destroyed = !0, n.captureUpIfMoved && i.eventCapture && (t = n.surface[0], ut(function(i) { - t.removeEventListener(i, n.preventIfMoving) - })), n.element.kendoDestroy(n.eventNS), n.surface.kendoDestroy(n.eventNS), n.element.removeData("handler"), n.surface.removeData("handler"), n._disposeAll(), n.unbind(), delete n.surface, delete n.element) - }, - capture: function() { - r.current = this - }, - cancel: function() { - this._disposeAll(); - this.trigger(k) - }, - notify: function(n, t) { - var r = this, - i = r.touches; - if (this._isMultiTouch()) { - switch (n) { - case e: - n = g; - break; - case o: - n = nt; - break; - case s: - n = tt - } - f(t, { - touches: i - }, it(i[0], i[1])) - } - return this.trigger(n, t) - }, - press: function(n, t, i) { - this._apiCall("_start", n, t, i) - }, - move: function(n, t) { - this._apiCall("_move", n, t) - }, - end: function(n, t) { - this._apiCall("_end", n, t) - }, - _isMultiTouch: function() { - return this.touches.length > 1 - }, - _maxTouchesReached: function() { - return this.touches.length >= this._maxTouches - }, - _disposeAll: function() { - for (var n = this.touches; n.length > 0;) n.pop().dispose() - }, - _isMoved: function() { - return n.grep(this.touches, function(n) { - return n.isMoved() - }).length - }, - _select: function(n) { - (!this.allowSelection || this.trigger(w, { - event: n - })) && ct(n) - }, - _start: function(t) { - var i = this, - f = 0, - s = i.filter, - e, o = h(t), - c = o.length, - u; - if (!i._maxTouchesReached()) - for (r.current = null, i.currentTarget = t.currentTarget, i.stopPropagation && t.stopPropagation(); f < c; f++) { - if (i._maxTouchesReached()) break; - (u = o[f], e = s ? n(u.currentTarget) : i.element, e.length) && (u = new ht(i, e, u), i.touches.push(u), u.press(), i._isMultiTouch() && i.notify("gesturestart", {})) - } - }, - _move: function(n) { - this._eachTouch("move", n) - }, - _end: function(n) { - this._eachTouch("end", n) - }, - _eachTouch: function(n, t) { - for (var c = this, e = {}, o = h(t), s = c.touches, r, u, f, i = 0; i < s.length; i++) r = s[i], e[r.id] = r; - for (i = 0; i < o.length; i++) u = o[i], f = e[u.id], f && f[n](u) - }, - _apiCall: function(t, i, r, u) { - this[t]({ - api: !0, - pageX: i, - pageY: r, - clientX: i, - clientY: r, - target: u || this.element, - stopPropagation: n.noop, - preventDefault: n.noop - }) - } - }); - r.minHold = function(n) { - v = n - }; - t.getTouches = h; - t.touchDelta = it; - t.UserEvents = r - }(window.kendo.jQuery); -kendo_module({ - id: "draganddrop", - name: "Drag & drop", - category: "framework", - description: "Drag & drop functionality for any DOM element.", - depends: ["core", "userevents"] - }), - function(n, t) { - function dt(t, i) { - try { - return n.contains(t, i) || t == i - } catch (r) { - return !1 - } - } - - function g(n) { - return kt ? l.elementFromPoint(n.x.screen, n.y.screen) : l.elementFromPoint(n.x.client, n.y.client) - } - - function w(n, t) { - return parseInt(n.css(t), 10) || 0 - } - - function st(n, t) { - return Math.min(Math.max(n, t.min), t.max) - } - - function ht(n, t) { - var i = b(n), - r = i.left + w(n, "borderLeftWidth") + w(n, "paddingLeft"), - u = i.top + w(n, "borderTopWidth") + w(n, "paddingTop"), - f = r + n.width() - t.outerWidth(!0), - e = u + n.height() - t.outerHeight(!0); - return { - x: { - min: r, - max: f - }, - y: { - min: u, - max: e - } - } - } - - function gt(n, i, r) { - for (var f, e, u = 0, o = i && i.length, s = r && r.length; n && n.parentNode;) { - for (u = 0; u < o; u++) - if (f = i[u], f.element[0] === n) return { - target: f, - targetElement: n - }; - for (u = 0; u < s; u++) - if (e = r[u], v.matchesSelector.call(n, e.options.filter)) return { - target: e, - targetElement: n - }; - n = n.parentNode - } - return t - } - var i = window.kendo, - v = i.support, - l = window.document, - pt = i.Class, - o = i.ui.Widget, - u = i.Observable, - wt = i.UserEvents, - f = n.proxy, - r = n.extend, - b = i.getOffset, - y = {}, - s = {}, - h = {}, - e, k = v.mobileOS, - bt = k && k.android, - kt = bt && k.browser == "chrome", - tt = "keyup", - a = "change", - it = "dragstart", - rt = "hold", - ut = "drag", - ft = "dragend", - et = "dragcancel", - d = "dragenter", - p = "dragleave", - ot = "drop", - ni = u.extend({ - init: function(t, r) { - var e = this, - o = t[0]; - e.capture = !1; - o.addEventListener ? (n.each(i.eventMap.down.split(" "), function() { - o.addEventListener(this, f(e._press, e), !0) - }), n.each(i.eventMap.up.split(" "), function() { - o.addEventListener(this, f(e._release, e), !0) - })) : (n.each(i.eventMap.down.split(" "), function() { - o.attachEvent(this, f(e._press, e)) - }), n.each(i.eventMap.up.split(" "), function() { - o.attachEvent(this, f(e._release, e)) - })); - u.fn.init.call(e); - e.bind(["press", "release"], r || {}) - }, - captureNext: function() { - this.capture = !0 - }, - cancelCapture: function() { - this.capture = !1 - }, - _press: function(n) { - var t = this; - t.trigger("press"); - t.capture && n.preventDefault() - }, - _release: function(n) { - var t = this; - t.trigger("release"); - t.capture && (n.preventDefault(), t.cancelCapture()) - } - }), - ct = u.extend({ - init: function(t) { - var i = this; - u.fn.init.call(i); - i.forcedEnabled = !1; - n.extend(i, t); - i.scale = 1; - i.horizontal ? (i.measure = "offsetWidth", i.scrollSize = "scrollWidth", i.axis = "x") : (i.measure = "offsetHeight", i.scrollSize = "scrollHeight", i.axis = "y") - }, - makeVirtual: function() { - n.extend(this, { - virtual: !0, - forcedEnabled: !0, - _virtualMin: 0, - _virtualMax: 0 - }) - }, - virtualSize: function(n, t) { - (this._virtualMin !== n || this._virtualMax !== t) && (this._virtualMin = n, this._virtualMax = t, this.update()) - }, - outOfBounds: function(n) { - return n > this.max || n < this.min - }, - forceEnabled: function() { - this.forcedEnabled = !0 - }, - getSize: function() { - return this.container[0][this.measure] - }, - getTotal: function() { - return this.element[0][this.scrollSize] - }, - rescale: function(n) { - this.scale = n - }, - update: function(n) { - var t = this, - u = t.virtual ? t._virtualMax : t.getTotal(), - r = u * t.scale, - i = t.getSize(); - t.max = t.virtual ? -t._virtualMin : 0; - t.size = i; - t.total = r; - t.min = Math.min(t.max, i - r); - t.minScale = i / u; - t.centerOffset = (r - i) / 2; - t.enabled = t.forcedEnabled || r > i; - n || t.trigger(a, t) - } - }), - ti = u.extend({ - init: function(n) { - var t = this; - u.fn.init.call(t); - t.x = new ct(r({ - horizontal: !0 - }, n)); - t.y = new ct(r({ - horizontal: !1 - }, n)); - t.container = n.container; - t.forcedMinScale = n.minScale; - t.maxScale = n.maxScale || 100; - t.bind(a, n) - }, - rescale: function(n) { - this.x.rescale(n); - this.y.rescale(n); - this.refresh() - }, - centerCoordinates: function() { - return { - x: Math.min(0, -this.x.centerOffset), - y: Math.min(0, -this.y.centerOffset) - } - }, - refresh: function() { - var n = this; - n.x.update(); - n.y.update(); - n.enabled = n.x.enabled || n.y.enabled; - n.minScale = n.forcedMinScale || Math.min(n.x.minScale, n.y.minScale); - n.fitScale = Math.max(n.x.minScale, n.y.minScale); - n.trigger(a) - } - }), - lt = u.extend({ - init: function(n) { - var t = this; - r(t, n); - u.fn.init.call(t) - }, - dragMove: function(n) { - var t = this, - i = t.dimension, - r = t.axis, - u = t.movable, - f = u[r] + n; - i.enabled && ((f < i.min && n < 0 || f > i.max && n > 0) && (n *= t.resistance), u.translateAxis(r, n), t.trigger(a, t)) - } - }), - ii = pt.extend({ - init: function(n) { - var t = this, - u, f, e, i; - r(t, { - elastic: !0 - }, n); - e = t.elastic ? .5 : 0; - i = t.movable; - t.x = u = new lt({ - axis: "x", - dimension: t.dimensions.x, - resistance: e, - movable: i - }); - t.y = f = new lt({ - axis: "y", - dimension: t.dimensions.y, - resistance: e, - movable: i - }); - t.userEvents.bind(["move", "end", "gesturestart", "gesturechange"], { - gesturestart: function(n) { - t.gesture = n; - t.offset = t.dimensions.container.offset() - }, - gesturechange: function(n) { - var h = t.gesture, - c = h.center, - l = n.center, - r = n.distance / h.distance, - v = t.dimensions.minScale, - a = t.dimensions.maxScale, - e, o, s; - i.scale <= v && r < 1 && (r += (1 - r) * .8); - i.scale * r >= a && (r = a / i.scale); - o = i.x + t.offset.left; - s = i.y + t.offset.top; - e = { - x: (o - c.x) * r + l.x - o, - y: (s - c.y) * r + l.y - s - }; - i.scaleWith(r); - u.dragMove(e.x); - f.dragMove(e.y); - t.dimensions.rescale(i.scale); - t.gesture = n; - n.preventDefault() - }, - move: function(n) { - n.event.target.tagName.match(/textarea|input/i) || (u.dimension.enabled || f.dimension.enabled ? (u.dragMove(n.x.delta), f.dragMove(n.y.delta), n.preventDefault()) : n.touch.skip()) - }, - end: function(n) { - n.preventDefault() - } - }) - } - }), - ri = v.transitions.prefix + "Transform", - nt, at, c, vt, yt; - nt = v.hasHW3D ? function(n, t, i) { - return "translate3d(" + n + "px," + t + "px,0) scale(" + i + ")" - } : function(n, t, i) { - return "translate(" + n + "px," + t + "px) scale(" + i + ")" - }; - at = u.extend({ - init: function(t) { - var i = this; - u.fn.init.call(i); - i.element = n(t); - i.element[0].style.webkitTransformOrigin = "left top"; - i.x = 0; - i.y = 0; - i.scale = 1; - i._saveCoordinates(nt(i.x, i.y, i.scale)) - }, - translateAxis: function(n, t) { - this[n] += t; - this.refresh() - }, - scaleTo: function(n) { - this.scale = n; - this.refresh() - }, - scaleWith: function(n) { - this.scale *= n; - this.refresh() - }, - translate: function(n) { - this.x += n.x; - this.y += n.y; - this.refresh() - }, - moveAxis: function(n, t) { - this[n] = t; - this.refresh() - }, - moveTo: function(n) { - r(this, n); - this.refresh() - }, - refresh: function() { - var n = this, - r = n.x, - u = n.y, - t; - n.round && (r = Math.round(r), u = Math.round(u)); - t = nt(r, u, n.scale); - t != n.coordinates && (i.support.browser.msie && i.support.browser.version < 10 ? (n.element[0].style.position = "absolute", n.element[0].style.left = n.x + "px", n.element[0].style.top = n.y + "px") : n.element[0].style[ri] = t, n._saveCoordinates(t), n.trigger(a)) - }, - _saveCoordinates: function(n) { - this.coordinates = n - } - }); - c = o.extend({ - init: function(n, t) { - var i = this, - r; - o.fn.init.call(i, n, t); - r = i.options.group; - r in s ? s[r].push(i) : s[r] = [i] - }, - events: [d, p, ot], - options: { - name: "DropTarget", - group: "default" - }, - destroy: function() { - var i = this.options.group, - t = s[i] || h[i], - n; - if (t.length > 1) { - for (o.fn.destroy.call(this), n = 0; n < t.length; n++) - if (t[n] == this) { - t.splice(n, 1); - break - } - } else c.destroyGroup(i) - }, - _trigger: function(n, t) { - var i = this, - u = y[i.options.group]; - if (u) return i.trigger(n, r({}, t.event, { - draggable: u, - dropTarget: t.dropTarget - })) - }, - _over: function(n) { - this._trigger(d, n) - }, - _out: function(n) { - this._trigger(p, n) - }, - _drop: function(n) { - var t = this, - i = y[t.options.group]; - i && (i.dropped = !t._trigger(ot, n)) - } - }); - c.destroyGroup = function(n) { - var t = s[n] || h[n], - i; - if (t) { - for (i = 0; i < t.length; i++) o.fn.destroy.call(t[i]); - t.length = 0; - delete s[n]; - delete h[n] - } - }; - c._cache = s; - vt = c.extend({ - init: function(n, t) { - var i = this, - r; - o.fn.init.call(i, n, t); - r = i.options.group; - r in h ? h[r].push(i) : h[r] = [i] - }, - options: { - name: "DropTargetArea", - group: "default", - filter: null - } - }); - yt = o.extend({ - init: function(n, t) { - var r = this; - o.fn.init.call(r, n, t); - r._activated = !1; - r.userEvents = new wt(r.element, { - global: !0, - stopPropagation: !0, - filter: r.options.filter, - threshold: r.options.distance, - start: f(r._start, r), - hold: f(r._hold, r), - move: f(r._drag, r), - end: f(r._end, r), - cancel: f(r._cancel, r) - }); - r._afterEndHandler = f(r._afterEnd, r); - r.captureEscape = function(n) { - n.keyCode === i.keys.ESC && (r._trigger(et, { - event: n - }), r.userEvents.cancel()) - } - }, - events: [rt, it, ut, ft, et], - options: { - name: "Draggable", - distance: 5, - group: "default", - cursorOffset: null, - axis: null, - container: null, - holdToDrag: !1, - dropped: !1 - }, - cancelHold: function() { - this._activated = !1 - }, - _updateHint: function(t) { - var r = this, - i, o = r.options, - u = r.boundaries, - e = o.axis, - f = r.options.cursorOffset; - f ? i = { - left: t.x.location + f.left, - top: t.y.location + f.top - } : (r.hintOffset.left += t.x.delta, r.hintOffset.top += t.y.delta, i = n.extend({}, r.hintOffset)); - u && (i.top = st(i.top, u.y), i.left = st(i.left, u.x)); - e === "x" ? delete i.top : e === "y" && delete i.left; - r.hint.css(i) - }, - _start: function(t) { - var r = this, - u = r.options, - o = u.container, - f = u.hint, - e; - if (u.holdToDrag && !r._activated) { - r.userEvents.cancel(); - return - } - r.currentTarget = t.target; - r.currentTargetOffset = b(r.currentTarget); - f && (r.hint && r.hint.stop(!0, !0).remove(), r.hint = i.isFunction(f) ? n(f.call(r, r.currentTarget)) : f, e = b(r.currentTarget), r.hintOffset = e, r.hint.css({ - position: "absolute", - zIndex: 2e4, - left: e.left, - top: e.top - }).appendTo(l.body)); - y[u.group] = r; - r.dropped = !1; - o && (r.boundaries = ht(o, r.hint)); - r._trigger(it, t) && (r.userEvents.cancel(), r._afterEnd()); - n(l).on(tt, r.captureEscape) - }, - _hold: function(n) { - this.currentTarget = n.target; - this._trigger(rt, n) ? this.userEvents.cancel() : this._activated = !0 - }, - _drag: function(t) { - var i = this; - t.preventDefault(); - i._withDropTarget(t, function(i, u) { - if (!i) { - e && (e._trigger(p, r(t, { - dropTarget: n(e.targetElement) - })), e = null); - return - } - if (e) { - if (u === e.targetElement) return; - e._trigger(p, r(t, { - dropTarget: n(e.targetElement) - })) - } - i._trigger(d, r(t, { - dropTarget: n(u) - })); - e = r(i, { - targetElement: u - }) - }); - i._trigger(ut, t); - i.hint && i._updateHint(t) - }, - _end: function(t) { - var i = this; - i._withDropTarget(t, function(i, u) { - i && (i._drop(r({}, t, { - dropTarget: n(u) - })), e = null) - }); - i._trigger(ft, t); - i._cancel(t.event) - }, - _cancel: function() { - var n = this; - n._activated = !1; - n.hint && !n.dropped ? setTimeout(function() { - n.hint.stop(!0, !0).animate(n.currentTargetOffset, "fast", n._afterEndHandler) - }, 0) : n._afterEnd() - }, - _trigger: function(n, t) { - var i = this; - return i.trigger(n, r({}, t.event, { - x: t.x, - y: t.y, - currentTarget: i.currentTarget, - dropTarget: t.dropTarget - })) - }, - _withDropTarget: function(n, t) { - var r = this, - i, u, o = r.options, - f = s[o.group], - e = h[o.group]; - (f && f.length || e && e.length) && (i = g(n), r.hint && dt(r.hint[0], i) && (r.hint.hide(), i = g(n), i || (i = g(n)), r.hint.show()), u = gt(i, f, e), u ? t(u.target, u.targetElement) : t()) - }, - destroy: function() { - var n = this; - o.fn.destroy.call(n); - n._afterEnd(); - n.userEvents.destroy() - }, - _afterEnd: function() { - var t = this; - t.hint && t.hint.remove(); - delete y[t.options.group]; - t.trigger("destroy"); - n(l).off(tt, t.captureEscape) - } - }); - i.ui.plugin(c); - i.ui.plugin(vt); - i.ui.plugin(yt); - i.TapCapture = ni; - i.containerBoundaries = ht; - r(i.ui, { - Pane: ii, - PaneDimensions: ti, - Movable: at - }) - }(window.kendo.jQuery); -kendo_module({ - id: "reorderable", - name: "Reorderable", - category: "framework", - depends: ["core", "draganddrop"], - advanced: !0 - }), - function(n) { - function u(t, i) { - t = n(t); - i ? t.find(".k-drag-status").removeClass("k-add").addClass("k-denied") : t.find(".k-drag-status").removeClass("k-denied").addClass("k-add") - } - var t = window.kendo, - i = t.ui.Widget, - r = "change", - f = "k-reorderable", - e = i.extend({ - init: function(e, o) { - var s = this, - h, c = t.guid() + "-reorderable"; - i.fn.init.call(s, e, o); - e = s.element.addClass(f); - o = s.options; - s.draggable = h = o.draggable || new t.ui.Draggable(e, { - group: c, - filter: o.filter, - hint: o.hint - }); - s.reorderDropCue = n('<div class="k-reorder-cue"><div class="k-icon k-i-arrow-s"><\/div><div class="k-icon k-i-arrow-n"><\/div><\/div>'); - e.find(h.options.filter).kendoDropTarget({ - group: h.options.group, - dragenter: function(n) { - if (s._draggable) { - var i = this.element, - r, f = i[0] === s._draggable[0]; - u(n.draggable.hint, f); - f || (r = t.getOffset(i), s.reorderDropCue.css({ - height: i.outerHeight(), - top: r.top, - left: r.left + (i.index() > s._draggable.index() ? i.outerWidth() : 0) - }).appendTo(document.body)) - } - }, - dragleave: function(n) { - u(n.draggable.hint, !0); - s.reorderDropCue.remove() - }, - drop: function() { - if (s._draggable) { - var t = s._draggable[0], - i = this.element[0], - n; - t !== i && (n = e.find(h.options.filter), s.trigger(r, { - element: s._draggable, - oldIndex: n.index(t), - newIndex: n.index(i) - })) - } - } - }); - h.bind(["dragcancel", "dragend", "dragstart"], { - dragcancel: function() { - s.reorderDropCue.remove(); - s._draggable = null - }, - dragend: function() { - s.reorderDropCue.remove(); - s._draggable = null - }, - dragstart: function(n) { - s._draggable = n.currentTarget - } - }) - }, - options: { - name: "Reorderable", - filter: "*" - }, - events: [r], - destroy: function() { - var n = this; - i.fn.destroy.call(n); - n.draggable && n.draggable.destroy(); - t.destroy(n.element) - } - }); - t.ui.plugin(e) - }(window.kendo.jQuery); -kendo_module({ - id: "resizable", - name: "Resizable", - category: "framework", - depends: ["core", "draganddrop"], - advanced: !0 - }), - function(n, t) { - var u = window.kendo, - o = u.ui, - f = o.Widget, - r = n.proxy, - e = u.isFunction, - s = n.extend, - i = "horizontal", - h = "vertical", - c = "start", - l = "resize", - a = "resizeend", - v = f.extend({ - init: function(n, t) { - var u = this; - f.fn.init.call(u, n, t); - u.orientation = u.options.orientation.toLowerCase() != h ? i : h; - u._positionMouse = u.orientation == i ? "x" : "y"; - u._position = u.orientation == i ? "left" : "top"; - u._sizingDom = u.orientation == i ? "outerWidth" : "outerHeight"; - u.draggable = new o.Draggable(n, { - distance: 0, - filter: t.handle, - drag: r(u._resize, u), - dragcancel: r(u._cancel, u), - dragstart: r(u._start, u), - dragend: r(u._stop, u) - }); - u.userEvents = u.draggable.userEvents - }, - events: [l, a, c], - options: { - name: "Resizable", - orientation: i - }, - resize: function() {}, - _max: function(n) { - var i = this, - u = i.hint ? i.hint[i._sizingDom]() : 0, - r = i.options.max; - return e(r) ? r(n) : r !== t ? i._initialElementPosition + r - u : r - }, - _min: function(n) { - var r = this, - i = r.options.min; - return e(i) ? i(n) : i !== t ? r._initialElementPosition + i : i - }, - _start: function(t) { - var i = this, - r = i.options.hint, - u = n(t.currentTarget); - i._initialElementPosition = u.position()[i._position]; - i._initialMousePosition = t[i._positionMouse].startLocation; - r && (i.hint = e(r) ? n(r(u)) : r, i.hint.css({ - position: "absolute" - }).css(i._position, i._initialElementPosition).appendTo(i.element)); - i.trigger(c, t); - i._maxPosition = i._max(t); - i._minPosition = i._min(t); - n(document.body).css("cursor", u.css("cursor")) - }, - _resize: function(n) { - var i = this, - u = i._maxPosition, - f = i._minPosition, - e = i._initialElementPosition + (n[i._positionMouse].location - i._initialMousePosition), - r; - r = f !== t ? Math.max(f, e) : e; - i.position = r = u !== t ? Math.min(u, r) : r; - i.hint && i.hint.toggleClass(i.options.invalidClass || "", r == u || r == f).css(i._position, r); - i.resizing = !0; - i.trigger(l, s(n, { - position: r - })) - }, - _stop: function(t) { - var i = this; - i.hint && i.hint.remove(); - i.resizing = !1; - i.trigger(a, s(t, { - position: i.position - })); - n(document.body).css("cursor", "") - }, - _cancel: function(n) { - var i = this; - i.hint && (i.position = t, i.hint.css(i._position, i._initialElementPosition), i._stop(n)) - }, - destroy: function() { - var n = this; - f.fn.destroy.call(n); - n.draggable && n.draggable.destroy() - }, - press: function(n) { - if (n) { - var t = n.position(), - i = this; - i.userEvents.press(t.left, t.top, n[0]); - i.targetPosition = t; - i.target = n - } - }, - move: function(n) { - var i = this, - f = i._position, - r = i.targetPosition, - u = i.position; - u === t && (u = r[f]); - r[f] = u + n; - i.userEvents.move(r.left, r.top) - }, - end: function() { - this.userEvents.end(); - this.target = this.position = t - } - }); - u.ui.plugin(v) - }(window.kendo.jQuery); -kendo_module({ - id: "sortable", - name: "Sortable", - category: "framework", - depends: ["data"], - advanced: !0 - }), - function(n, t) { - var i = window.kendo, - s = n.proxy, - r = "dir", - u = "asc", - h = "single", - c = "field", - f = "desc", - l = ".kendoSortable", - a = ".k-link", - e = "aria-sort", - o = i.ui.Widget, - v = o.extend({ - init: function(n, t) { - var i = this, - r; - o.fn.init.call(i, n, t); - i._refreshHandler = s(i.refresh, i); - i.dataSource = i.options.dataSource.bind("change", i._refreshHandler); - r = i.element.find(a); - r[0] || (r = i.element.wrapInner('<a class="k-link" href="#"/>').find(a)); - i.link = r; - i.element.on("click" + l, s(i._click, i)) - }, - options: { - name: "Sortable", - mode: h, - allowUnsort: !0, - compare: null, - filter: "" - }, - destroy: function() { - var n = this; - o.fn.destroy.call(n); - n.element.off(l); - n.dataSource.unbind("change", n._refreshHandler) - }, - refresh: function() { - var o = this, - a = o.dataSource.sort() || [], - s, v, h, l, t = o.element, - y = t.attr(i.attr(c)); - for (t.removeAttr(i.attr(r)), t.removeAttr(e), s = 0, v = a.length; s < v; s++) h = a[s], y == h.field && t.attr(i.attr(r), h.dir); - l = t.attr(i.attr(r)); - t.find(".k-i-arrow-n,.k-i-arrow-s").remove(); - l === u ? (n('<span class="k-icon k-i-arrow-n" />').appendTo(o.link), t.attr(e, "ascending")) : l === f && (n('<span class="k-icon k-i-arrow-s" />').appendTo(o.link), t.attr(e, "descending")) - }, - _click: function(n) { - var e = this, - v = e.element, - y = v.attr(i.attr(c)), - s = v.attr(i.attr(r)), - l = e.options, - p = e.options.compare == null ? t : e.options.compare, - o = e.dataSource.sort() || [], - a, w; - if (n.preventDefault(), !l.filter || v.is(l.filter)) { - if (s = s === u ? f : s === f && l.allowUnsort ? t : u, l.mode === h) o = [{ - field: y, - dir: s, - compare: p - }]; - else if (l.mode === "multiple") { - for (a = 0, w = o.length; a < w; a++) - if (o[a].field === y) { - o.splice(a, 1); - break - } - o.push({ - field: y, - dir: s, - compare: p - }) - } - e.dataSource.sort(o) - } - } - }); - i.ui.plugin(v) - }(window.kendo.jQuery); -kendo_module({ - id: "selectable", - name: "Selectable", - category: "framework", - depends: ["core", "userevents"], - advanced: !0 - }), - function(n) { - function y(n, t) { - var i = u.getOffset(n), - r = t.left + t.width, - f = t.top + t.height; - return i.right = i.left + n.outerWidth(), i.bottom = i.top + n.outerHeight(), !(i.left > r || i.right < t.left || i.top > f || i.bottom < t.top) - } - - function p(n, i, u, e) { - for (var o, s = 0, h = n.length; s < h; s++) o = n.eq(s), y(o, u) ? o.hasClass(t) ? e && i !== o[0] && o.removeClass(t).addClass(r) : o.hasClass(f) || o.hasClass(r) || o.addClass(f) : o.hasClass(f) ? o.removeClass(f) : e && o.hasClass(r) && o.removeClass(r).addClass(t) - } - var u = window.kendo, - s = u.ui.Widget, - i = n.proxy, - h = Math.abs, - c = "aria-selected", - t = "k-state-selected", - f = "k-state-selecting", - e = "k-selectable", - o = "change", - v = ".kendoSelectable", - r = "k-state-unselecting", - l = !1, - a; - (function(n) { - (function() { - n('<div class="parent"><span /><\/div>').on("click", ">*", function() { - l = !0 - }).find("span").click().end().off() - })() - })(n); - a = s.extend({ - init: function(t, r) { - var f = this, - o; - s.fn.init.call(f, t, r); - f._marquee = n("<div class='k-marquee'><div class='k-marquee-color'><\/div><\/div>"); - f._lastActive = null; - f.element.addClass(e); - o = f.options.multiple; - f.userEvents = new u.UserEvents(f.element, { - global: !0, - allowSelection: !0, - filter: (l ? "" : "." + e + " ") + f.options.filter, - tap: i(f._tap, f) - }); - o && f.userEvents.bind("start", i(f._start, f)).bind("move", i(f._move, f)).bind("end", i(f._end, f)).bind("select", i(f._select, f)) - }, - events: [o], - options: { - name: "Selectable", - filter: ">*", - multiple: !1 - }, - _tap: function(i) { - var u = n(i.target), - r = this, - f = i.event.ctrlKey || i.event.metaKey, - s = r.options.multiple, - a = s && i.event.shiftKey, - h, c = i.event.which, - l = i.event.button; - u.closest("." + e)[0] !== r.element[0] || c && c == 3 || l && l == 2 || (h = u.hasClass(t), s && f || r.clear(), a ? r.selectRange(r._firstSelectee(), u) : (h && f ? (r._unselect(u), r._notify(o)) : r.value(u), r._lastActive = r._downTarget = u)) - }, - _start: function(i) { - var u = this, - f = n(i.target), - s = f.hasClass(t), - o = i.event.ctrlKey || i.event.metaKey; - if (u._downTarget = f, f.closest("." + e)[0] !== u.element[0]) { - u.userEvents.cancel(); - u._downTarget = null; - return - } - u._marquee.appendTo(document.body).css({ - left: i.x.client + 1, - top: i.y.client + 1, - width: 0, - height: 0 - }); - o || u.clear(); - s && (u._selectElement(f, !0), o && f.addClass(r)) - }, - _move: function(n) { - var t = this, - i = { - left: n.x.startLocation > n.x.location ? n.x.location : n.x.startLocation, - top: n.y.startLocation > n.y.location ? n.y.location : n.y.startLocation, - width: h(n.x.initialDelta), - height: h(n.y.initialDelta) - }, - r = t.element.find(t.options.filter); - t._marquee.css(i); - p(r, t._downTarget[0], i, n.event.ctrlKey || n.event.metaKey); - n.preventDefault() - }, - _end: function() { - var n = this; - n._marquee.remove(); - n._unselect(n.element.find(n.options.filter + "." + r)).removeClass(r); - n.value(n.element.find(n.options.filter + "." + f)); - n._lastActive = n._downTarget - }, - value: function(n) { - var r = this, - u = i(r._selectElement, r); - if (n) { - n.each(function() { - u(this) - }); - r._notify(o); - return - } - return r.element.find(r.options.filter + "." + t) - }, - _firstSelectee: function() { - var n = this, - t; - return n._lastActive !== null ? n._lastActive : (t = n.value(), t.length > 0 ? t[0] : n.element.find(n.options.filter)) - }, - _selectElement: function(i, r) { - var u = n(i), - e = !r && this._notify("select", { - element: i - }); - u.removeClass(f); - e || (u.addClass(t), this.options.aria && u.attr(c, !0)) - }, - _notify: function(n, t) { - return t = t || {}, this.trigger(n, t) - }, - _unselect: function(n) { - return n.removeClass(t), this.options.aria && n.attr(c, !1), n - }, - _select: function(t) { - var i = "input,a,textarea,.k-multiselect-wrap,select", - r = u.support.browser.msie; - n(t.event.target).is(i) ? (this.userEvents.cancel(), this._downTarget = null) : r && (!r || n(u._activeElement()).is(i)) || t.preventDefault() - }, - clear: function() { - var n = this.element.find(this.options.filter + "." + t); - this._unselect(n) - }, - selectRange: function(r, u) { - var e = this, - s = !1, - h, l, a, f, v = e.element.find(e.options.filter), - c = i(e._selectElement, e); - for (r = n(r)[0], u = n(u)[0], h = 0, l = v.length; h < l; h++) f = v[h], s ? (c(f), s = f !== u) : f === r ? (s = r !== u, c(f)) : f === u ? (a = r, r = u, u = a, s = !0, c(f)) : n(f).removeClass(t); - e._notify(o) - }, - destroy: function() { - var n = this; - s.fn.destroy.call(n); - n.element.off(v); - n.userEvents.destroy() - } - }); - u.ui.plugin(a) - }(window.kendo.jQuery); -kendo_module({ - id: "button", - name: "Button", - category: "web", - description: "The Button widget displays styled buttons.", - depends: ["core"] - }), - function(n, t) { - var u = window.kendo, - o = u.ui.Widget, - i = n.proxy, - f = u.keys, - e = "click", - l = "k-button", - a = "k-button-icon", - v = "k-button-icontext", - r = ".kendoButton", - s = "disabled", - y = "k-state-disabled", - h = "k-state-focused", - c = "k-state-selected", - p = o.extend({ - init: function(n, t) { - var f = this; - o.fn.init.call(f, n, t); - n = f.wrapper = f.element; - t = f.options; - n.addClass(l).attr("role", "button"); - t.enable = t.enable && !n.attr(s); - f.enable(t.enable); - f._tabindex(); - f._graphics(); - n.on(e + r, i(f._click, f)).on("focus" + r, i(f._focus, f)).on("blur" + r, i(f._blur, f)).on("keydown" + r, i(f._keydown, f)).on("keyup" + r, i(f._keyup, f)); - u.notify(f) - }, - events: [e], - options: { - name: "Button", - icon: "", - spriteCssClass: "", - imageUrl: "", - enable: !0 - }, - _isNativeButton: function() { - return this.element.prop("tagName").toLowerCase() == "button" - }, - _click: function(n) { - this.options.enable && this.trigger(e, { - event: n - }) - }, - _focus: function() { - this.options.enable && this.element.addClass(h) - }, - _blur: function() { - this.element.removeClass(h) - }, - _keydown: function(n) { - var t = this; - t._isNativeButton() || (n.keyCode == f.ENTER || n.keyCode == f.SPACEBAR) && (n.keyCode == f.SPACEBAR && (n.preventDefault(), t.options.enable && t.element.addClass(c)), t._click(n)) - }, - _keyup: function() { - this.element.removeClass(c) - }, - _graphics: function() { - var h = this, - t = h.element, - u = h.options, - f = u.icon, - e = u.spriteCssClass, - o = u.imageUrl, - i, r, s; - (e || o || f) && (s = !0, t.contents().not("span.k-sprite").not("span.k-icon").not("img.k-image").each(function(t, i) { - (i.nodeType == 1 || i.nodeType == 3 && n.trim(i.nodeValue).length > 0) && (s = !1) - }), s ? t.addClass(a) : t.addClass(v)); - f ? (i = t.children("span.k-icon").first(), i[0] || (i = n('<span class="k-icon"><\/span>').prependTo(t)), i.addClass("k-i-" + f)) : e ? (i = t.children("span.k-sprite").first(), i[0] || (i = n('<span class="k-sprite"><\/span>').prependTo(t)), i.addClass(e)) : o && (r = t.children("img.k-image").first(), r[0] || (r = n('<img alt="icon" class="k-image" />').prependTo(t)), r.attr("src", o)) - }, - enable: function(n) { - var i = this, - r = i.element; - n === t && (n = !0); - n = !!n; - i.options.enable = n; - r.toggleClass(y, !n).attr("aria-disabled", !n).attr(s, !n) - } - }); - u.ui.plugin(p) - }(window.kendo.jQuery); -kendo_module({ - id: "pager", - name: "Pager", - category: "framework", - depends: ["data"], - advanced: !0 - }), - function(n, t) { - function v(n, t, r, u, f) { - return n({ - idx: t, - text: r, - ns: i.ns, - numeric: u, - title: f || "" - }) - } - - function e(n, t, i) { - return tt({ - className: n.substring(1), - text: t, - wrapClassName: i || "" - }) - } - - function o(n, t, r, u) { - n.find(t).parent().attr(i.attr("page"), r).attr("tabindex", -1).toggleClass("k-state-disabled", u) - } - - function w(n, t) { - o(n, h, 1, t <= 1) - } - - function b(n, t) { - o(n, l, Math.max(1, t - 1), t <= 1) - } - - function k(n, t, i) { - o(n, a, Math.min(i, t + 1), t >= i) - } - - function d(n, t, i) { - o(n, c, i, t >= i) - } - var i = window.kendo, - y = i.ui, - s = y.Widget, - u = n.proxy, - h = ".k-i-seek-w", - c = ".k-i-seek-e", - l = ".k-i-arrow-w", - a = ".k-i-arrow-e", - r = "change", - f = ".kendoPager", - p = "click", - g = "keydown", - nt = "disabled", - tt = i.template('<a href="\\#" title="#=text#" class="k-link k-pager-nav #= wrapClassName #"><span class="k-icon #= className #">#=text#<\/span><\/a>'), - it = s.extend({ - init: function(t, o) { - var v = this, - nt, y; - if (s.fn.init.call(v, t, o), o = v.options, v.dataSource = i.data.DataSource.create(o.dataSource), v.linkTemplate = i.template(v.options.linkTemplate), v.selectTemplate = i.template(v.options.selectTemplate), nt = v.page(), y = v.totalPages(), v._refreshHandler = u(v.refresh, v), v.dataSource.bind(r, v._refreshHandler), o.previousNext && (v.element.find(h).length || (v.element.append(e(h, o.messages.first, "k-pager-first")), w(v.element, nt, y)), v.element.find(l).length || (v.element.append(e(l, o.messages.previous)), b(v.element, nt, y))), o.numeric && (v.list = v.element.find(".k-pager-numbers"), v.list.length || (v.list = n('<ul class="k-pager-numbers k-reset" />').appendTo(v.element))), o.input) { - v.element.find(".k-pager-input").length || v.element.append('<span class="k-pager-input k-label">' + o.messages.page + '<input class="k-textbox">' + i.format(o.messages.of, y) + "<\/span>"); - v.element.on(g + f, ".k-pager-input input", u(v._keydown, v)) - } - if (o.previousNext && (v.element.find(a).length || (v.element.append(e(a, o.messages.next)), k(v.element, nt, y)), v.element.find(c).length || (v.element.append(e(c, o.messages.last, "k-pager-last")), d(v.element, nt, y))), o.pageSizes) { - v.element.find(".k-pager-sizes").length || n('<span class="k-pager-sizes k-label"><select/>' + o.messages.itemsPerPage + "<\/span>").appendTo(v.element).find("select").html(n.map(n.isArray(o.pageSizes) ? o.pageSizes : [5, 10, 20], function(n) { - return "<option>" + n + "<\/option>" - }).join("")).end().appendTo(v.element); - v.element.find(".k-pager-sizes select").val(v.pageSize()); - i.ui.DropDownList && v.element.find(".k-pager-sizes select").show().kendoDropDownList(); - v.element.on(r + f, ".k-pager-sizes select", u(v._change, v)) - } - if (o.refresh) { - v.element.find(".k-pager-refresh").length || v.element.append('<a href="#" class="k-pager-refresh k-link" title="' + o.messages.refresh + '"><span class="k-icon k-i-refresh">' + o.messages.refresh + "<\/span><\/a>"); - v.element.on(p + f, ".k-pager-refresh", u(v._refreshClick, v)) - } - o.info && (v.element.find(".k-pager-info").length || v.element.append('<span class="k-pager-info k-label" />')); - v.element.on(p + f, "a", u(v._click, v)).addClass("k-pager-wrap k-widget"); - o.autoBind && v.refresh(); - i.notify(v) - }, - destroy: function() { - var n = this; - s.fn.destroy.call(n); - n.element.off(f); - n.dataSource.unbind(r, n._refreshHandler); - i.destroy(n.element) - }, - events: [r], - options: { - name: "Pager", - selectTemplate: '<li><span class="k-state-selected">#=text#<\/span><\/li>', - linkTemplate: '<li><a tabindex="-1" href="\\#" class="k-link" data-#=ns#page="#=idx#" #if (title !== "") {# title="#=title#" #}#>#=text#<\/a><\/li>', - buttonCount: 10, - autoBind: !0, - numeric: !0, - info: !0, - input: !1, - previousNext: !0, - pageSizes: !1, - refresh: !1, - messages: { - display: "{0} - {1} of {2} items", - empty: "No items to display", - page: "Page", - of: "of {0}", - itemsPerPage: "items per page", - first: "Go to the first page", - previous: "Go to the previous page", - next: "Go to the next page", - last: "Go to the last page", - refresh: "Refresh", - morePages: "More pages" - } - }, - setDataSource: function(n) { - var t = this; - t.dataSource.unbind(r, t._refreshHandler); - t.dataSource = t.options.dataSource = n; - n.bind(r, t._refreshHandler); - t.options.autoBind && n.fetch() - }, - refresh: function(n) { - var t = this, - e, a, s = 1, - f = "", - y, r = t.page(), - u = t.options, - h = t.pageSize(), - c = t.dataSource.total(), - o = t.totalPages(), - p = t.linkTemplate, - l = u.buttonCount; - if (!n || n.action != "itemchange") { - if (u.numeric) { - for (r > l && (y = r % l, s = y === 0 ? r - l + 1 : r - y + 1), a = Math.min(s + l - 1, o), s > 1 && (f += v(p, s - 1, "...", !1, u.messages.morePages)), e = s; e <= a; e++) f += v(e == r ? t.selectTemplate : p, e, e, !0); - a < o && (f += v(p, e, "...", !1, u.messages.morePages)); - f === "" && (f = t.selectTemplate({ - text: 0 - })); - t.list.html(f) - } - u.info && (f = c > 0 ? i.format(u.messages.display, (r - 1) * h + 1, Math.min(r * h, c), c) : u.messages.empty, t.element.find(".k-pager-info").html(f)); - u.input && t.element.find(".k-pager-input").html(t.options.messages.page + '<input class="k-textbox">' + i.format(u.messages.of, o)).find("input").val(r).attr(nt, c < 1).toggleClass("k-state-disabled", c < 1); - u.previousNext && (w(t.element, r, o), b(t.element, r, o), k(t.element, r, o), d(t.element, r, o)); - u.pageSizes && t.element.find(".k-pager-sizes select").val(h).filter("[" + i.attr("role") + "=dropdownlist]").kendoDropDownList("value", h).kendoDropDownList("text", h) - } - }, - _keydown: function(n) { - if (n.keyCode === i.keys.ENTER) { - var r = this.element.find(".k-pager-input").find("input"), - t = parseInt(r.val(), 10); - (isNaN(t) || t < 1 || t > this.totalPages()) && (t = this.page()); - r.val(t); - this.page(t) - } - }, - _refreshClick: function(n) { - n.preventDefault(); - this.dataSource.read() - }, - _change: function(n) { - var t = parseInt(n.currentTarget.value, 10); - isNaN(t) || this.dataSource.pageSize(t) - }, - _click: function(t) { - var r = n(t.currentTarget); - t.preventDefault(); - r.is(".k-state-disabled") || this.page(r.attr(i.attr("page"))) - }, - totalPages: function() { - return Math.ceil((this.dataSource.total() || 0) / this.pageSize()) - }, - pageSize: function() { - return this.dataSource.pageSize() || this.dataSource.total() - }, - page: function(n) { - if (n !== t) this.dataSource.page(n), this.trigger(r, { - index: n - }); - else return this.dataSource.total() > 0 ? this.dataSource.page() : 0 - } - }); - y.plugin(it) - }(window.kendo.jQuery); -kendo_module({ - id: "popup", - name: "Pop-up", - category: "framework", - depends: ["core"], - advanced: !0 - }), - function(n) { - function y(t, i) { - return t === i || n.contains(t, i) - } - var t = window.kendo, - it = t.ui, - p = it.Widget, - f = t.support, - r = t.getOffset, - lt = t._activeElement, - w = "open", - b = "close", - rt = "deactivate", - ut = "activate", - u = "center", - ft = "left", - s = "right", - k = "top", - h = "bottom", - d = "absolute", - et = "hidden", - c = "body", - g = "location", - e = "position", - ot = "visible", - st = "effects", - ht = "k-state-active", - l = "k-state-border", - at = /k-state-border-(\w+)/, - ct = ".k-picker-wrap, .k-dropdown-wrap, .k-link", - a = "down", - nt = n(window), - tt = n(document.documentElement), - v = "resize scroll", - vt = f.transitions.css, - yt = vt + "transform", - i = n.extend, - o = ".kendoPopup", - pt = ["font-family", "font-size", "font-stretch", "font-style", "font-weight", "line-height"], - wt = p.extend({ - init: function(r, u) { - var f = this, - e; - u = u || {}; - u.isRtl && (u.origin = u.origin || h + " " + s, u.position = u.position || k + " " + s); - p.fn.init.call(f, r, u); - r = f.element; - u = f.options; - f.collisions = u.collision ? u.collision.split(" ") : []; - f.collisions.length === 1 && f.collisions.push(f.collisions[0]); - e = n(f.options.anchor).closest(".k-popup,.k-group").filter(":not([class^=km-])"); - u.appendTo = n(n(u.appendTo)[0] || e[0] || c); - f.element.hide().addClass("k-popup k-group k-reset").toggleClass("k-rtl", !!u.isRtl).css({ - position: d - }).appendTo(u.appendTo).on("mouseenter" + o, function() { - f._hovered = !0 - }).on("mouseleave" + o, function() { - f._hovered = !1 - }); - if (f.wrapper = n(), u.animation === !1 && (u.animation = { - open: { - effects: {} - }, - close: { - hide: !0, - effects: {} - } - }), i(u.animation.open, { - complete: function() { - f.wrapper.css({ - overflow: ot - }); - f.trigger(ut) - } - }), i(u.animation.close, { - complete: function() { - f.wrapper.hide(); - var o = f.wrapper.data(g), - s = n(u.anchor), - i, e; - o && f.wrapper.css(o); - u.anchor != c && (i = (s[0].className.match(at) || ["", "down"])[1], e = l + "-" + i, s.removeClass(e).children(ct).removeClass(ht).removeClass(e), r.removeClass(l + "-" + t.directions[i].reverse)); - f._closing = !1; - f.trigger(rt) - } - }), f._mousedownProxy = function(n) { - f._mousedown(n) - }, f._resizeProxy = function(n) { - f._resize(n) - }, u.toggleTarget) n(u.toggleTarget).on(u.toggleEvent + o, n.proxy(f.toggle, f)) - }, - events: [w, ut, b, rt], - options: { - name: "Popup", - toggleEvent: "click", - origin: h + " " + ft, - position: k + " " + ft, - anchor: c, - collision: "flip fit", - viewport: window, - copyAnchorStyles: !0, - autosize: !1, - modal: !1, - animation: { - open: { - effects: "slideIn:down", - transition: !0, - duration: 200 - }, - close: { - duration: 100, - hide: !0 - } - } - }, - destroy: function() { - var i = this, - r = i.options, - f = i.element.off(o), - u; - p.fn.destroy.call(i); - r.toggleTarget && n(r.toggleTarget).off(o); - r.modal || (tt.unbind(a, i._mousedownProxy), nt.unbind(v, i._resizeProxy)); - t.destroy(i.element.children()); - r.appendTo[0] === document.body && (u = f.parent(".k-animation-container"), u[0] ? u.remove() : f.remove()) - }, - open: function(r, u) { - var o = this, - rt = { - isFixed: !isNaN(parseInt(u, 10)), - x: r, - y: u - }, - y = o.element, - s = o.options, - p = "down", - h, b, g = n(s.anchor), - it; - if (!o.visible()) { - if (s.copyAnchorStyles && y.css(t.getComputedStyles(g[0], pt)), y.data("animating") || o.trigger(w)) return; - s.modal || (tt.unbind(a, o._mousedownProxy).bind(a, o._mousedownProxy), f.mobileOS.ios || f.mobileOS.android || nt.unbind(v, o._resizeProxy).bind(v, o._resizeProxy)); - o.wrapper = b = t.wrap(y, s.autosize).css({ - overflow: et, - display: "block", - position: d - }); - f.mobileOS.android && b.add(g).css(yt, "translatez(0)"); - b.css(e); - n(s.appendTo)[0] == document.body && b.css(k, "-10000px"); - h = i(!0, {}, s.animation.open); - o.flipped = o._position(rt); - h.effects = t.parseEffects(h.effects, o.flipped); - p = h.effects.slideIn ? h.effects.slideIn.direction : p; - s.anchor != c && (it = l + "-" + p, y.addClass(l + "-" + t.directions[p].reverse), g.addClass(it).children(ct).addClass(ht).addClass(it)); - y.data(st, h.effects).kendoStop(!0).kendoAnimate(h) - } - }, - toggle: function() { - var n = this; - n[n.visible() ? b : w]() - }, - visible: function() { - return this.element.is(":" + ot) - }, - close: function() { - var r = this, - s = r.options, - o, u, f, e; - if (r.visible()) { - if (o = r.wrapper[0] ? r.wrapper : t.wrap(r.element).hide(), r._closing || r.trigger(b)) return; - r.element.find(".k-popup").each(function() { - var i = n(this), - t = i.data("kendoPopup"); - t && t.close() - }); - tt.unbind(a, r._mousedownProxy); - nt.unbind(v, r._resizeProxy); - u = i(!0, {}, s.animation.close); - f = r.element.data(st); - e = u.effects; - !e && !t.size(e) && f && t.size(f) && (u.effects = f, u.reverse = !0); - r._closing = !0; - r.element.kendoStop(!0); - o.css({ - overflow: et - }); - r.element.kendoAnimate(u) - } - }, - _resize: function(n) { - var t = this; - n.type === "resize" ? (clearTimeout(t._resizeTimeout), t._resizeTimeout = setTimeout(function() { - t._position(); - t._resizeTimeout = null - }, 50)) : t._hovered || y(t.element[0], lt()) || t.close() - }, - _mousedown: function(i) { - var u = this, - s = u.element[0], - e = u.options, - h = n(e.anchor)[0], - o = e.toggleTarget, - f = t.eventTarget(i), - r = n(f).closest(".k-popup"), - c = r.parent().parent(".km-shim").length; - (r = r[0], c || !r || r === u.element[0]) && n(i.target).closest("a").data("rel") !== "popover" && (y(s, f) || y(h, f) || o && y(n(o)[0], f) || u.close()) - }, - _fit: function(n, t, i) { - var r = 0; - return n + t > i && (r = i - (n + t)), n < 0 && (r = -n), r - }, - _flip: function(n, t, i, r, f, e, o) { - var s = 0; - return o = o || t, e !== f && e !== u && f !== u && (n + o > r && (s += -(i + t)), n + s < 0 && (s += i + t)), s - }, - _position: function(t) { - var o = this, - nt = o.element.css(e, ""), - u = o.wrapper, - y = o.options, - c = n(y.viewport), - ot = n(c).offset(), - l = n(y.anchor), - tt = y.origin.toLowerCase().split(" "), - it = y.position.toLowerCase().split(" "), - p = o.collisions, - w = f.zoomLevel(), - b, rt, h, k = 10002, - ut = 0, - st, v, s, et; - if (b = l.parents().filter(u.siblings()), b[0]) - if (h = Number(n(b).css("zIndex")), h) k = h + 1; - else - for (rt = l.parentsUntil(b), st = rt.length; ut < st; ut++) h = Number(n(rt[ut]).css("zIndex")), h && k < h && (k = h + 1); - u.css("zIndex", k); - t && t.isFixed ? u.css({ - left: t.x, - top: t.y - }) : u.css(o._align(tt, it)); - var ft = r(u, e, l[0] === u.offsetParent()[0]), - a = r(u), - ht = l.offsetParent().parent(".k-animation-container,.k-popup,.k-group"); - return ht.length && (ft = r(u, e, !0), a = r(u)), c[0] === window ? (a.top -= window.pageYOffset || document.documentElement.scrollTop || 0, a.left -= window.pageXOffset || document.documentElement.scrollLeft || 0) : (a.top -= ot.top, a.left -= ot.left), o.wrapper.data(g) || u.data(g, i({}, ft)), v = i({}, a), s = i({}, ft), p[0] === "fit" && (s.top += o._fit(v.top, u.outerHeight(), c.height() / w)), p[1] === "fit" && (s.left += o._fit(v.left, u.outerWidth(), c.width() / w)), et = i({}, s), p[0] === "flip" && (s.top += o._flip(v.top, nt.outerHeight(), l.outerHeight(), c.height() / w, tt[0], it[0], u.outerHeight())), p[1] === "flip" && (s.left += o._flip(v.left, nt.outerWidth(), l.outerWidth(), c.width() / w, tt[1], it[1], u.outerWidth())), nt.css(e, d), u.css(s), s.left != et.left || s.top != et.top - }, - _align: function(t, i) { - var c = this, - v = c.wrapper, - l = n(c.options.anchor), - y = t[0], - p = t[1], - w = i[0], - b = i[1], - k = r(l), - d = n(c.options.appendTo), - a, g = v.outerWidth(), - nt = v.outerHeight(), - tt = l.outerWidth(), - it = l.outerHeight(), - f = k.top, - e = k.left, - o = Math.round; - return d[0] != document.body && (a = r(d), f -= a.top, e -= a.left), y === h && (f += it), y === u && (f += o(it / 2)), w === h && (f -= nt), w === u && (f -= o(nt / 2)), p === s && (e += tt), p === u && (e += o(tt / 2)), b === s && (e -= g), b === u && (e -= o(g / 2)), { - top: f, - left: e - } - } - }); - it.plugin(wt) - }(window.kendo.jQuery); -kendo_module({ - id: "tooltip", - name: "Tooltip", - category: "web", - description: "The Tooltip widget displays a popup hint for a given html element.", - depends: ["core", "popup"] - }), - function(n) { - function w(n) { - while (n.length) ot(n), n = n.parent() - } - - function ot(n) { - var i = n.data(t.ns + "title"); - i && (n.attr("title", i), n.removeData(t.ns + "title")) - } - - function st(n) { - var i = n.attr("title"); - i && (n.data(t.ns + "title", i), n.attr("title", "")) - } - - function b(n) { - while (n.length && !n.is("body")) st(n), n = n.parent() - } - var t = window.kendo, - u = t.ui.Widget, - k = t.ui.Popup, - d = t.isFunction, - g = n.isPlainObject, - s = n.extend, - r = n.proxy, - f = n(document), - nt = t.isLocalUrl, - h = "_tt_active", - c = "aria-describedby", - l = "show", - a = "hide", - v = "error", - e = "contentLoad", - y = "requestStart", - o = "k-content-frame", - tt = '<div role="tooltip" class="k-widget k-tooltip#if (!autoHide) {# k-tooltip-closable#}#">#if (!autoHide) {# <div class="k-tooltip-button"><a href="\\#" class="k-icon k-i-close">close<\/a><\/div> #}#<div class="k-tooltip-content"><\/div>#if (callout){ #<div class="k-callout k-callout-#=dir#"><\/div>#}#<\/div>', - it = t.template("<iframe frameborder='0' class='" + o + "' src='#= content.url #'>This page requires frames in order to show content<\/iframe>"), - i = ".kendoTooltip", - rt = { - bottom: { - origin: "bottom center", - position: "top center" - }, - top: { - origin: "top center", - position: "bottom center" - }, - left: { - origin: "center left", - position: "center right", - collision: "fit flip" - }, - right: { - origin: "center right", - position: "center left", - collision: "fit flip" - }, - center: { - position: "center center", - origin: "center center" - } - }, - ut = { - top: "bottom", - bottom: "top", - left: "right", - right: "left", - center: "center" - }, - p = { - bottom: "n", - top: "s", - left: "e", - right: "w", - center: "n" - }, - ft = { - horizontal: { - offset: "top", - size: "outerHeight" - }, - vertical: { - offset: "left", - size: "outerWidth" - } - }, - et = function(n) { - return n.target.data(t.ns + "title") - }, - ht = u.extend({ - init: function(n, t) { - var f = this, - e; - u.fn.init.call(f, n, t); - e = f.options.position.match(/left|right/) ? "horizontal" : "vertical"; - f.dimensions = ft[e]; - f._documentKeyDownHandler = r(f._documentKeyDown, f); - f.element.on(f.options.showOn + i, f.options.filter, r(f._showOn, f)).on("mouseenter" + i, f.options.filter, r(f._mouseenter, f)); - if (this.options.autoHide) f.element.on("mouseleave" + i, f.options.filter, r(f._mouseleave, f)) - }, - options: { - name: "Tooltip", - filter: "", - content: et, - showAfter: 100, - callout: !0, - position: "bottom", - showOn: "mouseenter", - autoHide: !0, - width: null, - height: null, - animation: { - open: { - effects: "fade:in", - duration: 0 - }, - close: { - effects: "fade:out", - duration: 40, - hide: !0 - } - } - }, - events: [l, a, e, v, y], - _mouseenter: function(t) { - b(n(t.currentTarget)) - }, - _showOn: function(t) { - var i = this, - r = n(t.currentTarget); - i.options.showOn && i.options.showOn.match(/click|focus/) ? i._show(r) : (clearTimeout(i.timeout), i.timeout = setTimeout(function() { - i._show(r) - }, i.options.showAfter)) - }, - _appendContent: function(n) { - var u = this, - r = u.options.content, - f = u.content, - h = u.options.iframe, - s; - if (g(r) && r.url) - if ("iframe" in u.options || (h = !nt(r.url)), u.trigger(y, { - options: r, - target: n - }), h) { - f.hide(); - s = f.find("." + o)[0]; - s ? s.src = r.url || s.src : f.html(it({ - content: r - })); - f.find("." + o).off("load" + i).on("load" + i, function() { - u.trigger(e); - f.show() - }) - } else f.empty(), t.ui.progress(f, !0), u._ajaxRequest(r); - else r && d(r) ? (r = r({ - sender: this, - target: n - }), u.content.html(r || "")) : u.content.html(r) - }, - _ajaxRequest: function(n) { - var i = this; - jQuery.ajax(s({ - type: "GET", - dataType: "html", - cache: !1, - error: function(n, r) { - t.ui.progress(i.content, !1); - i.trigger(v, { - status: r, - xhr: n - }) - }, - success: r(function(n) { - t.ui.progress(i.content, !1); - i.content.html(n); - i.trigger(e) - }, i) - }, n)) - }, - _documentKeyDown: function(n) { - n.keyCode === t.keys.ESC && this.hide() - }, - refresh: function() { - var t = this, - n = t.popup; - n && n.options.anchor && t._appendContent(n.options.anchor) - }, - hide: function() { - this.popup && this.popup.close() - }, - show: function(n) { - n = n || this.element; - b(n); - this._show(n) - }, - _show: function(n) { - var t = this, - r = t.target(); - t.popup || t._initPopup(); - r && r[0] != n[0] && (t.popup.close(), t.popup.element.kendoStop(!0, !0)); - r && r[0] == n[0] || (t._appendContent(n), t.popup.options.anchor = n); - t.popup.one("deactivate", function() { - w(n); - n.removeAttr(c); - this.element.removeAttr("id").attr("aria-hidden", !0); - f.off("keydown" + i, t._documentKeyDownHandler) - }); - t.popup.open() - }, - _initPopup: function() { - var u = this, - e = u.options, - o = n(t.template(tt)({ - callout: e.callout && e.position !== "center", - dir: p[e.position], - autoHide: e.autoHide - })); - if (u.popup = new k(o, s({ - activate: function() { - var t = this.options.anchor, - n = t[0].id || u.element[0].id; - n && (t.attr(c, n + h), this.element.attr("id", n + h)); - e.callout && u._positionCallout(); - this.element.removeAttr("aria-hidden"); - f.on("keydown" + i, u._documentKeyDownHandler); - u.trigger(l) - }, - close: function() { - u.trigger(a) - }, - copyAnchorStyles: !1, - animation: e.animation - }, rt[e.position])), o.css({ - width: e.width, - height: e.height - }), u.content = o.find(".k-tooltip-content"), u.arrow = o.find(".k-callout"), e.autoHide) o.on("mouseleave" + i, r(u._mouseleave, u)); - else o.on("click" + i, ".k-tooltip-button", r(u._closeButtonClick, u)) - }, - _closeButtonClick: function(n) { - n.preventDefault(); - this.hide() - }, - _mouseleave: function(t) { - if (this.popup) { - var r = n(t.currentTarget), - i = r.offset(), - u = t.pageX, - f = t.pageY; - if (i.right = i.left + r.outerWidth(), i.bottom = i.top + r.outerHeight(), u > i.left && u < i.right && f > i.top && f < i.bottom) return; - this.popup.close() - } else w(n(t.currentTarget)); - clearTimeout(this.timeout) - }, - _positionCallout: function() { - var t = this, - u = t.options.position, - f = t.dimensions, - i = f.offset, - r = t.popup, - e = r.options.anchor, - o = n(e).offset(), - s = parseInt(t.arrow.css("border-top-width"), 10), - h = n(r.element).offset(), - c = p[r.flipped ? ut[u] : u], - l = o[i] - h[i] + n(e)[f.size]() / 2 - s; - t.arrow.removeClass("k-callout-n k-callout-s k-callout-w k-callout-e").addClass("k-callout-" + c).css(i, l) - }, - target: function() { - return this.popup ? this.popup.options.anchor : null - }, - destroy: function() { - var n = this.popup; - n && (n.element.off(i), n.destroy()); - this.element.off(i); - f.off("keydown" + i, this._documentKeyDownHandler); - u.fn.destroy.call(this) - } - }); - t.ui.plugin(ht) - }(window.kendo.jQuery); -kendo_module({ - id: "list", - name: "List", - category: "framework", - depends: ["data", "popup"], - hidden: !0 - }), - function(n, t) { - function b(t, i) { - t.filters && (t.filters = n.grep(t.filters, function(n) { - return b(n, i), n.filters ? n.filters.length : n.field != i - })) - } - var i = window.kendo, - l = i.ui, - o = l.Widget, - f = i.keys, - u = i.support, - ft = i.htmlEncode, - et = i._activeElement, - s = "id", - a = "li", - r = "change", - v = "character", - k = "k-state-focused", - y = "k-state-hover", - d = "k-loading", - p = "open", - g = "close", - nt = "select", - w = "selected", - tt = "progress", - it = "requestEnd", - rt = "width", - ut = n.extend, - e = n.proxy, - h = u.browser, - ot = h.msie && h.version < 9, - st = /"/g, - ht = { - ComboBox: "DropDownList", - DropDownList: "ComboBox" - }, - c = o.extend({ - init: function(t, i) { - var r = this, - h = r.ns, - f; - o.fn.init.call(r, t, i); - t = r.element; - r._isSelect = t.is(nt); - r._template(); - r.ul = n('<ul unselectable="on" class="k-list k-reset"/>').css({ - overflow: u.kineticScrollNeeded ? "" : "auto" - }).on("mouseenter" + h, a, function() { - n(this).addClass(y) - }).on("mouseleave" + h, a, function() { - n(this).removeClass(y) - }).on("click" + h, a, e(r._click, r)).attr({ - tabIndex: -1, - role: "listbox", - "aria-hidden": !0 - }); - r.list = n("<div class='k-list-container'/>").append(r.ul).on("mousedown" + h, function(n) { - n.preventDefault() - }); - f = t.attr(s); - f && (r.list.attr(s, f + "-list"), r.ul.attr(s, f + "_listbox"), r._optionID = f + "_option_selected"); - r._header(); - r._accessors(); - r._initValue() - }, - options: { - valuePrimitive: !1, - headerTemplate: "" - }, - setOptions: function(n) { - o.fn.setOptions.call(this, n); - n && n.enable !== t && (n.enabled = n.enable) - }, - focus: function() { - this._focused.focus() - }, - readonly: function(n) { - this._editable({ - readonly: n === t ? !0 : n, - disable: !1 - }) - }, - enable: function(n) { - this._editable({ - readonly: !1, - disable: !(n = n === t ? !0 : n) - }) - }, - _filterSource: function(n) { - var i = this, - u = i.options, - r = i.dataSource, - t = r.filter() || {}; - b(t, u.dataTextField); - n && (t = t.filters || [], t.push(n)); - r.filter(t) - }, - _header: function() { - var t = this.options.headerTemplate, - i; - n.isFunction(t) && (t = t({})); - t && (this.list.prepend(t), i = this.ul.prev(), this.header = i[0] ? i : null) - }, - _initValue: function() { - var n = this, - t = n.options.value; - t !== null ? n.element.val(t) : (t = n._accessor(), n.options.value = t); - n._old = t - }, - _ignoreCase: function() { - var t = this, - i = t.dataSource.reader.model, - n; - i && i.fields && (n = i.fields[t.options.dataTextField], n && n.type && n.type !== "string" && (t.options.ignoreCase = !1)) - }, - items: function() { - return this.ul[0].children - }, - current: function(n) { - var i = this, - r = i._optionID; - if (n !== t) i._current && (i._current.removeClass(k).removeAttr("aria-selected").removeAttr(s), i._focused.removeAttr("aria-activedescendant")), n && (n.addClass(k), i._scroll(n), r && (n.attr("id", r), i._focused.attr("aria-activedescendant", r))), i._current = n; - else return i._current - }, - destroy: function() { - var n = this, - t = n.ns; - o.fn.destroy.call(n); - n._unbindDataSource(); - n.ul.off(t); - n.list.off(t); - n._touchScroller && n._touchScroller.destroy(); - n.popup.destroy(); - n._form && n._form.off("reset", n._resetHandler) - }, - dataItem: function(n) { - var i = this; - return n === t && (n = i.selectedIndex), i._data()[n] - }, - _accessors: function() { - var n = this, - r = n.element, - t = n.options, - u = i.getter, - f = r.attr(i.attr("text-field")), - e = r.attr(i.attr("value-field")); - f && (t.dataTextField = f); - e && (t.dataValueField = e); - n._text = u(t.dataTextField); - n._value = u(t.dataValueField) - }, - _aria: function(n) { - var i = this, - r = i.options, - u = i._focused; - r.suggest !== t && u.attr("aria-autocomplete", r.suggest ? "both" : "list"); - n = n ? n + " " + i.ul[0].id : i.ul[0].id; - u.attr("aria-owns", n); - i.ul.attr("aria-live", !r.filter || r.filter === "none" ? "off" : "polite") - }, - _blur: function() { - var n = this; - n._change(); - n.close() - }, - _change: function() { - var n = this, - i = n.selectedIndex, - e = n.options.value, - u = n.value(), - f; - n._isSelect && !n._bound && e && (u = e); - u !== n._old ? f = !0 : i !== t && i !== n._oldIndex && (f = !0); - f && (n._old = u, n._oldIndex = i, n.trigger(r), n.element.trigger(r)) - }, - _click: function(t) { - t.isDefaultPrevented() || this._accept(n(t.currentTarget)) - }, - _data: function() { - return this.dataSource.view() - }, - _enable: function() { - var n = this, - i = n.options, - r = n.element.is("[disabled]"); - i.enable !== t && (i.enabled = i.enable); - !i.enabled || r ? n.enable(!1) : n.readonly(n.element.is("[readonly]")) - }, - _focus: function(n) { - var t = this; - if (t.popup.visible() && n && t.trigger(nt, { - item: n - })) { - t.close(); - return - } - t._select(n); - t._triggerCascade(!0); - t._blur() - }, - _index: function(n) { - for (var i = this, u = i._data(), t = 0, r = u.length; t < r; t++) - if (i._dataValue(u[t]) == n) return t; - return -1 - }, - _dataValue: function(n) { - var i = this._value(n); - return i === t && (i = this._text(n)), i - }, - _height: function(n) { - if (n) { - var t = this, - r = t.list, - e = t.popup.visible(), - i = t.options.height, - f = t.header, - u; - u = r.add(r.parent(".k-animation-container")).show(); - i = t.ul[0].scrollHeight > i ? i : "auto"; - u.height(i); - f && t.ul.height(i == "auto" ? i : r.height() - f.height()); - e || u.hide() - } - }, - _adjustListWidth: function() { - var t = this.list, - i = t[0].style.width, - u = this.wrapper, - n, r; - if (t.data(rt) || !i) return n = window.getComputedStyle ? window.getComputedStyle(u[0], null) : 0, r = n ? parseFloat(n.width) : u.outerWidth(), n && (h.mozilla || h.msie) && (r += parseFloat(n.paddingLeft) + parseFloat(n.paddingRight) + parseFloat(n.borderLeftWidth) + parseFloat(n.borderRightWidth)), i = t.css("box-sizing") !== "border-box" ? r - (t.outerWidth() - t.width()) : r, t.css({ - fontFamily: u.css("font-family"), - width: i - }).data(rt, i), !0 - }, - _popup: function() { - var n = this, - e = n.list, - t = n._focused, - r = n.options, - f = n.wrapper; - n.popup = new l.Popup(e, ut({}, r.popup, { - anchor: f, - open: function(i) { - n._adjustListWidth(); - n.trigger(p) ? i.preventDefault() : (t.attr("aria-expanded", !0), n.ul.attr("aria-hidden", !1)) - }, - close: function(i) { - n.trigger(g) ? i.preventDefault() : (t.attr("aria-expanded", !1), n.ul.attr("aria-hidden", !0)) - }, - animation: r.animation, - isRtl: u.isRtl(f) - })); - n.popup.one(p, function() { - n._height(n._data().length) - }); - n._touchScroller = i.touchScroller(n.popup.element) - }, - _makeUnselectable: function() { - ot && this.list.find("*").attr("unselectable", "on") - }, - _toggleHover: function(t) { - n(t.currentTarget).toggleClass(y, t.type === "mouseenter") - }, - _toggle: function(n) { - var i = this, - r = u.touch && u.MSPointers && u.pointers; - n = n !== t ? n : !i.popup.visible(); - r || i._focused[0] === et() || i._focused.focus(); - i[n ? p : g]() - }, - _scroll: function(n) { - if (n) { - n[0] && (n = n[0]); - var r = this.ul[0], - t = n.offsetTop, - o = n.offsetHeight, - u = r.scrollTop, - s = r.clientHeight, - h = t + o, - f = this._touchScroller, - i, e; - f ? (i = f.dimensions.y, i.enabled && t > i.size && (t = t - i.size + o + 4, f.scrollTo(0, -t))) : (e = this.header ? this.header.outerHeight() : 0, r.scrollTop = u > t ? t - e : h > u + s ? h - s - e : u) - } - }, - _template: function() { - var t = this, - n = t.options, - r = n.template, - u = n.dataSource; - t._isSelect && t.element[0].length && (u || (n.dataTextField = n.dataTextField || "text", n.dataValueField = n.dataValueField || "value")); - r ? (r = i.template(r), t.template = function(n) { - return '<li tabindex="-1" role="option" unselectable="on" class="k-item">' + r(n) + "<\/li>" - }) : t.template = i.template('<li tabindex="-1" role="option" unselectable="on" class="k-item">${' + i.expr(n.dataTextField, "data") + "}<\/li>", { - useWithBlock: !1 - }) - }, - _triggerCascade: function(n) { - var t = this, - i = t.value(); - (!t._bound && i || t._old !== i) && t.trigger("cascade", { - userTriggered: n - }) - }, - _unbindDataSource: function() { - var n = this; - n.dataSource.unbind(r, n._refreshHandler).unbind(tt, n._progressHandler).unbind(it, n._requestEndHandler).unbind("error", n._errorHandler) - } - }); - ut(c, { - caret: function(n) { - var t = n.ownerDocument.selection; - return t ? Math.abs(t.createRange().moveStart(v, -n.value.length)) : n.selectionStart - }, - selectText: function(n, t, i) { - try { - if (n.createTextRange) { - n.focus(); - var r = n.createTextRange(); - r.collapse(!0); - r.moveStart(v, t); - r.moveEnd(v, i - t); - r.select() - } else n.setSelectionRange(t, i) - } catch (u) {} - }, - inArray: function(n, t) { - var i, r, u = t.children; - if (!n || n.parentNode !== t) return -1; - for (i = 0, r = u.length; i < r; i++) - if (n === u[i]) return i; - return -1 - } - }); - i.ui.List = c; - l.Select = c.extend({ - init: function(n, t) { - c.fn.init.call(this, n, t); - this._initial = this.element.val() - }, - setDataSource: function(n) { - this.options.dataSource = n; - this._dataSource(); - this._bound = !1; - this.options.autoBind && this.dataSource.fetch() - }, - close: function() { - this.popup.close() - }, - select: function(n) { - var i = this; - if (n === t) return i.selectedIndex; - i._select(n); - i._triggerCascade(); - i._old = i._accessor(); - i._oldIndex = i.selectedIndex - }, - _accessor: function(n, i) { - var r = this.element[0], - e = this._isSelect, - f = r.selectedIndex, - u; - if (n === t) return e ? f > -1 && (u = r.options[f], u && (n = u.value)) : n = r.value, n; - e ? (f > -1 && r.options[f].removeAttribute(w), r.selectedIndex = i, u = r.options[i], u && u.setAttribute(w, w)) : r.value = n - }, - _hideBusy: function() { - var n = this; - clearTimeout(n._busy); - n._arrow.removeClass(d); - n._focused.attr("aria-busy", !1); - n._busy = null - }, - _showBusy: function() { - var n = this; - (n._request = !0, n._busy) || (n._busy = setTimeout(function() { - n._focused.attr("aria-busy", !0); - n._arrow.addClass(d) - }, 100)) - }, - _requestEnd: function() { - this._request = !1 - }, - _dataSource: function() { - var t = this, - s = t.element, - f = t.options, - u = f.dataSource || {}, - o; - u = n.isArray(u) ? { - data: u - } : u; - t._isSelect && (o = s[0].selectedIndex, o > -1 && (f.index = o), u.select = s, u.fields = [{ - field: f.dataTextField - }, { - field: f.dataValueField - }]); - t.dataSource && t._refreshHandler ? t._unbindDataSource() : (t._refreshHandler = e(t.refresh, t), t._progressHandler = e(t._showBusy, t), t._requestEndHandler = e(t._requestEnd, t), t._errorHandler = e(t._hideBusy, t)); - t.dataSource = i.data.DataSource.create(u).bind(r, t._refreshHandler).bind(tt, t._progressHandler).bind(it, t._requestEndHandler).bind("error", t._errorHandler) - }, - _get: function(t) { - var r = this, - u = r._data(), - i, f; - if (typeof t == "function") - for (i = 0, f = u.length; i < f; i++) - if (t(u[i])) { - t = i; - break - } - if (typeof t == "number") { - if (t < 0) return n(); - t = n(r.ul[0].children[t]) - } - return t && t.nodeType && (t = n(t)), t - }, - _move: function(n) { - var t = this, - e = n.keyCode, - o = t.ul[0], - c = t.popup.visible() ? "_select" : "_accept", - i = t._current, - h = e === f.DOWN, - u, s; - if (e === f.UP || h) { - if (n.altKey) t.toggle(h); - else { - if (u = o.firstChild, !u && !t._accessor() && t._state !== "filter") { - if (!t._fetch) { - t.dataSource.one(r, function() { - t._move(n); - t._fetch = !1 - }); - t._fetch = !0; - t._filterSource() - } - return n.preventDefault(), !0 - } - h ? (i && (t.selectedIndex !== -1 || t.value() || i[0] !== u) ? (i = i[0].nextSibling, i || u !== o.lastChild || (i = u)) : i = u, t[c](i)) : (i = i ? i[0].previousSibling : o.lastChild, i || u !== o.lastChild || (i = u), t[c](i)) - } - n.preventDefault(); - s = !0 - } else e === f.ENTER || e === f.TAB ? (t.popup.visible() && n.preventDefault(), (t._typing || !t.popup.visible() && t.selectedIndex === -1) && (i = null), t._accept(i), s = !0) : e === f.ESC && (t.popup.visible() && n.preventDefault(), t.close(), s = !0); - return s - }, - _selectItem: function() { - var n = this, - i = n.options, - u, r; - u = n._isSelect && !n._initial && !i.value && i.index && !n._bound; - u || (r = n._selectedValue || i.value || n._accessor()); - r ? n.value(r) : n._bound === t && n.select(i.index) - }, - _fetchItems: function(n) { - var t = this, - i = t.ul[0].firstChild; - if (t._request) return !0; - if (!t._fetch && !i) { - if (t.options.cascadeFrom) return !i; - t.dataSource.one(r, function() { - t.value(n); - t._fetch = !1 - }); - return t._fetch = !0, t.dataSource.fetch(), !0 - } - }, - _options: function(n, i) { - var e = this, - c = e.element, - l = n.length, - o = "", - u, s, h, r, f = 0; - for (i && (f = 1, o = i); f < l; f++) u = "<option", s = n[f], h = e._text(s), r = e._value(s), r !== t && (r += "", r.indexOf('"') !== -1 && (r = r.replace(st, """)), u += ' value="' + r + '"'), u += ">", h !== t && (u += ft(h)), u += "<\/option>", o += u; - c.html(o) - }, - _reset: function() { - var t = this, - i = t.element, - r = i.attr("form"), - u = r ? n("#" + r) : i.closest("form"); - u[0] && (t._resetHandler = function() { - setTimeout(function() { - t.value(t._initial) - }) - }, t._form = u.on("reset", t._resetHandler)) - }, - _cascade: function() { - var t = this, - u = t.options, - s = u.cascadeFrom, - i, f, e, o, h; - if (s) { - if (t._selectedValue = u.value || t._accessor(), f = n("#" + s), i = f.data("kendo" + u.name), i || (i = f.data("kendo" + ht[u.name])), !i) return; - u.autoBind = !1; - o = u.cascadeFromField || i.options.dataValueField; - h = function() { - var n = t._selectedValue || t.value(); - t._userTriggered ? t._clearSelection(i, !0) : n ? (t.value(n), t.dataSource.view()[0] && t.selectedIndex !== -1 || t._clearSelection(i, !0)) : t.select(u.index); - t.enable(); - t._triggerCascade(t._userTriggered); - t._userTriggered = !1 - }; - e = function() { - var e = i.dataItem(), - n = e ? i._value(e) : null, - u, f; - n || n === 0 ? (u = t.dataSource.filter() || {}, b(u, o), f = u.filters || [], f.push({ - field: o, - operator: "eq", - value: n - }), t.dataSource.one(r, h).filter(f)) : (t.enable(!1), t._clearSelection(i), t._triggerCascade(t._userTriggered), t._userTriggered = !1) - }; - i.bind("cascade", function(n) { - t._userTriggered = n.userTriggered; - e() - }); - i._bound ? e() : i.value() || t.enable(!1) - } - } - }) - }(window.kendo.jQuery); -kendo_module({ - id: "calendar", - name: "Calendar", - category: "web", - description: "The Calendar widget renders a graphical calendar that supports navigation and selection.", - depends: ["core"] - }), - function(n, t) { - function li(n, t, i, r) { - var u = n.getFullYear(), - e = t.getFullYear(), - o = i.getFullYear(), - f; - return u = u - u % r, f = u + (r - 1), u < e && (u = e), f > o && (f = o), u + "-" + f - } - - function d(n) { - for (var t = 0, i, f = n.min, e = n.max, r = n.start, o = n.setter, s = n.build, h = n.cells || 12, c = n.perRow || 4, l = n.content || bi, a = n.empty || ki, u = n.html || '<table tabindex="0" role="grid" class="k-content k-meta-view" cellspacing="0"><tbody><tr role="row">'; t < h; t++) t > 0 && t % c == 0 && (u += '<\/tr><tr role="row">'), i = s(r, t), u += nt(r, f, e) ? l(i) : a(i), o(r, 1); - return u + "<\/tr><\/tbody><\/table>" - } - - function st(n, t, i) { - var f = n.getFullYear(), - r = t.getFullYear(), - e = r, - u = 0; - return i && (r = r - r % i, e = r - r % i + i - 1), f > e ? u = 1 : f < r && (u = -1), u - } - - function g() { - var n = new i; - return new i(n.getFullYear(), n.getMonth(), n.getDate()) - } - - function v(n, t, r) { - var u = g(); - return n && (u = new i(+n)), t > u ? u = new i(+t) : r < u && (u = new i(+r)), u - } - - function nt(n, t, i) { - return +n >= +t && +n <= +i - } - - function ai(n, t) { - return n.slice(t).concat(n.slice(0, t)) - } - - function vi(n, t, r) { - t = t instanceof i ? t.getFullYear() : n.getFullYear() + r * t; - n.setFullYear(t) - } - - function yi(t) { - n(this).toggleClass(nr, tr.indexOf(t.type) > -1 || t.type == ri) - } - - function ur(n) { - n.preventDefault() - } - - function ht(n) { - return at(n).calendars.standard - } - - function ct(n) { - var i = o[n.start], - r = o[n.depth], - u = at(n.culture); - n.format = wi(n.format || u.calendars.standard.patterns.d); - isNaN(i) && (i = 0, n.start = a); - (r === t || r > i) && (n.depth = a); - n.dates || (n.dates = []) - } - - function pi(n) { - di && n.find("*").attr("unselectable", "on") - } - - function fr(n, t) { - for (var i = 0, r = t.length; i < r; i++) - if (n === +t[i]) return !0; - return !1 - } - - function er(n, t) { - return n ? n.getFullYear() === t.getFullYear() && n.getMonth() === t.getMonth() && n.getDate() === t.getDate() : !1 - } - - function or(n, t) { - return n ? n.getFullYear() === t.getFullYear() && n.getMonth() === t.getMonth() : !1 - } - var r = window.kendo, - tt = r.support, - lt = r.ui, - y = lt.Widget, - u = r.keys, - it = r.parseDate, - p = r.date.adjustDST, - wi = r._extractFormat, - l = r.template, - at = r.getCulture, - vt = r.support.transitions, - yt = vt ? vt.css + "transform-origin" : "", - bi = l('<td#=data.cssClass# role="gridcell"><a tabindex="-1" class="k-link" href="\\#" data-#=data.ns#value="#=data.dateString#">#=data.value#<\/a><\/td>', { - useWithBlock: !1 - }), - ki = l('<td role="gridcell"> <\/td>', { - useWithBlock: !1 - }), - pt = r.support.browser, - di = pt.msie && pt.version < 9, - f = ".kendoCalendar", - s = "click" + f, - gi = "keydown" + f, - rt = "id", - wt = "min", - bt = "left", - ut = "slideIn", - a = "month", - kt = "century", - ft = "change", - dt = "navigate", - et = "value", - nr = "k-state-hover", - h = "k-state-disabled", - c = "k-state-focused", - w = "k-other-month", - gt = ' class="' + w + '"', - ni = "k-nav-today", - ti = "td:has(.k-link)", - ii = "blur" + f, - ri = "focus", - ui = ri + f, - tr = tt.touch ? "touchstart" : "mouseenter", - fi = tt.touch ? "touchstart" + f : "mouseenter" + f, - ei = tt.touch ? "touchend" + f + " touchmove" + f : "mouseleave" + f, - ir = 6e4, - oi = 864e5, - b = "_prevArrow", - k = "_nextArrow", - ot = "aria-disabled", - si = "aria-selected", - hi = n.proxy, - ci = n.extend, - i = Date, - o = { - month: 0, - year: 1, - decade: 2, - century: 3 - }, - rr = y.extend({ - init: function(t, u) { - var e = this, - h, l; - y.fn.init.call(e, t, u); - t = e.wrapper = e.element; - u = e.options; - u.url = window.unescape(u.url); - e._templates(); - e._header(); - e._footer(e.footer); - l = t.addClass("k-widget k-calendar").on(fi + " " + ei, ti, yi).on(gi, "table.k-content", hi(e._move, e)).on(s, ti, function(t) { - var i = t.currentTarget.firstChild; - i.href.indexOf("#") != -1 && t.preventDefault(); - e._click(n(i)) - }).on("mouseup" + f, function() { - e._focusView(e.options.focusOnNav !== !1) - }).attr(rt); - l && (e._cellID = l + "_cell_selected"); - ct(u); - h = it(u.value, u.format, u.culture); - e._index = o[u.start]; - e._current = new i(+v(h, u.min, u.max)); - e._addClassProxy = function() { - e._active = !0; - e._cell.addClass(c) - }; - e._removeClassProxy = function() { - e._active = !1; - e._cell.removeClass(c) - }; - e.value(h); - r.notify(e) - }, - options: { - name: "Calendar", - value: null, - min: new i(1900, 0, 1), - max: new i(2099, 11, 31), - dates: [], - url: "", - culture: "", - footer: "", - format: "", - month: {}, - start: a, - depth: a, - animation: { - horizontal: { - effects: ut, - reverse: !0, - duration: 500, - divisor: 2 - }, - vertical: { - effects: "zoomIn", - duration: 400 - } - } - }, - events: [ft, dt], - setOptions: function(n) { - var t = this; - ct(n); - y.fn.setOptions.call(t, n); - t._templates(); - t._footer(t.footer); - t._index = o[t.options.start]; - t.navigate() - }, - destroy: function() { - var n = this, - t = n._today; - n.element.off(f); - n._title.off(f); - n[b].off(f); - n[k].off(f); - r.destroy(n._table); - t && r.destroy(t.off(f)); - y.fn.destroy.call(n) - }, - current: function() { - return this._current - }, - view: function() { - return this._view - }, - focus: function(n) { - n = n || this._table; - this._bindTable(n); - n.focus() - }, - min: function(n) { - return this._option(wt, n) - }, - max: function(n) { - return this._option("max", n) - }, - navigateToPast: function() { - this._navigate(b, -1) - }, - navigateToFuture: function() { - this._navigate(k, 1) - }, - navigateUp: function() { - var n = this, - t = n._index; - n._title.hasClass(h) || n.navigate(n._current, ++t) - }, - navigateDown: function(n) { - var t = this, - i = t._index, - r = t.options.depth; - if (n) { - if (i === o[r]) { - +t._value != +n && (t.value(n), t.trigger(ft)); - return - } - t.navigate(n, --i) - } - }, - navigate: function(r, u) { - u = isNaN(u) ? o[u] : u; - var f = this, - l = f.options, - tt = l.culture, - p = l.min, - w = l.max, - it = f._title, - y = f._table, - d = f._oldTable, - rt = f._value, - ut = f._current, - ft = r && +r > +ut, - et = u !== t && u !== f._index, - g, a, nt, s; - r || (r = ut); - f._current = r = new i(+v(r, p, w)); - u === t ? u = f._index : f._index = u; - f._view = a = e.views[u]; - nt = a.compare; - s = u === o[kt]; - it.toggleClass(h, s).attr(ot, s); - s = nt(r, p) < 1; - f[b].toggleClass(h, s).attr(ot, s); - s = nt(r, w) > -1; - f[k].toggleClass(h, s).attr(ot, s); - y && d && d.data("animating") && (d.kendoStop(!0, !0), y.kendoStop(!0, !0)); - f._oldTable = y; - (!y || f._changeView) && (it.html(a.title(r, p, w, tt)), f._table = g = n(a.content(ci({ - min: p, - max: w, - date: r, - url: l.url, - dates: l.dates, - format: l.format, - culture: tt - }, f[a.name]))), pi(g), f._animate({ - from: y, - to: g, - vertical: et, - future: ft - }), f._focus(r), f.trigger(dt)); - u === o[l.depth] && rt && f._class("k-state-selected", a.toDateString(rt)); - f._class(c, a.toDateString(r)); - !y && f._cell && f._cell.removeClass(c); - f._changeView = !0 - }, - value: function(n) { - var r = this, - f = r._view, - u = r.options, - e = r._view, - o = u.min, - s = u.max; - if (n === t) return r._value; - n = it(n, u.format, u.culture); - n !== null && (n = new i(+n), nt(n, o, s) || (n = null)); - r._value = n; - e && n === null && r._cell ? r._cell.removeClass("k-state-selected") : (r._changeView = !n || f && f.compare(n, r._current) !== 0, r.navigate(n)) - }, - _move: function(t) { - var f = this, - y = f.options, - e = t.keyCode, - p = f._view, - w = f._index, - s = new i(+f._current), - h = r.support.isRtl(f.wrapper), - c, o, l, a; - return t.target === f._table[0] && (f._active = !0), t.ctrlKey ? e == u.RIGHT && !h || e == u.LEFT && h ? (f.navigateToFuture(), o = !0) : e == u.LEFT && !h || e == u.RIGHT && h ? (f.navigateToPast(), o = !0) : e == u.UP ? (f.navigateUp(), o = !0) : e == u.DOWN && (f._click(n(f._cell[0].firstChild)), o = !0) : (e == u.RIGHT && !h || e == u.LEFT && h ? (c = 1, o = !0) : e == u.LEFT && !h || e == u.RIGHT && h ? (c = -1, o = !0) : e == u.UP ? (c = w === 0 ? -7 : -4, o = !0) : e == u.DOWN ? (c = w === 0 ? 7 : 4, o = !0) : e == u.ENTER ? (f._click(n(f._cell[0].firstChild)), o = !0) : e == u.HOME || e == u.END ? (l = e == u.HOME ? "first" : "last", a = p[l](s), s = new i(a.getFullYear(), a.getMonth(), a.getDate(), s.getHours(), s.getMinutes(), s.getSeconds(), s.getMilliseconds()), o = !0) : e == u.PAGEUP ? (o = !0, f.navigateToPast()) : e == u.PAGEDOWN && (o = !0, f.navigateToFuture()), (c || l) && (l || p.setDate(s, c), f._focus(v(s, y.min, y.max)))), o && t.preventDefault(), f._current - }, - _animate: function(n) { - var t = this, - i = n.from, - r = n.to, - u = t._active; - i ? i.parent().data("animating") ? (i.parent().kendoStop(!0, !0).remove(), i.remove(), r.insertAfter(t.element[0].firstChild), t._focusView(u)) : i.is(":visible") && t.options.animation !== !1 ? t[n.vertical ? "_vertical" : "_horizontal"](i, r, n.future) : (r.insertAfter(i), i.remove(), t._focusView(u)) : (r.insertAfter(t.element[0].firstChild), t._bindTable(r)) - }, - _horizontal: function(n, i, r) { - var u = this, - o = u._active, - f = u.options.animation.horizontal, - s = f.effects, - e = n.outerWidth(); - s && s.indexOf(ut) != -1 && (n.add(i).css({ - width: e - }), n.wrap("<div/>"), u._focusView(o, n), n.parent().css({ - position: "relative", - width: e * 2, - float: bt, - "margin-left": r ? 0 : -e - }), i[r ? "insertAfter" : "insertBefore"](n), ci(f, { - effects: ut + ":" + (r ? "right" : bt), - complete: function() { - n.remove(); - i.unwrap(); - u._focusView(o); - u._oldTable = t - } - }), n.parent().kendoStop(!0, !0).kendoAnimate(f)) - }, - _vertical: function(n, i) { - var r = this, - e = r.options.animation.vertical, - o = e.effects, - s = r._active, - f, u; - o && o.indexOf("zoom") != -1 && (i.css({ - position: "absolute", - top: n.prev().outerHeight(), - left: 0 - }).insertBefore(n), yt && (f = r._cellByDate(r._view.toDateString(r._current)), u = f.position(), u = u.left + parseInt(f.width() / 2, 10) + "px " + (u.top + parseInt(f.height() / 2, 10) + "px"), i.css(yt, u)), n.kendoStop(!0, !0).kendoAnimate({ - effects: "fadeOut", - duration: 600, - complete: function() { - n.remove(); - i.css({ - position: "static", - top: 0, - left: 0 - }); - r._focusView(s); - r._oldTable = t - } - }), i.kendoStop(!0, !0).kendoAnimate(e)) - }, - _cellByDate: function(t) { - return this._table.find("td:not(." + w + ")").filter(function() { - return n(this.firstChild).attr(r.attr(et)) === t - }) - }, - _class: function(t, i) { - var u = this, - e = u._cellID, - f = u._cell; - f && f.removeAttr(si).removeAttr("aria-label").removeAttr(rt); - f = u._table.find("td:not(." + w + ")").removeClass(t).filter(function() { - return n(this.firstChild).attr(r.attr(et)) === i - }).attr(si, !0); - t !== c || u._active || u.options.focusOnNav === !1 || (t = ""); - f.addClass(t); - f[0] && (u._cell = f); - e && (f.attr(rt, e), u._table.removeAttr("aria-activedescendant").attr("aria-activedescendant", e)) - }, - _bindTable: function(n) { - n.on(ui, this._addClassProxy).on(ii, this._removeClassProxy) - }, - _click: function(n) { - var u = this, - f = u.options, - e = new Date(+u._current), - t = n.attr(r.attr(et)).split("/"); - t = new i(t[0], t[1], t[2]); - p(t, 0); - u._view.setDate(e, t); - u.navigateDown(v(e, f.min, f.max)) - }, - _focus: function(n) { - var t = this, - i = t._view; - i.compare(n, t._current) !== 0 ? t.navigate(n) : (t._current = n, t._class(c, i.toDateString(n))) - }, - _focusView: function(n, t) { - n && this.focus(t) - }, - _footer: function(t) { - var i = this, - f = g(), - e = i.element, - u = e.find(".k-footer"); - if (!t) { - i._toggle(!1); - u.hide(); - return - } - u[0] || (u = n('<div class="k-footer"><a href="#" class="k-link k-nav-today"><\/a><\/div>').appendTo(e)); - i._today = u.show().find(".k-link").html(t(f)).attr("title", r.toString(f, "D", i.options.culture)); - i._toggle() - }, - _header: function() { - var n = this, - i = n.element, - t; - i.find(".k-header")[0] || i.html('<div class="k-header"><a href="#" role="button" class="k-link k-nav-prev"><span class="k-icon k-i-arrow-w"><\/span><\/a><a href="#" role="button" aria-live="assertive" aria-atomic="true" class="k-link k-nav-fast"><\/a><a href="#" role="button" class="k-link k-nav-next"><span class="k-icon k-i-arrow-e"><\/span><\/a><\/div>'); - t = i.find(".k-link").on(fi + " " + ei + " " + ui + " " + ii, yi).click(!1); - n._title = t.eq(1).on(s, function() { - n._focusView(n.options.focusOnNav !== !1); - n.navigateUp() - }); - n[b] = t.eq(0).on(s, function() { - n._focusView(n.options.focusOnNav !== !1); - n.navigateToPast() - }); - n[k] = t.eq(2).on(s, function() { - n._focusView(n.options.focusOnNav !== !1); - n.navigateToFuture() - }) - }, - _navigate: function(n, t) { - var r = this, - f = r._index + 1, - u = new i(+r._current); - n = r[n]; - n.hasClass(h) || (f > 3 ? u.setFullYear(u.getFullYear() + 100 * t) : e.views[f].setDate(u, t), r.navigate(u)) - }, - _option: function(n, r) { - var u = this, - f = u.options, - e = u._value || u._current, - o; - if (r === t) return f[n]; - (r = it(r, f.format, f.culture), r) && (f[n] = new i(+r), o = n === wt ? r > e : e > r, (o || or(e, r)) && (o && (u._value = null), u._changeView = !0), u._changeView || (u._changeView = !!(f.month.content || f.month.empty)), u.navigate(u._value), u._toggle()) - }, - _toggle: function(n) { - var i = this, - u = i.options, - r = i._today; - if (n === t && (n = nt(g(), u.min, u.max)), r) - if (r.off(s), n) r.addClass(ni).removeClass(h).on(s, hi(i._todayClick, i)); - else r.removeClass(ni).addClass(h).on(s, ur) - }, - _todayClick: function(n) { - var t = this, - r = o[t.options.depth], - i = g(); - n.preventDefault(); - t._view.compare(t._current, i) === 0 && t._index == r && (t._changeView = !1); - t._value = i; - t.navigate(i, r); - t.trigger(ft) - }, - _templates: function() { - var n = this, - t = n.options, - i = t.footer, - u = t.month, - f = u.content, - e = u.empty; - n.month = { - content: l('<td#=data.cssClass# role="gridcell"><a tabindex="-1" class="k-link#=data.linkClass#" href="#=data.url#" ' + r.attr("value") + '="#=data.dateString#" title="#=data.title#">' + (f || "#=data.value#") + "<\/a><\/td>", { - useWithBlock: !!f - }), - empty: l('<td role="gridcell">' + (e || " ") + "<\/td>", { - useWithBlock: !!e - }) - }; - n.footer = i !== !1 ? l(i || '#= kendo.toString(data,"D","' + t.culture + '") #', { - useWithBlock: !1 - }) : null - } - }), - e; - lt.plugin(rr); - e = { - firstDayOfMonth: function(n) { - return new i(n.getFullYear(), n.getMonth(), 1) - }, - firstVisibleDay: function(n, t) { - t = t || r.culture().calendar; - for (var f = t.firstDay, u = new i(n.getFullYear(), n.getMonth(), 0, n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds()); u.getDay() != f;) e.setTime(u, -1 * oi); - return u - }, - setTime: function(n, t) { - var u = n.getTimezoneOffset(), - r = new i(n.getTime() + t), - f = r.getTimezoneOffset() - u; - n.setTime(r.getTime() + f * ir) - }, - views: [{ - name: a, - title: function(n, t, i, r) { - return ht(r).months.names[n.getMonth()] + " " + n.getFullYear() - }, - content: function(n) { - for (var u = this, f = 0, o = n.min, s = n.max, h = n.date, c = n.dates, nt = n.format, l = n.culture, y = n.url, tt = y && c[0], a = ht(l), b = a.firstDay, k = a.days, it = ai(k.names, b), rt = ai(k.namesShort, b), v = e.firstVisibleDay(h, a), ut = u.first(h), ft = u.last(h), et = u.toDateString, t = new i, g = '<table tabindex="0" role="grid" class="k-content" cellspacing="0"><thead><tr role="row">'; f < 7; f++) g += '<th scope="col" title="' + it[f] + '">' + rt[f] + "<\/th>"; - return t = new i(t.getFullYear(), t.getMonth(), t.getDate()), p(t, 0), t = +t, d({ - cells: 42, - perRow: 7, - html: g += '<\/tr><\/thead><tbody><tr role="row">', - start: new i(v.getFullYear(), v.getMonth(), v.getDate()), - min: new i(o.getFullYear(), o.getMonth(), o.getDate()), - max: new i(s.getFullYear(), s.getMonth(), s.getDate()), - content: n.content, - empty: n.empty, - setter: u.setDate, - build: function(n) { - var i = [], - u = n.getDay(), - f = "", - e = "#"; - return (n < ut || n > ft) && i.push(w), +n === t && i.push("k-today"), (u === 0 || u === 6) && i.push("k-weekend"), tt && fr(+n, c) && (e = y.replace("{0}", r.toString(n, nt, l)), f = " k-action-link"), { - date: n, - dates: c, - ns: r.ns, - title: r.toString(n, "D", l), - value: n.getDate(), - dateString: et(n), - cssClass: i[0] ? ' class="' + i.join(" ") + '"' : "", - linkClass: f, - url: e - } - } - }) - }, - first: function(n) { - return e.firstDayOfMonth(n) - }, - last: function(n) { - var t = new i(n.getFullYear(), n.getMonth() + 1, 0), - r = e.firstDayOfMonth(n), - u = Math.abs(t.getTimezoneOffset() - r.getTimezoneOffset()); - return u && t.setHours(r.getHours() + u / 60), t - }, - compare: function(n, t) { - var i = n.getMonth(), - r = n.getFullYear(), - u = t.getMonth(), - f = t.getFullYear(); - return r > f ? 1 : r < f ? -1 : i == u ? 0 : i > u ? 1 : -1 - }, - setDate: function(n, t) { - var r = n.getHours(); - t instanceof i ? n.setFullYear(t.getFullYear(), t.getMonth(), t.getDate()) : e.setTime(n, t * oi); - p(n, r) - }, - toDateString: function(n) { - return n.getFullYear() + "/" + n.getMonth() + "/" + n.getDate() - } - }, { - name: "year", - title: function(n) { - return n.getFullYear() - }, - content: function(n) { - var f = ht(n.culture).months.namesAbbr, - e = this.toDateString, - t = n.min, - u = n.max; - return d({ - min: new i(t.getFullYear(), t.getMonth(), 1), - max: new i(u.getFullYear(), u.getMonth(), 1), - start: new i(n.date.getFullYear(), 0, 1), - setter: this.setDate, - build: function(n) { - return { - value: f[n.getMonth()], - ns: r.ns, - dateString: e(n), - cssClass: "" - } - } - }) - }, - first: function(n) { - return new i(n.getFullYear(), 0, n.getDate()) - }, - last: function(n) { - return new i(n.getFullYear(), 11, n.getDate()) - }, - compare: function(n, t) { - return st(n, t) - }, - setDate: function(n, t) { - var r, u = n.getHours(); - t instanceof i ? (r = t.getMonth(), n.setFullYear(t.getFullYear(), r, n.getDate()), r !== n.getMonth() && n.setDate(0)) : (r = n.getMonth() + t, n.setMonth(r), r > 11 && (r -= 12), r > 0 && n.getMonth() != r && n.setDate(0)); - p(n, u) - }, - toDateString: function(n) { - return n.getFullYear() + "/" + n.getMonth() + "/1" - } - }, { - name: "decade", - title: function(n, t, i) { - return li(n, t, i, 10) - }, - content: function(n) { - var t = n.date.getFullYear(), - u = this.toDateString; - return d({ - start: new i(t - t % 10 - 1, 0, 1), - min: new i(n.min.getFullYear(), 0, 1), - max: new i(n.max.getFullYear(), 0, 1), - setter: this.setDate, - build: function(n, t) { - return { - value: n.getFullYear(), - ns: r.ns, - dateString: u(n), - cssClass: t === 0 || t == 11 ? gt : "" - } - } - }) - }, - first: function(n) { - var t = n.getFullYear(); - return new i(t - t % 10, n.getMonth(), n.getDate()) - }, - last: function(n) { - var t = n.getFullYear(); - return new i(t - t % 10 + 9, n.getMonth(), n.getDate()) - }, - compare: function(n, t) { - return st(n, t, 10) - }, - setDate: function(n, t) { - vi(n, t, 1) - }, - toDateString: function(n) { - return n.getFullYear() + "/0/1" - } - }, { - name: kt, - title: function(n, t, i) { - return li(n, t, i, 100) - }, - content: function(n) { - var o = n.date.getFullYear(), - f = n.min.getFullYear(), - e = n.max.getFullYear(), - s = this.toDateString, - t = f, - u = e; - return t = t - t % 10, u = u - u % 10, u - t < 10 && (u = t + 9), d({ - start: new i(o - o % 100 - 10, 0, 1), - min: new i(t, 0, 1), - max: new i(u, 0, 1), - setter: this.setDate, - build: function(n, t) { - var i = n.getFullYear(), - u = i + 9; - return i < f && (i = f), u > e && (u = e), { - ns: r.ns, - value: i + " - " + u, - dateString: s(n), - cssClass: t === 0 || t == 11 ? gt : "" - } - } - }) - }, - first: function(n) { - var t = n.getFullYear(); - return new i(t - t % 100, n.getMonth(), n.getDate()) - }, - last: function(n) { - var t = n.getFullYear(); - return new i(t - t % 100 + 99, n.getMonth(), n.getDate()) - }, - compare: function(n, t) { - return st(n, t, 100) - }, - setDate: function(n, t) { - vi(n, t, 10) - }, - toDateString: function(n) { - var t = n.getFullYear(); - return t - t % 10 + "/0/1" - } - }] - }; - e.isEqualDatePart = er; - e.makeUnselectable = pi; - e.restrictValue = v; - e.isInRange = nt; - e.normalize = ct; - e.viewsEnum = o; - r.calendar = e - }(window.kendo.jQuery); -kendo_module({ - id: "datepicker", - name: "DatePicker", - category: "web", - description: "The DatePicker widget allows the user to select a date from a calendar or by direct input.", - depends: ["calendar", "popup"] - }), - function(n, t) { - function d(t) { - var i = t.parseFormats, - r = t.format; - o.normalize(t); - i = n.isArray(i) ? i : [i]; - n.inArray(r, i) === -1 && i.splice(0, 0, t.format); - t.parseFormats = i - } - - function pt(n) { - n.preventDefault() - } - var i = window.kendo, - f = i.ui, - e = f.Widget, - c = i.parseDate, - u = i.keys, - bt = i.template, - kt = i._activeElement, - g = "<div />", - nt = "<span />", - r = ".kendoDatePicker", - tt = "click" + r, - l = "open", - a = "close", - v = "change", - it = "disabled", - rt = "readonly", - y = "k-state-default", - ut = "k-state-focused", - ft = "k-state-selected", - p = "k-state-disabled", - dt = "k-state-hover", - ii = "keydown" + r, - gt = "mouseenter" + r + " mouseleave" + r, - et = "mousedown" + r, - w = "id", - ot = "min", - st = "max", - ht = "month", - ct = "aria-disabled", - lt = "aria-expanded", - b = "aria-hidden", - at = "aria-readonly", - o = i.calendar, - ni = o.isInRange, - vt = o.restrictValue, - ti = o.isEqualDatePart, - k = n.extend, - s = n.proxy, - yt = Date, - h = function(t) { - var r = this, - u, o = document.body, - e = n(g).attr(b, "true").addClass("k-calendar-container").appendTo(o); - r.options = t = t || {}; - u = t.id; - u && (u += "_dateview", e.attr(w, u), r._dateViewID = u); - r.popup = new f.Popup(e, k(t.popup, t, { - name: "Popup", - isRtl: i.support.isRtl(t.anchor) - })); - r.div = e; - r.value(t.value) - }, - wt; - h.prototype = { - _calendar: function() { - var t = this, - r = t.calendar, - u = t.options, - e; - r || (e = n(g).attr(w, i.guid()).appendTo(t.popup.element).on(et, pt).on(tt, "td:has(.k-link)", s(t._click, t)), t.calendar = r = new f.Calendar(e), t._setOptions(u), i.calendar.makeUnselectable(r.element), r.navigate(t._value || t._current, u.start), t.value(t._value)) - }, - _setOptions: function(n) { - this.calendar.setOptions({ - focusOnNav: !1, - change: n.change, - culture: n.culture, - dates: n.dates, - depth: n.depth, - footer: n.footer, - format: n.format, - max: n.max, - min: n.min, - month: n.month, - start: n.start - }) - }, - setOptions: function(n) { - var t = this.options; - this.options = k(t, n, { - change: t.change, - close: t.close, - open: t.open - }); - this.calendar && this._setOptions(this.options) - }, - destroy: function() { - this.popup.destroy() - }, - open: function() { - var n = this; - n._calendar(); - n.popup.open() - }, - close: function() { - this.popup.close() - }, - min: function(n) { - this._option(ot, n) - }, - max: function(n) { - this._option(st, n) - }, - toggle: function() { - var n = this; - n[n.popup.visible() ? a : l]() - }, - move: function(n) { - var t = this, - i = n.keyCode, - r = t.calendar, - f = n.ctrlKey && i == u.DOWN || i == u.ENTER; - if (i == u.ESC) { - t.close(); - return - } - if (n.altKey) { - i == u.DOWN ? (t.open(), n.preventDefault()) : i == u.UP && (t.close(), n.preventDefault()); - return - } - if (t.popup.visible()) { - if (f && r._cell.hasClass(ft)) { - t.close(); - n.preventDefault(); - return - } - t._current = r._move(n) - } - }, - current: function(n) { - this._current = n; - this.calendar._focus(n) - }, - value: function(n) { - var t = this, - i = t.calendar, - r = t.options; - t._value = n; - t._current = new yt(+vt(n, r.min, r.max)); - i && i.value(n) - }, - _click: function(n) { - n.currentTarget.className.indexOf(ft) !== -1 && this.close() - }, - _option: function(n, t) { - var i = this, - r = i.calendar; - i.options[n] = t; - r && r[n](t) - } - }; - h.normalize = d; - i.DateView = h; - wt = e.extend({ - init: function(n, t) { - var r = this, - f, u; - e.fn.init.call(r, n, t); - n = r.element; - t = r.options; - d(t); - r._wrapper(); - r.dateView = new h(k({}, t, { - id: n.attr(w), - anchor: r.wrapper, - change: function() { - r._change(this.value()); - r.close() - }, - close: function(t) { - r.trigger(a) ? t.preventDefault() : (n.attr(lt, !1), u.attr(b, !0)) - }, - open: function(t) { - var f = r.options, - i; - r.trigger(l) ? t.preventDefault() : (r.element.val() !== r._oldText && (i = c(n.val(), f.parseFormats, f.culture), r.dateView[i ? "current" : "value"](i)), n.attr(lt, !0), u.attr(b, !1), r._updateARIA(i)) - } - })); - u = r.dateView.div; - r._icon(); - try { - n[0].setAttribute("type", "text") - } catch (o) { - n[0].type = "text" - } - n.addClass("k-input").attr({ - role: "combobox", - "aria-expanded": !1, - "aria-owns": r.dateView._dateViewID - }); - r._reset(); - r._template(); - f = n.is("[disabled]"); - f ? r.enable(!1) : r.readonly(n.is("[readonly]")); - r._old = r._update(t.value || r.element.val()); - r._oldText = n.val(); - i.notify(r) - }, - events: [l, a, v], - options: { - name: "DatePicker", - value: null, - footer: "", - format: "", - culture: "", - parseFormats: [], - min: new Date(1900, 0, 1), - max: new Date(2099, 11, 31), - start: ht, - depth: ht, - animation: {}, - month: {}, - dates: [], - ARIATemplate: 'Current focused date is #=kendo.toString(data.current, "D")#' - }, - setOptions: function(n) { - var t = this, - r = t._value; - e.fn.setOptions.call(t, n); - n = t.options; - d(n); - t.dateView.setOptions(n); - r && (t.element.val(i.toString(r, n.format, n.culture)), t._updateARIA(r)) - }, - _editable: function(n) { - var t = this, - o = t._dateIcon.off(r), - f = t.element.off(r), - e = t._inputWrapper.off(r), - u = n.readonly, - i = n.disable; - if (u || i) e.addClass(i ? p : y).removeClass(i ? y : p), f.attr(it, i).attr(rt, u).attr(ct, i).attr(at, u); - else { - e.addClass(y).removeClass(p).on(gt, t._toggleHover); - f.removeAttr(it).removeAttr(rt).attr(ct, !1).attr(at, !1).on("keydown" + r, s(t._keydown, t)).on("blur" + r, s(t._blur, t)).on("focus" + r, function() { - t._inputWrapper.addClass(ut) - }); - o.on(tt, s(t._click, t)).on(et, pt) - } - }, - readonly: function(n) { - this._editable({ - readonly: n === t ? !0 : n, - disable: !1 - }) - }, - enable: function(n) { - this._editable({ - readonly: !1, - disable: !(n = n === t ? !0 : n) - }) - }, - destroy: function() { - var n = this; - e.fn.destroy.call(n); - n.dateView.destroy(); - n.element.off(r); - n._dateIcon.off(r); - n._inputWrapper.off(r); - n._form && n._form.off("reset", n._resetHandler) - }, - open: function() { - this.dateView.open() - }, - close: function() { - this.dateView.close() - }, - min: function(n) { - return this._option(ot, n) - }, - max: function(n) { - return this._option(st, n) - }, - value: function(n) { - var i = this; - if (n === t) return i._value; - i._old = i._update(n); - i._old === null && i.element.val(""); - i._oldText = i.element.val() - }, - _toggleHover: function(t) { - n(t.currentTarget).toggleClass(dt, t.type === "mouseenter") - }, - _blur: function() { - var n = this, - t = n.element.val(); - n.close(); - t !== n._oldText && n._change(t); - n._inputWrapper.removeClass(ut) - }, - _click: function() { - var n = this, - t = n.element; - n.dateView.toggle(); - i.support.touch || t[0] === kt() || t.focus() - }, - _change: function(n) { - var t = this; - n = t._update(n); + t._old != +n && (t._old = n, t._oldText = t.element.val(), t.trigger(v), t.element.trigger(v)) - }, - _keydown: function(n) { - var t = this, - i = t.dateView, - r = t.element.val(); - i.popup.visible() || n.keyCode != u.ENTER || r === t._oldText ? (i.move(n), t._updateARIA(i._current)) : t._change(r) - }, - _icon: function() { - var i = this, - r = i.element, - t; - t = r.next("span.k-select"); - t[0] || (t = n('<span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-calendar">select<\/span><\/span>').insertAfter(r)); - i._dateIcon = t.attr({ - role: "button", - "aria-controls": i.dateView._dateViewID - }) - }, - _option: function(n, i) { - var u = this, - r = u.options; - if (i === t) return r[n]; - (i = c(i, r.parseFormats, r.culture), i) && (r[n] = new yt(+i), u.dateView[n](i)) - }, - _update: function(n) { - var u = this, - r = u.options, - f = r.min, - o = r.max, - t = c(n, r.parseFormats, r.culture), - e; - return +t == +u._value ? (e = i.toString(t, r.format, r.culture), e !== n && u.element.val(t === null ? n : e), t) : (t !== null && ti(t, f) ? t = vt(t, f, o) : ni(t, f, o) || (t = null), u._value = t, u.dateView.value(t), u.element.val(t ? i.toString(t, r.format, r.culture) : n), u._updateARIA(t), t) - }, - _wrapper: function() { - var r = this, - i = r.element, - t; - t = i.parents(".k-datepicker"); - t[0] || (t = i.wrap(nt).parent().addClass("k-picker-wrap k-state-default"), t = t.wrap(nt).parent()); - t[0].style.cssText = i[0].style.cssText; - i.css({ - width: "100%", - height: i[0].style.height - }); - r.wrapper = t.addClass("k-widget k-datepicker k-header").addClass(i[0].className); - r._inputWrapper = n(t[0].firstChild) - }, - _reset: function() { - var t = this, - i = t.element, - r = i.attr("form"), - u = r ? n("#" + r) : i.closest("form"); - u[0] && (t._resetHandler = function() { - t.value(i[0].defaultValue) - }, t._form = u.on("reset", t._resetHandler)) - }, - _template: function() { - this._ariaTemplate = bt(this.options.ARIATemplate) - }, - _updateARIA: function(n) { - var i, t = this, - r = t.dateView.calendar; - t.element.removeAttr("aria-activedescendant"); - r && (i = r._cell, i.attr("aria-label", t._ariaTemplate({ - current: n || r.current() - })), t.element.attr("aria-activedescendant", i.attr("id"))) - } - }); - f.plugin(wt) - }(window.kendo.jQuery); -kendo_module({ - id: "dropdownlist", - name: "DropDownList", - category: "web", - description: "The DropDownList widget displays a list of values and allows the selection of a single value from the list.", - depends: ["list"], - features: [{ - id: "mobile-scroller", - name: "Mobile scroller", - description: "Support for kinetic scrolling in mobile device", - depends: ["mobile.scroller"] - }] - }), - function(n, t) { - function o(n, t, i) { - for (var u = 0, f = t.length - 1, r; u < f; ++u) r = t[u], r in n || (n[r] = {}), n = n[r]; - n[t[f]] = i - } - var r = window.kendo, - s = r.ui, - u = s.Select, - f = r.support.mobileOS, - i = ".kendoDropDownList", - a = "disabled", - v = "readonly", - y = "change", - p = "k-state-focused", - h = "k-state-default", - c = "k-state-disabled", - w = "aria-disabled", - b = "aria-readonly", - l = "k-state-selected", - k = "mouseenter" + i + " mouseleave" + i, - e = "tabindex", - d = n.proxy, - g = u.extend({ - init: function(f, o) { - var s = this, - a = o && o.index, - c, l, h; - s.ns = i; - o = n.isArray(o) ? { - dataSource: o - } : o; - u.fn.init.call(s, f, o); - s._focusHandler = function() { - s.wrapper.focus() - }; - o = s.options; - f = s.element.on("focus" + i, s._focusHandler); - this._inputTemplate(); - s._reset(); - s._word = ""; - s._wrapper(); - s._tabindex(); - s.wrapper.data(e, s.wrapper.attr(e)); - s._aria(); - s._span(); - s._popup(); - s._mobile(); - s._dataSource(); - s._ignoreCase(); - s._enable(); - s._oldIndex = s.selectedIndex = -1; - s._cascade(); - a !== t && (o.index = a); - o.autoBind ? s.dataSource.fetch() : s.selectedIndex === -1 && (h = o.text || "", h || (c = o.optionLabel, l = c && o.index === 0, s._isSelect ? h = l ? c : f.children(":selected").text() : !f[0].value && l && (h = c)), s._textAccessor(h)); - r.notify(s) - }, - options: { - name: "DropDownList", - enabled: !0, - autoBind: !0, - index: 0, - text: null, - value: null, - template: "", - valueTemplate: "", - delay: 500, - height: 200, - dataTextField: "", - dataValueField: "", - optionLabel: "", - cascadeFrom: "", - cascadeFromField: "", - ignoreCase: !0, - animation: {} - }, - events: ["open", "close", y, "select", "dataBinding", "dataBound", "cascade"], - setOptions: function(n) { - u.fn.setOptions.call(this, n); - this._template(); - this._inputTemplate(); - this._accessors(); - this._aria() - }, - destroy: function() { - var n = this; - n.wrapper.off(i); - n.element.off(i); - n._inputWrapper.off(i); - u.fn.destroy.call(n) - }, - open: function() { - var n = this; - n.ul[0].firstChild ? (n.popup.open(), n._scroll(n._current)) : (n._open = !0, n._request || n.dataSource.fetch()) - }, - toggle: function(n) { - this._toggle(n) - }, - refresh: function() { - var n = this, - u = n._data(), - t = u.length, - i = n.options.optionLabel, - e = n.element[0], - f; - n.trigger("dataBinding"); - n._current && n.current(null); - n.ul[0].innerHTML = r.render(n.template, u); - n._height(t); - n.popup.visible() && n.popup._position(); - n._isSelect && (f = e.selectedIndex, i && t && (i = '<option value="">' + n._optionLabelText(i) + "<\/option>"), n._options(u, i), e.selectedIndex = f === -1 ? 0 : f); - n._open && (n._open = !1, n.toggle(!!t)); - n._hideBusy(); - n._makeUnselectable(); - n._fetch || (t ? n._selectItem() : n._textAccessor() !== i && (n.element.val(""), n._textAccessor(""))); - n._bound = !!t; - n.trigger("dataBound") - }, - search: function(n) { - if (n) { - var i = this, - r = i.options.ignoreCase; - r && (n = n.toLowerCase()); - i._select(function(u) { - var f = i._text(u); - if (f !== t) return f = f + "", r && (f = f.toLowerCase()), f.indexOf(n) === 0 - }) - } - }, - text: function(n) { - var i = this, - r, u, f = i.options.ignoreCase; - if (n = n === null ? "" : n, n !== t) typeof n == "string" && (u = f ? n.toLowerCase() : n, r = i._select(function(n) { - return n = i._text(n), f && (n = (n + "").toLowerCase()), n === u - }), r && (n = r)), i._textAccessor(n); - else return i._textAccessor() - }, - value: function(n) { - var i = this, - r, u; - if (n !== t) { - if (n !== null && (n = n.toString()), i._selectedValue = n, u = n || i.options.optionLabel && !i.element[0].disabled && n === "", u && i._fetchItems(n)) return; - r = i._index(n); - i.select(r > -1 ? r : 0) - } else return i._accessor() - }, - _editable: function(n) { - var t = this, - s = t.element, - o = n.disable, - l = n.readonly, - u = t.wrapper.off(i), - f = t._inputWrapper.off(k), - y = function() { - f.addClass(p); - t._blured = !1 - }, - g = function() { - if (!t._blured) { - t._triggerCascade(); - var n = window.self !== window.top; - r.support.mobileOS.ios && n ? t._change() : t._blur(); - f.removeClass(p); - t._blured = !0; - s.blur() - } - }; - if (l || o) { - if (o) u.removeAttr(e), f.addClass(c).removeClass(h); - else { - f.addClass(h).removeClass(c); - u.on("focusin" + i, y).on("focusout" + i, g) - } - s.attr(a, o).attr(v, l); - u.attr(w, o).attr(b, l) - } else { - s.removeAttr(a).removeAttr(v); - f.addClass(h).removeClass(c).on(k, t._toggleHover); - u.attr(e, u.data(e)).attr(w, !1).attr(b, !1).on("click" + i, function(n) { - t._blured = !1; - n.preventDefault(); - t.toggle() - }).on("keydown" + i, d(t._keydown, t)).on("keypress" + i, d(t._keypress, t)).on("focusin" + i, y).on("focusout" + i, g) - } - }, - _accept: function(n) { - this._focus(n) - }, - _optionLabelText: function() { - var t = this.options, - i = t.dataTextField, - n = t.optionLabel; - return n && i && typeof n == "object" ? this._text(n) : n - }, - _data: function() { - var h = this, - f = h.options, - t = f.optionLabel, - i = f.dataTextField, - e = f.dataValueField, - u = h.dataSource.view(), - c = u.length, - n = t, - s = 0; - if (t && c) { - for (typeof t == "object" ? n = t : i && (n = {}, i = i.split("."), e = e.split("."), o(n, e, ""), o(n, i, t)), n = new r.data.ObservableArray([n]); s < c; s++) n.push(u[s]); - u = n - } - return u - }, - _selectItem: function() { - u.fn._selectItem.call(this); - this.current() || this.select(0) - }, - _keydown: function(n) { - var u = this, - t = n.keyCode, - i = r.keys, - f = u.ul[0]; - t === i.LEFT ? t = i.UP : t === i.RIGHT && (t = i.DOWN); - n.keyCode = t; - u._move(n); - t === i.HOME ? (n.preventDefault(), u._select(f.firstChild)) : t === i.END && (n.preventDefault(), u._select(f.lastChild)) - }, - _selectNext: function(n, t) { - for (var i = this, r, f = t, u = i._data(), o = u.length, s = i.options.ignoreCase, e = function(t, r) { - return t = t + "", s && (t = t.toLowerCase()), t.indexOf(n) === 0 ? (i._select(r), i._triggerEvents(), !0) : void 0 - }; t < o; t++) - if (r = i._text(u[t]), r && e(r, t)) return !0; - if (f > 0) - for (t = 0; t <= f; t++) - if (r = i._text(u[t]), r && e(r, t)) return !0; - return !1 - }, - _keypress: function(n) { - if (n.charCode !== 0) { - var t = this, - i = String.fromCharCode(n.charCode || n.keyCode), - u = t.selectedIndex, - r = t._word; - (t.options.ignoreCase && (i = i.toLowerCase()), i === " " && n.preventDefault(), t._last === i && r.length <= 1 && u > -1 && (r || (r = i), t._selectNext(r, u + 1))) || (t._word = r + i, t._last = i, t._search()) - } - }, - _popup: function() { - u.fn._popup.call(this); - this.popup.one("open", function() { - this.wrapper = r.wrap(this.element).addClass("km-popup") - }) - }, - _search: function() { - var n = this, - i = n.dataSource, - t = n.selectedIndex, - r = n._word; - if (clearTimeout(n._typing), n._typing = setTimeout(function() { - n._word = "" - }, n.options.delay), t === -1 && (t = 0), !n.ul[0].firstChild) { - i.one(y, function() { - i.data()[0] && t > -1 && n._selectNext(r, t) - }).fetch(); - return - } - n._selectNext(r, t); - n._triggerEvents() - }, - _select: function(n) { - var i = this, - e = i._current, - r = null, - f, u; - return n = i._get(n), n && n[0] && !n.hasClass(l) && (e && e.removeClass(l), u = s.List.inArray(n[0], i.ul[0]), u > -1 && (r = i._data()[u], f = i._value(r), i.selectedIndex = u, i._textAccessor(r), i._accessor(f !== t ? f : i._text(r), u), i._selectedValue = i._accessor(), i.current(n.addClass(l)), i._optionID && i._current.attr("aria-selected", !0))), r - }, - _triggerEvents: function() { - this.popup.visible() || (this._triggerCascade(), this._change()) - }, - _mobile: function() { - var t = this, - n = t.popup, - i = n.element.parents(".km-root").eq(0); - i.length && f && (n.options.animation.open.effects = f.android || f.meego ? "fadeIn" : f.ios || f.wp ? "slideIn:up" : n.options.animation.open.effects) - }, - _span: function() { - var t = this, - i = t.wrapper, - u = "span.k-input", - r; - r = i.find(u); - r[0] || (i.append('<span unselectable="on" class="k-dropdown-wrap k-state-default"><span unselectable="on" class="k-input"> <\/span><span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-arrow-s">select<\/span><\/span><\/span>').append(t.element), r = i.find(u)); - t.span = r; - t._inputWrapper = n(i[0].firstChild); - t._arrow = i.find(".k-icon").mousedown(function(n) { - n.preventDefault() - }) - }, - _wrapper: function() { - var i = this, - t = i.element, - r = t[0], - n; - n = t.parent(); - n.is("span.k-widget") || (n = t.wrap("<span />").parent(), n[0].style.cssText = r.style.cssText); - t.hide(); - i._focused = i.wrapper = n.addClass("k-widget k-dropdown k-header").addClass(r.className).css("display", "").attr({ - unselectable: "on", - role: "listbox", - "aria-haspopup": !0, - "aria-expanded": !1 - }) - }, - _clearSelection: function() { - var n = this, - t = n.options.optionLabel; - if (n.options.value = "", n._selectedValue = "", n.dataSource.view()[0] && (t || n._userTriggered)) { - n.select(0); - return - } - n.selectedIndex = -1; - n.element.val(""); - n._textAccessor(n.options.optionLabel) - }, - _inputTemplate: function() { - var i = this, - t = i.options.valueTemplate; - t = t ? r.template(t) : n.proxy(r.template("#:this._text(data)#"), i); - i.valueTemplate = t - }, - _textAccessor: function(i) { - var u = this.dataItem(), - f = this.options, - e = this.span; - if (i !== t) n.isPlainObject(i) || i instanceof r.data.ObservableObject ? u = i : u && this._text(u) === i || (f.dataTextField ? (u = {}, o(u, f.dataTextField.split("."), i), o(u, f.dataValueField.split("."), this._accessor())) : u = i), e.html(this.valueTemplate(u)); - else return e.text() - } - }); - s.plugin(g) - }(window.kendo.jQuery); -kendo_module({ - id: "combobox", - name: "ComboBox", - category: "web", - description: "The ComboBox widget allows the selection from pre-defined values or entering a new value.", - depends: ["list"], - features: [{ - id: "mobile-scroller", - name: "Mobile scroller", - description: "Support for kinetic scrolling in mobile device", - depends: ["mobile.scroller"] - }] - }), - function(n, t) { - var r = window.kendo, - o = r.ui, - u = o.List, - f = o.Select, - ut = r.support, - v = ut.placeholder, - s = r._activeElement, - h = r.keys, - i = ".kendoComboBox", - y = "click" + i, - p = "mousedown" + i, - w = "disabled", - b = "readonly", - k = "change", - c = "k-state-default", - d = "k-state-focused", - l = "k-state-disabled", - g = "aria-disabled", - nt = "aria-readonly", - tt = "k-state-selected", - e = "filter", - a = "accept", - it = "rebind", - ft = "mouseenter" + i + " mouseleave" + i, - rt = null, - et = n.proxy, - ot = f.extend({ - init: function(t, u) { - var e = this, - o; - e.ns = i; - u = n.isArray(u) ? { - dataSource: u - } : u; - f.fn.init.call(e, t, u); - e._focusHandler = function() { - e.input.focus() - }; - u = e.options; - t = e.element.on("focus" + i, e._focusHandler); - u.placeholder = u.placeholder || t.attr("placeholder"); - e._reset(); - e._wrapper(); - e._input(); - e._tabindex(e.input); - e._popup(); - e._dataSource(); - e._ignoreCase(); - e._enable(); - e._cascade(); - e._aria(); - e._oldIndex = e.selectedIndex = -1; - u.autoBind ? e._filterSource() : (o = u.text, !o && e._isSelect && (o = t.children(":selected").text()), o && (e.input.val(o), e._prev = o)); - o || e._placeholder(); - r.notify(e) - }, - options: { - name: "ComboBox", - enabled: !0, - index: -1, - text: null, - value: null, - autoBind: !0, - delay: 200, - dataTextField: "", - dataValueField: "", - minLength: 0, - height: 200, - highlightFirst: !0, - template: "", - filter: "none", - placeholder: "", - suggest: !1, - cascadeFrom: "", - cascadeFromField: "", - ignoreCase: !0, - animation: {} - }, - events: ["open", "close", k, "select", "dataBinding", "dataBound", "cascade"], - setOptions: function(n) { - f.fn.setOptions.call(this, n); - this._template(); - this._accessors(); - this._aria() - }, - current: function(n) { - var r = this, - i = r._current; - if (n === t) return i; - i && i.removeClass(tt); - f.fn.current.call(r, n) - }, - destroy: function() { - var n = this; - n.input.off(i); - n.element.off(i); - n._inputWrapper.off(i); - f.fn.destroy.call(n) - }, - _editable: function(n) { - var t = this, - r = n.disable, - f = n.readonly, - u = t._inputWrapper.off(i), - e = t.element.add(t.input.off(i)), - o = t._arrow.parent().off(y + " " + p); - if (f || r) u.addClass(r ? l : c).removeClass(r ? c : l), e.attr(w, r).attr(b, f).attr(g, r).attr(nt, f); - else { - u.addClass(c).removeClass(l).on(ft, t._toggleHover); - e.removeAttr(w).removeAttr(b).attr(g, !1).attr(nt, !1); - o.on(y, function() { - t.toggle() - }).on(p, function(n) { - n.preventDefault() - }); - t.input.on("keydown" + i, et(t._keydown, t)).on("focus" + i, function() { - u.addClass(d); - t._placeholder(!1) - }).on("blur" + i, function() { - u.removeClass(d); - clearTimeout(t._typing); - t.options.text !== t.input.val() && t.text(t.text()); - t._placeholder(); - t._blur(); - t.element.blur() - }) - } - }, - open: function() { - var n = this, - t = n.dataSource.options.serverFiltering; - n.popup.visible() || (n.ul[0].firstChild && (n._state !== a || t) ? (n.popup.open(), n._scroll(n._current)) : (n._open = !0, n._state = it, n._filterSource())) - }, - refresh: function() { - var i = this, - f = i.ul[0], - l = i.options, - a = i._state, - o = i._data(), - h = o.length, - v = !0, - y, c, u; - i.trigger("dataBinding"); - f.innerHTML = r.render(i.template, o); - i._height(h); - i.popup.visible() && i.popup._position(); - i._isSelect && (y = i.element[0].firstChild, a === it && (i._state = ""), u = i._option, i._option = t, i._options(o), u && u[0].selected ? i._custom(u.val(), v) : i._bound || y || i._custom("", v)); - h && (l.highlightFirst && i.current(n(f.firstChild)), l.suggest && i.input.val() && i._request !== t && i.suggest(n(f.firstChild))); - a === e || i._fetch || i._selectItem(); - i._open && (i._open = !1, c = !!h, i._typing && i.input[0] !== s() && (c = !1), i.toggle(c), i._typing = t); - i._touchScroller && i._touchScroller.reset(); - i._makeUnselectable(); - i._hideBusy(); - i._bound = !0; - i.trigger("dataBound") - }, - search: function(n) { - n = typeof n == "string" ? n : this.text(); - var t = this, - f = n.length, - i = t.options, - r = i.ignoreCase, - u = i.filter, - o = i.dataTextField; - clearTimeout(t._typing); - f >= i.minLength && (t._state = e, u === "none" ? t._filter(n) : (t._open = !0, t._filterSource({ - value: r ? n.toLowerCase() : n, - field: o, - operator: u, - ignoreCase: r - }))) - }, - suggest: function(n) { - var r = this, - o = r.input[0], - i = r.text(), - e = u.caret(o), - c = r._last, - f; - if (c == h.BACKSPACE || c == h.DELETE) { - r._last = t; - return - } - n = n || ""; - typeof n != "string" && (f = u.inArray(n[0], r.ul[0]), n = f > -1 ? r._text(r.dataSource.view()[f]) : ""); - e <= 0 && (e = i.toLowerCase().indexOf(n.toLowerCase()) + 1); - n ? (f = n.toLowerCase().indexOf(i.toLowerCase()), f > -1 && (i += n.substring(f + i.length))) : i = i.substring(0, e); - i.length === e && n || (o.value = i, o === s() && u.selectText(o, e, i.length)) - }, - text: function(n) { - n = n === null ? "" : n; - var i = this, - u = i.input[0], - e = i.options.ignoreCase, - f = n, - r; - if (n !== t) { - if (r = i.dataItem(), r && i._text(r) === n && i._value(r).toString() === i._old) { - i._triggerCascade(); - return - } - e && (f = f.toLowerCase()); - i._select(function(n) { - return n = i._text(n), e && (n = (n + "").toLowerCase()), n === f - }); - i.selectedIndex < 0 && (i._custom(n), u.value = n); - i._prev = u.value; - i._triggerCascade() - } else return u.value - }, - toggle: function(n) { - var t = this; - t._toggle(n) - }, - value: function(n) { - var i = this, - u = i.options, - r; - if (n !== t) { - if (n !== null && (n = n.toString()), i._selectedValue = n, !i._open && n && i._fetchItems(n)) return; - r = i._index(n); - r > -1 ? i.select(r) : (i.current(rt), i._custom(n), (u.value !== n || u.text !== i.input.val()) && (i.text(n), i._placeholder())); - i._old = i._accessor(); - i._oldIndex = i.selectedIndex - } else return i._accessor() - }, - _accept: function(n) { - var t = this; - n ? t._focus(n) : (t.text(t.text()), t._change()) - }, - _custom: function(t, i) { - var r = this, - f = r.element, - u = r._option; - r._state !== e || i || (r._state = a); - r._isSelect ? (u || (u = r._option = n("<option/>"), f.append(u)), u.text(t), u[0].selected = !0) : f.val(t); - r._selectedValue = t - }, - _filter: function(n) { - var i = this, - r = i.options, - u = i.dataSource, - f = r.ignoreCase, - e = function(r) { - var u = i._text(r); - if (u !== t) return (u = u + "", u !== "" && n === "") ? !1 : (f && (u = u.toLowerCase()), u.indexOf(n) === 0) - }; - if (f && (n = n.toLowerCase()), !i.ul[0].firstChild) { - u.one(k, function() { - u.data()[0] && i.search(n) - }).fetch(); - return - } - i._highlight(e) !== -1 && (r.suggest && i._current && i.suggest(i._current), i.open()); - i._hideBusy() - }, - _highlight: function(i) { - var r = this, - f; - return i === t || i === null ? -1 : (i = r._get(i), f = u.inArray(i[0], r.ul[0]), f == -1 && (r.options.highlightFirst && !r.text() ? (i = r.ul[0].firstChild, i && (i = n(i))) : i = rt), r.current(i), f) - }, - _input: function() { - var t = this, - i = t.element.removeClass("k-input")[0], - e = i.accessKey, - u = t.wrapper, - o = "input.k-input", - f = i.name || "", - r; - f && (f = 'name="' + f + '_input" '); - r = u.find(o); - r[0] || (u.append('<span tabindex="-1" unselectable="on" class="k-dropdown-wrap k-state-default"><input ' + f + 'class="k-input" type="text" autocomplete="off"/><span tabindex="-1" unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-arrow-s">select<\/span><\/span><\/span>').append(t.element), r = u.find(o)); - r[0].style.cssText = i.style.cssText; - i.maxLength > -1 && (r[0].maxLength = i.maxLength); - r.addClass(i.className).val(this.options.text || i.value).css({ - width: "100%", - height: i.style.height - }).attr({ - role: "combobox", - "aria-expanded": !1 - }).show(); - v && r.attr("placeholder", t.options.placeholder); - e && (i.accessKey = "", r[0].accessKey = e); - t._focused = t.input = r; - t._inputWrapper = n(u[0].firstChild); - t._arrow = u.find(".k-icon").attr({ - role: "button", - tabIndex: -1 - }); - i.id && t._arrow.attr("aria-controls", t.ul[0].id) - }, - _keydown: function(n) { - var t = this, - i = n.keyCode; - t._last = i; - clearTimeout(t._typing); - i == h.TAB || t._move(n) || t._search() - }, - _placeholder: function(n) { - if (!v) { - var f = this, - i = f.input, - r = f.options.placeholder, - e; - if (r) { - if (e = f.value(), n === t && (n = !e), i.toggleClass("k-readonly", n), !n) { - if (e) return; - r = "" - } - i.val(r); - r || i[0] !== s() || u.selectText(i[0], 0, 0) - } - } - }, - _search: function() { - var n = this; - n._typing = setTimeout(function() { - var t = n.text(); - n._prev !== t && (n._prev = t, n.search(t)); - n._typing = null - }, n.options.delay) - }, - _select: function(n) { - var i = this, - f, o, r = i._data(), - u = i._highlight(n); - i.selectedIndex = u; - u !== -1 && (i._state === e && (i._state = a), i._current.addClass(tt), r = r[u], f = i._text(r), o = i._value(r), i._prev = i.input[0].value = f, i._accessor(o !== t ? o : f, u), i._selectedValue = i._accessor(), i._placeholder(), i._optionID && i._current.attr("aria-selected", !0)) - }, - _wrapper: function() { - var i = this, - n = i.element, - t = n.parent(); - t.is("span.k-widget") || (t = n.hide().wrap("<span />").parent(), t[0].style.cssText = n[0].style.cssText); - i.wrapper = t.addClass("k-widget k-combobox k-header").addClass(n[0].className).css("display", "") - }, - _clearSelection: function(n, t) { - var i = this, - r = n._selectedValue || n.value(), - u = r && n.selectedIndex === -1; - (t || !r || u) && (i.value(""), i.options.value = "") - } - }); - o.plugin(ot) - }(window.kendo.jQuery); -kendo_module({ - id: "multiselect", - name: "MultiSelect", - category: "web", - description: "The MultiSelect widget allows the selection from pre-defined values.", - depends: ["list"], - features: [{ - id: "mobile-scroller", - name: "Mobile scroller", - description: "Support for kinetic scrolling in mobile device", - depends: ["mobile.scroller"] - }] - }), - function(n, t) { - function ni(n, t) { - var i; - if (n === null && t !== null || n !== null && t === null || (i = n.length, i !== t.length)) return !1; - while (i--) - if (n[i] !== t[i]) return !1; - return !0 - } - - function s(t) { - var i = t.firstChild; - return (i && i.style.display === "none" && (i = h(i, it)), i) ? n(i) : i - } - - function lt(t) { - var i = t.lastChild; - return (i && i.style.display === "none" && (i = h(i, rt)), i) ? n(i) : i - } - - function h(n, t) { - return n = n[t], n && n.style.display === "none" && (n = h(n, t)), n - } - var i = window.kendo, - d = i.ui, - f = d.List, - r = i.keys, - g = i._activeElement, - at = i.data.ObservableArray, - c = n.proxy, - e = "id", - v = "li", - y = "accept", - p = "filter", - nt = "open", - tt = "close", - o = "change", - vt = "progress", - w = "select", - it = "nextSibling", - rt = "previousSibling", - yt = ' style="display:none"', - ut = "aria-disabled", - ft = "aria-readonly", - l = "k-state-focused", - b = "k-loading-hidden", - et = "k-state-hover", - k = "k-state-disabled", - ot = "disabled", - st = "readonly", - u = ".kendoMultiSelect", - pt = "click" + u, - wt = "keydown" + u, - ht = "mouseenter" + u, - ct = "mouseleave" + u, - bt = ht + " " + ct, - kt = /"/g, - a = n.isArray, - dt = ["font-family", "font-size", "font-stretch", "font-style", "font-weight", "letter-spacing", "text-transform", "line-height"], - gt = f.extend({ - init: function(t, r) { - var o = this, - s, h; - o.ns = u; - f.fn.init.call(o, t, r); - o._wrapper(); - o._tagList(); - o._input(); - o._textContainer(); - o._loader(); - o._tabindex(o.input); - t = o.element.attr("multiple", "multiple").hide(); - r = o.options; - h = r.value; - r.placeholder || (r.placeholder = t.data("placeholder")); - s = t.attr(e); - s && (o._tagID = s + "_tag_active", s = s + "_taglist", o.tagList.attr(e, s)); - o._aria(s); - o._dataSource(); - o._ignoreCase(); - o._popup(); - o._values = []; - o._dataItems = []; - o._reset(); - o._enable(); - o._placeholder(); - r.autoBind ? o.dataSource.fetch() : h && (a(h) || (h = [h]), (n.isPlainObject(h[0]) || !r.dataValueField) && (o._retrieveData = !0, o.dataSource.data(h), o.value(o._initialValues))); - i.notify(o) - }, - options: { - name: "MultiSelect", - enabled: !0, - autoBind: !0, - autoClose: !0, - highlightFirst: !0, - dataTextField: "", - dataValueField: "", - filter: "startswith", - ignoreCase: !0, - minLength: 0, - delay: 100, - value: null, - maxSelectedItems: null, - itemTemplate: "", - tagTemplate: "", - placeholder: "", - height: 200, - animation: {} - }, - events: [nt, tt, o, w, "dataBinding", "dataBound"], - setDataSource: function(n) { - this.options.dataSource = n; - this._dataSource(); - this.options.autoBind && this.dataSource.fetch() - }, - setOptions: function(n) { - f.fn.setOptions.call(this, n); - this._template(); - this._accessors(); - this._aria(this.tagList.attr(e)) - }, - current: function(n) { - return this.currentTag(null), f.fn.current.call(this, n) - }, - currentTag: function(n) { - var i = this; - if (n !== t) i._currentTag && (i._currentTag.removeClass(l).removeAttr(e), i.input.removeAttr("aria-activedescendant")), n && (n.addClass(l).attr(e, i._tagID), i.input.attr("aria-activedescendant", i._tagID)), i._currentTag = n; - else return i._currentTag - }, - dataItems: function() { - return this._dataItems - }, - destroy: function() { - var n = this, - t = n.ns; - n.wrapper.off(t); - n.tagList.off(t); - n.input.off(t); - f.fn.destroy.call(n) - }, - _editable: function(t) { - var i = this, - r = t.disable, - f = t.readonly, - e = i.wrapper.off(u), - s = i.tagList.off(u), - o = i.element.add(i.input.off(u)); - if (f || r) r ? e.addClass(k) : e.removeClass(k), o.attr(ot, r).attr(st, f).attr(ut, r).attr(ft, f); - else { - e.removeClass(k).on(bt, i._toggleHover).on("mousedown" + u, function(n) { - var t = n.target.nodeName.toLowerCase() !== "input"; - t && n.preventDefault(); - n.target.className.indexOf("k-delete") === -1 && (i.input[0] !== g() && t && i.input.focus(), i.options.minLength === 0 && i.open()) - }); - i.input.on(wt, c(i._keydown, i)).on("paste" + u, c(i._search, i)).on("focus" + u, function() { - i._placeholder(!1) - }).on("blur" + u, function() { - clearTimeout(i._typing); - i._placeholder(); - i.close(); - i._state === p && (i._state = y); - i.element.blur() - }); - o.removeAttr(ot).removeAttr(st).attr(ut, !1).attr(ft, !1); - s.on(ht, v, function() { - n(this).addClass(et) - }).on(ct, v, function() { - n(this).removeClass(et) - }).on(pt, ".k-delete", function(t) { - i._unselect(n(t.target).closest(v)); - i._change(); - i.close() - }) - } - }, - _close: function() { - var n = this; - n.options.autoClose || !n._visibleItems ? n.close() : (n.current(n.options.highlightFirst ? s(n.ul[0]) : null), n.popup._position()) - }, - close: function() { - this.popup.close(); - this.current(null) - }, - open: function() { - var n = this; - !n.ul[0].firstChild || n._state === y || n._retrieveData ? (n._state = "", n._open = !0, n._retrieveData = !1, n._filterSource()) : n._visibleItems && n._allowSelection() && (n.popup.open(), n.current(n.options.highlightFirst ? s(n.ul[0]) : null)) - }, - toggle: function(n) { - n = n !== t ? n : !this.popup.visible(); - this[n ? nt : tt]() - }, - refresh: function() { - var n = this, - i = null, - t; - n.trigger("dataBinding"); - t = n._render(n.dataSource.view()); - n._height(t); - n._setInitialValues && (n._setInitialValues = !1, n.value(n._initialValues)); - n._open && (n._open = !1, n.toggle(t)); - n.popup.visible() && (n.popup._position(), n.options.highlightFirst && (i = s(n.ul[0]))); - n.current(i); - n._touchScroller && n._touchScroller.reset(); - n._makeUnselectable(); - n._hideBusy(); - n.trigger("dataBound") - }, - search: function(n) { - var t = this, - i = t.options, - u = i.ignoreCase, - f = i.filter, - e = i.dataTextField, - r = t.input.val(); - i.placeholder === r && (r = ""); - clearTimeout(t._typing); - n = typeof n == "string" ? n : r; - n.length >= i.minLength && (t._state = p, t._open = !0, t._filterSource({ - value: u ? n.toLowerCase() : n, - field: e, - operator: f, - ignoreCase: u - })) - }, - value: function(i) { - var r = this, - o = n(r.tagList[0].children), - f = o.length, - e, u = 0; - if (i === t) return r._values; - if (!r._fetchItems(i)) { - for (; u < f; u++) r._unselect(o.eq(u)); - if (i !== null) { - for (i = a(i) || i instanceof at ? i : [i], u = 0, f = i.length; u < f; u++) e = r._index(i[u]), e > -1 && r._select(e); - r._old = r._values.slice() - } - } - }, - _dataSource: function() { - var n = this, - u = n.element, - r = n.options, - t = r.dataSource || {}; - t = a(t) ? { - data: t - } : t; - t.select = u; - t.fields = [{ - field: r.dataTextField - }, { - field: r.dataValueField - }]; - n.dataSource && n._refreshHandler ? n._unbindDataSource() : (n._refreshHandler = c(n.refresh, n), n._progressHandler = c(n._showBusy, n)); - n.dataSource = i.data.DataSource.create(t).bind(o, n._refreshHandler).bind(vt, n._progressHandler) - }, - _fetchItems: function(t) { - var i = this, - r = n.isArray(t) && t.length === 0; - if (!r && t && !i._fetch && !i.ul[0].firstChild) { - i.dataSource.one(o, function() { - i.value(t); - i._fetch = !1 - }); - return i._fetch = !0, i.dataSource.fetch(), !0 - } - }, - _reset: function() { - var t = this, - i = t.element, - r = i.attr("form"), - u = r ? n("#" + r) : i.closest("form"); - u[0] && (t._resetHandler = function() { - setTimeout(function() { - t.value(t._initialValues) - }) - }, t._form = u.on("reset", t._resetHandler)) - }, - _initValue: function() { - var t = this, - n = t.options.value || t.element.val(); - n === null ? n = [] : (a(n) || (n = [n]), n = t._mapValues(n)); - t._old = t._initialValues = n; - t._setInitialValues = !!n[0] - }, - _mapValues: function(t) { - var i = this; - return t && n.isPlainObject(t[0]) && (t = n.map(t, function(n) { - return i._value(n) - })), t - }, - _change: function() { - var n = this, - t = n.value(); - ni(t, n._old) || (n._old = t.slice(), n.trigger(o), n.element.trigger(o)) - }, - _click: function(t) { - var i = this, - r = n(t.currentTarget); - if (!t.isDefaultPrevented()) { - if (i.trigger(w, { - item: r - })) { - i._close(); - return - } - i._select(r); - i._change(); - i._close() - } - }, - _item: function(n, t) { - return n = n[t](), n[0] && !n.is(":visible") && (n = this._item(n, t)), n - }, - _keydown: function(t) { - var u = this, - e = t.keyCode, - f = u._currentTag, - o = u._current, - l = u.input.val(), - a = i.support.isRtl(u.wrapper), - c = u.popup.visible(); - if (e === r.DOWN) { - if (t.preventDefault(), !c) { - u.open(); - return - } - o = o ? h(o[0], it) : s(u.ul[0]); - o && u.current(n(o)) - } else if (e === r.UP) c && (o = o ? h(o[0], rt) : lt(u.ul[0]), u.current(n(o)), u._current[0] || u.close()), t.preventDefault(); - else if (e === r.LEFT && !a || e === r.RIGHT && a) l || (f = f ? f.prev() : n(u.tagList[0].lastChild), f[0] && u.currentTag(f)); - else if (e === r.RIGHT && !a || e === r.LEFT && a) !l && f && (f = f.next(), u.currentTag(f[0] ? f : null)); - else if (e === r.ENTER && c) { - if (o) { - if (u.trigger(w, { - item: o - })) { - u._close(); - return - } - u._select(o) - } - u._change(); - u._close(); - t.preventDefault() - } else e === r.ESC ? (c ? t.preventDefault() : u.currentTag(null), u.close()) : e === r.HOME ? c ? u.current(s(u.ul[0])) : l || (f = u.tagList[0].firstChild, f && u.currentTag(n(f))) : e === r.END ? c ? u.current(lt(u.ul[0])) : l || (f = u.tagList[0].lastChild, f && u.currentTag(n(f))) : e !== r.DELETE && e !== r.BACKSPACE || l ? (clearTimeout(u._typing), setTimeout(function() { - u._scale() - }), u._search()) : (e !== r.BACKSPACE || f || (f = n(u.tagList[0].lastChild)), f && f[0] && (u._unselect(f), u._change(), u._close())) - }, - _hideBusy: function() { - var n = this; - clearTimeout(n._busy); - n.input.attr("aria-busy", !1); - n._loading.addClass(b); - n._busy = null - }, - _showBusy: function() { - var n = this; - n._busy || (n._busy = setTimeout(function() { - n.input.attr("aria-busy", !0); - n._loading.removeClass(b) - }, 100)) - }, - _placeholder: function(n) { - var i = this, - r = i.input, - u = g(); - n === t ? (n = !1, r[0] !== u && (n = !i._dataItems[0]), i.wrapper.removeClass(l)) : i.wrapper.addClass(l); - i._prev = ""; - r.toggleClass("k-readonly", n).val(n ? i.options.placeholder : ""); - r[0] === u && f.selectText(r[0], 0, 0); - i._scale() - }, - _scale: function() { - var n = this, - r = n.wrapper, - u = r.width(), - t = n._span.text(n.input.val()), - i; - r.is(":visible") ? i = t.width() + 25 : (t.appendTo(document.documentElement), u = i = t.width() + 25, t.appendTo(r)); - n.input.width(i > u ? u : i) - }, - _option: function(n, r) { - var f = "<option", - e = this._text(n), - u = this._value(n); - return u !== t && (u += "", u.indexOf('"') !== -1 && (u = u.replace(kt, """)), f += ' value="' + u + '"'), r && (f += ' selected="selected"'), f += ">", e !== t && (f += i.htmlEncode(e)), f + "<\/option>" - }, - _render: function(n) { - for (var t = this, r = n.length, c = t.itemTemplate, e = t._dataItems.slice(0), o = 0, i = 0, s = "", h = "", u, f; i < r; i++) u = n[i], f = t._selected(e, u), h += c(u, i, f), s += t._option(u, f), f || (o += 1); - if (r = e.length, r) - for (i = 0; i < r; i++) s += t._option(e[i], !0); - return t.ul[0].innerHTML = h, t.element.html(s), t._visibleItems = o, o - }, - _selected: function(n, i) { - var o = this, - s = o._text, - h = o._value, - f = h(i), - c = n.length, - e = !1, - r, u = 0; - for (f === t && (f = s(i)); u < c; u++) - if (i = n[u], r = h(i), r === t && (r = s(i)), r !== t && r === f) { - e = !0; - break - } - return e && n.splice(u, 1), e - }, - _search: function() { - var n = this; - n._typing = setTimeout(function() { - var t = n.input.val(); - n._prev !== t && (n._prev = t, n.search(t)) - }, n.options.delay) - }, - _allowSelection: function() { - var n = this.options.maxSelectedItems; - return n === null || n > this._values.length - }, - _select: function(n) { - var t = this, - u = t._values, - r, i; - t._allowSelection() && (isNaN(n) ? i = n.hide().data("idx") : (i = n, t.ul[0].children[i].style.display = "none"), t.element[0].children[i].selected = !0, r = t.dataSource.view()[i], t.tagList.append(t.tagTemplate(r)), t._dataItems.push(r), u.push(t._dataValue(r)), t._visibleItems -= 1, t.currentTag(null), t._placeholder(), t._height(t._visibleItems), t._state === p && (t._state = y)) - }, - _unselect: function(t) { - var i = this, - r = t.index(), - o, u, f, e, s; - if (t.remove(), i.currentTag(null), i._values.splice(r, 1), o = i._dataItems.splice(r, 1)[0], u = i._dataValue(o), r = i._index(u), r !== -1) n(i.ul[0].children[r]).show(), i.element[0].children[r].selected = !1, i._visibleItems += 1, i._height(i._visibleItems); - else - for (r = i.dataSource.view().length, f = i.element[0].children, s = f.length; r < s; r++) - if (e = f[r], e.value == u) { - e.selected = !1; - break - } - i._placeholder() - }, - _template: function() { - var t = this, - n = t.options, - r = n.itemTemplate, - u = n.tagTemplate, - e = n.dataSource, - f; - t.element[0].length && !e && (n.dataTextField = n.dataTextField || "text", n.dataValueField = n.dataValueField || "value"); - f = i.template("#:" + i.expr(n.dataTextField, "data") + "#", { - useWithBlock: !1 - }); - r = r ? i.template(r) : f; - u = u ? i.template(u) : f; - t.itemTemplate = function(n, t, i) { - return '<li tabindex="-1" role="option" data-idx="' + t + '" unselectable="on" class="k-item"' + (i ? yt : "") + ">" + r(n) + "<\/li>" - }; - t.tagTemplate = function(n) { - return '<li class="k-button" unselectable="on"><span unselectable="on">' + u(n) + '<\/span><span unselectable="on" class="k-icon k-delete">delete<\/span><\/li>' - } - }, - _input: function() { - var t = this, - r = t.element[0].accessKey, - i = t._innerWrapper.children("input.k-input"); - i[0] || (i = n('<input class="k-input" style="width: 25px" />').appendTo(t._innerWrapper)); - t.element.removeAttr("accesskey"); - t._focused = t.input = i.attr({ - accesskey: r, - role: "listbox", - "aria-expanded": !1 - }) - }, - _tagList: function() { - var t = this, - i = t._innerWrapper.children("ul"); - i[0] || (i = n('<ul role="listbox" unselectable="on" class="k-reset"/>').appendTo(t._innerWrapper)); - t.tagList = i - }, - _loader: function() { - this._loading = n('<span class="k-icon k-loading ' + b + '"><\/span>').insertAfter(this.input) - }, - _textContainer: function() { - var t = i.getComputedStyles(this.input[0], dt); - t.position = "absolute"; - t.visibility = "hidden"; - t.top = -3333; - t.left = -3333; - this._span = n("<span/>").css(t).appendTo(this.wrapper) - }, - _wrapper: function() { - var r = this, - t = r.element, - i = t.parent("span.k-multiselect"); - i[0] || (i = t.wrap('<div class="k-widget k-multiselect k-header" unselectable="on" />').parent(), i[0].style.cssText = t[0].style.cssText, n('<div class="k-multiselect-wrap k-floatwrap" unselectable="on" />').insertBefore(t)); - r.wrapper = i.addClass(t[0].className).css("display", ""); - r._innerWrapper = n(i[0].firstChild) - } - }); - d.plugin(gt) - }(window.kendo.jQuery); -kendo_module({ - id: "columnmenu", - name: "Column Menu", - category: "framework", - depends: ["popup", "filtermenu", "menu"], - advanced: !0 - }), - function(n, t) { - function g(t) { - return n.trim(t).replace(/ /gi, "") - } - var i = window.kendo, - a = i.ui, - e = n.proxy, - d = n.extend, - s = n.grep, - v = n.map, - h = n.inArray, - u = "k-state-selected", - c = "asc", - y = "desc", - p = "change", - w = "init", - o = "select", - l = "kendoPopup", - b = "kendoFilterMenu", - k = "kendoMenu", - r = ".kendoColumnMenu", - f = a.Widget, - nt = f.extend({ - init: function(t, u) { - var o = this, - s; - f.fn.init.call(o, t, u); - t = o.element; - u = o.options; - o.owner = u.owner; - o.dataSource = u.dataSource; - o.field = t.attr(i.attr("field")); - s = t.find(".k-header-column-menu"); - s[0] || (s = t.addClass("k-with-icon").prepend('<a class="k-header-column-menu" href="#"><span class="k-icon k-i-arrowhead-s"/><\/a>').find(".k-header-column-menu")); - o.link = s.attr("tabindex", -1).on("click" + r, e(o._click, o)); - o.wrapper = n('<div class="k-column-menu"/>') - }, - _init: function() { - var n = this; - n.pane = n.options.pane; - n.pane && (n._isMobile = !0); - n._isMobile ? n._createMobileMenu() : n._createMenu(); - n._sort(); - n._columns(); - n._filter(); - n.trigger(w, { - field: n.field, - container: n.wrapper - }) - }, - events: [w], - options: { - name: "ColumnMenu", - messages: { - sortAscending: "Sort Ascending", - sortDescending: "Sort Descending", - filter: "Filter", - columns: "Columns", - done: "Done", - settings: "Column Settings" - }, - filter: "", - columns: !0, - sortable: !0, - filterable: !0, - animations: { - left: "slide" - } - }, - _createMenu: function() { - var n = this, - t = n.options; - n.wrapper.html(i.template(tt)({ - ns: i.ns, - messages: t.messages, - sortable: t.sortable, - filterable: t.filterable, - columns: n._ownerColumns(), - showColumns: t.columns - })); - n.popup = n.wrapper[l]({ - anchor: n.link, - open: e(n._open, n), - activate: e(n._activate, n), - close: n.options.closeCallback - }).data(l); - n.menu = n.wrapper.children()[k]({ - orientation: "vertical", - closeOnClick: !1 - }).data(k) - }, - _createMobileMenu: function() { - var n = this, - t = n.options, - r = i.template(it)({ - ns: i.ns, - field: n.field, - messages: t.messages, - sortable: t.sortable, - filterable: t.filterable, - columns: n._ownerColumns(), - showColumns: t.columns - }); - n.view = n.pane.append(r); - n.wrapper = n.view.element.find(".k-column-menu"); - n.menu = new rt(n.wrapper.children(), { - pane: n.pane - }); - n.view.element.on("click", ".k-done", function(t) { - n.close(); - t.preventDefault() - }) - }, - destroy: function() { - var n = this; - f.fn.destroy.call(n); - n.filterMenu && n.filterMenu.destroy(); - n._refreshHandler && n.dataSource.unbind(p, n._refreshHandler); - n.options.columns && n.owner && (n.owner.unbind("columnShow", n._updateColumnsMenuHandler), n.owner.unbind("columnHide", n._updateColumnsMenuHandler)); - n.menu && (n.menu.element.off(r), n.menu.destroy()); - n.wrapper.off(r); - n.popup && n.popup.destroy(); - n.view && n.view.purge(); - n.link.off(r) - }, - close: function() { - this.menu.close(); - this.popup && (this.popup.close(), this.popup.element.off("keydown" + r)) - }, - _click: function(n) { - n.preventDefault(); - n.stopPropagation(); - var t = this.options; - t.filter && this.element.is(!t.filter) || (this.popup || this.pane || this._init(), this._isMobile ? this.pane.navigate(this.view, this.options.animations.left) : this.popup.toggle()) - }, - _open: function() { - var t = this; - n(".k-column-menu").not(t.wrapper).each(function() { - n(this).data(l).close() - }); - t.popup.element.on("keydown" + r, function(n) { - n.keyCode == i.keys.ESC && t.close() - }) - }, - _activate: function() { - this.menu.element.focus() - }, - _ownerColumns: function() { - var n = this.owner.columns, - t = s(n, function(n) { - var t = !0, - i = g(n.title || ""); - return n.menu !== !1 && (n.field || i.length) || (t = !1), t - }); - return v(t, function(t) { - return { - originalField: t.field, - field: t.field || t.title, - title: t.title || t.field, - hidden: t.hidden, - index: h(t, n) - } - }) - }, - _sort: function() { - var t = this; - t.options.sortable && (t.refresh(), t._refreshHandler = e(t.refresh, t), t.dataSource.bind(p, t._refreshHandler), t.menu.bind(o, function(i) { - var f = n(i.item), - r; - (f.hasClass("k-sort-asc") ? r = c : f.hasClass("k-sort-desc") && (r = y), r) && (f.parent().find(".k-sort-" + (r == c ? y : c)).removeClass(u), t._sortDataSource(f, r), t.close()) - })) - }, - _sortDataSource: function(n, i) { - var f = this, - o = f.options.sortable, - s = f.dataSource, - e, h, r = s.sort() || []; - if (n.hasClass(u) && o && o.allowUnsort !== !1 ? (n.removeClass(u), i = t) : n.addClass(u), o === !0 || o.mode === "single") r = [{ - field: f.field, - dir: i - }]; - else { - for (e = 0, h = r.length; e < h; e++) - if (r[e].field === f.field) { - r.splice(e, 1); - break - } - r.push({ - field: f.field, - dir: i - }) - } - s.sort(r) - }, - _columns: function() { - var t = this; - t.options.columns && (t._updateColumnsMenu(), t._updateColumnsMenuHandler = e(t._updateColumnsMenu, t), t.owner.bind(["columnHide", "columnShow"], t._updateColumnsMenuHandler), t.menu.bind(o, function(r) { - var c = n(r.item), - u, f, e, l = t.owner.columns, - o; - (t._isMobile && r.preventDefault(), c.parent().closest("li.k-columns-item")[0]) && ((u = c.find(":checkbox"), u.attr("disabled")) || (o = u.attr(i.attr("field")), e = s(l, function(n) { - return n.field == o || n.title == o - })[0], f = h(e, l), e.hidden === !0 ? t.owner.showColumn(f) : t.owner.hideColumn(f))) - })) - }, - _updateColumnsMenu: function() { - var r = i.attr("field"), - t = s(this._ownerColumns(), function(n) { - return !n.hidden - }), - u = s(t, function(n) { - return n.originalField - }).length; - t = v(t, function(n) { - return n.field - }); - this.wrapper.find(".k-columns-item input[" + r + "]").prop("checked", !1).filter(function() { - return h(n(this).attr(r), t) > -1 - }).prop("checked", !0).prop("disabled", u == 1) - }, - _filter: function() { - var t = this, - i = t.options; - i.filterable !== !1 && (t.filterMenu = t.wrapper.find(".k-filterable")[b](d(!0, {}, { - appendToElement: !0, - dataSource: i.dataSource, - values: i.values, - field: t.field - }, i.filterable)).data(b), t._isMobile && t.menu.bind(o, function(i) { - var r = n(i.item); - r.hasClass("k-filter-item") && t.pane.navigate(t.filterMenu.view, t.options.animations.left) - })) - }, - refresh: function() { - var n = this, - r = n.options.dataSource.sort() || [], - i, e = n.field, - t, f; - for (n.wrapper.find(".k-sort-asc, .k-sort-desc").removeClass(u), t = 0, f = r.length; t < f; t++) i = r[t], e == i.field && n.wrapper.find(".k-sort-" + i.dir).addClass(u) - } - }), - tt = '<ul>#if(sortable){#<li class="k-item k-sort-asc"><span class="k-link"><span class="k-sprite k-i-sort-asc"><\/span>${messages.sortAscending}<\/span><\/li><li class="k-item k-sort-desc"><span class="k-link"><span class="k-sprite k-i-sort-desc"><\/span>${messages.sortDescending}<\/span><\/li>#if(showColumns || filterable){#<li class="k-separator"><\/li>#}##}##if(showColumns){#<li class="k-item k-columns-item"><span class="k-link"><span class="k-sprite k-i-columns"><\/span>${messages.columns}<\/span><ul>#for (var idx = 0; idx < columns.length; idx++) {#<li><input type="checkbox" data-#=ns#field="#=columns[idx].field.replace(/"/g,"&\\#34;")#" data-#=ns#index="#=columns[idx].index#"/>#=columns[idx].title#<\/li>#}#<\/ul><\/li>#if(filterable){#<li class="k-separator"><\/li>#}##}##if(filterable){#<li class="k-item k-filter-item"><span class="k-link"><span class="k-sprite k-filter"><\/span>${messages.filter}<\/span><ul><li><div class="k-filterable"><\/div><\/li><\/ul><\/li>#}#<\/ul>', - it = '<div data-#=ns#role="view" data-#=ns#init-widgets="false" class="k-grid-column-menu"><div data-#=ns#role="header" class="k-header">${messages.settings}<button class="k-button k-done">#=messages.done#<\/button><\/div><div class="k-column-menu k-mobile-list"><ul><li><span class="k-link">${field}<\/span><ul>#if(sortable){#<li class="k-item k-sort-asc"><span class="k-link"><span class="k-sprite k-i-sort-asc"><\/span>${messages.sortAscending}<\/span><\/li><li class="k-item k-sort-desc"><span class="k-link"><span class="k-sprite k-i-sort-desc"><\/span>${messages.sortDescending}<\/span><\/li>#}##if(filterable){#<li class="k-item k-filter-item"><span class="k-link k-filterable"><span class="k-sprite k-filter"><\/span>${messages.filter}<\/span><\/li>#}#<\/ul><\/li>#if(showColumns){#<li class="k-columns-item"><span class="k-link">${messages.columns}<\/span><ul>#for (var idx = 0; idx < columns.length; idx++) {#<li class="k-item"><label class="k-label"><input type="checkbox" class="k-check" data-#=ns#field="#=columns[idx].field.replace(/"/g,"&\\#34;")#" data-#=ns#index="#=columns[idx].index#"/>#=columns[idx].title#<\/label><\/li>#}#<\/ul><\/li>#}#<\/ul><\/div><\/div>', - rt = f.extend({ - init: function(n, t) { - f.fn.init.call(this, n, t); - this.element.on("click" + r, "li:not(.k-separator)", "_click") - }, - events: [o], - _click: function(n) { - this.trigger(o, { - item: n.currentTarget - }) && n.preventDefault() - }, - close: function() { - this.options.pane.navigate("") - }, - destroy: function() { - f.fn.destroy.call(this); - this.element.off(r) - } - }); - a.plugin(nt) - }(window.kendo.jQuery); -kendo_module({ - id: "grid", - name: "Grid", - category: "web", - description: "The Grid widget displays tabular data and offers rich support for interacting with data,including paging, sorting, grouping, and selection.", - depends: ["data"], - features: [{ - id: "grid-editing", - name: "Editing", - description: "Support for record editing", - depends: ["editable", "window"] - }, { - id: "grid-filtering", - name: "Filtering", - description: "Support for record filtering", - depends: ["filtermenu"] - }, { - id: "grid-columnmenu", - name: "Column menu", - description: "Support for header column menu", - depends: ["columnmenu"] - }, { - id: "grid-grouping", - name: "Grouping", - description: "Support for grid grouping", - depends: ["groupable"] - }, { - id: "grid-paging", - name: "Paging", - description: "Suppot for grid paging", - depends: ["pager"] - }, { - id: "grid-selection", - name: "Selection", - description: "Support for row selection", - depends: ["selectable"] - }, { - id: "grid-sorting", - name: "Sorting", - description: "Support for grid sorting", - depends: ["sortable"] - }, { - id: "grid-column-reorder", - name: "Column reordering", - description: "Support for column reordering", - depends: ["reorderable"] - }, { - id: "grid-column-resize", - name: "Column resizing", - description: "Support for column resizing", - depends: ["resizable"] - }, { - id: "grid-mobile", - name: "Grid adaptive rendering", - description: "Support for adaptive rendering", - depends: ["mobile.actionsheet", "mobile.pane"] - }] - }), - function(n, t) { - function pt(n) { - return new Array(n + 1).join('<td class="k-group-cell"> <\/td>') - } - - function lt(n) { - var t, i = " "; - if (n) { - if (typeof n === c) return n; - for (t in n) i += t + '="' + n[t] + '"' - } - return i - } - - function pr(t) { - var i = 0; - return n("> .k-grouping-header, > .k-grid-toolbar", t).each(function() { - i += this.offsetHeight - }), i - } - - function ui(t, i) { - n("th, th .k-grid-filter, th .k-link", t).add(document.body).css("cursor", i) - } - - function fi(n) { - var t, i, r = {}, - u = {}; - if (!at(n)) - for (k(n) || (n = [n]), t = 0, i = n.length; t < i; t++) r[n[t].aggregate] = 0, u[n[t].field] = r; - return u - } - - function et(n, t, i) { - var r = n.eq(t), - u = n.eq(i); - r[t > i ? "insertBefore" : "insertAfter"](u) - } - - function wr(n, t, i) { - var e, c, u, s; - for (i = k(i) ? i : [i], e = 0, c = i.length; e < c; e++) - if (u = i[e], o(u) && u.click) { - s = u.name || u.text; - t.on(h + r, "a.k-grid-" + (s || "").replace(/\s/g, ""), { - commandName: s - }, f(u.click, n)) - } - } - - function tt(n) { - return b(n, function(n) { - return !n.hidden - }) - } - - function ot(n) { - n = n || {}; - var t = n.style; - return t ? (t = t.replace(/((.*)?display)(.*)?:([^;]*)/i, "$1:none"), t === n.style && (t = t.replace(/(.*)?/i, "display:none;$1"))) : t = "display:none", u({}, n, { - style: t - }) - } - - function ei(n) { - n = n || {}; - var t = n.style; - return t && (n.style = t.replace(/(display\s*:\s*none\s*;?)*/ig, "")), n - } - - function ir(t, r, u, f) { - var o = t.find(">colgroup"), - s, h = bt(r, function(n) { - return (s = n.width, s && parseInt(s, 10) !== 0) ? i.format('<col style="width:{0}"/>', typeof s === c ? s : s + "px") : "<col />" - }); - (u || o.find(".k-hierarchy-col").length) && h.splice(0, 0, '<col class="k-hierarchy-col" />'); - o.length && o.remove(); - o = n(new Array(f + 1).join('<col class="k-group-col">') + h.join("")); - o.is("colgroup") || (o = n("<colgroup/>").append(o)); - t.prepend(o); - e.msie && e.version == 8 && (t.css("display", "inline-table"), window.setTimeout(function() { - t.css("display", "") - }, 1)) - } - - function rr(n) { - for (var r = {}, i, t = 0, u = n.length; t < u; t++) i = n[t], r[i.value] = i.text; - return r - } - - function br(n, t, r) { - var f = r && r.length && o(r[0]) && "value" in r[0], - u = f ? rr(r)[n] : n; - return u = u != null ? u : "", t ? i.format(t, u) : u - } - - function st(n, t, i) { - for (var u = 0, f, r = n[u]; r;) { - if (f = i ? !0 : r.style.display !== "none", f && !ar.test(r.className) && --t < 0) { - r.style.display = i ? "" : "none"; - break - } - r = n[++u] - } - } - - function oi(n, t) { - var r, u, i; - if (typeof n === c && n === t || o(n) && n.name === t) return n; - if (k(n)) - for (r = 0, u = n.length; r < u; r++) - if (i = n[r], typeof i === c && i === t || i.name === t) return i; - return null - } - - function l(t, i) { - var u = e.msie, - r, f, o; - if (i === !0) { - if (t = n(t), r = u && t.parent().is(".k-grid-content,.k-grid-header-wrap"), r && (f = t.parent().scrollTop(), o = t.parent().scrollLeft()), u) try { - t[0].setActive() - } catch (s) { - t[0].focus() - } else t[0].focus(); - r && (t.parent().scrollTop(f), t.parent().scrollLeft(o)) - } else n(t).one("focusin", function(n) { - n.preventDefault() - }).focus() - } - - function dr(t) { - var r = n(t.currentTarget), - f = r.is("th"), - u = r.closest("table")[0]; - i.support.touch || (u === this.table[0] || u === this.thead.parent()[0]) && (this.current(r), (f || !n(t.target).is(":button,a,:input,a>.k-icon,textarea,span.k-icon,span.k-link,.k-input,.k-multiselect-wrap")) && setTimeout(function() { - yr && n(i._activeElement()).hasClass("k-widget") || l(u, !0) - }), f && t.preventDefault()) - } - var i = window.kendo, - it = i.ui, - ur = i.data.DataSource, - fr = it.Groupable, - er = i.support.tbodyInnerHtml, - rt = i._activeElement, - w = it.Widget, - s = i.keys, - o = n.isPlainObject, - u = n.extend, - bt = n.map, - b = n.grep, - k = n.isArray, - d = n.inArray, - f = n.proxy, - or = i.isFunction, - at = n.isEmptyObject, - y = Math, - kt = "progress", - dt = "error", - g = ":not(.k-group-cell):not(.k-hierarchy-cell):visible", - sr = "tbody>tr:not(.k-grouping-row):not(.k-detail-row):not(.k-group-footer) > td:not(.k-group-cell):not(.k-hierarchy-cell)", - ut = "tr:not(.k-footer-template):visible", - v = ":not(.k-group-cell):not(.k-hierarchy-cell):visible", - ft = ut + ":first>" + v + ":first", - vt = "th.k-header:not(.k-group-cell,.k-hierarchy-cell)", - r = ".kendoGrid", - yt = "edit", - gt = "save", - si = "remove", - ni = "detailInit", - hi = "filterMenuInit", - ci = "columnMenuInit", - a = "change", - li = "columnHide", - ai = "columnShow", - vi = "saveChanges", - yi = "dataBound", - pi = "detailExpand", - wi = "detailCollapse", - ht = "k-state-focused", - bi = "k-state-selected", - ki = "columnResize", - di = "columnReorder", - h = "click", - ti = "height", - nt = "tabIndex", - ct = "function", - c = "string", - gi = "Are you sure you want to delete this record?", - hr = "Delete", - cr = "Cancel", - lr = /(\}|\#)/ig, - ii = /#/ig, - nr = "[\\x20\\t\\r\\n\\f]", - ar = new RegExp("(^|" + nr + ")(k-group-cell|k-hierarchy-cell)(" + nr + "|$)"), - vr = '<a class="k-button k-button-icontext #=className#" #=attr# href="\\#"><span class="#=iconClass# #=imageClass#"><\/span>#=text#<\/a>', - p = !1, - e = i.support.browser, - ri = e.msie && e.version == 7, - yr = e.msie && e.version == 8, - tr = w.extend({ - init: function(n, t) { - var i = this; - w.fn.init.call(i, n, t); - i._refreshHandler = f(i.refresh, i); - i.setDataSource(t.dataSource); - i.wrap() - }, - setDataSource: function(n) { - var t = this; - t.dataSource && t.dataSource.unbind(a, t._refreshHandler); - t.dataSource = n; - t.dataSource.bind(a, t._refreshHandler) - }, - options: { - name: "VirtualScrollable", - itemHeight: n.noop - }, - destroy: function() { - var n = this; - w.fn.destroy.call(n); - n.dataSource.unbind(a, n._refreshHandler); - n.wrapper.add(n.verticalScrollbar).off(r); - n.drag && n.drag.destroy() - }, - wrap: function() { - var t = this, - o = i.support.scrollbar() + 1, - u = t.element, - e; - u.css({ - width: "auto", - overflow: "hidden" - }).css(p ? "padding-left" : "padding-right", o); - t.content = u.children().first(); - e = t.wrapper = t.content.wrap('<div class="k-virtual-scrollable-wrap"/>').parent().bind("DOMMouseScroll" + r + " mousewheel" + r, f(t._wheelScroll, t)); - i.support.kineticScrollNeeded && (t.drag = new i.UserEvents(t.wrapper, { - global: !0, - move: function(n) { - t.verticalScrollbar.scrollTop(t.verticalScrollbar.scrollTop() - n.y.delta); - e.scrollLeft(e.scrollLeft() - n.x.delta); - n.preventDefault() - } - })); - t.verticalScrollbar = n('<div class="k-scrollbar k-scrollbar-vertical" />').css({ - width: o - }).appendTo(u).bind("scroll" + r, f(t._scroll, t)) - }, - _wheelScroll: function(n) { - var u = this, - e = u.verticalScrollbar.scrollTop(), - i = n.originalEvent, - f = i.wheelDeltaY, - r; - i.wheelDelta ? (f === t || f) && (r = i.wheelDelta) : i.detail && i.axis === i.VERTICAL_AXIS && (r = -i.detail * 10); - r && (n.preventDefault(), u.verticalScrollbar.scrollTop(e + -r)) - }, - _scroll: function(n) { - var t = this, - i = n.currentTarget.scrollTop, - f = t.dataSource, - r = t.itemHeight, - e = f.skip() || 0, - o = t._rangeStart || e, - s = t.element.innerHeight(), - h = !!(t._scrollbarTop && t._scrollbarTop > i), - u = y.max(y.floor(i / r), 0), - c = y.max(u + y.floor(s / r), 0); - t._scrollTop = i - o * r; - t._scrollbarTop = i; - t._fetch(u, c, h) || (t.wrapper[0].scrollTop = t._scrollTop) - }, - _fetch: function(n, t, i) { - var u = this, - e = u.dataSource, - h = u.itemHeight, - r = e.take(), - f = u._rangeStart || e.skip() || 0, - o = y.floor(n / r) * r, - s = !1, - c = .33; - return n < f ? (s = !0, f = y.max(0, t - r), u._scrollTop = (n - f) * h, u._page(f, r)) : t >= f + r && !i ? (s = !0, f = n, u._scrollTop = h, u._page(f, r)) : u._fetching || (n < o + r - r * c && n > r && e.prefetch(o - r, r), t > o + r * c && e.prefetch(o + r, r)), s - }, - _page: function(n, t) { - var r = this, - u = r.dataSource; - clearTimeout(r._timeout); - r._fetching = !0; - r._rangeStart = n; - u.inRange(n, t) ? u.range(n, t) : (i.ui.progress(r.wrapper.parent(), !0), r._timeout = setTimeout(function() { - u.range(n, t) - }, 100)) - }, - refresh: function() { - var n = this, - u = "", - t = 25e4, - o = n.dataSource, - c = n._rangeStart, - l = i.support.kineticScrollNeeded ? 0 : i.support.scrollbar(), - f = n.wrapper[0], - r, e, s, h; - for (i.ui.progress(n.wrapper.parent(), !1), clearTimeout(n._timeout), s = n.itemHeight = n.options.itemHeight() || 0, h = f.scrollWidth > f.offsetWidth ? l : 0, r = o.total() * s + h, e = 0; e < y.floor(r / t); e++) u += '<div style="width:1px;height:' + t + 'px"><\/div>'; - r % t && (u += '<div style="width:1px;height:' + r % t + 'px"><\/div>'); - n.verticalScrollbar.html(u); - f.scrollTop = n._scrollTop; - n.drag && n.drag.cancel(); - c && !n._fetching && (n._rangeStart = o.skip()); - n._fetching = !1 - } - }), - wt = { - create: { - text: "Add new record", - imageClass: "k-add", - className: "k-grid-add", - iconClass: "k-icon" - }, - cancel: { - text: "Cancel changes", - imageClass: "k-cancel", - className: "k-grid-cancel-changes", - iconClass: "k-icon" - }, - save: { - text: "Save changes", - imageClass: "k-update", - className: "k-grid-save-changes", - iconClass: "k-icon" - }, - destroy: { - text: "Delete", - imageClass: "k-delete", - className: "k-grid-delete", - iconClass: "k-icon" - }, - edit: { - text: "Edit", - imageClass: "k-edit", - className: "k-grid-edit", - iconClass: "k-icon" - }, - update: { - text: "Update", - imageClass: "k-update", - className: "k-grid-update", - iconClass: "k-icon" - }, - canceledit: { - text: "Cancel", - imageClass: "k-cancel", - className: "k-grid-cancel", - iconClass: "k-icon" - } - }, - kr = w.extend({ - init: function(n, t) { - var r = this; - t = k(t) ? { - dataSource: t - } : t; - w.fn.init.call(r, n, t); - p = i.support.isRtl(n); - r._element(); - r._aria(); - r._columns(r.options.columns); - r._dataSource(); - r._tbody(); - r._pageable(); - r._thead(); - r._groupable(); - r._toolbar(); - r._setContentHeight(); - r._templates(); - r._navigatable(); - r._selectable(); - r._details(); - r._editable(); - r._attachCustomCommandsEvent(); - r.options.autoBind ? r.dataSource.fetch() : r._footer(); - i.notify(r) - }, - events: [a, "dataBinding", "cancel", yi, pi, wi, ni, hi, ci, yt, gt, si, vi, ki, di, ai, li], - setDataSource: function(n) { - var t = this; - t.options.dataSource = n; - t._dataSource(); - t._pageable(); - t.options.groupable && t._groupable(); - t._thead(); - t.virtualScrollable && t.virtualScrollable.setDataSource(t.options.dataSource); - t.options.autoBind && n.fetch() - }, - options: { - name: "Grid", - columns: [], - toolbar: null, - autoBind: !0, - filterable: !1, - scrollable: !0, - sortable: !1, - selectable: !1, - navigatable: !1, - pageable: !1, - editable: !1, - groupable: !1, - rowTemplate: "", - altRowTemplate: "", - dataSource: {}, - height: null, - resizable: !1, - reorderable: !1, - columnMenu: !1, - detailTemplate: null, - columnResizeHandleWidth: 3, - mobile: "" - }, - destroy: function() { - var t = this, - u; - w.fn.destroy.call(t); - t.pager && t.pager.destroy(); - t.groupable && t.groupable.destroy(); - t.options.reorderable && t.wrapper.data("kendoReorderable").destroy(); - t.selectable && t.selectable.destroy(); - t.resizable && (t.resizable.destroy(), t._resizeUserEvents && (t._resizeHandleDocumentClickHandler && n(document).off("click", t._resizeHandleDocumentClickHandler), t._resizeUserEvents.destroy())); - t.virtualScrollable && t.virtualScrollable.destroy(); - t._destroyColumnAttachments(); - t._destroyEditable(); - t.dataSource.unbind(a, t._refreshHandler).unbind(kt, t._progressHandler).unbind(dt, t._errorHandler); - u = t.element.add(t.wrapper).add(t.table).add(t.thead).add(t.wrapper.find(">.k-grid-toolbar")); - t.content && (u = u.add(t.content).add(t.content.find(">.k-virtual-scrollable-wrap"))); - t.pane && t.pane.destroy(); - u.off(r); - i.destroy(t.wrapper) - }, - setOptions: function(n) { - var t = this; - w.fn.setOptions.call(this, n); - t._templates() - }, - items: function() { - return this.tbody.children(":not(.k-grouping-row,.k-detail-row,.k-group-footer)") - }, - _destroyColumnAttachments: function() { - var t = this; - t.resizeHandle = null; - t.thead.find("th").each(function() { - var t = n(this), - i = t.data("kendoFilterMenu"), - r = t.data("kendoSortable"), - u = t.data("kendoColumnMenu"); - i && i.destroy(); - r && r.destroy(); - u && u.destroy() - }) - }, - _attachCustomCommandsEvent: function() { - for (var t = this, r = t.columns || [], i, n = 0, u = r.length; n < u; n++) i = r[n].command, i && wr(t, t.wrapper, i) - }, - _aria: function() { - var n = this.element.attr("id") || "aria"; - n && (this._cellId = n + "_active_cell") - }, - _element: function() { - var t = this, - i = t.element; - i.is("table") || (i = t.options.scrollable ? t.element.find("> .k-grid-content > table") : t.element.children("table"), i.length || (i = n("<table />").appendTo(t.element))); - ri && i.attr("cellspacing", 0); - t.table = i.attr("role", t._hasDetails() ? "treegrid" : "grid"); - t._wrapper() - }, - _createResizeHandle: function(t, i) { - var u = this, - s = u.options.columnResizeHandleWidth, - h = u.options.scrollable, - f = u.resizeHandle, - o; - if (f || (f = u.resizeHandle = n('<div class="k-resize-handle"><div class="k-resize-handle-inner"><\/div><\/div>'), t.append(f)), p) { - var r = i.closest(".k-grid-header-wrap"), - c = e.msie ? r.scrollLeft() : 0, - l = e.webkit ? r[0].scrollWidth - r[0].offsetWidth - r.scrollLeft() : 0, - a = e.mozilla ? r[0].scrollWidth - r[0].offsetWidth - (r[0].scrollWidth - r[0].offsetWidth - r.scrollLeft()) : 0; - o = i.position().left - l + a - c - } else o = i[0].offsetWidth, i.prevAll(":visible").each(function() { - o += this.offsetWidth - }); - f.css({ - top: h ? 0 : pr(u.wrapper), - left: o - s, - height: i.outerHeight(), - width: s * 3 - }).data("th", i).show() - }, - _positionColumnResizeHandle: function(t) { - var i = this, - u = i.resizeHandle, - f = i.options.columnResizeHandleWidth; - i.thead.on("mousemove" + r, "th:not(.k-group-cell,.k-hierarchy-cell)", function(r) { - var e = n(this), - o = r.clientX, - s = n(window).scrollLeft(), - h = e.offset().left + (p ? 0 : this.offsetWidth); - o + s > h - f && o + s < h + f ? i._createResizeHandle(t, e) : u ? u.hide() : ui(i.wrapper, "") - }) - }, - _resizeHandleDocumentClick: function(t) { - n(t.target).closest(".k-column-active").length || (n(document).off(t), this._hideResizeHandle()) - }, - _hideResizeHandle: function() { - this.resizeHandle && (this.resizeHandle.data("th").removeClass("k-column-active"), this.resizeHandle.hide()) - }, - _positionColumnResizeHandleTouch: function(t) { - var r = this; - r._resizeUserEvents = new i.UserEvents(r.thead, { - filter: "th:not(.k-group-cell,.k-hierarchy-cell)", - threshold: 10, - hold: function(i) { - var u = n(i.target); - i.preventDefault(); - u.addClass("k-column-active"); - r._createResizeHandle(t, u); - r._resizeHandleDocumentClickHandler || (r._resizeHandleDocumentClickHandler = f(r._resizeHandleDocumentClick, r)); - n(document).on("click", r._resizeHandleDocumentClickHandler) - } - }) - }, - _resizable: function() { - var t = this, - r = t.options, - u, e, f, o, h = this._isMobile, - s, i; - r.resizable && (u = r.scrollable ? t.wrapper.find(".k-grid-header-wrap:first") : t.wrapper, h ? t._positionColumnResizeHandleTouch(u) : t._positionColumnResizeHandle(u), t.resizable = new it.Resizable(u, { - handle: ".k-resize-handle", - hint: function(i) { - return n('<div class="k-grid-resize-indicator" />').css({ - height: i.data("th").outerHeight() + t.tbody.attr("clientHeight") - }) - }, - start: function(u) { - i = n(u.currentTarget).data("th"); - h && t._hideResizeHandle(); - var c = n.inArray(i[0], i.parent().children(":visible")), - l = t.tbody.parent(), - a = t.footer || n(); - ui(t.wrapper, "col-resize"); - s = r.scrollable ? t.thead.parent().find("col:eq(" + c + ")").add(l.children("colgroup").find("col:eq(" + c + ")")).add(a.find("colgroup").find("col:eq(" + c + ")")) : l.children("colgroup").find("col:eq(" + c + ")"); - e = u.x.location; - f = i.outerWidth(); - o = t.tbody.outerWidth() - }, - resize: function(i) { - var u = p ? -1 : 1, - h = f + i.x.location * u - e * u, - c = t.footer || n(); - h > 10 && (s.css("width", h), r.scrollable && o && (t._footerWidth = o + i.x.location * u - e * u, t.tbody.parent().add(t.thead.parent()).add(c.find("table")).css("width", t._footerWidth))) - }, - resizeend: function() { - var n = i.outerWidth(), - r; - ui(t.wrapper, ""); - f != n && (r = t.columns[i.parent().find("th:not(.k-group-cell,.k-hierarchy-cell)").index(i)], r.width = n, t.trigger(ki, { - column: r, - oldWidth: f, - newWidth: n - })); - t._hideResizeHandle(); - i = null - } - })) - }, - _draggable: function() { - var t = this; - t.options.reorderable && (t._draggableInstance && t._draggableInstance.destroy(), t._draggableInstance = t.wrapper.kendoDraggable({ - group: i.guid(), - filter: t.content ? ".k-grid-header:first " + vt : "table:first>.k-grid-header " + vt, - drag: function() { - t._hideResizeHandle() - }, - hint: function(t) { - return n('<div class="k-header k-drag-clue" />').css({ - width: t.width(), - paddingLeft: t.css("paddingLeft"), - paddingRight: t.css("paddingRight"), - lineHeight: t.height() + "px", - paddingTop: t.css("paddingTop"), - paddingBottom: t.css("paddingBottom") - }).html(t.attr(i.attr("title")) || t.attr(i.attr("field")) || t.text()).prepend('<span class="k-icon k-drag-status k-denied" />') - } - }).data("kendoDraggable")) - }, - _reorderable: function() { - var n = this; - n.options.reorderable && n.wrapper.kendoReorderable({ - draggable: n._draggableInstance, - change: function(t) { - var r = d(n.columns[t.newIndex], n.columns), - i = n.columns[t.oldIndex]; - n.trigger(di, { - newIndex: r, - oldIndex: d(i, n.columns), - column: i - }); - n.reorderColumn(r, i) - } - }) - }, - reorderColumn: function(n, t) { - var i = this, - r = d(t, i.columns), - e = d(t, tt(i.columns)), - o = d(i.columns[n], tt(i.columns)), - s, u, h, f = i.footer || i.wrapper.find(".k-grid-footer"); - if (r !== n) - for (i._hideResizeHandle(), i.columns.splice(r, 1), i.columns.splice(n, 0, t), i._templates(), et(i.thead.prev().find("col:not(.k-group-col,.k-hierarchy-col)"), e, o), i.options.scrollable && et(i.tbody.prev().find("col:not(.k-group-col,.k-hierarchy-col)"), e, o), et(i.thead.find(".k-header:not(.k-group-cell,.k-hierarchy-cell)"), r, n), f && f.length && (et(f.find(".k-grid-footer-wrap>table>colgroup>col:not(.k-group-col,.k-hierarchy-col)"), e, o), et(f.find(".k-footer-template>td:not(.k-group-cell,.k-hierarchy-cell)"), r, n)), s = i.tbody.children(":not(.k-grouping-row,.k-detail-row)"), u = 0, h = s.length; u < h; u += 1) et(s.eq(u).find(">td:not(.k-group-cell,.k-hierarchy-cell)"), r, n) - }, - cellIndex: function(t) { - return n(t).parent().children("td:not(.k-group-cell,.k-hierarchy-cell)").index(t) - }, - _modelForContainer: function(t) { - t = n(t); - t.is("tr") || this._editMode() === "popup" || (t = t.closest("tr")); - var r = t.attr(i.attr("uid")); - return this.dataSource.getByUid(r) - }, - _editable: function() { - var t = this, - f = t.selectable && t.selectable.options.multiple, - i = t.options.editable, - e = function() { - var i = rt(), - r = t._editContainer; - !r || n.contains(r[0], i) || r[0] === i || n(i).closest(".k-animation-container").length || t.editable.end() && t.closeCell() - }, - u; - if (i) { - if (u = t._editMode(), u === "incell") { - if (i.update !== !1) t.wrapper.on(h + r, "tr:not(.k-grouping-row) > td", function(i) { - var r = n(this); - r.hasClass("k-hierarchy-cell") || r.hasClass("k-detail-cell") || r.hasClass("k-group-cell") || r.hasClass("k-edit-cell") || r.has("a.k-grid-delete").length || r.has("button.k-grid-delete").length || r.closest("tbody")[0] !== t.tbody[0] || n(i.target).is(":input") || (t.editable ? t.editable.end() && (f && n(rt()).blur(), t.closeCell(), t.editCell(r)) : t.editCell(r)) - }).on("focusin" + r, function() { - clearTimeout(t.timer); - t.timer = null - }).on("focusout" + r, function() { - t.timer = setTimeout(e, 1) - }) - } else if (i.update !== !1) t.wrapper.on(h + r, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible a.k-grid-edit", function(i) { - i.preventDefault(); - t.editRow(n(this).closest("tr")) - }); - if (i.destroy !== !1) t.wrapper.on(h + r, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible .k-grid-delete", function(i) { - i.preventDefault(); - i.stopPropagation(); - t.removeRow(n(this).closest("tr")) - }); - else t.wrapper.on(h + r, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible button.k-grid-delete", function(n) { - n.stopPropagation(); - t._confirmation() || n.preventDefault() - }) - } - }, - editCell: function(t) { - t = n(t); - var i = this, - r = i.columns[i.cellIndex(t)], - u = i._modelForContainer(t); - u && (!u.editable || u.editable(r.field)) && !r.command && r.field && (i._attachModelChange(u), i._editContainer = t, i.editable = t.addClass("k-edit-cell").kendoEditable({ - fields: { - field: r.field, - format: r.format, - editor: r.editor, - values: r.values - }, - model: u, - change: function(n) { - i.trigger(gt, { - values: n.values, - container: t, - model: u - }) && n.preventDefault() - } - }).data("kendoEditable"), t.parent().addClass("k-grid-edit-row"), i.trigger(yt, { - container: t, - model: u - })) - }, - _destroyEditable: function() { - var n = this, - t = function() { - n.editable && (n._detachModelChange(), n.editable.destroy(), n.editable = null, n._editContainer = null, n._destroyEditView()) - }; - n.editable && (n._editMode() !== "popup" || n._isMobile ? t() : n._editContainer.data("kendoWindow").bind("deactivate", t).close()); - n._actionSheet && (n._actionSheet.destroy(), n._actionSheet = null) - }, - _destroyEditView: function() { - this.editView && (this.editView.purge(), this.editView = null, this.pane.navigate("")) - }, - _attachModelChange: function(n) { - var t = this; - t._modelChangeHandler = function(n) { - t._modelChange({ - field: n.field, - model: this - }) - }; - n.bind("change", t._modelChangeHandler) - }, - _detachModelChange: function() { - var n = this, - i = n._editContainer, - t = n._modelForContainer(i); - t && t.unbind(a, n._modelChangeHandler) - }, - closeCell: function(t) { - var u = this, - r = u._editContainer, - e, o, f; - r && ((e = r.closest("tr").attr(i.attr("uid")), f = u.dataSource.getByUid(e), t && u.trigger("cancel", { - container: r, - model: f - })) || (r.removeClass("k-edit-cell"), o = u.columns[u.cellIndex(r)], r.parent().removeClass("k-grid-edit-row"), u._destroyEditable(), u._displayCell(r, o, f), r.hasClass("k-dirty-cell") && n('<span class="k-dirty"/>').prependTo(r))) - }, - _displayCell: function(n, t, r) { - var s = this, - e = { - storage: {}, - count: 0 - }, - h = u({}, i.Template, s.options.templateSettings), - o = i.template(s._cellTmpl(t, e), h); - e.count > 0 && (o = f(o, e.storage)); - n.empty().html(o(r)) - }, - removeRow: function(n) { - this._confirmation(n) && this._removeRow(n) - }, - _removeRow: function(t) { - var i = this, - r, u; - t = n(t).hide(); - r = i._modelForContainer(t); - r && !i.trigger(si, { - row: t, - model: r - }) && (u = i._editMode(), u !== "incell" && i.cancelRow(), i.dataSource.remove(r), (u === "inline" || u === "popup") && i.dataSource.sync()) - }, - _editMode: function() { - var t = "incell", - n = this.options.editable; - return n !== !0 && (t = typeof n == "string" ? n : n.mode || t), t - }, - editRow: function(t) { - var f, u = this, - e, s, o; - if (t instanceof i.data.ObservableObject ? f = t : (t = n(t), f = u._modelForContainer(t)), e = u._editMode(), s = u.options.navigatable, u.cancelRow(), f) { - u._attachModelChange(f); - e === "popup" ? u._createPopupEditor(f) : e === "inline" ? u._createInlineEditor(t, f) : e === "incell" && n(t).children(g).each(function() { - var t = n(this), - i = u.columns[t.index()]; - return f = u._modelForContainer(t), f && (!f.editable || f.editable(i.field)) && i.field ? (u.editCell(t), !1) : void 0 - }); - o = u.editView ? u.editView.element : u._editContainer; - o.on(h + r, "a.k-grid-cancel", function(t) { - if (t.preventDefault(), t.stopPropagation(), !u.trigger("cancel", { - container: o, - model: f - })) { - var i = u.items().index(n(u.current()).parent()); - u.cancelRow(); - s && (u.current(u.items().eq(i).children().filter(v).first()), l(u.table, !0)) - } - }); - o.on(h + r, "a.k-grid-update", function(n) { - n.preventDefault(); - n.stopPropagation(); - u.saveRow() - }) - } - }, - _createPopupEditor: function(t) { - var r = this, - s = "<div " + i.attr("uid") + '="' + t.uid + '" class="k-popup-edit-form' + (r._isMobile ? " k-mobile-list" : "") + '"><div class="k-edit-form-container">', - e, h, ut = [], - a, k, d, tt, it, y, p, rt = r.options.editable, - w = rt.template, - g = o(rt) ? rt.window : {}, - ft = u({}, i.Template, r.options.templateSettings), - nt, b; - if (g = g || {}, w) - for (typeof w === c && (w = window.unescape(w)), s += i.template(w, ft)(t), a = 0, k = r.columns.length; a < k; a++) e = r.columns[a], e.command && (y = oi(e.command, "edit"), y && (h = y)); - else - for (a = 0, k = r.columns.length; a < k; a++) e = r.columns[a], e.command ? e.command && (y = oi(e.command, "edit"), y && (h = y)) : (s += '<div class="k-edit-label"><label for="' + e.field + '">' + (e.title || e.field || "") + "<\/label><\/div>", (!t.editable || t.editable(e.field)) && e.field ? (ut.push({ - field: e.field, - format: e.format, - editor: e.editor, - values: e.values - }), s += "<div " + i.attr("container-for") + '="' + e.field + '" class="k-edit-field"><\/div>') : (nt = { - storage: {}, - count: 0 - }, d = i.template(r._cellTmpl(e, nt), ft), nt.count > 0 && (d = f(d, nt.storage)), s += '<div class="k-edit-field">' + d(t) + "<\/div>")); - h && o(h) && (h.text && o(h.text) && (tt = h.text.update, it = h.text.cancel), h.attr && (p = h.attr)); - r._isMobile ? (s += "<\/div><\/div>", r.editView = r.pane.append("<div data-" + i.ns + 'role="view" data-' + i.ns + 'init-widgets="false" class="k-grid-edit-form"><div data-' + i.ns + 'role="header" class="k-header">' + r._createButton({ - name: "update", - text: tt, - attr: p - }) + (g.title || "Edit") + r._createButton({ - name: "canceledit", - text: it, - attr: p - }) + "<\/div>" + s + "<\/div>"), b = r._editContainer = r.editView.element.find(".k-popup-edit-form")) : (s += '<div class="k-edit-buttons k-state-default">', s += r._createButton({ - name: "update", - text: tt, - attr: p - }) + r._createButton({ - name: "canceledit", - text: it, - attr: p - }), s += "<\/div><\/div><\/div>", b = r._editContainer = n(s).appendTo(r.wrapper).eq(0).kendoWindow(u({ - modal: !0, - resizable: !1, - draggable: !0, - title: "Edit", - visible: !1, - close: function(i) { - if (i.userTriggered) { - if (i.sender.element.focus(), r.trigger("cancel", { - container: b, - model: t - })) { - i.preventDefault(); - return - } - var u = r.items().index(n(r.current()).parent()); - r.cancelRow(); - r.options.navigatable && (r.current(r.items().eq(u).children().filter(v).first()), l(r.table, !0)) - } - } - }, g))); - r.editable = r._editContainer.kendoEditable({ - fields: ut, - model: t, - clearContainer: !1 - }).data("kendoEditable"); - r._isMobile && b.find("input[type=checkbox],input[type=radio]").parent(".k-edit-field").addClass("k-check").prev(".k-edit-label").addClass("k-check").click(function() { - n(this).next().children("input").click() - }); - r._openPopUpEditor(); - r.trigger(yt, { - container: b, - model: t - }) - }, - _openPopUpEditor: function() { - this._isMobile ? this.pane.navigate(this.editView, this._editAnimation) : this._editContainer.data("kendoWindow").center().open() - }, - _createInlineEditor: function(t, r) { - var e = this, - u, s, f, h = []; - t.children(":not(.k-group-cell,.k-hierarchy-cell)").each(function() { - if (s = n(this), u = e.columns[e.cellIndex(s)], !u.command && u.field && (!r.editable || r.editable(u.field))) h.push({ - field: u.field, - format: u.format, - editor: u.editor, - values: u.values - }), s.attr(i.attr("container-for"), u.field), s.empty(); - else if (u.command && (f = oi(u.command, "edit"), f)) { - s.empty(); - var c, l, t; - o(f) && (f.text && o(f.text) && (c = f.text.update, l = f.text.cancel), f.attr && (t = f.attr)); - n(e._createButton({ - name: "update", - text: c, - attr: t - }) + e._createButton({ - name: "canceledit", - text: l, - attr: t - })).appendTo(s) - } - }); - e._editContainer = t; - e.editable = t.addClass("k-grid-edit-row").kendoEditable({ - fields: h, - model: r, - clearContainer: !1 - }).data("kendoEditable"); - e.trigger(yt, { - container: t, - model: r - }) - }, - cancelRow: function() { - var n = this, - t = n._editContainer, - r; - t && (r = n._modelForContainer(t), n._destroyEditable(), n.dataSource.cancelChanges(r), n._editMode() !== "popup" ? n._displayRow(t) : n._displayRow(n.items().filter("[" + i.attr("uid") + "=" + r.uid + "]"))) - }, - saveRow: function() { - var n = this, - t = n._editContainer, - r = n._modelForContainer(t), - i = n.editable; - t && i && i.end() && !n.trigger(gt, { - container: t, - model: r - }) && n.dataSource.sync() - }, - _displayRow: function(t) { - var i = this, - r = i._modelForContainer(t); - r && t.replaceWith(n((t.hasClass("k-alt") ? i.altRowTemplate : i.rowTemplate)(r))) - }, - _showMessage: function(t, r) { - var u = this; - if (!u._isMobile) return window.confirm(t.title); - var f = i.template('<ul><li class="km-actionsheet-title">#:title#<\/li><li><a href="\\#" class="k-button k-grid-delete">#:confirmDelete#<\/a><\/li><\/ul>'), - e = n(f(t)).appendTo(u.view.element), - o = u._actionSheet = new i.mobile.ui.ActionSheet(e, { - cancel: t.cancelDelete, - cancelTemplate: '<li class="km-actionsheet-cancel"><a class="k-button" href="\\#">#:cancel#<\/a><\/li>', - close: function() { - this.destroy() - }, - command: function(t) { - var i = n(t.currentTarget).parent(); - i.hasClass("km-actionsheet-cancel") || u._removeRow(r) - }, - popup: u._actionSheetPopupOptions - }); - return o.open(r), !1 - }, - _confirmation: function(n) { - var r = this, - t = r.options.editable, - i = t === !0 || typeof t === c ? gi : t.confirmation; - return i !== !1 && i != null ? r._showMessage({ - confirmDelete: t.confirmDelete || hr, - cancelDelete: t.cancelDelete || cr, - title: i === !0 ? gi : i - }, n) : !0 - }, - cancelChanges: function() { - this.dataSource.cancelChanges() - }, - saveChanges: function() { - var n = this; - (n.editable && n.editable.end() || !n.editable) && !n.trigger(vi) && n.dataSource.sync() - }, - addRow: function() { - var n = this, - r, t = n.dataSource, - f = n._editMode(), - c = n.options.editable.createAt || "", - e = t.pageSize(), - o = t.view() || []; - if (n.editable && n.editable.end() || !n.editable) { - f != "incell" && n.cancelRow(); - r = t.indexOf(o[0]); - c.toLowerCase() == "bottom" && (r += o.length, e && !t.options.serverPaging && e <= o.length && (r -= 1)); - r < 0 && (r = t.page() > t.totalPages() ? (t.page() - 1) * e : 0); - var s = t.insert(r, {}), - l = s.uid, - u = n.table.find("tr[" + i.attr("uid") + "=" + l + "]"), - h = u.children("td:not(.k-group-cell,.k-hierarchy-cell)").eq(n._firstEditableColumnIndex(u)); - f === "inline" && u.length ? n.editRow(u) : f === "popup" ? n.editRow(s) : h.length && n.editCell(h) - } - }, - _firstEditableColumnIndex: function(n) { - for (var u = this, i, f = u.columns, r = u._modelForContainer(n), t = 0, e = f.length; t < e; t++) - if (i = f[t], r && (!r.editable || r.editable(i.field)) && !i.command && i.field) return t; - return -1 - }, - _toolbar: function() { - var t = this, - s = t.wrapper, - u = t.options.toolbar, - o = t.options.editable, - e; - if (u && (e = t.wrapper.find(".k-grid-toolbar"), e.length || (or(u) || (u = typeof u === c ? u : t._toolbarTmpl(u).replace(ii, "\\#"), u = f(i.template(u), t)), e = n('<div class="k-toolbar k-grid-toolbar" />').html(u({})).prependTo(s)), o && o.create !== !1)) e.on(h + r, ".k-grid-add", function(n) { - n.preventDefault(); - t.addRow() - }).on(h + r, ".k-grid-cancel-changes", function(n) { - n.preventDefault(); - t.cancelChanges() - }).on(h + r, ".k-grid-save-changes", function(n) { - n.preventDefault(); - t.saveChanges() - }) - }, - _toolbarTmpl: function(n) { - var u = this, - t, i, r = ""; - if (k(n)) - for (t = 0, i = n.length; t < i; t++) r += u._createButton(n[t]); - return r - }, - _createButton: function(n) { - var f = n.template || vr, - t = typeof n === c ? n : n.name || n.text, - e = wt[t] ? wt[t].className : "k-grid-" + (t || "").replace(/\s/g, ""), - r = { - className: e, - text: t, - imageClass: "", - attr: "", - iconClass: "" - }; - if (!t && !(o(n) && n.template)) throw new Error("Custom commands should have name specified"); - return o(n) ? (n.className && (n.className += " " + r.className), t === "edit" && o(n.text) && (n = u(!0, {}, n), n.text = n.text.edit), n.attr && o(n.attr) && (n.attr = lt(n.attr)), r = u(!0, r, wt[t], n)) : r = u(!0, r, wt[t]), i.template(f)(r) - }, - _hasFooters: function() { - for (var t = this.columns, i = t.length, n = 0; n < i; n++) - if (t[n].footerTemplate !== "" || t[n].groupFooterTemplate !== "") return !0; - return !1 - }, - _groupable: function() { - var t = this; - t._groupableClickHandler ? t.table.off(h + r, t._groupableClickHandler) : t._groupableClickHandler = function(i) { - var r = n(this), - u = r.closest("tr"); - r.hasClass("k-i-collapse") ? t.collapseGroup(u) : t.expandGroup(u); - i.preventDefault(); - i.stopPropagation() - }; - t.table.on(h + r, ".k-grouping-row .k-i-collapse, .k-grouping-row .k-i-expand", t._groupableClickHandler); - t._attachGroupable() - }, - _attachGroupable: function() { - var t = this, - r = t.wrapper, - f = t.options.groupable, - e = vt + ":visible[" + i.attr("field") + "]", - o = vt + "[" + i.attr("field") + "]"; - f && (r.has("div.k-grouping-header")[0] || n("<div> <\/div>").addClass("k-grouping-header").prependTo(r), t.groupable && t.groupable.destroy(), t.groupable = new fr(r, u({}, f, { - draggable: t._draggableInstance, - groupContainer: ">div.k-grouping-header", - dataSource: t.dataSource, - draggableElements: t.content ? ".k-grid-header:first " + e : "table:first>.k-grid-header " + e, - filter: t.content ? ".k-grid-header:first " + o : "table:first>.k-grid-header " + o, - allowDrag: t.options.reorderable - }))) - }, - _selectable: function() { - var n = this, - f, e, t = [], - u = n.options.selectable; - if (u && (f = typeof u === c && u.toLowerCase().indexOf("multiple") > -1, e = typeof u === c && u.toLowerCase().indexOf("cell") > -1, n._hasDetails() && (t[t.length] = ".k-detail-row"), (n.options.groupable || n._hasFooters()) && (t[t.length] = ".k-grouping-row,.k-group-footer"), t = t.join(","), t !== "" && (t = ":not(" + t + ")"), n.selectable = new i.ui.Selectable(n.table, { - filter: ">" + (e ? sr : "tbody>tr" + t), - aria: !0, - multiple: f, - change: function() { - n.trigger(a) - } - }), n.options.navigatable)) n.table.on("keydown" + r, function(t) { - var i = n.current(); - if (t.keyCode === s.SPACEBAR && t.target == n.table[0] && !i.is(".k-edit-cell,.k-header") && i.parent().is(":not(.k-grouping-row,.k-detail-row,.k-group-footer)")) { - if (t.preventDefault(), t.stopPropagation(), i = e ? i : i.parent(), f) - if (t.ctrlKey) { - if (i.hasClass(bi)) { - i.removeClass(bi); - n.trigger(a); - return - } - } else n.selectable.clear(); - else n.selectable.clear(); - n.selectable.value(i) - } - }) - }, - clearSelection: function() { - var n = this; - n.selectable.clear(); - n.trigger(a) - }, - select: function(t) { - var r = this, - i = r.selectable; - if (t = n(t), t.length) { - i.options.multiple || (i.clear(), t = t.first()); - i.value(t); - return - } - return i.value() - }, - current: function(i) { - var r = this, - f = r.options.scrollable, - u = r._current, - e = r.table.add(r.thead.parent()); - return i !== t && i.length && (u && u[0] === i[0] || (u && (u.removeClass(ht).removeAttr("id"), e.removeAttr("aria-activedescendant")), i.attr("id", r._cellId), r._current = i.addClass(ht), e.attr("aria-activedescendant", r._cellId), i.length && f && (n.contains(r.content[0], i[0]) && r._scrollTo(i.parent()[0], r.content[0]), f.virtual ? r._scrollTo(i[0], r.content.find(">.k-virtual-scrollable-wrap")[0]) : r._scrollTo(i[0], r.content[0])))), r._current - }, - _removeCurrent: function() { - this._current && (this._current.removeClass(ht), this._current = null) - }, - _scrollTo: function(n, t) { - var e = n.tagName.toLowerCase(), - i = e === "td" || e === "th", - r = n[i ? "offsetLeft" : "offsetTop"], - o = n[i ? "offsetWidth" : "offsetHeight"], - u = t[i ? "scrollLeft" : "scrollTop"], - f = t[i ? "clientWidth" : "clientHeight"], - s = r + o, - h = 0; - h = u > r ? r : s > u + f ? o <= f ? s - f : r : u; - t[i ? "scrollLeft" : "scrollTop"] = h - }, - _navigatable: function() { - var t = this, - o = f(t.current, t), - u = t.table, - h = t.thead.parent(), - c = u, - a = i.support.isRtl(t.element); - if (t.options.navigatable) { - t.options.scrollable && (c = u.add(h), h.attr(nt, -1)); - h.on("keydown" + r, function(n) { - n.altKey && n.keyCode == s.DOWN && (o().find(".k-grid-filter, .k-header-column-menu").click(), n.stopImmediatePropagation()) - }).find("a.k-link").attr("tabIndex", -1); - u.attr(nt, y.max(u.attr(nt) || 0, 0)).on("mousedown" + r + " keydown" + r, ".k-detail-cell", function(n) { - n.target !== n.currentTarget && n.stopImmediatePropagation() - }); - c.on(i.support.touch ? "touchstart" + r : "mousedown" + r, ut + ">" + v, f(dr, t)).on("focus" + r, function() { - if (!i.support.touch) { - var t = o(); - t && t.is(":visible") ? t.addClass(ht) : o(n(this).find(ft)); - this == u[0] ? (h.attr(nt, -1), u.attr(nt, 0)) : (u.attr(nt, -1), h.attr(nt, 0)) - } - }).on("focusout" + r, function() { - var n = o(); - n && n.removeClass(ht) - }).on("keydown" + r, function(i) { - var h = i.keyCode, - f = !1, - p = !i.isDefaultPrevented() && !n(i.target).is(":button,a,:input,a>.k-icon"), - st = t.options.pageable, - w = t.dataSource, - nt = t._editMode() == "incell", - b, tt, c, k, it, et = i.shiftKey, - r = o(), - ot, d, y; - r && r.is("th") && (p = !0); - p && h == s.UP ? (r ? (c = r.parent().prevAll(ut).first(), c[0] || (it = t.thead.parent(), l(it, !0), c = it.find(ut).first()), k = r.index(), r = c.children().eq(k), r[0] && r.is(v) || (r = c.children(v).first())) : r = u.find(ft), f = !0, o(r)) : p && h == s.DOWN ? (r ? (c = r.parent().nextAll(ut).first(), !c[0] && r.is("th") && (l(t.tbody.parent()), c = t.tbody.find(ut).first()), k = r.index(), r = c.children().eq(k), r[0] && r.is(v) || (r = c.children(v).first())) : r = u.find(ft), f = !0, o(r)) : p && h == (a ? s.RIGHT : s.LEFT) ? (o(r ? r.prevAll(g + ":first") : u.find(ft)), f = !0) : p && h == (a ? s.LEFT : s.RIGHT) ? (r ? r.next()[0] && (r = r.nextAll(g + ":first")) : r = u.find(ft), f = !0, o(r)) : p && st && s.PAGEDOWN == h ? (w.page(w.page() + 1), f = !0) : p && st && s.PAGEUP == h ? (w.page(w.page() - 1), f = !0) : h == s.ENTER || s.F2 == h ? (r = r ? r : u.find(ft), r.is("th") ? (r.find(".k-link").click(), f = !0) : r.parent().is(".k-master-row,.k-grouping-row") ? (r.parent().find(".k-icon:first").click(), f = !0) : (ot = r.find(":kendoFocusable:first"), !r.hasClass("k-edit-cell") && ot[0] && r.hasClass("k-state-focused") ? (ot.focus(), f = !0) : t.options.editable && !n(i.target).is(":button,.k-button,textarea") && (d = n(i.target).closest("[role=gridcell]"), d[0] || (d = r), t._handleEditing(d), f = !0))) : s.ESC == h ? (b = rt(), r && n.contains(r[0], b) && !r.hasClass("k-edit-cell") && !r.parent().hasClass("k-grid-edit-row") ? (l(t.table[0], !0), f = !0) : t._editContainer && (!r || t._editContainer.has(r[0]) || r[0] === t._editContainer[0]) && (nt ? t.closeCell(!0) : (tt = t.items().index(n(r).parent()), b && b.blur(), t.cancelRow(), tt >= 0 && t.current(t.items().eq(tt).children().filter(v).first())), e.msie && e.version < 9 && document.body.focus(), l(u, !0), f = !0)) : s.TAB == h && (r = n(r), t.options.editable && nt && (y = n(rt()).closest(".k-edit-cell"), y[0] && y[0] !== r[0] && (r = y)), y = et ? r.prevAll(g + ":first") : r.nextAll(":visible:first"), y.length || (y = r.parent()[et ? "prevAll" : "nextAll"]("tr:not(.k-grouping-row):not(.k-detail-row):visible:first").children(g + (et ? ":last" : ":first"))), !r.is("th") && y.length && t.options.editable && nt && (t._handleEditing(r, y), f = !0)); - f && (i.preventDefault(), i.stopPropagation()) - }) - } - }, - _handleEditing: function(t, i) { - var r = this, - u = n(rt()), - f = r._editMode(), - c = e.msie, - a = c && e.version < 9, - o = r._editContainer, - s, h; - if (h = f == "incell" ? t.hasClass("k-edit-cell") : t.parent().hasClass("k-grid-edit-row"), r.editable) { - if (n.contains(o[0], u[0]) && (e.opera || a ? u.change().triggerHandler("blur") : (u.blur(), c && u.blur())), !r.editable) { - l(r.table); - return - } - if (r.editable.end()) f == "incell" ? r.closeCell() : (r.saveRow(), h = !0); - else { - f == "incell" ? r.current(o) : r.current(o.children().filter(g).first()); - s = o.find(":kendoFocusable:first")[0]; - s && s.focus(); - return - } - } - i && r.current(i); - a && document.body.focus(); - l(r.table, !0); - (h || i) && !i || (f == "incell" ? r.editCell(r.current()) : r.editRow(r.current().parent())) - }, - _wrapper: function() { - var n = this, - r = n.table, - i = n.options.height, - t = n.element; - t.is("div") || (t = t.wrap("<div/>").parent()); - n.wrapper = t.addClass("k-grid k-widget k-secondary"); - i && (n.wrapper.css(ti, i), r.css(ti, "auto")); - n._initMobile() - }, - _initMobile: function() { - var t = this.options, - r; - this._isMobile = t.mobile === !0 && i.support.mobileOS || t.mobile === "phone" || t.mobile === "tablet"; - this._isMobile && (r = this.wrapper.addClass("k-grid-mobile").wrap("<div data-" + i.ns + 'role="view" data-' + i.ns + 'init-widgets="false"><\/div>').parent(), this.pane = i.mobile.ui.Pane.wrap(r), this.view = this.pane.view(), this._actionSheetPopupOptions = n(document.documentElement).hasClass("km-root") ? { - modal: !1 - } : { - align: "bottom center", - position: "bottom center", - effect: "slideIn:up" - }, t.height && this.pane.element.parent().css(ti, t.height), this._editAnimation = "slide") - }, - _tbody: function() { - var i = this, - r = i.table, - t; - t = r.find(">tbody"); - t.length || (t = n("<tbody/>").appendTo(r)); - i.tbody = t - }, - _scrollable: function() { - var t = this, - u, s, y = t.options, - o = y.scrollable, - v = o !== !0 && o.virtual && !t.virtualScrollable, - c = !i.support.kineticScrollNeeded || v ? i.support.scrollbar() : 0, - l, a, h; - o && (u = t.wrapper.children(".k-grid-header"), u[0] || (u = n('<div class="k-grid-header" />').insertBefore(t.table)), u.css(p ? "padding-left" : "padding-right", o.virtual ? c + 1 : c), s = n('<table role="grid" />'), ri && s.attr("cellspacing", 0), s.append(t.thead), u.empty().append(n('<div class="k-grid-header-wrap" />').append(s)), t.content = t.table.parent(), t.content.is(".k-virtual-scrollable-wrap") && (t.content = t.content.parent()), t.content.is(".k-grid-content, .k-virtual-scrollable-wrap") || (t.content = t.table.wrap('<div class="k-grid-content" />').parent()), v && (t.virtualScrollable = new tr(t.content, { - dataSource: t.dataSource, - itemHeight: f(t._averageRowHeight, t) - })), t.scrollables = u.children(".k-grid-header-wrap"), l = t.wrapper.find(".k-grid-footer"), a = p && e.webkit ? c : 0, l.length && (t.scrollables = t.scrollables.add(l.children(".k-grid-footer-wrap"))), o.virtual ? t.content.find(">.k-virtual-scrollable-wrap").bind("scroll" + r, function() { - t.scrollables.scrollLeft(this.scrollLeft + a) - }) : (t.content.bind("scroll" + r, function() { - t.scrollables.scrollLeft(this.scrollLeft + a) - }), h = i.touchScroller(t.content), h && h.movable && h.movable.bind("change", function(n) { - t.scrollables.scrollLeft(-n.sender.x) - }))) - }, - _setContentWidth: function() { - var t = this, - u = "k-grid-content-expander", - e = '<div class="' + u + '"><\/div>', - r = t.resizable, - i; - t.options.scrollable && t.wrapper.is(":visible") && (i = t.table.parent().children("." + u), t._setContentWidthHandler = f(t._setContentWidth, t), t.dataSource && t.dataSource.view().length ? i[0] && (i.remove(), r && r.unbind("resize", t._setContentWidthHandler)) : (i[0] || (i = n(e).appendTo(t.table.parent()), r && r.bind("resize", t._setContentWidthHandler)), t.thead && i.width(t.thead.width()))) - }, - _setContentHeight: function() { - var n = this, - r = n.options, - t = n.wrapper.innerHeight(), - e = n.wrapper.children(".k-grid-header"), - u = i.support.scrollbar(), - f; - r.scrollable && n.wrapper.is(":visible") && (t -= e.outerHeight(), n.pager && (t -= n.pager.element.outerHeight()), r.groupable && (t -= n.wrapper.children(".k-grouping-header").outerHeight()), r.toolbar && (t -= n.wrapper.children(".k-grid-toolbar").outerHeight()), n.footerTemplate && (t -= n.wrapper.children(".k-grid-footer").outerHeight()), f = function(n) { - var t, i; - return n[0].style.height ? !0 : (t = n.height(), n.height("auto"), i = n.height(), t != i) ? (n.height(""), !0) : (n.height(""), !1) - }, f(n.wrapper) && (t > u * 2 ? n.content.height(t) : n.content.height(u * 2 + 1))) - }, - _averageRowHeight: function() { - var n = this, - t = n._rowHeight, - i; - return n._rowHeight || (n._rowHeight = t = n.table.outerHeight() / n.items().length, n._sum = t, n._measures = 1), i = n.table.outerHeight() / n.items().length, t !== i && (n._measures++, n._sum += i, n._rowHeight = n._sum / n._measures), t - }, - _dataSource: function() { - var n = this, - e = n.options, - r, i = e.dataSource; - i = k(i) ? { - data: i - } : i; - o(i) && (u(i, { - table: n.table, - fields: n.columns - }), r = e.pageable, o(r) && r.pageSize !== t && (i.pageSize = r.pageSize)); - n.dataSource && n._refreshHandler ? n.dataSource.unbind(a, n._refreshHandler).unbind(kt, n._progressHandler).unbind(dt, n._errorHandler) : (n._refreshHandler = f(n.refresh, n), n._progressHandler = f(n._requestStart, n), n._errorHandler = f(n._error, n)); - n.dataSource = ur.create(i).bind(a, n._refreshHandler).bind(kt, n._progressHandler).bind(dt, n._errorHandler) - }, - _error: function() { - this._progress(!1) - }, - _requestStart: function() { - this._progress(!0) - }, - _modelChange: function(t) { - var r = this, - h = t.model, - f = r.tbody.find("tr[" + i.attr("uid") + "=" + h.uid + "]"), - u, o, l = f.hasClass("k-alt"), - s, e = r.items().index(f), - c; - if (f.children(".k-edit-cell").length && !r.options.rowTemplate) f.children(":not(.k-group-cell,.k-hierarchy-cell)").each(function() { - u = n(this); - o = r.columns[r.cellIndex(u)]; - o.field === t.field && (u.hasClass("k-edit-cell") ? u.addClass("k-dirty-cell") : (r._displayCell(u, o, h), n('<span class="k-dirty"/>').prependTo(u))) - }); - else if (!f.hasClass("k-grid-edit-row")) { - for (s = (l ? r.altRowTemplate : r.rowTemplate)(h), f.replaceWith(s), s = r.items().eq(e), e = 0, c = r.columns.length; e < c; e++) o = r.columns[e], o.field === t.field && (u = s.children(":not(.k-group-cell,.k-hierarchy-cell)").eq(e), n('<span class="k-dirty"/>').prependTo(u)); - r.trigger("itemChange", { - item: s, - data: h, - ns: it - }) - } - }, - _pageable: function() { - var t = this, - f, r = t.options.pageable; - r && (f = t.wrapper.children("div.k-grid-pager"), f.length || (f = n('<div class="k-pager-wrap k-grid-pager"/>').appendTo(t.wrapper)), t.pager && t.pager.destroy(), t.pager = typeof r == "object" && r instanceof i.ui.Pager ? r : new i.ui.Pager(f, u({}, r, { - dataSource: t.dataSource - }))) - }, - _footer: function() { - var t = this, - u = t.dataSource.aggregates(), - r = "", - s = t.footerTemplate, - e = t.options, - f, i = t.footer || t.wrapper.find(".k-grid-footer"), - o; - s ? (u = at(u) ? fi(t.dataSource.aggregate()) : u, r = n(t._wrapFooter(s(u))), i.length ? (o = r, i.replaceWith(o), i = t.footer = o) : i = e.scrollable ? t.footer = e.pageable ? r.insertBefore(t.wrapper.children("div.k-grid-pager")) : r.appendTo(t.wrapper) : t.footer = r.insertBefore(t.tbody)) : i && !t.footer && (t.footer = i); - i.length && (e.scrollable && (f = i.attr("tabindex", -1).children(".k-grid-footer-wrap"), t.scrollables = t.scrollables.not(".k-grid-footer-wrap").add(f)), t._footerWidth && i.find("table").css("width", t._footerWidth), f && f.scrollLeft(t.content.scrollLeft())) - }, - _wrapFooter: function(t) { - var u = this, - r = "", - f = i.support.mobileOS ? 0 : i.support.scrollbar(); - return u.options.scrollable ? (r = n('<div class="k-grid-footer"><div class="k-grid-footer-wrap"><table' + (ri ? ' cellspacing="0"' : "") + "><tbody>" + t + "<\/tbody><\/table><\/div><\/div>"), u._appendCols(r.find("table")), r.css(p ? "padding-left" : "padding-right", f), r) : '<tfoot class="k-grid-footer">' + t + "<\/tfoot>" - }, - _columnMenu: function() { - var t = this, - s, v = t.columns, - r, e = t.options, - f = e.columnMenu, - h, c, a, y = this._isMobile, - p = function() { - l(t.thead.parent(), !0) - }, - w = function(n) { - t.trigger(ci, { - field: n.field, - container: n.container - }) - }, - o; - f && (typeof f == "boolean" && (f = {}), t.thead.find("th:not(.k-hierarchy-cell,.k-group-cell)").each(function(l) { - r = v[l]; - o = n(this); - !r.command && (r.field || o.attr("data-" + i.ns + "field")) && (s = o.data("kendoColumnMenu"), s && s.destroy(), c = r.sortable !== !1 && f.sortable !== !1 ? e.sortable : !1, a = e.filterable && r.filterable !== !1 && f.filterable !== !1 ? u({ - pane: t.pane - }, r.filterable, e.filterable) : !1, h = { - dataSource: t.dataSource, - values: r.values, - columns: f.columns, - sortable: c, - filterable: a, - messages: f.messages, - owner: t, - closeCallback: p, - init: w, - pane: t.pane, - filter: y ? ":not(.k-column-active)" : "" - }, o.kendoColumnMenu(h)) - })) - }, - _filterable: function() { - var t = this, - r = t.columns, - f, e, s = function() { - l(t.thead.parent(), !0) - }, - o = t.options.filterable; - o && !t.options.columnMenu && t.thead.find("th:not(.k-hierarchy-cell,.k-group-cell)").each(function(h) { - if (f = n(this), r[h].filterable !== !1 && !r[h].command && (r[h].field || f.attr("data-" + i.ns + "field"))) { - e = f.data("kendoFilterMenu"); - e && e.destroy(); - var c = r[h].filterable, - l = u({}, o, c, { - dataSource: t.dataSource, - values: r[h].values, - closeCallback: s, - init: function(n) { - t.trigger(hi, { - field: n.field, - container: n.container - }) - }, - pane: t.pane - }); - c && c.messages && (l.messages = u(!0, {}, o.messages, c.messages)); - f.kendoFilterMenu(l) - } - }) - }, - _sortable: function() { - var r = this, - s = r.columns, - t, f, e, o = r.options.sortable; - o && r.thead.find("th:not(.k-hierarchy-cell,.k-group-cell)").each(function(h) { - t = s[h]; - t.sortable !== !1 && !t.command && t.field && (f = n(this), e = f.data("kendoSortable"), e && e.destroy(), f.attr("data-" + i.ns + "field", t.field).kendoSortable(u({}, o, t.sortable, { - dataSource: r.dataSource, - aria: !0, - filter: ":not(.k-column-active)" - }))) - }) - }, - _columns: function(t) { - var r = this, - f = r.table, - e, s = f.find("col"), - o = r.options.dataSource; - t = t.length ? t : bt(f.find("th"), function(t, r) { - t = n(t); - var f = t.attr(i.attr("sortable")), - e = t.attr(i.attr("filterable")), - o = t.attr(i.attr("type")), - h = t.attr(i.attr("groupable")), - u = t.attr(i.attr("field")), - c = t.attr(i.attr("menu")); - return u || (u = t.text().replace(/\s|[^A-z0-9]/g, "")), { - field: u, - type: o, - sortable: f !== "false", - filterable: e !== "false", - groupable: h !== "false", - menu: c, - template: t.attr(i.attr("template")), - width: s.eq(r).css("width") - } - }); - e = !(r.table.find("tbody tr").length > 0 && (!o || !o.transport)); - r.columns = bt(t, function(n) { - return n = typeof n === c ? { - field: n - } : n, n.hidden && (n.attributes = ot(n.attributes), n.footerAttributes = ot(n.footerAttributes), n.headerAttributes = ot(n.headerAttributes)), u({ - encoded: e - }, n) - }) - }, - _groups: function() { - var n = this.dataSource.group(); - return n ? n.length : 0 - }, - _tmpl: function(n, t) { - var r = this, - c = u({}, i.Template, r.options.templateSettings), - e, l = r.columns.length, - a, h = { - storage: {}, - count: 0 - }, - o, p, v = r._hasDetails(), - s = [], - y = r._groups(); - if (!n) { - for (n = "<tr", t && s.push("k-alt"), v && s.push("k-master-row"), s.length && (n += ' class="' + s.join(" ") + '"'), l && (n += " " + i.attr("uid") + '="#=' + i.expr("uid", c.paramName) + '#"'), n += " role='row'>", y > 0 && (n += pt(y)), v && (n += '<td class="k-hierarchy-cell"><a class="k-icon k-plus" href="\\#" tabindex="-1"><\/a><\/td>'), e = 0; e < l; e++) o = r.columns[e], a = o.template, p = typeof a, n += "<td" + lt(o.attributes) + " role='gridcell'>", n += r._cellTmpl(o, h), n += "<\/td>"; - n += "<\/tr>" - } - return (n = i.template(n, c), h.count > 0) ? f(n, h.storage) : n - }, - _headerCellText: function(n) { - var e = this, - o = u({}, i.Template, e.options.templateSettings), - t = n.headerTemplate, - f = typeof t, - r = n.title || n.field || ""; - return f === ct ? r = i.template(t, o)({}) : f === c && (r = t), r - }, - _cellTmpl: function(n, t) { - var h = this, - y = u({}, i.Template, h.options.templateSettings), - l = n.template, - a = y.paramName, - f = n.field, - r = "", - s, p, v = n.format, - w = typeof l, - e = n.values; - if (n.command) { - if (k(n.command)) { - for (s = 0, p = n.command.length; s < p; s++) r += h._createButton(n.command[s]); - return r.replace(ii, "\\#") - } - return h._createButton(n.command).replace(ii, "\\#") - } - return w === ct ? (t.storage["tmpl" + t.count] = l, r += "#=this.tmpl" + t.count + "(" + a + ")#", t.count++) : w === c ? r += l : e && e.length && o(e[0]) && "value" in e[0] && f ? (r += "#var v =" + i.stringify(rr(e)) + "#", r += "#var f = v[", y.useWithBlock || (r += a + "."), r += f + "]#", r += "${f != null ? f : ''}") : (r += n.encoded ? "#:" : "#=", v && (r += 'kendo.format("' + v.replace(lr, "\\$1") + '",'), f ? (f = i.expr(f, a), r += f + "==null?'':" + f) : r += "''", v && (r += ")"), r += "#"), r - }, - _templates: function() { - var t = this, - r = t.options, - u = t.dataSource, - f = u.group(), - e = t.footer || t.wrapper.find(".k-grid-footer"), - i = u.aggregate(); - t.rowTemplate = t._tmpl(r.rowTemplate); - t.altRowTemplate = t._tmpl(r.altRowTemplate || r.rowTemplate, !0); - t._hasDetails() && (t.detailTemplate = t._detailTmpl(r.detailTemplate || "")); - (!t._group || at(i)) && (at(i) || e.length) && !b(t.columns, function(n) { - return n.footerTemplate - }).length || (t.footerTemplate = t._footerTmpl(i, "footerTemplate", "k-footer-template")); - f && b(t.columns, function(n) { - return n.groupFooterTemplate - }).length && (i = n.map(f, function(n) { - return n.aggregates - }), t.groupFooterTemplate = t._footerTmpl(i, "groupFooterTemplate", "k-group-footer")) - }, - _footerTmpl: function(n, t, r) { - var s = this, - a = u({}, i.Template, s.options.templateSettings), - v = a.paramName, - e = "", - c, y, d = s.columns, - o, p, w = {}, - l = 0, - b = {}, - k = s._groups(), - g = fi(n), - h; - for (e += '<tr class="' + r + '">', k > 0 && (e += pt(k)), s._hasDetails() && (e += '<td class="k-hierarchy-cell"> <\/td>'), c = 0, y = s.columns.length; c < y; c++) h = d[c], o = h[t], p = typeof o, e += "<td" + lt(h.footerAttributes) + ">", o ? (p !== ct && (b = g[h.field] ? u({}, a, { - paramName: v + "." + h.field - }) : {}, o = i.template(o, b)), w["tmpl" + l] = o, e += "#=this.tmpl" + l + "(" + v + ")#", l++) : e += " ", e += "<\/td>"; - return (e += "<\/tr>", e = i.template(e, a), l > 0) ? f(e, w) : e - }, - _detailTmpl: function(n) { - var e = this, - t = "", - o = u({}, i.Template, e.options.templateSettings), - l = o.paramName, - s = {}, - r = 0, - h = e._groups(), - c = tt(e.columns).length, - a = typeof n; - return (t += '<tr class="k-detail-row">', h > 0 && (t += pt(h)), t += '<td class="k-hierarchy-cell"><\/td><td class="k-detail-cell"' + (c ? ' colspan="' + c + '"' : "") + ">", a === ct ? (s["tmpl" + r] = n, t += "#=this.tmpl" + r + "(" + l + ")#", r++) : t += n, t += "<\/td><\/tr>", t = i.template(t, o), r > 0) ? f(t, s) : t - }, - _hasDetails: function() { - var n = this; - return n.options.detailTemplate !== null || (n._events[ni] || []).length - }, - _details: function() { - var t = this; - t.table.on(h + r, ".k-hierarchy-cell .k-plus, .k-hierarchy-cell .k-minus", function(i) { - var f = n(this), - u = f.hasClass("k-plus"), - r = f.closest("tr.k-master-row"), - e, s = t.detailTemplate, - o, h = t._hasDetails(); - return f.toggleClass("k-plus", !u).toggleClass("k-minus", u), h && !r.next().hasClass("k-detail-row") && (o = t.dataItem(r), n(s(o)).addClass(r.hasClass("k-alt") ? "k-alt" : "").insertAfter(r), t.trigger(ni, { - masterRow: r, - detailRow: r.next(), - data: o, - detailCell: r.next().find(".k-detail-cell") - })), e = r.next(), t.trigger(u ? pi : wi, { - masterRow: r, - detailRow: e - }), e.toggle(u), t._current && t._current.attr("aria-expanded", u), i.preventDefault(), !1 - }) - }, - dataItem: function(t) { - if (t = n(t)[0], !t) return null; - for (var f = this.tbody.children(), u = t.sectionRowIndex, r = u, i = 0; i < u; i++) /k-grouping-row|k-detail-row|k-group-footer/.test(f[i].className) && r--; - return this._data[r] - }, - expandRow: function(t) { - n(t).find("> td .k-plus, > td .k-i-expand").click() - }, - collapseRow: function(t) { - n(t).find("> td .k-minus, > td .k-i-collapse").click() - }, - _thead: function() { - var r = this, - h = r.columns, - l = r._hasDetails() && h.length, - s, a, e = "", - o = r.table.find(">thead"), - f, c, u; - if (o.length || (o = n("<thead/>").insertBefore(r.tbody)), f = r.element.find("tr:has(th):first"), f.length || (f = o.children().first(), f.length || (f = n("<tr/>"))), f.children().length) l && !f.find(".k-hierarchy-cell")[0] && f.prepend('<th class="k-hierarchy-cell"> <\/th>'); - else { - for (l && (e += '<th class="k-hierarchy-cell"> <\/th>'), s = 0, a = h.length; s < a; s++) u = h[s], c = r._headerCellText(u), u.command ? e += "<th" + lt(u.headerAttributes) + ">" + c + "<\/th>" : (e += "<th role='columnheader' " + i.attr("field") + "='" + (u.field || "") + "' ", u.title && (e += i.attr("title") + '="' + u.title.replace(/'/g, "'") + '" '), u.groupable !== t && (e += i.attr("groupable") + "='" + u.groupable + "' "), u.aggregates && (e += i.attr("aggregates") + "='" + u.aggregates + "'"), e += lt(u.headerAttributes), e += ">" + c + "<\/th>"); - f.html(e) - } - f.find("th").addClass("k-header"); - r.options.scrollable || o.addClass("k-grid-header"); - f.find("script").remove().end().appendTo(o); - r.thead && r._destroyColumnAttachments(); - r.thead = o; - r._sortable(); - r._filterable(); - r._scrollable(); - r._updateCols(); - r._resizable(); - r._draggable(); - r._reorderable(); - r.groupable && r._attachGroupable(); - r._columnMenu() - }, - _updateCols: function() { - var n = this; - n._appendCols(n.thead.parent().add(n.table)) - }, - _appendCols: function(n) { - var t = this; - ir(n, tt(t.columns), t._hasDetails(), t._groups()) - }, - _autoColumns: function(n) { - if (n && n.toJSON) { - var t = this, - i; - n = n.toJSON(); - for (i in n) t.columns.push({ - field: i - }); - t._thead(); - t._templates() - } - }, - _rowsHtml: function(n) { - for (var i = this, r = "", f = i.rowTemplate, e = i.altRowTemplate, t = 0, u = n.length; t < u; t++) r += t % 2 ? e(n[t]) : f(n[t]), i._data.push(n[t]); - return r - }, - _groupRowHtml: function(n, t, r) { - var f = this, - e = "", - o, l, a = n.field, - s = b(f.columns, function(n) { - return n.field == a - })[0] || {}, - h = s.groupHeaderTemplate, - v = (s.title || a) + ": " + br(n.value, s.format, s.values), - y = u({}, { - field: n.field, - value: n.value - }, n.aggregates[n.field]), - p = f._groupAggregatesDefaultObject || {}, - c = n.items; - if (h && (v = typeof h === ct ? h(y) : i.template(h)(y)), e += '<tr class="k-grouping-row">' + pt(r) + '<td colspan="' + t + '" aria-expanded="true"><p class="k-reset"><a class="k-icon k-i-collapse" href="#" tabindex="-1"><\/a>' + v + "<\/p><\/td><\/tr>", n.hasSubgroups) - for (o = 0, l = c.length; o < l; o++) e += f._groupRowHtml(c[o], t - 1, r + 1); - else e += f._rowsHtml(c); - return f.groupFooterTemplate && (e += f.groupFooterTemplate(u(p, n.aggregates))), e - }, - collapseGroup: function(t) { - t = n(t).find(".k-icon").addClass("k-i-expand").removeClass("k-i-collapse").end(); - var f = t.find(".k-group-cell").length, - r = 1, - u, i; - t.find("td:first").attr("aria-expanded", !1); - t.nextAll("tr").each(function() { - if (i = n(this), u = i.find(".k-group-cell").length, i.hasClass("k-grouping-row") ? r++ : i.hasClass("k-group-footer") && r--, u <= f || i.hasClass("k-group-footer") && r < 0) return !1; - i.hide() - }) - }, - expandGroup: function(t) { - t = n(t).find(".k-icon").addClass("k-i-collapse").removeClass("k-i-expand").end(); - var e = this, - f = t.find(".k-group-cell").length, - i, r, u = 1; - t.find("td:first").attr("aria-expanded", !0); - t.nextAll("tr").each(function() { - if (i = n(this), r = i.find(".k-group-cell").length, r <= f) return !1; - r != f + 1 || i.hasClass("k-detail-row") || (i.show(), i.hasClass("k-grouping-row") && i.find(".k-icon").hasClass("k-i-collapse") && e.expandGroup(i), i.hasClass("k-master-row") && i.find(".k-icon").hasClass("k-minus") && i.next().show()); - i.hasClass("k-grouping-row") && u++; - i.hasClass("k-group-footer") && (u == 1 ? i.show() : u--) - }) - }, - _updateHeader: function(t) { - var r = this, - u = r.thead.find("th.k-group-cell"), - i = u.length; - t > i ? n(new Array(t - i + 1).join('<th class="k-group-cell k-header"> <\/th>')).prependTo(r.thead.find("tr")) : t < i && (i = i - t, n(b(u, function(n, t) { - return i > t - })).remove()) - }, - _firstDataItem: function(n, t) { - return n && t && (n = n.hasSubgroups ? this._firstDataItem(n.items[0], t) : n.items[0]), n - }, - hideColumn: function(t) { - var i = this, - a, f, r, h, u, v, c, o = 0, - l, y = i.footer || i.wrapper.find(".k-grid-footer"), - p = i.columns, - s; - if (t = typeof t == "number" ? p[t] : b(p, function(n) { - return n.field === t - })[0], t && !t.hidden) { - for (s = d(t, tt(p)), t.hidden = !0, t.attributes = ot(t.attributes), t.footerAttributes = ot(t.footerAttributes), t.headerAttributes = ot(t.headerAttributes), i._templates(), i._updateCols(), st(i.thead.find(">tr")[0].cells, s, !1), y[0] && (i._appendCols(y.find("table:first")), st(y.find(".k-footer-template")[0].cells, s, !1)), a = i.tbody.children(), u = 0, l = a.length; u < l; u += 1) f = a.eq(u), f.is(".k-grouping-row,.k-detail-row") ? (r = f.children(":not(.k-group-cell):first,.k-detail-cell").last(), r.attr("colspan", parseInt(r.attr("colspan"), 10) - 1)) : (f.hasClass("k-grid-edit-row") && (r = f.children(".k-edit-container")[0]) && (r = n(r), r.attr("colspan", parseInt(r.attr("colspan"), 10) - 1), r.find("col").eq(s).remove(), f = r.find("tr:first")), st(f[0].cells, s, !1)); - for (v = i.thead.prev().find("col"), u = 0, l = v.length; u < l; u += 1) - if (c = v[u].style.width, c && c.indexOf("%") == -1) o += parseInt(c, 10); - else { - o = 0; - break - } - h = n(">.k-grid-header table:first,>.k-grid-footer table:first", i.wrapper).add(i.table); - i._footerWidth = null; - o && (h.width(o), i._footerWidth = o); - e.msie && e.version == 8 && (h.css("display", "inline-table"), setTimeout(function() { - h.css("display", "table") - }, 1)); - i.trigger(li, { - column: t - }) - } - }, - showColumn: function(t) { - var i = this, - c, u, o, f, r, l, e, a, v, s = i.columns, - y = i.footer || i.wrapper.find(".k-grid-footer"), - h; - if (t = typeof t == "number" ? s[t] : b(s, function(n) { - return n.field === t - })[0], t && t.hidden) { - for (h = d(t, s), t.hidden = !1, t.attributes = ei(t.attributes), t.footerAttributes = ei(t.footerAttributes), t.headerAttributes = ei(t.headerAttributes), i._templates(), i._updateCols(), st(i.thead.find(">tr")[0].cells, h, !0), y[0] && (i._appendCols(y.find("table:first")), st(y.find(".k-footer-template")[0].cells, h, !0)), c = i.tbody.children(), u = 0, o = c.length; u < o; u += 1) f = c.eq(u), f.is(".k-grouping-row,.k-detail-row") ? (r = f.children(":not(.k-group-cell):first,.k-detail-cell").last(), r.attr("colspan", parseInt(r.attr("colspan"), 10) + 1)) : (f.hasClass("k-grid-edit-row") && (r = f.children(".k-edit-container")[0]) && (r = n(r), r.attr("colspan", parseInt(r.attr("colspan"), 10) + 1), ir(r.find(">form>table"), tt(s), !1, 0), f = r.find("tr:first")), st(f[0].cells, h, !0)); - if (l = n(">.k-grid-header table:first,>.k-grid-footer table:first", i.wrapper).add(i.table), t.width) { - for (e = 0, v = i.thead.prev().find("col"), u = 0, o = v.length; u < o; u += 1) { - if (a = v[u].style.width, a.indexOf("%") > -1) { - e = 0; - break - } - e += parseInt(a, 10) - } - i._footerWidth = null; - e && (l.width(e), i._footerWidth = e) - } else l.width(""); - i.trigger(ai, { - column: t - }) - } - }, - _progress: function(n) { - var t = this, - r = t.element.is("table") ? t.element.parent() : t.content && t.content.length ? t.content : t.element; - i.ui.progress(r, n) - }, - _resize: function() { - this.content && (this._setContentHeight(), this._setContentWidth()) - }, - refresh: function(t) { - var i = this, - y, f, e = "", - o = i.dataSource.view(), - w = i.options.navigatable, - s, h, u, p = n(i.current()), - c = !1, - r = (i.dataSource.group() || []).length, - a = r + tt(i.columns).length, - v; - if ((!t || t.action !== "itemchange" || !i.editable) && (t = t || {}, !i.trigger("dataBinding", { - action: t.action || "rebind", - index: t.index, - items: t.items - }))) { - if (v = rt(), w && (i.table[0] === v || n.contains(i.table[0], v) || i._editContainer && i._editContainer.data("kendoWindow")) && (c = p.is("th"), u = 0, c && (u = i.thead.find("th:not(.k-group-cell)").index(p))), i._destroyEditable(), i._progress(!1), i._hideResizeHandle(), i._data = [], i.columns.length || (i._autoColumns(i._firstDataItem(o[0], r)), a = r + i.columns.length), i._group = r > 0 || i._group, i._group && (i._templates(), i._updateCols(), i._updateHeader(r), i._group = r > 0), r > 0) - for (i.detailTemplate && a++, i.groupFooterTemplate && (i._groupAggregatesDefaultObject = fi(i.dataSource.aggregate())), f = 0, y = o.length; f < y; f++) e += i._groupRowHtml(o[f], a, 0); - else e += i._rowsHtml(o); - er ? i.tbody[0].innerHTML = e : (h = document.createElement("div"), h.innerHTML = "<table><tbody>" + e + "<\/tbody><\/table>", s = h.firstChild.firstChild, i.table[0].replaceChild(s, i.tbody[0]), i.tbody = n(s)); - i._footer(); - i._setContentHeight(); - i._setContentWidth(); - u >= 0 && (i._removeCurrent(), c ? i.current(i.thead.find("th:not(.k-group-cell)").eq(u)) : i.current(i.items().eq(u).children().filter(g).first()), i._current && l(i._current.closest("table")[0], !0)); - i.trigger(yi) - } - } - }); - it.plugin(kr); - it.plugin(tr) - }(window.kendo.jQuery); -kendo_module({ - id: "listview", - name: "ListView", - category: "web", - description: "The ListView widget offers rich support for interacting with data.", - depends: ["data"], - features: [{ - id: "listview-editing", - name: "Editing", - description: "Support for record editing", - depends: ["editable"] - }, { - id: "listview-selection", - name: "Selection", - description: "Support for selection", - depends: ["selectable"] - }] - }), - function(n, t) { - var i = window.kendo, - f = "change", - c = "cancel", - l = "dataBound", - a = "dataBinding", - e = i.ui.Widget, - r = i.keys, - v = ">*", - y = "progress", - p = "error", - s = "k-state-focused", - w = "k-state-selected", - h = "k-edit-item", - tt = "string", - b = "edit", - k = "remove", - d = "save", - it = "click", - u = ".kendoListView", - o = n.proxy, - g = i._activeElement, - nt = i.ui.progress, - rt = i.data.DataSource, - ut = e.extend({ - init: function(t, r) { - var u = this; - r = n.isArray(r) ? { - dataSource: r - } : r; - e.fn.init.call(u, t, r); - r = u.options; - u.wrapper = t = u.element; - t[0].id && (u._itemId = t[0].id + "_lv_active"); - u._element(); - u._dataSource(); - u._templates(); - u._navigatable(); - u._selectable(); - u._pageable(); - u._crudHandlers(); - u.options.autoBind && u.dataSource.fetch(); - i.notify(u) - }, - events: [f, c, a, l, b, k, d], - options: { - name: "ListView", - autoBind: !0, - selectable: !1, - navigatable: !1, - template: "", - altTemplate: "", - editTemplate: "" - }, - setOptions: function(n) { - e.fn.setOptions.call(this, n); - this._templates() - }, - _templates: function() { - var n = this.options; - this.template = i.template(n.template || ""); - this.altTemplate = i.template(n.altTemplate || n.template); - this.editTemplate = i.template(n.editTemplate || "") - }, - _item: function(n) { - return this.element.children()[n]() - }, - items: function() { - return this.element.children() - }, - setDataSource: function(n) { - this.options.dataSource = n; - this._dataSource(); - this.options.autoBind && n.fetch() - }, - _unbindDataSource: function() { - var n = this; - n.dataSource.unbind(f, n._refreshHandler).unbind(y, n._progressHandler).unbind(p, n._errorHandler) - }, - _dataSource: function() { - var n = this; - n.dataSource && n._refreshHandler ? n._unbindDataSource() : (n._refreshHandler = o(n.refresh, n), n._progressHandler = o(n._progress, n), n._errorHandler = o(n._error, n)); - n.dataSource = rt.create(n.options.dataSource).bind(f, n._refreshHandler).bind(y, n._progressHandler).bind(p, n._errorHandler) - }, - _progress: function() { - nt(this.element, !0) - }, - _error: function() { - nt(this.element, !1) - }, - _element: function() { - this.element.addClass("k-widget k-listview").attr("role", "listbox") - }, - refresh: function(n) { - var t = this, - f = t.dataSource.view(), - e, s, u, h = "", - r, o, c = t.template, - v = t.altTemplate, - y = g(); - if (n = n || {}, n.action === "itemchange") { - t._hasBindingTarget() || t.editable || (e = n.items[0], u = t.items().filter("[" + i.attr("uid") + "=" + e.uid + "]"), u.length > 0 && (r = u.index(), u.replaceWith(c(e)), u = t.items().eq(r), u.attr(i.attr("uid"), e.uid), t.trigger("itemChange", { - item: u, - data: e - }))); - return - } - if (!t.trigger(a, { - action: n.action || "rebind", - items: n.items, - index: n.index - })) { - for (t._destroyEditable(), r = 0, o = f.length; r < o; r++) h += r % 2 ? v(f[r]) : c(f[r]); - for (t.element.html(h), s = t.items(), r = 0, o = f.length; r < o; r++) s.eq(r).attr(i.attr("uid"), f[r].uid).attr("role", "option").attr("aria-selected", "false"); - t.element[0] === y && t.options.navigatable && t.current(s.eq(0)); - t.trigger(l) - } - }, - _pageable: function() { - var t = this, - r = t.options.pageable, - u, f; - n.isPlainObject(r) && (f = r.pagerId, u = n.extend({}, r, { - dataSource: t.dataSource, - pagerId: null - }), t.pager = new i.ui.Pager(n("#" + f), u)) - }, - _selectable: function() { - var n = this, - e, t, o = n.options.selectable, - s = n.options.navigatable; - if (o && (e = typeof o === tt && o.toLowerCase().indexOf("multiple") > -1, e && n.element.attr("aria-multiselectable", !0), n.selectable = new i.ui.Selectable(n.element, { - aria: !0, - multiple: e, - filter: v, - change: function() { - n.trigger(f) - } - }), s)) n.element.on("keydown" + u, function(i) { - if (i.keyCode === r.SPACEBAR) { - if (t = n.current(), i.target == i.currentTarget && i.preventDefault(), e) - if (i.ctrlKey) { - if (t && t.hasClass(w)) { - t.removeClass(w); - return - } - } else n.selectable.clear(); - else n.selectable.clear(); - n.selectable.value(t) - } - }) - }, - current: function(n) { - var r = this, - f = r.element, - i = r._current, - u = r._itemId; - if (n === t) return i; - i && i[0] && (i[0].id === u && i.removeAttr("id"), i.removeClass(s), f.removeAttr("aria-activedescendant")); - n && n[0] && (u = n[0].id || u, r._scrollTo(n[0]), f.attr("aria-activedescendant", u), n.addClass(s).attr("id", u)); - r._current = n - }, - _scrollTo: function(t) { - var u = this, - i, e = !1, - r = "scroll", - f; - u.wrapper.css("overflow") == "auto" || u.wrapper.css("overflow") == r ? i = u.wrapper[0] : (i = window, e = !0); - f = function(u, f) { - var o = e ? n(t).offset()[u.toLowerCase()] : t["offset" + u], - s = t["client" + f], - h = n(i)[r + u](), - c = n(i)[f.toLowerCase()](); - o + s > h + c ? n(i)[r + u](o + s - c) : o < h && n(i)[r + u](o) - }; - f("Top", "Height"); - f("Left", "Width") - }, - _navigatable: function() { - var t = this, - e = t.options.navigatable, - f = t.element, - c = function(i) { - t.current(n(i.currentTarget)); - n(i.target).is(":button,a,:input,a>.k-icon,textarea") || f.focus() - }; - if (e) { - t._tabindex(); - f.on("focus" + u, function() { - var n = t._current; - n && n.is(":visible") || (n = t._item("first")); - t.current(n) - }).on("focusout" + u, function() { - t._current && t._current.removeClass(s) - }).on("keydown" + u, function(u) { - var e = u.keyCode, - o = t.current(), - v = n(u.target), - y = !v.is(":button,textarea,a,a>.t-icon,input"), - a = v.is(":text"), - s = i.preventDefault, - c = f.find("." + h), - p = g(), - l, w; - if ((y || a || r.ESC == e) && (!a || r.ESC == e || r.ENTER == e)) - if (r.UP === e || r.LEFT === e) o && (o = o.prev()), t.current(!o || !o[0] ? t._item("last") : o), s(u); - else if (r.DOWN === e || r.RIGHT === e) o && (o = o.next()), t.current(!o || !o[0] ? t._item("first") : o), s(u); - else if (r.PAGEUP === e) t.current(null), t.dataSource.page(t.dataSource.page() - 1), s(u); - else if (r.PAGEDOWN === e) t.current(null), t.dataSource.page(t.dataSource.page() + 1), s(u); - else if (r.HOME === e) t.current(t._item("first")), s(u); - else if (r.END === e) t.current(t._item("last")), s(u); - else if (r.ENTER === e) - if (c.length !== 0 && (y || a)) { - l = t.items().index(c); - p && p.blur(); - t.save(); - w = function() { - t.element.trigger("focus"); - t.current(t.items().eq(l)) - }; - t.one("dataBound", w) - } else t.options.editTemplate !== "" && t.edit(o); - else if (r.ESC === e) { - if (c = f.find("." + h), c.length === 0) return; - l = t.items().index(c); - t.cancel(); - t.element.trigger("focus"); - t.current(t.items().eq(l)) - } - }); - f.on("mousedown" + u + " touchstart" + u, v, o(c, t)) - } - }, - clearSelection: function() { - var n = this; - n.selectable.clear(); - n.trigger(f) - }, - select: function(t) { - var r = this, - i = r.selectable; - if (t = n(t), t.length) { - i.options.multiple || (i.clear(), t = t.first()); - i.value(t); - return - } - return i.value() - }, - _destroyEditable: function() { - var n = this; - n.editable && (n.editable.destroy(), delete n.editable) - }, - _modelFromElement: function(n) { - var t = n.attr(i.attr("uid")); - return this.dataSource.getByUid(t) - }, - _closeEditable: function(n) { - var t = this, - r = t.editable, - u, e, o = t.template, - f = !0; - return r && (n && (f = r.end()), f && (r.element.index() % 2 && (o = t.altTemplate), u = t._modelFromElement(r.element), t._destroyEditable(), e = r.element.index(), r.element.replaceWith(o(u)), t.items().eq(e).attr(i.attr("uid"), u.uid))), f - }, - edit: function(n) { - var t = this, - r = t._modelFromElement(n), - u, e = r.uid, - f; - t.cancel(); - n = t.items().filter("[" + i.attr("uid") + "=" + e + "]"); - f = n.index(); - n.replaceWith(t.editTemplate(r)); - u = t.items().eq(f).addClass(h).attr(i.attr("uid"), r.uid); - t.editable = u.kendoEditable({ - model: r, - clearContainer: !1, - errorTemplate: !1 - }).data("kendoEditable"); - t.trigger(b, { - model: r, - item: u - }) - }, - save: function() { - var n = this, - t = n.editable, - i; - t && (t = t.element, i = n._modelFromElement(t), !n.trigger(d, { - model: i, - item: t - }) && n._closeEditable(!0) && n.dataSource.sync()) - }, - remove: function(n) { - var t = this, - i = t.dataSource, - r = t._modelFromElement(n); - t.trigger(k, { - model: r, - item: n - }) || (n.hide(), i.remove(r), i.sync()) - }, - add: function() { - var n = this, - t = n.dataSource, - i = t.indexOf((t.view() || [])[0]); - i < 0 && (i = 0); - n.cancel(); - t.insert(i, {}); - n.edit(n.element.children().first()) - }, - cancel: function() { - var n = this, - r = n.dataSource, - t, i; - n.editable && (t = n.editable.element, i = n._modelFromElement(t), n.trigger(c, { - model: i, - container: t - }) || (r.cancelChanges(i), n._closeEditable(!1))) - }, - _crudHandlers: function() { - var t = this, - r = it + u; - t.element.on(r, ".k-edit-button", function(r) { - var u = n(this).closest("[" + i.attr("uid") + "]"); - t.edit(u); - r.preventDefault() - }); - t.element.on(r, ".k-delete-button", function(r) { - var u = n(this).closest("[" + i.attr("uid") + "]"); - t.remove(u); - r.preventDefault() - }); - t.element.on(r, ".k-update-button", function(n) { - t.save(); - n.preventDefault() - }); - t.element.on(r, ".k-cancel-button", function(n) { - t.cancel(); - n.preventDefault() - }) - }, - destroy: function() { - var n = this; - e.fn.destroy.call(n); - n._unbindDataSource(); - n._destroyEditable(); - n.element.off(u); - n.pager && n.pager.destroy(); - n.selectable && n.selectable.destroy(); - i.destroy(n.element) - } - }); - i.ui.plugin(ut) - }(window.kendo.jQuery); -kendo_module({ - id: "numerictextbox", - name: "NumericTextBox", - category: "web", - description: "The NumericTextBox widget can format and display numeric, percentage or currency textbox.", - depends: ["core", "userevents"] - }), - function(n, t) { - function ut(n, t) { - return '<span unselectable="on" class="k-link"><span unselectable="on" class="k-icon k-i-arrow-' + n + '" title="' + t + '">' + t + "<\/span><\/span>" - } - - function y(i, r) { - var f, s = r !== t, - u, e, o, h; - return i.selectionStart !== t ? s ? (i.focus(), i.setSelectionRange(r, r)) : r = [i.selectionStart, i.selectionEnd] : document.selection && (n(i).is(":visible") && i.focus(), f = document.selection.createRange(), s ? (f.move("character", r), f.select()) : (u = i.createTextRange(), e = u.duplicate(), u.moveToBookmark(f.getBookmark()), e.setEndPoint("EndToStart", u), o = e.text.length, h = o + u.text.length, r = [o, h])), r - } - var r = window.kendo, - e = r.keys, - p = r.ui, - s = p.Widget, - ft = r._activeElement, - et = r._extractFormat, - ot = r.parseFloat, - st = r.support.placeholder, - ht = r.getCulture, - w = r._round, - h = "change", - b = "disabled", - k = "readonly", - ct = "k-input", - d = "spin", - u = ".kendoNumericTextBox", - lt = "touchend", - at = "mouseleave" + u, - g = "mouseenter" + u + " " + at, - c = "k-state-default", - nt = "k-state-focused", - tt = "k-state-hover", - l = "focus", - f = ".", - a = "k-state-selected", - v = "k-state-disabled", - it = "aria-disabled", - rt = "aria-readonly", - vt = /^(-)?(\d*)$/, - i = null, - o = n.proxy, - yt = s.extend({ - init: function(n, f) { - var e = this, - p = f && f.step !== t, - h, c, a, v, y; - if (s.fn.init.call(e, n, f), f = e.options, n = e.element.on("blur" + u, o(e._focusout, e)).attr("role", "spinbutton"), f.placeholder = f.placeholder || n.attr("placeholder"), e._reset(), e._wrapper(), e._arrows(), e._input(), r.support.mobileOS) e._text.on(lt + u + " " + l + u, function(t) { - e._toggleText(!1); - t.type === l && n.focus() - }); - else e._text.on(l + u, o(e._click, e)); - h = e.min(n.attr("min")); - c = e.max(n.attr("max")); - a = e._parse(n.attr("step")); - f.min === i && h !== i && (f.min = h); - f.max === i && c !== i && (f.max = c); - p || a === i || (f.step = a); - n.attr("aria-valuemin", f.min).attr("aria-valuemax", f.max); - f.format = et(f.format); - v = f.value; - e.value(v !== i ? v : n.val()); - y = n.is("[disabled]"); - y ? e.enable(!1) : e.readonly(n.is("[readonly]")); - r.notify(e) - }, - options: { - name: "NumericTextBox", - decimals: i, - min: i, - max: i, - value: i, - step: 1, - culture: "", - format: "n", - spinners: !0, - placeholder: "", - upArrowText: "Increase value", - downArrowText: "Decrease value" - }, - events: [h, d], - _editable: function(n) { - var t = this, - f = t.element, - i = n.disable, - r = n.readonly, - e = t._text.add(f), - s = t._inputWrapper.off(g); - if (t._toggleText(!0), t._upArrowEventHandler.unbind("press"), t._downArrowEventHandler.unbind("press"), f.off("keydown" + u).off("keypress" + u).off("paste" + u), r || i) s.addClass(i ? v : c).removeClass(i ? c : v), e.attr(b, i).attr(k, r).attr(it, i).attr(rt, r); - else { - s.addClass(c).removeClass(v).on(g, t._toggleHover); - e.removeAttr(b).removeAttr(k).attr(it, !1).attr(rt, !1); - t._upArrowEventHandler.bind("press", function(n) { - n.preventDefault(); - t._spin(1); - t._upArrow.addClass(a) - }); - t._downArrowEventHandler.bind("press", function(n) { - n.preventDefault(); - t._spin(-1); - t._downArrow.addClass(a) - }); - t.element.on("keydown" + u, o(t._keydown, t)).on("keypress" + u, o(t._keypress, t)).on("paste" + u, o(t._paste, t)) - } - }, - readonly: function(n) { - this._editable({ - readonly: n === t ? !0 : n, - disable: !1 - }) - }, - enable: function(n) { - this._editable({ - readonly: !1, - disable: !(n = n === t ? !0 : n) - }) - }, - destroy: function() { - var n = this; - n.element.add(n._text).add(n._upArrow).add(n._downArrow).add(n._inputWrapper).off(u); - n._upArrowEventHandler.destroy(); - n._downArrowEventHandler.destroy(); - n._form && n._form.off("reset", n._resetHandler); - s.fn.destroy.call(n) - }, - min: function(n) { - return this._option("min", n) - }, - max: function(n) { - return this._option("max", n) - }, - step: function(n) { - return this._option("step", n) - }, - value: function(n) { - var i = this, - r; - if (n === t) return i._value; - (n = i._parse(n), r = i._adjust(n), n === r) && (i._update(n), i._old = i._value) - }, - focus: function() { - this._focusin() - }, - _adjust: function(n) { - var f = this, - u = f.options, - t = u.min, - r = u.max; - return n === i ? n : (t !== i && n < t ? n = t : r !== i && n > r && (n = r), n) - }, - _arrows: function() { - var t = this, - i, f = function() { - clearTimeout(t._spinning); - i.removeClass(a) - }, - u = t.options, - e = u.spinners, - o = t.element; - i = o.siblings(".k-icon"); - i[0] || (i = n(ut("n", u.upArrowText) + ut("s", u.downArrowText)).insertAfter(o), i.wrapAll('<span class="k-select"/>')); - e || (i.parent().toggle(e), t._inputWrapper.addClass("k-expand-padding")); - t._upArrow = i.eq(0); - t._upArrowEventHandler = new r.UserEvents(t._upArrow, { - release: f - }); - t._downArrow = i.eq(1); - t._downArrowEventHandler = new r.UserEvents(t._downArrow, { - release: f - }) - }, - _blur: function() { - var n = this; - n._toggleText(!0); - n._change(n.element.val()) - }, - _click: function(n) { - var t = this; - clearTimeout(t._focusing); - t._focusing = setTimeout(function() { - var o = n.target, - l = y(o)[0], - s = o.value.substring(0, l), - h = t._format(t.options.format), - i = h[","], - r, c, u, e = 0; - i && (c = new RegExp("\\" + i, "g"), u = new RegExp("([\\d\\" + i + "]+)(\\" + h[f] + ")?(\\d+)?")); - u && (r = u.exec(s)); - r && (e = r[0].replace(c, "").length, s.indexOf("(") != -1 && t._value < 0 && e++); - t._focusin(); - y(t.element[0], e) - }) - }, - _change: function(n) { - var t = this; - t._update(n); - n = t._value; - t._old != n && (t._old = n, t.trigger(h), t.element.trigger(h)) - }, - _culture: function(n) { - return n || ht(this.options.culture) - }, - _focusin: function() { - var n = this; - n._inputWrapper.addClass(nt); - n._toggleText(!1); - n.element[0].focus() - }, - _focusout: function() { - var n = this; - clearTimeout(n._focusing); - n._inputWrapper.removeClass(nt).removeClass(tt); - n._blur() - }, - _format: function(n, t) { - var i = this._culture(t).numberFormat; - return n = n.toLowerCase(), n.indexOf("c") > -1 ? i = i.currency : n.indexOf("p") > -1 && (i = i.percent), i - }, - _input: function() { - var r = this, - u = "k-formatted-value", - t = r.element.addClass(ct).show()[0], - e = t.accessKey, - o = r.wrapper, - i; - i = o.find(f + u); - i[0] || (i = n('<input type="text"/>').insertBefore(t).addClass(u)); - try { - t.setAttribute("type", "text") - } catch (s) { - t.type = "text" - } - i[0].tabIndex = t.tabIndex; - i[0].style.cssText = t.style.cssText; - i.prop("placeholder", r.options.placeholder); - e && (i.attr("accesskey", e), t.accessKey = ""); - r._text = i.addClass(t.className) - }, - _keydown: function(n) { - var t = this, - i = n.keyCode; - i == e.DOWN ? t._step(-1) : i == e.UP ? t._step(1) : i == e.ENTER && t._change(t.element.val()) - }, - _keypress: function(n) { - if (n.which !== 0 && n.keyCode !== e.BACKSPACE && n.keyCode !== e.ENTER) { - var i = this.element, - f = String.fromCharCode(n.which), - r = y(i[0]), - o = r[0], - s = r[1], - u = this.options.min, - t = i.val(); - t = t.substring(0, o) + f + t.substring(s); - (u !== null && u >= 0 && t.charAt(0) === "-" || !this._numericRegex().test(t)) && n.preventDefault() - } - }, - _numericRegex: function() { - var t = this, - u = t.options, - e = t._format(u.format), - n = e[f], - r = u.decimals; - return (n === f && (n = "\\" + n), r === i && (r = e.decimals), r === 0) ? vt : (t._separator !== n && (t._separator = n, t._floatRegExp = new RegExp("^(-)?(((\\d+(" + n + "\\d*)?)|(" + n + "\\d*)))?$")), t._floatRegExp) - }, - _paste: function(n) { - var t = this, - r = n.target, - u = r.value; - setTimeout(function() { - t._parse(r.value) === i && t._update(u) - }) - }, - _option: function(n, i) { - var r = this, - u = r.options; - if (i === t) return u[n]; - (i = r._parse(i), i || n !== "step") && (u[n] = i, r.element.attr("aria-value" + n, i).attr(n, i)) - }, - _spin: function(n, t) { - var i = this; - t = t || 500; - clearTimeout(i._spinning); - i._spinning = setTimeout(function() { - i._spin(n, 50) - }, t); - i._step(n) - }, - _step: function(n) { - var t = this, - i = t.element, - r = t._parse(i.val()) || 0; - ft() != i[0] && t._focusin(); - r += t.options.step * n; - t._update(t._adjust(r)); - t.trigger(d) - }, - _toggleHover: function(t) { - n(t.currentTarget).toggleClass(tt, t.type === "mouseenter") - }, - _toggleText: function(n) { - var t = this; - t._text.toggle(n); - t.element.toggle(!n) - }, - _parse: function(n, t) { - return ot(n, this._culture(t), this.options.format) - }, - _update: function(n) { - var t = this, - s = t.options, - h = s.format, - u = s.decimals, - e = t._culture(), - c = t._format(h, e), - o; - u === i && (u = c.decimals); - n = t._parse(n, e); - o = n !== i; - o && (n = parseFloat(w(n, u))); - t._value = n = t._adjust(n); - t._placeholder(r.toString(n, h, e)); - o ? (n = n.toString(), n.indexOf("e") !== -1 && (n = w(+n, u)), n = n.replace(f, c[f])) : n = ""; - t.element.val(n).attr("aria-valuenow", n) - }, - _placeholder: function(n) { - this._text.val(n); - st || n || this._text.val(this.options.placeholder) - }, - _wrapper: function() { - var i = this, - r = i.element, - u = r[0], - t; - t = r.parents(".k-numerictextbox"); - t.is("span.k-numerictextbox") || (t = r.hide().wrap('<span class="k-numeric-wrap k-state-default" />').parent(), t = t.wrap("<span/>").parent()); - t[0].style.cssText = u.style.cssText; - u.style.width = ""; - i.wrapper = t.addClass("k-widget k-numerictextbox").addClass(u.className).css("display", ""); - i._inputWrapper = n(t[0].firstChild) - }, - _reset: function() { - var t = this, - i = t.element, - r = i.attr("form"), - u = r ? n("#" + r) : i.closest("form"); - u[0] && (t._resetHandler = function() { - setTimeout(function() { - t.value(i[0].value) - }) - }, t._form = u.on("reset", t._resetHandler)) - } - }); - p.plugin(yt) - }(window.kendo.jQuery); -kendo_module({ - id: "menu", - name: "Menu", - category: "web", - description: "The Menu widget displays hierarchical data as a multi-level menu.", - depends: ["popup"] - }), - function(n, t) { - function yi(n, t) { - return n = n.split(" ")[!t + 0] || n, n.replace("top", "up").replace("bottom", "down") - } - - function pi(n, t, r) { - n = n.split(" ")[!t + 0] || n; - var u = { - origin: ["bottom", r ? "right" : "left"], - position: ["top", r ? "right" : "left"] - }, - f = /left|right/.test(n); - return f ? (u.origin = ["top", n], u.position[1] = i.directions[n].reverse) : (u.origin[0] = n, u.position[0] = i.directions[n].reverse), u.origin = u.origin.join(" "), u.position = u.position.join(" "), u - } - - function d(t, i) { - try { - return n.contains(t, i) - } catch (r) { - return !1 - } - } - - function oi(t) { - t = n(t); - t.addClass("k-item").children(pt).addClass(kt); - t.children("a").addClass(k).children(pt).addClass(kt); - t.filter(":not([disabled])").addClass(ui); - t.filter(".k-separator:empty").append(" "); - t.filter("li[disabled]").addClass(y).removeAttr("disabled").attr("aria-disabled", !0); - t.filter("[role]").length || t.attr("role", "menuitem"); - t.children("." + k).length || t.contents().filter(function() { - return !this.nodeName.match(ci) && !(this.nodeType == 3 && !n.trim(this.nodeValue)) - }).wrapAll("<span class='" + k + "'/>"); - b(t); - c(t) - } - - function b(t) { - t = n(t); - t.find("> .k-link > [class*=k-i-arrow]:not(.k-sprite)").remove(); - t.filter(":has(.k-group)").children(".k-link:not(:has([class*=k-i-arrow]:not(.k-sprite)))").each(function() { - var t = n(this), - i = t.parent().parent(); - t.append("<span class='k-icon " + (i.hasClass(h + "-horizontal") ? "k-i-arrow-s" : "k-i-arrow-e") + "'/>") - }) - } - - function c(t) { - t = n(t); - t.filter(".k-first:not(:first-child)").removeClass(bt); - t.filter(".k-last:not(:last-child)").removeClass(wt); - t.filter(":first-child").addClass(bt); - t.filter(":last-child").addClass(wt) - } - var i = window.kendo, - si = i.ui, - hi = i._activeElement, - ft = i.support.touch && i.support.mobileOS, - et = "mousedown", - ot = "click", - f = n.extend, - u = n.proxy, - st = n.each, - o = i.template, - e = i.keys, - g = si.Widget, - ci = /^(ul|a|div)$/i, - r = ".kendoMenu", - pt = "img", - ht = "open", - h = "k-menu", - k = "k-link", - wt = "k-last", - nt = "close", - tt = "timer", - bt = "k-first", - kt = "k-image", - dt = "select", - a = "zIndex", - gt = "activate", - ni = "deactivate", - ti = "touchstart" + r + " MSPointerDown" + r + " pointerdown" + r, - it = i.support.pointers, - rt = i.support.msPointers, - ct = it ? "pointerover" : rt ? "MSPointerOver" : "mouseenter", - ii = it ? "pointerout" : rt ? "MSPointerOut" : "mouseleave", - ri = ft || rt || it, - ut = "kendoPopup", - ui = "k-state-default", - lt = "k-state-hover", - v = "k-state-focused", - y = "k-state-disabled", - at = ".k-group", - p = ":not(.k-list) > .k-item", - li = ".k-item.k-state-disabled", - vt = ".k-item:not(.k-state-disabled)", - ai = ".k-item:not(.k-state-disabled) > .k-link", - fi = ":not(.k-item.k-separator)", - w = fi + ":eq(0)", - ei = fi + ":last", - vi = "div:not(.k-animation-container,.k-list-container)", - s = { - content: o("<div class='k-content k-group' tabindex='-1'>#= content(item) #<\/div>"), - group: o("<ul class='#= groupCssClass(group) #'#= groupAttributes(group) # role='menu' aria-hidden='true'>#= renderItems(data) #<\/ul>"), - itemWrapper: o("<#= tag(item) # class='#= textClass(item) #'#= textAttributes(item) #>#= image(item) ##= sprite(item) ##= text(item) ##= arrow(data) #<\/#= tag(item) #>"), - item: o("<li class='#= wrapperCssClass(group, item) #' role='menuitem' #=item.items ? \"aria-haspopup='true'\": \"\"##=item.enabled === false ? \"aria-disabled='true'\" : ''#>#= itemWrapper(data) ## if (item.items) { ##= subGroup({ items: item.items, menu: menu, group: { expanded: item.expanded } }) ## } else if (item.content || item.contentUrl) { ##= renderContent(data) ## } #<\/li>"), - image: o("<img class='k-image' alt='' src='#= imageUrl #' />"), - arrow: o("<span class='#= arrowClass(item, group) #'><\/span>"), - sprite: o("<span class='k-sprite #= spriteCssClass #'><\/span>"), - empty: o("") - }, - yt = { - wrapperCssClass: function(n, t) { - var i = "k-item", - r = t.index; - return i += t.enabled === !1 ? " k-state-disabled" : " k-state-default", n.firstLevel && r === 0 && (i += " k-first"), r == n.length - 1 && (i += " k-last"), t.cssClass && (i += " " + t.cssClass), i - }, - textClass: function() { - return k - }, - textAttributes: function(n) { - return n.url ? " href='" + n.url + "'" : "" - }, - arrowClass: function(n, t) { - return "k-icon" + (t.horizontal ? " k-i-arrow-s" : " k-i-arrow-e") - }, - text: function(n) { - return n.encoded === !1 ? n.text : i.htmlEncode(n.text) - }, - tag: function(n) { - return n.url ? "a" : "span" - }, - groupAttributes: function(n) { - return n.expanded !== !0 ? " style='display:none'" : "" - }, - groupCssClass: function() { - return "k-group" - }, - content: function(n) { - return n.content ? n.content : " " - } - }, - l = g.extend({ - init: function(t, f) { - var e = this; - g.fn.init.call(e, t, f); - t = e.wrapper = e.element; - f = e.options; - e._initData(f); - e._updateClasses(); - e._animations(f); - e.nextItemZIndex = 100; - e._tabindex(); - e._focusProxy = u(e._focusHandler, e); - t.on(ti, e._focusProxy).on(ot + r, li, !1).on(ot + r, vt, u(e._click, e)).on("keydown" + r, u(e._keydown, e)).on("focus" + r, u(e._focus, e)).on("focus" + r, ".k-content", u(e._focus, e)).on(ti + " " + et + r, ".k-content", u(e._preventClose, e)).on("blur" + r, u(e._removeHoverItem, e)).on("blur" + r, "[tabindex]", u(e._checkActiveElement, e)).on(ct + r, vt, u(e._mouseenter, e)).on(ii + r, vt, u(e._mouseleave, e)).on(ct + r + " " + ii + r + " " + et + r + " " + ot + r, ai, u(e._toggleHover, e)); - f.openOnClick && (e.clicked = !1, e._documentClickHandler = u(e._documentClick, e), n(document).click(e._documentClickHandler)); - t.attr("role", "menubar"); - t[0].id && (e._ariaId = i.format("{0}_mn_active", t[0].id)); - i.notify(e) - }, - events: [ht, nt, gt, ni, dt], - options: { - name: "Menu", - animation: { - open: { - duration: 200 - }, - close: { - duration: 100 - } - }, - orientation: "horizontal", - direction: "default", - openOnClick: !1, - closeOnClick: !0, - hoverDelay: 100 - }, - _initData: function(n) { - var t = this; - n.dataSource && (t.element.empty(), t.append(n.dataSource, t.element)) - }, - setOptions: function(n) { - var t = this.options.animation; - this._animations(n); - n.animation = f(!0, t, n.animation); - "dataSource" in n && this._initData(n); - g.fn.setOptions.call(this, n) - }, - destroy: function() { - var t = this; - g.fn.destroy.call(t); - t.element.off(r); - t._documentClickHandler && n(document).unbind("click", t._documentClickHandler); - i.destroy(t.element) - }, - enable: function(n, t) { - return this._toggleDisabled(n, t !== !1), this - }, - disable: function(n) { - return this._toggleDisabled(n, !1), this - }, - append: function(n, t) { - t = this.element.find(t); - var i = this._insert(n, t, t.length ? t.find("> .k-group, > .k-animation-container > .k-group") : null); - return st(i.items, function() { - i.group.append(this); - b(this) - }), b(t), c(i.group.find(".k-first, .k-last").add(i.items)), this - }, - insertBefore: function(n, t) { - t = this.element.find(t); - var i = this._insert(n, t, t.parent()); - return st(i.items, function() { - t.before(this); - b(this); - c(this) - }), c(t), this - }, - insertAfter: function(n, t) { - t = this.element.find(t); - var i = this._insert(n, t, t.parent()); - return st(i.items, function() { - t.after(this); - b(this); - c(this) - }), c(t), this - }, - _insert: function(t, i, r) { - var c = this, - u, s, e, o; - return i && i.length || (r = c.element), e = n.isPlainObject(t), o = { - firstLevel: r.hasClass(h), - horizontal: r.hasClass(h + "-horizontal"), - expanded: !0, - length: r.children().length - }, i && !r.length && (r = n(l.renderGroup({ - group: o - })).appendTo(i)), e || n.isArray(t) ? u = n(n.map(e ? [t] : t, function(t, i) { - return typeof t == "string" ? n(t).get() : n(l.renderItem({ - group: o, - item: f(t, { - index: i - }) - })).get() - })) : (u = n(t), s = u.find("> ul").addClass("k-group").attr("role", "menu"), u = u.filter("li"), u.add(s.find("> li")).each(function() { - oi(this) - })), { - items: u, - group: r - } - }, - remove: function(n) { - var r; - n = this.element.find(n); - var u = this, - t = n.parentsUntil(u.element, p), - i = n.parent("ul:not(.k-menu)"); - return n.remove(), i && !i.children(p).length && (r = i.parent(".k-animation-container"), r.length ? r.remove() : i.remove()), t.length && (t = t.eq(0), b(t), c(t)), u - }, - open: function(r) { - var u = this, - e = u.options, - s = e.orientation == "horizontal", - o = e.direction, - c = i.support.isRtl(u.wrapper); - return r = u.element.find(r), /^(top|bottom|default)$/.test(o) && (o = c ? s ? (o + " left").replace("default", "bottom") : "left" : s ? (o + " right").replace("default", "bottom") : "right"), r.siblings().find(">.k-popup:visible,>.k-animation-container>.k-popup:visible").each(function() { - var t = n(this).data("kendoPopup"); - t && t.close() - }), r.each(function() { - var i = n(this); - clearTimeout(i.data(tt)); - i.data(tt, setTimeout(function() { - var r = i.find(".k-group:first:hidden"), - l; - if (r[0] && u.trigger(ht, { - item: i[0] - }) === !1) { - !r.find(".k-group")[0] && r.children(".k-item").length > 1 ? setTimeout(function() { - r.css({ - maxHeight: n(window).height(), - overflow: "auto" - }) - }) : r.css({ - maxHeight: "", - overflow: "" - }); - i.data(a, i.css(a)); - i.css(a, u.nextItemZIndex++); - l = r.data(ut); - var y = i.parent().hasClass(h), - b = y && s, - v = pi(o, y, c), - p = e.animation.open.effects, - w = p !== t ? p : "slideIn:" + yi(o, y); - l ? (l = r.data(ut), l.options.origin = v.origin, l.options.position = v.position, l.options.animation.open.effects = w) : l = r.kendoPopup({ - activate: function() { - u.trigger(gt, { - item: this.wrapper.parent() - }) - }, - deactivate: function() { - u.trigger(ni, { - item: this.wrapper.parent() - }) - }, - origin: v.origin, - position: v.position, - collision: e.popupCollision !== t ? e.popupCollision : b ? "fit" : "fit flip", - anchor: i, - appendTo: i, - animation: { - open: f(!0, { - effects: w - }, e.animation.open), - close: e.animation.close - }, - close: function(n) { - var t = n.sender.wrapper.parent(); - u.trigger(nt, { - item: t[0] - }) ? n.preventDefault() : (t.css(a, t.data(a)), t.removeData(a), ri && (t.removeClass(lt), u._removeHoverItem())) - } - }).data(ut); - r.removeAttr("aria-hidden"); - l.open() - } - }, u.options.hoverDelay)) - }), u - }, - close: function(t) { - var i = this, - r = i.element; - return t = r.find(t), t.length || (t = r.find(">.k-item")), t.each(function() { - var t = n(this); - i._isRootItem(t) && (i.clicked = !1); - clearTimeout(t.data(tt)); - t.data(tt, setTimeout(function() { - var n = t.find(".k-group:not(.k-list-container):not(.k-calendar-container):first:visible").data(ut); - n && (n.close(), n.element.attr("aria-hidden", !0)) - }, i.options.hoverDelay)) - }), i - }, - _toggleDisabled: function(t, i) { - this.element.find(t).each(function() { - n(this).toggleClass(ui, i).toggleClass(y, !i).attr("aria-disabled", !i) - }) - }, - _toggleHover: function(t) { - var r = n(i.eventTarget(t) || t.target).closest(p), - u = t.type == ct || et.indexOf(t.type) !== -1; - r.parents("li." + y).length || r.toggleClass(lt, u || t.type == "mousedown" || t.type == "click"); - this._removeHoverItem() - }, - _preventClose: function() { - this.options.closeOnClick || (this._closurePrevented = !0) - }, - _checkActiveElement: function(t) { - var u = this, - f = n(t ? t.currentTarget : this._hoverItem()), - r = u._findRootParent(f)[0]; - this._closurePrevented || setTimeout(function() { - document.hasFocus() && (d(r, i._activeElement()) || !t || d(r, t.currentTarget)) || u.close(r) - }, 0); - this._closurePrevented = !1 - }, - _removeHoverItem: function() { - var n = this._hoverItem(); - n && n.hasClass(v) && (n.removeClass(v), this._oldHoverItem = null) - }, - _updateClasses: function() { - var n = this.element, - t; - n.addClass("k-widget k-reset k-header " + h).addClass(h + "-" + this.options.orientation); - n.find("li > ul").addClass("k-group").attr("role", "menu").attr("aria-hidden", n.is(":visible")).end().find("li > div").addClass("k-content").attr("tabindex", "-1"); - t = n.find("> li,.k-group > li"); - t.each(function() { - oi(this) - }) - }, - _mouseenter: function(t) { - var i = this, - r = n(t.currentTarget), - f = r.children(".k-animation-container").length || r.children(at).length; - t.delegateTarget == r.parents(".k-menu")[0] && (i.options.openOnClick && !i.clicked || ft || !d(t.currentTarget, t.relatedTarget) && f && i.open(r), (i.options.openOnClick && i.clicked || ri) && r.siblings().each(u(function(n, t) { - i.close(t) - }, i))) - }, - _mouseleave: function(t) { - var r = this, - i = n(t.currentTarget), - u = i.children(".k-animation-container").length || i.children(at).length; - if (i.parentsUntil(".k-animation-container", ".k-list-container,.k-calendar-container")[0]) { - t.stopImmediatePropagation(); - return - } - r.options.openOnClick || ft || (it || rt) && t.originalEvent.pointerType == t.originalEvent.MSPOINTER_TYPE_TOUCH || d(t.currentTarget, t.relatedTarget || t.target) || !u || r.close(i) - }, - _click: function(t) { - var r = this, - c, f = r.options, - e = n(i.eventTarget(t)), - o = e[0] ? e[0].nodeName.toUpperCase() : "", - v = o == "INPUT" || o == "SELECT" || o == "BUTTON" || o == "LABEL", - l = e.closest("." + k), - u = e.closest(p), - w = l.attr("href"), - s, b, a = !!w && w !== n("<a href='#' />").attr("href"); - if (!u.children(vi)[0]) { - if (u.hasClass(y)) { - t.preventDefault(); - return - } - if (t.handled || !r.trigger(dt, { - item: u[0] - }) || v || t.preventDefault(), t.handled = !0, s = u.children(at + ",.k-animation-container"), b = s.is(":visible"), f.closeOnClick && !a && (!s.length || f.openOnClick && b)) { - u.removeClass(lt).css("height"); - r._oldHoverItem = r._findRootParent(u); - r.close(l.parentsUntil(r.element, p)); - r.clicked = !1; - "MSPointerUp".indexOf(t.type) != -1 && t.preventDefault(); - return - }(a && t.enterKey && l[0].click(), u.parent().hasClass(h) && f.openOnClick || i.support.touch) && (a || v || t.preventDefault(), r.clicked = !0, c = s.is(":visible") ? nt : ht, f.closeOnClick || c != nt) && r[c](u) - } - }, - _documentClick: function(n) { - d(this.element[0], n.target) || (this.clicked = !1) - }, - _focus: function(t) { - var i = this, - r = t.target, - u = i._hoverItem(), - f = hi(); - if (r != i.wrapper[0] && !n(r).is(":kendoFocusable")) { - t.stopPropagation(); - n(r).closest(".k-content").closest(".k-group").closest(".k-item").addClass(v); - i.wrapper.focus(); - return - } - f === t.currentTarget && (u.length ? i._moveHover([], u) : i._oldHoverItem || i._moveHover([], i.wrapper.children().first())) - }, - _keydown: function(n) { - var t = this, - f = n.keyCode, - r = t._oldHoverItem, - u, o, s, h = i.support.isRtl(t.wrapper); - if (n.target == n.currentTarget || f == e.ESC) { - if (r || (r = t._oldHoverItem = t._hoverItem()), o = t._itemBelongsToVertival(r), s = t._itemHasChildren(r), f == e.RIGHT) u = t[h ? "_itemLeft" : "_itemRight"](r, o, s); - else if (f == e.LEFT) u = t[h ? "_itemRight" : "_itemLeft"](r, o, s); - else if (f == e.DOWN) u = t._itemDown(r, o, s); - else if (f == e.UP) u = t._itemUp(r, o, s); - else if (f == e.ESC) u = t._itemEsc(r, o); - else if (f == e.ENTER || f == e.SPACEBAR) u = r.children(".k-link"), u.length > 0 && (t._click({ - target: u[0], - preventDefault: function() {}, - enterKey: !0 - }), t._moveHover(r, t._findRootParent(r))); - else if (f == e.TAB) { - u = t._findRootParent(r); - t._moveHover(r, u); - t._checkActiveElement(); - return - } - u && u[0] && (n.preventDefault(), n.stopPropagation()) - } - }, - _hoverItem: function() { - return this.wrapper.find(".k-item.k-state-hover,.k-item.k-state-focused").filter(":visible") - }, - _itemBelongsToVertival: function(n) { - var t = this.wrapper.hasClass("k-menu-vertical"); - return n.length ? n.parent().hasClass("k-group") || t : t - }, - _itemHasChildren: function(n) { - return n.length ? n.children("ul.k-group, div.k-animation-container").length > 0 : !1 - }, - _moveHover: function(n, t) { - var r = this, - i = r._ariaId; - n.length && t.length && (n.removeClass(v), n[0].id === i && n.removeAttr("id")); - t.length && (t[0].id && (i = t[0].id), t.addClass(v), r._oldHoverItem = t, i && (r.element.removeAttr("aria-activedescendant"), t.attr("id", i), r.element.attr("aria-activedescendant", i))) - }, - _findRootParent: function(n) { - return n.parent().hasClass("k-menu") ? n : n.parentsUntil(".k-menu", "li.k-item").last() - }, - _isRootItem: function(n) { - return n.parent().hasClass("k-menu") - }, - _itemRight: function(n, t, i) { - var u = this, - r, f; - if (!n.hasClass(y)) return t ? i ? (u.open(n), r = n.find(".k-group").children().first()) : u.options.orientation == "horizontal" && (f = u._findRootParent(n), u.close(f), r = f.nextAll(w)) : (r = n.nextAll(w), r.length || (r = n.prevAll(ei))), r && !r.length ? r = u.wrapper.children(".k-item").first() : r || (r = []), u._moveHover(n, r), r - }, - _itemLeft: function(n, t) { - var r = this, - i; - return t ? (i = n.parent().closest(".k-item"), r.close(i), r._isRootItem(i) && r.options.orientation == "horizontal" && (i = i.prevAll(w))) : (i = n.prevAll(w), i.length || (i = n.nextAll(ei))), i.length || (i = r.wrapper.children(".k-item").last()), r._moveHover(n, i), i - }, - _itemDown: function(n, t, i) { - var u = this, - r; - if (t) r = n.nextAll(w); - else { - if (!i || n.hasClass(y)) return; - u.open(n); - r = n.find(".k-group").children().first() - } - return !r.length && n.length ? r = n.parent().children().first() : n.length || (r = u.wrapper.children(".k-item").first()), u._moveHover(n, r), r - }, - _itemUp: function(n, t) { - var r = this, - i; - if (t) i = n.prevAll(w); - else return; - return !i.length && n.length ? i = n.parent().children().last() : n.length || (i = r.wrapper.children(".k-item").last()), r._moveHover(n, i), i - }, - _itemEsc: function(n, t) { - var r = this, - i; - if (t) i = n.parent().closest(".k-item"), r.close(i), r._moveHover(n, i); - else return n; - return i - }, - _focusHandler: function(t) { - var u = this, - r = n(i.eventTarget(t)).closest(p); - setTimeout(function() { - u._moveHover([], r); - r.children(".k-content")[0] && r.parent().closest(".k-item").removeClass(v) - }, 200) - }, - _animations: function(n) { - n && "animation" in n && !n.animation && (n.animation = { - open: { - effects: {} - }, - close: { - hide: !0, - effects: {} - } - }) - } - }); - f(l, { - renderItem: function(n) { - n = f({ - menu: {}, - group: {} - }, n); - var i = s.empty, - t = n.item; - return s.item(f(n, { - image: t.imageUrl ? s.image : i, - sprite: t.spriteCssClass ? s.sprite : i, - itemWrapper: s.itemWrapper, - renderContent: l.renderContent, - arrow: t.items || t.content ? s.arrow : i, - subGroup: l.renderGroup - }, yt)) - }, - renderGroup: function(n) { - return s.group(f({ - renderItems: function(n) { - for (var r = "", t = 0, i = n.items, u = i ? i.length : 0, e = f({ - length: u - }, n.group); t < u; t++) r += l.renderItem(f(n, { - group: e, - item: f({ - index: t - }, i[t]) - })); - return r - } - }, n, yt)) - }, - renderContent: function(n) { - return s.content(f(n, yt)) - } - }); - i.ui.plugin(l) - }(window.kendo.jQuery); -kendo_module({ - id: "filtermenu", - name: "Filtering Menu", - category: "framework", - depends: ["datepicker", "numerictextbox", "dropdownlist"], - advanced: !0 - }), - function(n) { - function c(t, i) { - t.filters && (t.filters = n.grep(t.filters, function(n) { - return c(n, i), n.filters ? n.filters.length : n.field != i - })) - } - - function l(n) { - var i, u, t, f, e, r; - if (n && n.length) - for (r = [], i = 0, u = n.length; i < u; i++) t = n[i], e = t.text || t.value || t, f = t.value == null ? t.text || t : t.value, r[i] = { - text: e, - value: f - }; - return r - } - - function d(t, i) { - return n.grep(t, function(t) { - return t.filters ? (t.filters = n.grep(t.filters, function(n) { - return n.field != i - }), t.filters.length) : t.field != i - }) - } - var t = window.kendo, - s = t.ui, - i = n.proxy, - u = "kendoPopup", - h = "init", - r = ".kendoFilterMenu", - f = "Is equal to", - e = "Is not equal to", - a = { - number: "numerictextbox", - date: "datepicker" - }, - v = { - string: "text", - number: "number", - date: "date" - }, - y = t.isFunction, - o = s.Widget, - p = '<div><div class="k-filter-help-text">#=messages.info#<\/div><label><input type="radio" data-#=ns#bind="checked: filters[0].value" value="true" name="filters[0].value"/>#=messages.isTrue#<\/label><label><input type="radio" data-#=ns#bind="checked: filters[0].value" value="false" name="filters[0].value"/>#=messages.isFalse#<\/label><div><button type="submit" class="k-button">#=messages.filter#<\/button><button type="reset" class="k-button">#=messages.clear#<\/button><\/div><\/div>', - w = '<div><div class="k-filter-help-text">#=messages.info#<\/div><select data-#=ns#bind="value: filters[0].operator" data-#=ns#role="dropdownlist">#for(var op in operators){#<option value="#=op#">#=operators[op]#<\/option>#}#<\/select>#if(values){#<select data-#=ns#bind="value:filters[0].value" data-#=ns#text-field="text" data-#=ns#value-field="value" data-#=ns#source=\'#=kendo.stringify(values).replace(/\'/g,"&\\#39;")#\' data-#=ns#role="dropdownlist" data-#=ns#option-label="#=messages.selectValue#"><\/select>#}else{#<input data-#=ns#bind="value:filters[0].value" class="k-textbox" type="text" #=role ? "data-" + ns + "role=\'" + role + "\'" : ""# />#}##if(extra){#<select class="k-filter-and" data-#=ns#bind="value: logic" data-#=ns#role="dropdownlist"><option value="and">#=messages.and#<\/option><option value="or">#=messages.or#<\/option><\/select><select data-#=ns#bind="value: filters[1].operator" data-#=ns#role="dropdownlist">#for(var op in operators){#<option value="#=op#">#=operators[op]#<\/option>#}#<\/select>#if(values){#<select data-#=ns#bind="value:filters[1].value" data-#=ns#text-field="text" data-#=ns#value-field="value" data-#=ns#source=\'#=kendo.stringify(values).replace(/\'/g,"&\\#39;")#\' data-#=ns#role="dropdownlist" data-#=ns#option-label="#=messages.selectValue#"><\/select>#}else{#<input data-#=ns#bind="value: filters[1].value" class="k-textbox" type="text" #=role ? "data-" + ns + "role=\'" + role + "\'" : ""#/>#}##}#<div><button type="submit" class="k-button">#=messages.filter#<\/button><button type="reset" class="k-button">#=messages.clear#<\/button><\/div><\/div>', - b = '<div data-#=ns#role="view" data-#=ns#init-widgets="false" class="k-grid-filter-menu"><div data-#=ns#role="header" class="k-header"><button class="k-button k-cancel">#=messages.cancel#<\/button>#=field#<button type="submit" class="k-button k-submit">#=messages.filter#<\/button><\/div><form class="k-filter-menu k-mobile-list k-secondary"><ul class="k-filter-help-text"><li><span class="k-link">#=messages.info#<\/span><ul><li class="k-item"><label class="k-label">#=messages.operator#<select data-#=ns#bind="value: filters[0].operator">#for(var op in operators){#<option value="#=op#">#=operators[op]#<\/option>#}#<\/select><\/label><\/li><li class="k-item"><label class="k-label">#=messages.value##if(values){#<select data-#=ns#bind="value:filters[0].value"><option value="">#=messages.selectValue#<\/option>#for(var val in values){#<option value="#=values[val].value#">#=values[val].text#<\/option>#}#<\/select>#}else{#<input data-#=ns#bind="value:filters[0].value" class="k-textbox" type="#=inputType#" #=useRole ? "data-" + ns + "role=\'" + role + "\'" : ""# />#}#<\/label><\/li>#if(extra){#<\/ul><ul class="k-filter-help-text"><li><span class="k-link"><\/span><li class="k-item"><label class="k-label"><input type="radio" name="logic" class="k-check" data-#=ns#bind="checked: logic" value="and" />#=messages.and#<\/label><\/li><li class="k-item"><label class="k-label"><input type="radio" name="logic" class="k-check" data-#=ns#bind="checked: logic" value="or" />#=messages.or#<\/label><\/li><\/ul><ul class="k-filter-help-text"><li><span class="k-link"><\/span><li class="k-item"><label class="k-label">#=messages.operator#<select data-#=ns#bind="value: filters[1].operator">#for(var op in operators){#<option value="#=op#">#=operators[op]#<\/option>#}#<\/select><\/label><\/li><li class="k-item"><label class="k-label">#=messages.value##if(values){#<select data-#=ns#bind="value:filters[1].value"><option value="">#=messages.selectValue#<\/option>#for(var val in values){#<option value="#=values[val].value#">#=values[val].text#<\/option>#}#<\/select>#}else{#<input data-#=ns#bind="value:filters[1].value" class="k-textbox" type="#=inputType#" #=useRole ? "data-" + ns + "role=\'" + role + "\'" : ""# />#}#<\/label><\/li>#}#<\/ul><\/li><li class="k-button-container"><button type="reset" class="k-button">#=messages.clear#<\/button><\/li><\/ul><\/div><\/form><\/div>', - k = '<div data-#=ns#role="view" data-#=ns#init-widgets="false" class="k-grid-filter-menu"><div data-#=ns#role="header" class="k-header"><button class="k-button k-cancel">#=messages.cancel#<\/button>#=field#<button type="submit" class="k-button k-submit">#=messages.filter#<\/button><\/div><form class="k-filter-menu k-mobile-list k-secondary"><ul class="k-filter-help-text"><li><span class="k-link">#=messages.info#<\/span><ul><li class="k-item"><label class="k-label"><input class="k-check" type="radio" data-#=ns#bind="checked: filters[0].value" value="true" name="filters[0].value"/>#=messages.isTrue#<\/label><\/li><li class="k-item"><label class="k-label"><input class="k-check" type="radio" data-#=ns#bind="checked: filters[0].value" value="false" name="filters[0].value"/>#=messages.isFalse#<\/label><\/li><\/ul><\/li><li class="k-button-container"><button type="reset" class="k-button">#=messages.clear#<\/button><\/li><\/ul><\/form><\/div>', - g = o.extend({ - init: function(u, f) { - var e = this, - h = "string", - l, a, c, s; - if (o.fn.init.call(e, u, f), l = e.operators = f.operators || {}, u = e.element, f = e.options, !f.appendToElement) { - c = u.addClass("k-with-icon k-filterable").find(".k-grid-filter"); - c[0] || (c = u.prepend('<a class="k-grid-filter" href="#"><span class="k-icon k-filter"/><\/a>').find(".k-grid-filter")); - c.attr("tabindex", -1).on("click" + r, i(e._click, e)) - } - e.link = c || n(); - e.dataSource = f.dataSource; - e.field = f.field || u.attr(t.attr("field")); - e.model = e.dataSource.reader.model; - e._parse = function(n) { - return n + "" - }; - e.model && e.model.fields && (s = e.model.fields[e.field], s && (h = s.type || "string", s.parse && (e._parse = i(s.parse, s)))); - f.values && (h = "enums"); - e.type = h; - l = l[h] || f.operators[h]; - for (a in l) break; - e._defaultFilter = function() { - return { - field: e.field, - operator: a || "eq", - value: "" - } - }; - e._refreshHandler = i(e.refresh, e); - e.dataSource.bind("change", e._refreshHandler); - f.appendToElement ? e._init() : e.refresh() - }, - _init: function() { - var u = this, - f = u.options.ui, - o = y(f), - e; - u.pane = u.options.pane; - u.pane && (u._isMobile = !0); - o || (e = f || a[u.type]); - u._isMobile ? u._createMobileForm(e) : u._createForm(e); - u.form.on("submit" + r, i(u._submit, u)).on("reset" + r, i(u._reset, u)); - o && u.form.find(".k-textbox").removeClass("k-textbox").each(function() { - f(n(this)) - }); - u.form.find("[" + t.attr("role") + "=numerictextbox]").removeClass("k-textbox").end().find("[" + t.attr("role") + "=datetimepicker]").removeClass("k-textbox").end().find("[" + t.attr("role") + "=timepicker]").removeClass("k-textbox").end().find("[" + t.attr("role") + "=datepicker]").removeClass("k-textbox"); - u.refresh(); - u.trigger(h, { - field: u.field, - container: u.form - }) - }, - _createForm: function(f) { - var e = this, - o = e.options, - h = e.operators || {}, - s = e.type; - h = h[s] || o.operators[s]; - e.form = n('<form class="k-filter-menu k-secondary"/>').html(t.template(s === "boolean" ? p : w)({ - field: e.field, - format: o.format, - ns: t.ns, - messages: o.messages, - extra: o.extra, - operators: h, - type: s, - role: f, - values: l(o.values) - })); - o.appendToElement ? (e.element.append(e.form), e.popup = e.element.closest(".k-popup").data(u)) : e.popup = e.form[u]({ - anchor: e.link, - open: i(e._open, e), - activate: i(e._activate, e), - close: e.options.closeCallback - }).data(u); - e.form.on("keydown" + r, i(e._keydown, e)) - }, - _createMobileForm: function(i) { - var r = this, - f = r.options, - e = r.operators || {}, - u = r.type; - e = e[u] || f.operators[u]; - r.form = n("<div />").html(t.template(u === "boolean" ? k : b)({ - field: r.field, - format: f.format, - ns: t.ns, - messages: f.messages, - extra: f.extra, - operators: e, - type: u, - role: i, - useRole: !t.support.input.date && u === "date" || u === "number", - inputType: v[u], - values: l(f.values) - })); - r.view = r.pane.append(r.form.html()); - r.form = r.view.element.find("form"); - r.view.element.on("click", ".k-submit", function(n) { - r.form.submit(); - n.preventDefault() - }).on("click", ".k-cancel", function(n) { - r._closeForm(); - n.preventDefault() - }) - }, - refresh: function() { - var n = this, - i = n.dataSource.filter() || { - filters: [], - logic: "and" - }; - n.filterModel = t.observable({ - logic: "and", - filters: [n._defaultFilter(), n._defaultFilter()] - }); - n.form && t.bind(n.form.children().first(), n.filterModel); - n._bind(i) ? n.link.addClass("k-state-active") : n.link.removeClass("k-state-active") - }, - destroy: function() { - var n = this; - o.fn.destroy.call(n); - n.form && (t.unbind(n.form), t.destroy(n.form), n.form.unbind(r), n.popup && n.popup.destroy()); - n.view && n.view.purge(); - n.link.unbind(r); - n._refreshHandler && n.dataSource.unbind("change", n._refreshHandler) - }, - _bind: function(n) { - for (var i = this, s = n.filters, f = !1, o = 0, e = i.filterModel, r, t, u = 0, h = s.length; u < h; u++) t = s[u], t.field == i.field ? (e.set("logic", n.logic), r = e.filters[o], r || (e.filters.push({ - field: i.field - }), r = e.filters[o]), r.set("value", i._parse(t.value)), r.set("operator", t.operator), o++, f = !0) : t.filters && (f = f || i._bind(t)); - return f - }, - _merge: function(t) { - var f = this, - s = t.logic || "and", - r = t.filters, - e, i = f.dataSource.filter() || { - filters: [], - logic: "and" - }, - u, o; - for (c(i, f.field), r = n.grep(r, function(n) { - return n.value !== "" && n.value != null - }), u = 0, o = r.length; u < o; u++) e = r[u], e.value = f._parse(e.value); - return r.length && (i.filters.length ? (t.filters = r, i.logic !== "and" && (i.filters = [{ - logic: i.logic, - filters: i.filters - }], i.logic = "and"), r.length > 1 ? i.filters.push(t) : i.filters.push(r[0])) : (i.filters = r, i.logic = s)), i - }, - filter: function(n) { - n = this._merge(n); - n.filters.length && this.dataSource.filter(n) - }, - clear: function() { - var i = this, - t = i.dataSource.filter() || { - filters: [] - }; - t.filters = n.grep(t.filters, function(n) { - return n.filters ? (n.filters = d(n.filters, i.field), n.filters.length) : n.field != i.field - }); - t.filters.length || (t = null); - i.dataSource.filter(t) - }, - _submit: function(n) { - n.preventDefault(); - n.stopPropagation(); - this.filter(this.filterModel.toJSON()); - this._closeForm() - }, - _reset: function() { - this.clear(); - this._closeForm() - }, - _closeForm: function() { - this._isMobile ? this.pane.navigate("", this.options.animations.right) : this.popup.close() - }, - _click: function(n) { - n.preventDefault(); - n.stopPropagation(); - this.popup || this.pane || this._init(); - this._isMobile ? this.pane.navigate(this.view, this.options.animations.left) : this.popup.toggle() - }, - _open: function() { - var t; - n(".k-filter-menu").not(this.form).each(function() { - t = n(this).data(u); - t && t.close() - }) - }, - _activate: function() { - this.form.find(":kendoFocusable:first").focus() - }, - _keydown: function(n) { - n.keyCode == t.keys.ESC && this.popup.close() - }, - events: [h], - options: { - name: "FilterMenu", - extra: !0, - appendToElement: !1, - type: "string", - operators: { - string: { - eq: f, - neq: e, - startswith: "Starts with", - contains: "Contains", - doesnotcontain: "Does not contain", - endswith: "Ends with" - }, - number: { - eq: f, - neq: e, - gte: "Is greater than or equal to", - gt: "Is greater than", - lte: "Is less than or equal to", - lt: "Is less than" - }, - date: { - eq: f, - neq: e, - gte: "Is after or equal to", - gt: "Is after", - lte: "Is before or equal to", - lt: "Is before" - }, - enums: { - eq: f, - neq: e - } - }, - messages: { - info: "Show items with value that:", - isTrue: "is true", - isFalse: "is false", - filter: "Filter", - clear: "Clear", - and: "And", - or: "Or", - selectValue: "-Select value-", - operator: "Operator", - value: "Value", - cancel: "Cancel" - }, - animations: { - left: "slide", - right: "slide:right" - } - } - }); - s.plugin(g) - }(window.kendo.jQuery); -kendo_module({ - id: "panelbar", - name: "PanelBar", - category: "web", - description: "The PanelBar widget displays hierarchical data as a multi-level expandable panel bar.", - depends: ["core"] - }), - function(n, t) { - function wt(t) { - t = n(t); - t.children(r).children(".k-icon").remove(); - t.filter(":has(.k-panel),:has(.k-content)").children(".k-link:not(:has([class*=k-i-arrow]))").each(function() { - var t = n(this), - i = t.parent(); - t.append("<span class='k-icon " + (i.hasClass(w) ? "k-i-arrow-n k-panelbar-collapse" : "k-i-arrow-s k-panelbar-expand") + "'/>") - }) - } - - function a(t) { - t = n(t); - t.filter(".k-first:not(:first-child)").removeClass(ct); - t.filter(".k-last:not(:last-child)").removeClass(ht); - t.filter(":first-child").addClass(ct); - t.filter(":last-child").addClass(ht) - } - var e = window.kendo, - oi = e.ui, - o = e.keys, - i = n.extend, - ot = n.each, - s = e.template, - nt = oi.Widget, - si = /^(ul|a|div)$/i, - h = ".kendoPanelBar", - bt = "img", - st = "href", - ht = "k-last", - tt = "k-link", - r = "." + tt, - kt = "error", - u = ".k-item", - b = ".k-group:visible", - dt = "k-image", - ct = "k-first", - lt = "expand", - at = "select", - it = "k-content", - gt = "activate", - rt = "collapse", - ni = "mouseenter", - hi = "mouseleave", - ti = "contentLoad", - w = "k-state-active", - v = "> .k-panel", - k = "> .k-content", - ii = "k-state-focused", - f = "k-state-disabled", - d = "k-state-selected", - ut = "." + d, - c = "k-state-highlight", - ft = u + ":not(.k-state-disabled)", - ri = ft + " > .k-link", - ci = u + ".k-state-disabled > .k-link", - ui = "> li > " + ut + ", .k-panel > li > " + ut, - fi = "k-state-default", - vt = "aria-disabled", - g = "aria-expanded", - yt = "aria-hidden", - et = "aria-selected", - y = ":visible", - li = ":empty", - ei = "single", - l = { - content: s("<div role='region' class='k-content'#= contentAttributes(data) #>#= content(item) #<\/div>"), - group: s("<ul role='group' aria-hidden='true' class='#= groupCssClass(group) #'#= groupAttributes(group) #>#= renderItems(data) #<\/ul>"), - itemWrapper: s("<#= tag(item) # class='#= textClass(item, group) #' #= contentUrl(item) ##= textAttributes(item) #>#= image(item) ##= sprite(item) ##= text(item) ##= arrow(data) #<\/#= tag(item) #>"), - item: s("<li role='menuitem' #=aria(item)#class='#= wrapperCssClass(group, item) #'>#= itemWrapper(data) ## if (item.items) { ##= subGroup({ items: item.items, panelBar: panelBar, group: { expanded: item.expanded } }) ## } else if (item.content || item.contentUrl) { ##= renderContent(data) ## } #<\/li>"), - image: s("<img class='k-image' alt='' src='#= imageUrl #' />"), - arrow: s("<span class='#= arrowClass(item) #'><\/span>"), - sprite: s("<span class='k-sprite #= spriteCssClass #'><\/span>"), - empty: s("") - }, - pt = { - aria: function(n) { - var t = ""; - return (n.items || n.content || n.contentUrl) && (t += g + "='" + (n.expanded ? "true" : "false") + "' "), n.enabled === !1 && (t += vt + "='true'"), t - }, - wrapperCssClass: function(n, t) { - var i = "k-item", - r = t.index; - return i += t.enabled === !1 ? " " + f : t.expanded === !0 ? " " + w : " k-state-default", r === 0 && (i += " k-first"), r == n.length - 1 && (i += " k-last"), t.cssClass && (i += " " + t.cssClass), i - }, - textClass: function(n, t) { - var i = tt; - return t.firstLevel && (i += " k-header"), i - }, - textAttributes: function(n) { - return n.url ? " href='" + n.url + "'" : "" - }, - arrowClass: function(n) { - return "k-icon" + (n.expanded ? " k-i-arrow-n k-panelbar-collapse" : " k-i-arrow-s k-panelbar-expand") - }, - text: function(n) { - return n.encoded === !1 ? n.text : e.htmlEncode(n.text) - }, - tag: function(n) { - return n.url || n.contentUrl ? "a" : "span" - }, - groupAttributes: function(n) { - return n.expanded !== !0 ? " style='display:none'" : "" - }, - groupCssClass: function() { - return "k-group k-panel" - }, - contentAttributes: function(n) { - return n.item.expanded !== !0 ? " style='display:none'" : "" - }, - content: function(n) { - return n.content ? n.content : n.contentUrl ? "" : " " - }, - contentUrl: function(n) { - return n.contentUrl ? 'href="' + n.contentUrl + '"' : "" - } - }, - p = nt.extend({ - init: function(t, i) { - var r = this, - u; - nt.fn.init.call(r, t, i); - t = r.wrapper = r.element.addClass("k-widget k-reset k-header k-panelbar"); - i = r.options; - t[0].id && (r._itemId = t[0].id + "_pb_active"); - r._tabindex(); - r._initData(i); - r._updateClasses(); - r._animations(i); - t.on("click" + h, ri, function(t) { - r._click(n(t.currentTarget)) && t.preventDefault() - }).on(ni + h + " " + hi + h, ri, r._toggleHover).on("click" + h, ci, !1).on("keydown" + h, n.proxy(r._keydown, r)).on("focus" + h, function() { - var n = r.select(); - r._current(n[0] ? n : r._first()) - }).on("blur" + h, function() { - r._current(null) - }).attr("role", "menu"); - u = t.find("li." + w + " > ." + it); - u[0] && r.expand(u.parent(), !1); - e.notify(r) - }, - events: [lt, rt, at, gt, kt, ti], - options: { - name: "PanelBar", - animation: { - expand: { - effects: "expand:vertical", - duration: 200 - }, - collapse: { - duration: 200 - } - }, - expandMode: "multiple" - }, - destroy: function() { - nt.fn.destroy.call(this); - this.element.off(h); - e.destroy(this.element) - }, - _initData: function(n) { - var t = this; - n.dataSource && (t.element.empty(), t.append(n.dataSource, t.element)) - }, - setOptions: function(n) { - var t = this.options.animation; - this._animations(n); - n.animation = i(!0, t, n.animation); - "dataSource" in n && this._initData(n); - nt.fn.setOptions.call(this, n) - }, - expand: function(t, i) { - var r = this, - u = {}; - return i = i !== !1, t = this.element.find(t), t.each(function(e, o) { - o = n(o); - var s = o.find(v).add(o.find(k)); - if (!o.hasClass(f) && s.length > 0) { - if (r.options.expandMode == ei && r._collapseAllExpanded(o)) return r; - t.find("." + c).removeClass(c); - o.addClass(c); - i || (u = r.options.animation, r.options.animation = { - expand: { - effects: {} - }, - collapse: { - hide: !0, - effects: {} - } - }); - r._triggerEvent(lt, o) || r._toggleItem(o, !1); - i || (r.options.animation = u) - } - }), r - }, - collapse: function(t, i) { - var r = this, - u = {}; - return i = i !== !1, t = r.element.find(t), t.each(function(t, e) { - e = n(e); - var o = e.find(v).add(e.find(k)); - !e.hasClass(f) && o.is(y) && (e.removeClass(c), i || (u = r.options.animation, r.options.animation = { - expand: { - effects: {} - }, - collapse: { - hide: !0, - effects: {} - } - }), r._triggerEvent(rt, e) || r._toggleItem(e, !0), i || (r.options.animation = u)) - }), r - }, - _toggleDisabled: function(n, t) { - n = this.element.find(n); - n.toggleClass(fi, t).toggleClass(f, !t).attr(vt, !t) - }, - select: function(i) { - var u = this; - return i === t ? u.element.find(ui).parent() : (u.element.find(i).each(function() { - var t = n(this), - i = t.children(r); - if (t.hasClass(f)) return u; - u._triggerEvent(at, t) || u._updateSelected(i) - }), u) - }, - enable: function(n, t) { - return this._toggleDisabled(n, t !== !1), this - }, - disable: function(n) { - return this._toggleDisabled(n, !1), this - }, - append: function(n, t) { - t = this.element.find(t); - var i = this._insert(n, t, t.length ? t.find(v) : null); - return ot(i.items, function() { - i.group.append(this); - a(this) - }), wt(t), a(i.group.find(".k-first, .k-last")), i.group.height("auto"), this - }, - insertBefore: function(n, t) { - t = this.element.find(t); - var i = this._insert(n, t, t.parent()); - return ot(i.items, function() { - t.before(this); - a(this) - }), a(t), i.group.height("auto"), this - }, - insertAfter: function(n, t) { - t = this.element.find(t); - var i = this._insert(n, t, t.parent()); - return ot(i.items, function() { - t.after(this); - a(this) - }), a(t), i.group.height("auto"), this - }, - remove: function(n) { - n = this.element.find(n); - var r = this, - t = n.parentsUntil(r.element, u), - i = n.parent("ul"); - return n.remove(), !i || i.hasClass("k-panelbar") || i.children(u).length || i.remove(), t.length && (t = t.eq(0), wt(t), a(t)), r - }, - reload: function(t) { - var i = this; - t = i.element.find(t); - t.each(function() { - var t = n(this); - i._ajaxRequest(t, t.children("." + it), !t.is(y)) - }) - }, - _first: function() { - return this.element.children(ft).first() - }, - _last: function() { - var n = this.element.children(ft).last(), - t = n.children(b); - return t[0] ? t.children(ft).last() : n - }, - _current: function(n) { - var i = this, - u = i._focused, - f = i._itemId; - if (n === t) return u; - i.element.removeAttr("aria-activedescendant"); - u && (u[0].id === f && u.removeAttr("id"), u.children(r).removeClass(ii)); - n && (f = n[0].id || f, n.attr("id", f).children(r).addClass(ii), i.element.attr("aria-activedescendant", f)); - i._focused = n - }, - _keydown: function(n) { - var t = this, - i = n.keyCode, - u = t._current(); - n.target == n.currentTarget && (i == o.DOWN || i == o.RIGHT ? (t._current(t._nextItem(u)), n.preventDefault()) : i == o.UP || i == o.LEFT ? (t._current(t._prevItem(u)), n.preventDefault()) : i == o.ENTER || i == o.SPACEBAR ? (t._click(u.children(r)), n.preventDefault()) : i == o.HOME ? (t._current(t._first()), n.preventDefault()) : i == o.END && (t._current(t._last()), n.preventDefault())) - }, - _nextItem: function(n) { - if (!n) return this._first(); - var i = n.children(b), - t = n.next(); - return i[0] && (t = i.children("." + ct)), t[0] || (t = n.parent(b).parent(u).next()), t[0] && t.is(":visible") || (t = this._first()), t.hasClass(f) && (t = this._nextItem(t)), t - }, - _prevItem: function(n) { - if (!n) return this._last(); - var t = n.prev(), - i; - if (t[0]) - for (i = t; i[0];) i = i.children(b).children("." + ht), i[0] && (t = i); - else t = n.parent(b).parent(u), t[0] || (t = this._last()); - return t.hasClass(f) && (t = this._prevItem(t)), t - }, - _insert: function(t, r, u) { - var s = this, - f, h = n.isPlainObject(t), - e = r && r[0], - o; - return e || (u = s.element), o = { - firstLevel: u.hasClass("k-panelbar"), - expanded: u.parent().hasClass(w), - length: u.children().length - }, e && !u.length && (u = n(p.renderGroup({ - group: o - })).appendTo(r)), h || n.isArray(t) ? (f = n.map(h ? [t] : t, function(t, r) { - return typeof t == "string" ? n(t) : n(p.renderItem({ - group: o, - item: i(t, { - index: r - }) - })) - }), e && r.attr(g, !1)) : (f = n(t), s._updateItemsClasses(f)), { - items: f, - group: u - } - }, - _toggleHover: function(t) { - var i = n(t.currentTarget); - i.parents("li." + f).length || i.toggleClass("k-state-hover", t.type == ni) - }, - _updateClasses: function() { - var i = this, - r, t; - r = i.element.find("li > ul").not(function() { - return n(this).parentsUntil(".k-panelbar", "div").length - }).addClass("k-group k-panel").attr("role", "group"); - r.parent().attr(g, !1).not("." + w).children("ul").attr(yt, !0).hide(); - t = i.element.add(r).children(); - i._updateItemsClasses(t); - wt(t); - a(t) - }, - _updateItemsClasses: function(n) { - for (var i = n.length, t = 0; t < i; t++) this._updateItemClasses(n[t], t) - }, - _updateItemClasses: function(t, i) { - var s = this._selected, - f = this.options.contentUrls, - h = f && f[i], - c = this.element[0], - o, u; - t = n(t).addClass("k-item").attr("role", "menuitem"); - e.support.browser.msie && t.css("list-style-position", "inside").css("list-style-position", ""); - t.children(bt).addClass(dt); - u = t.children("a").addClass(tt); - u[0] && (u.attr("href", h), u.children(bt).addClass(dt)); - t.filter(":not([disabled]):not([class*=k-state])").addClass("k-state-default"); - t.filter("li[disabled]").addClass("k-state-disabled").attr(vt, !0).removeAttr("disabled"); - t.children("div").addClass(it).attr("role", "region").attr(yt, !0).hide().parent().attr(g, !1); - u = t.children(ut); - u[0] && (s && s.removeAttr(et).children(ut).removeClass(d), u.addClass(d), this._selected = t.attr(et, !0)); - t.children(r)[0] || (o = "<span class='" + tt + "'/>", f && f[i] && t[0].parentNode == c && (o = '<a class="k-link k-header" href="' + f[i] + '"/>'), t.contents().filter(function() { - return !this.nodeName.match(si) && !(this.nodeType == 3 && !n.trim(this.nodeValue)) - }).wrapAll(o)); - t.parent(".k-panelbar")[0] && t.children(r).addClass("k-header") - }, - _click: function(n) { - var t = this, - a = t.element, - i, o, s, l, h, e, c; - if (!n.parents("li." + f).length) return n.closest(".k-widget")[0] != a[0] ? void 0 : (h = n.closest(r), e = h.closest(u), t._updateSelected(h), o = e.find(v).add(e.find(k)), s = h.attr(st), l = s && (s.charAt(s.length - 1) == "#" || s.indexOf("#" + t.element[0].id + "-") != -1), i = !!(l || o.length), o.data("animating")) ? i : (t._triggerEvent(at, e) && (i = !0), i === !1) ? void 0 : t.options.expandMode == ei && t._collapseAllExpanded(e) ? i : (o.length && (c = o.is(y), t._triggerEvent(c ? rt : lt, e) || (i = t._toggleItem(e, c))), i) - }, - _toggleItem: function(n, i) { - var e = this, - o = n.find(v), - s = n.find(r), - h = s.attr(st), - f, u; - return o.length ? (this._toggleGroup(o, i), f = !0) : (u = n.children("." + it), u.length && (f = !0, u.is(li) && h !== t ? e._ajaxRequest(n, u, i) : e._toggleGroup(u, i))), f - }, - _toggleGroup: function(n, t) { - var e = this, - o = e.options.animation, - r = o.expand, - f = i({}, o.collapse), - s = f && "effects" in f; - n.is(y) == t && (n.parent().attr(g, !t).attr(yt, t).toggleClass(fi, t).toggleClass(w, !t).find("> .k-link > .k-icon").toggleClass("k-i-arrow-n", !t).toggleClass("k-panelbar-collapse", !t).toggleClass("k-i-arrow-s", t).toggleClass("k-panelbar-expand", t), r = t ? i(s ? f : i({ - reverse: !0 - }, r), { - hide: !0 - }) : i({ - complete: function(n) { - e._triggerEvent(gt, n.closest(u)) - } - }, r), n.kendoStop(!0, !0).kendoAnimate(r)) - }, - _collapseAllExpanded: function(t) { - var e = this, - o, i = !1, - f; - if (t.children(r).hasClass("k-header")) return f = t.find(v).add(t.find(k)), f.is(y) && (i = !0), f.is(y) || f.length === 0 || (o = n(e.element).children(), o.find(v).add(o.find(k)).filter(function() { - return n(this).is(y) - }).each(function(t, r) { - r = n(r); - i = e._triggerEvent(rt, r.closest(u)); - i || e._toggleGroup(r, !0) - })), i - }, - _ajaxRequest: function(t, i, u) { - var f = this, - e = t.find(".k-panelbar-collapse, .k-panelbar-expand"), - s = t.find(r), - h = setTimeout(function() { - e.addClass("k-loading") - }, 100), - o = s.attr(st); - n.ajax({ - type: "GET", - cache: !1, - url: o, - dataType: "html", - data: {}, - error: function(n, t) { - e.removeClass("k-loading"); - f.trigger(kt, { - xhr: n, - status: t - }) && this.complete() - }, - complete: function() { - clearTimeout(h); - e.removeClass("k-loading") - }, - success: function(n) { - try { - i.html(n) - } catch (e) { - var r = window.console; - r && r.error && r.error(e.name + ": " + e.message + " in " + o); - this.error(this.xhr, "error") - } - f._toggleGroup(i, u); - f.trigger(ti, { - item: t[0], - contentElement: i[0] - }) - } - }) - }, - _triggerEvent: function(n, t) { - var i = this; - return i.trigger(n, { - item: t[0] - }) - }, - _updateSelected: function(n) { - var t = this, - i = t.element, - r = n.parent(u), - f = t._selected; - f && f.removeAttr(et); - t._selected = r.attr(et, !0); - i.find(ui).removeClass(d); - i.find("> ." + c + ", .k-panel > ." + c).removeClass(c); - n.addClass(d); - n.parentsUntil(i, u).filter(":has(.k-header)").addClass(c); - t._current(r) - }, - _animations: function(n) { - n && "animation" in n && !n.animation && (n.animation = { - expand: { - effects: {} - }, - collapse: { - hide: !0, - effects: {} - } - }) - } - }); - i(p, { - renderItem: function(n) { - n = i({ - panelBar: {}, - group: {} - }, n); - var r = l.empty, - t = n.item; - return l.item(i(n, { - image: t.imageUrl ? l.image : r, - sprite: t.spriteCssClass ? l.sprite : r, - itemWrapper: l.itemWrapper, - renderContent: p.renderContent, - arrow: t.items || t.content || t.contentUrl ? l.arrow : r, - subGroup: p.renderGroup - }, pt)) - }, - renderGroup: function(n) { - return l.group(i({ - renderItems: function(n) { - for (var u = "", t = 0, r = n.items, f = r ? r.length : 0, e = i({ - length: f - }, n.group); t < f; t++) u += p.renderItem(i(n, { - group: e, - item: i({ - index: t - }, r[t]) - })); - return u - } - }, n, pt)) - }, - renderContent: function(n) { - return l.content(i(n, pt)) - } - }); - e.ui.plugin(p) - }(window.kendo.jQuery); -kendo_module({ - id: "timepicker", - name: "TimePicker", - category: "web", - description: "The TimePicker widget allows the end user to select a value from a list of predefined values or to type a new value.", - depends: ["popup"] - }), - function(n, t) { - function ui(n, t, i) { - var u = n.getTimezoneOffset(), - r; - n.setTime(n.getTime() + t); - i || (r = n.getTimezoneOffset() - u, n.setTime(n.getTime() + r * h)) - } - - function fi() { - var n = new u, - t = new u(n.getFullYear(), n.getMonth(), n.getDate(), 0, 0, 0), - i = new u(n.getFullYear(), n.getMonth(), n.getDate(), 12, 0, 0); - return -1 * (t.getTimezoneOffset() - i.getTimezoneOffset()) - } - - function e(n) { - return n.getHours() * 60 * h + n.getMinutes() * h + n.getSeconds() * 1e3 + n.getMilliseconds() - } - - function kt(n, t, i) { - var u = e(t), - f = e(i), - r; - return !n || u == f ? !0 : (r = e(n), u > r && (r += s), f < u && (f += s), r >= u && r <= f) - } - - function gt(n) { - var t = n.parseFormats; - n.format = ii(n.format || r.getCulture(n.culture).calendars.standard.patterns.t); - t = bt(t) ? t : [t]; - t.splice(0, 0, n.format); - n.parseFormats = t - } - - function ni(n) { - n.preventDefault() - } - var r = window.kendo, - o = r.keys, - ti = r._activeElement, - ii = r._extractFormat, - l = r.support, - tt = l.browser, - p = r.ui, - a = p.Widget, - it = "open", - rt = "close", - w = "change", - i = ".kendoTimePicker", - ut = "click" + i, - b = "k-state-default", - ft = "disabled", - et = "readonly", - k = "li", - ot = "<span/>", - st = "k-state-focused", - d = "k-state-hover", - ri = "mouseenter" + i + " mouseleave" + i, - ht = "mousedown" + i, - h = 6e4, - s = 864e5, - ct = "k-state-selected", - g = "k-state-disabled", - lt = "aria-selected", - at = "aria-expanded", - vt = "aria-hidden", - yt = "aria-disabled", - pt = "aria-readonly", - wt = "aria-activedescendant", - v = "id", - bt = n.isArray, - nt = n.extend, - y = n.proxy, - u = Date, - f = new u, - c, dt; - f = new u(f.getFullYear(), f.getMonth(), f.getDate(), 0, 0, 0); - c = function(t) { - var u = this, - f = t.id; - u.options = t; - u.ul = n('<ul tabindex="-1" role="listbox" aria-hidden="true" unselectable="on" class="k-list k-reset"/>').css({ - overflow: l.kineticScrollNeeded ? "" : "auto" - }).on(ut, k, y(u._click, u)).on("mouseenter" + i, k, function() { - n(this).addClass(d) - }).on("mouseleave" + i, k, function() { - n(this).removeClass(d) - }); - u.list = n("<div class='k-list-container'/>").append(u.ul).on(ht, ni); - f && (u._timeViewID = f + "_timeview", u._optionID = f + "_option_selected", u.ul.attr(v, u._timeViewID)); - u._popup(); - u.template = r.template('<li tabindex="-1" role="option" class="k-item" unselectable="on">#=data#<\/li>', { - useWithBlock: !1 - }) - }; - c.prototype = { - current: function(i) { - var r = this, - u = r.options.active; - if (i !== t) r._current && r._current.removeClass(ct).removeAttr(lt).removeAttr(v), i && (i = n(i).addClass(ct).attr(v, r._optionID).attr(lt, !0), r.scroll(i[0])), r._current = i, u && u(i); - else return r._current - }, - close: function() { - this.popup.close() - }, - destroy: function() { - var n = this; - n.ul.off(i); - n.list.off(i); - n._touchScroller && n._touchScroller.destroy(); - n.popup.destroy() - }, - open: function() { - var n = this; - n.ul[0].firstChild || n.bind(); - n.popup.open(); - n._current && n.scroll(n._current[0]) - }, - dataBind: function(n) { - for (var i = this, t = i.options, s = t.format, h = r.toString, c = i.template, e = n.length, u = 0, f, o = ""; u < e; u++) f = n[u], kt(f, t.min, t.max) && (o += c(h(f, s, t.culture))); - i._html(o, e) - }, - refresh: function() { - var l = this, - i = l.options, - g = i.format, - y = fi(), - p = y < 0, - w = i.min, - b = i.max, - a = e(w), - n = e(b), - o = i.interval * h, - nt = r.toString, - tt = l.template, - t = new u(+w), - it = t.getDate(), - v, k, c = 0, - f, d = ""; - for (f = p ? (s + y * h) / o : s / o, a != n && (a > n && (n += s), f = (n - a) / o + 1), k = parseInt(f, 10); c < f; c++) c && ui(t, o, p), n && k == c && (v = e(t), it < t.getDate() && (v += s), v > n && (t = new u(+b))), d += tt(nt(t, g, i.culture)); - l._html(d, f) - }, - bind: function() { - var n = this, - t = n.options.dates; - t && t[0] ? n.dataBind(t) : n.refresh() - }, - _html: function(n, t) { - var i = this; - i.ul[0].innerHTML = n; - i._height(t); - i.current(null); - i.select(i._value) - }, - scroll: function(n) { - if (n) { - var i = this.ul[0], - t = n.offsetTop, - f = n.offsetHeight, - r = i.scrollTop, - e = i.clientHeight, - o = t + f, - s = this._touchScroller, - u; - s ? (u = this.list.height(), t > u && (t = t - u + f), s.scrollTo(0, -t)) : i.scrollTop = r > t ? t : o > r + e ? o - e : r - } - }, - select: function(t) { - var i = this, - f = i.options, - u = i._current; - t instanceof Date && (t = r.toString(t, f.format, f.culture)); - typeof t == "string" && (u && u.text() === t ? t = u : (t = n.grep(i.ul[0].childNodes, function(n) { - return (n.textContent || n.innerText) == t - }), t = t[0] ? t : null)); - i.current(t) - }, - setOptions: function(n) { - var t = this.options; - this.options = nt(t, n, { - active: t.active, - change: t.change, - close: t.close, - open: t.open - }); - this.bind() - }, - toggle: function() { - var n = this; - n.popup.visible() ? n.close() : n.open() - }, - value: function(n) { - var t = this; - t._value = n; - t.ul[0].firstChild && t.select(n) - }, - _click: function(t) { - var i = this, - r = n(t.currentTarget); - t.isDefaultPrevented() || (i.select(r), i.options.change(r.text(), !0), i.close()) - }, - _height: function(n) { - if (n) { - var t = this, - i = t.list, - u = i.parent(".k-animation-container"), - r = t.options.height; - i.add(u).show().height(t.ul[0].scrollHeight > r ? r : "auto").hide() - } - }, - _parse: function(n) { - var o = this, - s = o.options, - t = o._value || f, - i, e; - return n instanceof u ? n : (n != null && (i = n.indexOf(":"), i == -1 ? n = n.length <= 2 ? n + ":00" : n.slice(2).length == 1 ? n.slice(0, 2) + ":" + n.slice(2) + "0" : n.slice(0, 2) + ":" + n.slice(2) : i == 0 ? n = "00" + n : (e = n.split(":"), e[1].length == 0 ? n = n + "00" : e[1].length == 1 && (n = n + "0"))), n = r.parseDate(n, s.parseFormats, s.culture), n && (n = new u(t.getFullYear(), t.getMonth(), t.getDate(), n.getHours(), n.getMinutes(), n.getSeconds(), n.getMilliseconds())), n) - }, - _adjustListWidth: function() { - var t = this.list, - i = t[0].style.width, - r = this.options.anchor, - n, u; - (t.data("width") || !i) && (n = window.getComputedStyle ? window.getComputedStyle(r[0], null) : 0, u = n ? parseFloat(n.width) : r.outerWidth(), n && (tt.mozilla || tt.msie) && (u += parseFloat(n.paddingLeft) + parseFloat(n.paddingRight) + parseFloat(n.borderLeftWidth) + parseFloat(n.borderRightWidth)), i = u - (t.outerWidth() - t.width()), t.css({ - fontFamily: r.css("font-family"), - width: i - }).data("width", i)) - }, - _popup: function() { - var t = this, - i = t.list, - n = t.options, - u = n.anchor; - t.popup = new p.Popup(i, nt(n.popup, { - anchor: u, - open: n.open, - close: n.close, - animation: n.animation, - isRtl: l.isRtl(n.anchor) - })); - t._touchScroller = r.touchScroller(t.popup.element) - }, - move: function(n) { - var i = this, - r = n.keyCode, - f = i.ul[0], - t = i._current, - u = r === o.DOWN; - if (r === o.UP || u) { - if (n.altKey) { - i.toggle(u); - return - } - t = u ? t ? t[0].nextSibling : f.firstChild : t ? t[0].previousSibling : f.lastChild; - t && i.select(t); - i.options.change(i._current.text()); - n.preventDefault() - } else(r === o.ENTER || r === o.TAB || r === o.ESC) && (n.preventDefault(), t && i.options.change(t.text(), !0), i.close()) - } - }; - c.getMilliseconds = e; - r.TimeView = c; - dt = a.extend({ - init: function(n, t) { - var i = this, - f, u, e; - a.fn.init.call(i, n, t); - n = i.element; - t = i.options; - gt(t); - i._wrapper(); - i.timeView = u = new c(nt({}, t, { - id: n.attr(v), - anchor: i.wrapper, - format: t.format, - change: function(t, r) { - r ? i._change(t) : n.val(t) - }, - open: function(t) { - i.timeView._adjustListWidth(); - i.trigger(it) ? t.preventDefault() : (n.attr(at, !0), f.attr(vt, !1)) - }, - close: function(t) { - i.trigger(rt) ? t.preventDefault() : (n.attr(at, !1), f.attr(vt, !0)) - }, - active: function(t) { - n.removeAttr(wt); - t && n.attr(wt, u._optionID) - } - })); - f = u.ul; - i._icon(); - i._reset(); - try { - n[0].setAttribute("type", "text") - } catch (o) { - n[0].type = "text" - } - n.addClass("k-input").attr({ - role: "combobox", - "aria-expanded": !1, - "aria-owns": u._timeViewID - }); - e = n.is("[disabled]"); - e ? i.enable(!1) : i.readonly(n.is("[readonly]")); - i._old = i._update(t.value || i.element.val()); - i._oldText = n.val(); - r.notify(i) - }, - options: { - name: "TimePicker", - min: f, - max: f, - format: "", - dates: [], - parseFormats: [], - value: null, - interval: 30, - height: 200, - animation: {} - }, - events: [it, rt, w], - setOptions: function(n) { - var t = this, - i = t._value; - a.fn.setOptions.call(t, n); - n = t.options; - gt(n); - t.timeView.setOptions(n); - i && t.element.val(r.toString(i, n.format, n.culture)) - }, - dataBind: function(n) { - bt(n) && this.timeView.dataBind(n) - }, - _editable: function(n) { - var t = this, - r = n.disable, - u = n.readonly, - o = t._arrow.off(i), - f = t.element.off(i), - e = t._inputWrapper.off(i); - if (u || r) e.addClass(r ? g : b).removeClass(r ? b : g), f.attr(ft, r).attr(et, u).attr(yt, r).attr(pt, u); - else { - e.addClass(b).removeClass(g).on(ri, t._toggleHover); - f.removeAttr(ft).removeAttr(et).attr(yt, !1).attr(pt, !1).on("keydown" + i, y(t._keydown, t)).on("blur" + i, y(t._blur, t)).on("focus" + i, function() { - t._inputWrapper.addClass(st) - }); - o.on(ut, y(t._click, t)).on(ht, ni) - } - }, - readonly: function(n) { - this._editable({ - readonly: n === t ? !0 : n, - disable: !1 - }) - }, - enable: function(n) { - this._editable({ - readonly: !1, - disable: !(n = n === t ? !0 : n) - }) - }, - destroy: function() { - var n = this; - a.fn.destroy.call(n); - n.timeView.destroy(); - n.element.off(i); - n._arrow.off(i); - n._inputWrapper.off(i); - n._form && n._form.off("reset", n._resetHandler) - }, - close: function() { - this.timeView.close() - }, - open: function() { - this.timeView.open() - }, - min: function(n) { - return this._option("min", n) - }, - max: function(n) { - return this._option("max", n) - }, - value: function(n) { - var i = this; - if (n === t) return i._value; - i._old = i._update(n); - i._old === null && i.element.val(""); - i._oldText = i.element.val() - }, - _blur: function() { - var n = this, - t = n.element.val(); - n.close(); - t !== n._oldText && n._change(t); - n._inputWrapper.removeClass(st) - }, - _click: function() { - var n = this, - t = n.element; - n.timeView.toggle(); - l.touch || t[0] === ti() || t.focus() - }, - _change: function(n) { - var t = this; - n = t._update(n); + t._old != +n && (t._old = n, t._oldText = t.element.val(), t.trigger(w), t.element.trigger(w)) - }, - _icon: function() { - var i = this, - r = i.element, - t; - t = r.next("span.k-select"); - t[0] || (t = n('<span unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-clock">select<\/span><\/span>').insertAfter(r)); - i._arrow = t.attr({ - role: "button", - "aria-controls": i.timeView._timeViewID - }) - }, - _keydown: function(n) { - var t = this, - u = n.keyCode, - i = t.timeView, - r = t.element.val(); - i.popup.visible() || n.altKey ? i.move(n) : u === o.ENTER && r !== t._oldText && t._change(r) - }, - _option: function(n, i) { - var r = this, - f = r.options; - if (i === t) return f[n]; - (i = r.timeView._parse(i), i) && (i = new u(+i), f[n] = i, r.timeView.options[n] = i, r.timeView.bind()) - }, - _toggleHover: function(t) { - n(t.currentTarget).toggleClass(d, t.type === "mouseenter") - }, - _update: function(n) { - var i = this, - u = i.options, - f = i.timeView, - t = f._parse(n); - return kt(t, u.min, u.max) || (t = null), i._value = t, i.element.val(t ? r.toString(t, u.format, u.culture) : n), f.value(t), t - }, - _wrapper: function() { - var r = this, - i = r.element, - t; - t = i.parents(".k-timepicker"); - t[0] || (t = i.wrap(ot).parent().addClass("k-picker-wrap k-state-default"), t = t.wrap(ot).parent()); - t[0].style.cssText = i[0].style.cssText; - r.wrapper = t.addClass("k-widget k-timepicker k-header").addClass(i[0].className); - i.css({ - width: "100%", - height: i[0].style.height - }); - r._inputWrapper = n(t[0].firstChild) - }, - _reset: function() { - var t = this, - i = t.element, - r = i.attr("form"), - u = r ? n("#" + r) : i.closest("form"); - u[0] && (t._resetHandler = function() { - t.value(i[0].defaultValue) - }, t._form = u.on("reset", t._resetHandler)) - } - }); - p.plugin(dt) - }(window.kendo.jQuery); -kendo_module({ - id: "window", - name: "Window", - category: "web", - description: "The Window widget displays content in a modal or non-modal HTML window.", - depends: ["draganddrop"] - }), - function(n, t) { - function rt(n) { - return typeof n != "undefined" - } - - function o(n, t, i) { - return Math.max(Math.min(parseInt(n, 10), i === Infinity ? i : parseInt(i, 10)), parseInt(t, 10)) - } - - function ii(n, t) { - return function() { - var i = this, - r = i.wrapper, - f = r[0].style, - o = i.options; - if (!o.isMaximized && !o.isMinimized) return i.restoreOptions = { - width: f.width, - height: f.height - }, r.children(h).hide().end().children(e).find(gt).parent().hide().eq(0).before(u.action({ - name: "Restore" - })), t.call(i), n == "maximize" ? i.wrapper.children(e).find(st).parent().hide() : i.wrapper.children(e).find(st).parent().show(), i - } - } - - function ri(n) { - var t = this; - t.owner = n; - t._draggable = new ht(n.wrapper, { - filter: h, - group: n.wrapper.id + "-resizing", - dragstart: f(t.dragstart, t), - drag: f(t.drag, t), - dragend: f(t.dragend, t) - }) - } - - function ui(n, t) { - var i = this; - i.owner = n; - i._draggable = new ht(n.wrapper, { - filter: t, - group: n.wrapper.id + "-moving", - dragstart: f(i.dragstart, i), - drag: f(i.drag, i), - dragend: f(i.dragend, i), - dragcancel: f(i.dragcancel, i) - }); - i._draggable.userEvents.stopPropagation = !1 - } - var i = window.kendo, - d = i.ui.Widget, - ht = i.ui.Draggable, - ct = n.isPlainObject, - fi = i._activeElement, - f = n.proxy, - l = n.extend, - ut = n.each, - s = i.template, - g = "body", - u, r = ".kendoWindow", - a = ".k-window", - ft = ".k-window-title", - e = ft + "bar", - v = ".k-window-content", - h = ".k-resize-handle", - nt = ".k-overlay", - w = "k-content-frame", - lt = "k-loading", - at = "k-state-hover", - vt = "k-state-focused", - yt = "k-window-maximized", - y = ":visible", - tt = "hidden", - p = "cursor", - et = "open", - ot = "activate", - pt = "deactivate", - wt = "close", - it = "refresh", - bt = "dragstart", - kt = "dragend", - dt = "error", - c = "overflow", - b = "zIndex", - gt = ".k-window-actions .k-i-minimize,.k-window-actions .k-i-maximize", - ni = ".k-i-pin", - ti = ".k-i-unpin", - st = ni + "," + ti, - k = ".k-window-titlebar .k-window-action", - ei = i.isLocalUrl, - oi = d.extend({ - init: function(u, o) { - var s = this, - h, w = {}, - g, nt, c, it = !1, - l, b, ut = o && o.actions && !o.actions.length, - p; - d.fn.init.call(s, u, o); - o = s.options; - c = o.position; - u = s.element; - l = o.content; - ut && (o.actions = []); - s.appendTo = n(o.appendTo); - s._animations(); - l && !ct(l) && (l = o.content = { - url: l - }); - u.find("script").filter(function() { - return !this.type || this.type.toLowerCase().indexOf("script") >= 0 - }).remove(); - u.parent().is(s.appendTo) || c.top !== t && c.left !== t || (u.is(y) ? (w = u.offset(), it = !0) : (g = u.css("visibility"), nt = u.css("display"), u.css({ - visibility: tt, - display: "" - }), w = u.offset(), u.css({ - visibility: g, - display: nt - })), c.top === t && (c.top = w.top), c.left === t && (c.left = w.left)); - rt(o.visible) && o.visible !== null || (o.visible = u.is(y)); - h = s.wrapper = u.closest(a); - u.is(".k-content") && h[0] || (u.addClass("k-window-content k-content"), s._createWindow(u, o), h = s.wrapper = u.closest(a), s._dimensions()); - s._position(); - o.pinned && s.pin(!0); - l && s.refresh(l); - o.visible && s.toFront(); - b = h.children(v); - s._tabindex(b); - o.visible && o.modal && s._overlay(h.is(y)).css({ - opacity: .5 - }); - h.on("mouseenter" + r, k, function() { - n(this).addClass(at) - }).on("mouseleave" + r, k, function() { - n(this).removeClass(at) - }).on("click" + r, "> " + k, f(s._windowActionHandler, s)); - b.on("keydown" + r, f(s._keydown, s)).on("focus" + r, function() { - h.addClass(vt) - }).on("blur" + r, function() { - h.removeClass(vt) - }); - this._resizable(); - this._draggable(); - p = u.attr("id"); - p && (p = p + "_wnd_title", h.children(e).children(ft).attr("id", p), b.attr({ - role: "dialog", - "aria-labelledby": p - })); - h.add(h.children(".k-resize-handle," + e)).on("mousedown" + r, f(s.toFront, s)); - s.touchScroller = i.touchScroller(u); - s._resizeHandler = function(n) { - return s._onDocumentResize(n) - }; - n(window).on("resize", s._resizeHandler); - o.visible && (s.trigger(et), s.trigger(ot)); - i.notify(s) - }, - _dimensions: function() { - var i = this, - t = i.wrapper, - n = i.options, - r = n.width, - u = n.height, - f = n.maxHeight; - i.title(n.title); - ut(["minWidth", "minHeight", "maxWidth", "maxHeight"], function(i, r) { - var u = n[r]; - u && u != Infinity && t.css(r, u) - }); - f && f != Infinity && i.element.css("maxHeight", f); - r && (r.toString().indexOf("%") > 0 ? t.width(r) : t.width(o(r, n.minWidth, n.maxWidth))); - u && (u.toString().indexOf("%") > 0 ? t.height(u) : t.height(o(u, n.minHeight, n.maxHeight))); - n.visible || t.hide() - }, - _position: function() { - var t = this, - i = t.wrapper, - n = t.options.position; - n.top === 0 && (n.top = n.top.toString()); - n.left === 0 && (n.left = n.left.toString()); - i.css({ - top: n.top || "", - left: n.left || "" - }) - }, - _animations: function() { - var n = this.options; - n.animation === !1 && (n.animation = { - open: { - effects: {} - }, - close: { - hide: !0, - effects: {} - } - }) - }, - _resize: function() { - i.resize(this.element.children()) - }, - _resizable: function() { - var i = this.options.resizable, - t = this.wrapper; - if (this.resizing && (t.off("dblclick" + r).children(h).remove(), this.resizing.destroy(), this.resizing = null), i) { - t.on("dblclick" + r, e, f(function(t) { - n(t.target).closest(".k-window-action").length || this.toggleMaximization() - }, this)); - ut("n e s w se sw ne nw".split(" "), function(n, i) { - t.append(u.resizeHandle(i)) - }); - this.resizing = new ri(this) - } - }, - _draggable: function() { - var n = this.options.draggable; - this.dragging && (this.dragging.destroy(), this.dragging = null); - n && (this.dragging = new ui(this, n.dragHandle || e)) - }, - setOptions: function(n) { - var t = this; - d.fn.setOptions.call(t, n); - t._animations(); - t._dimensions(); - t._position(); - t._resizable(); - t._draggable() - }, - events: [et, ot, pt, wt, it, "resize", bt, kt, dt], - options: { - name: "Window", - animation: { - open: { - effects: { - zoom: { - direction: "in" - }, - fade: { - direction: "in" - } - }, - duration: 350 - }, - close: { - effects: { - zoom: { - direction: "out", - properties: { - scale: .7 - } - }, - fade: { - direction: "out" - } - }, - duration: 350, - hide: !0 - } - }, - title: "", - actions: ["Close"], - autoFocus: !0, - modal: !1, - resizable: !0, - draggable: !0, - minWidth: 90, - minHeight: 50, - maxWidth: Infinity, - maxHeight: Infinity, - pinned: !1, - position: {}, - content: null, - visible: null, - height: null, - width: null, - appendTo: "body" - }, - _closable: function() { - return n.inArray("close", n.map(this.options.actions, function(n) { - return n.toLowerCase() - })) > -1 - }, - _keydown: function(n) { - var u = this, - h = u.options, - f = i.keys, - e = n.keyCode, - t = u.wrapper, - c, r, s = 10, - p = u.options.isMaximized, - v, y, l, a; - n.target != n.currentTarget || u._closing || (e == f.ESC && u._closable() && u._close(!0), !h.draggable || n.ctrlKey || p || (c = i.getOffset(t), e == f.UP ? r = t.css("top", c.top - s) : e == f.DOWN ? r = t.css("top", c.top + s) : e == f.LEFT ? r = t.css("left", c.left - s) : e == f.RIGHT && (r = t.css("left", c.left + s))), h.resizable && n.ctrlKey && !p && (e == f.UP ? (r = !0, y = t.height() - s) : e == f.DOWN && (r = !0, y = t.height() + s), e == f.LEFT ? (r = !0, v = t.width() - s) : e == f.RIGHT && (r = !0, v = t.width() + s), r && (l = o(v, h.minWidth, h.maxWidth), a = o(y, h.minHeight, h.maxHeight), isNaN(l) || (t.width(l), u.options.width = l + "px"), isNaN(a) || (t.height(a), u.options.height = a + "px"), u.resize())), r && n.preventDefault()) - }, - _overlay: function(t) { - var i = this.appendTo.children(nt), - r = this.wrapper; - return i.length || (i = n("<div class='k-overlay' />")), i.insertBefore(r[0]).toggle(t).css(b, parseInt(r.css(b), 10) - 1), i - }, - _windowActionHandler: function(t) { - var r = n(t.target).closest(".k-window-action").find(".k-icon"), - i = this; - i._closing || ut({ - "k-i-close": function() { - i._close(!0) - }, - "k-i-maximize": i.maximize, - "k-i-minimize": i.minimize, - "k-i-restore": i.restore, - "k-i-refresh": i.refresh, - "k-i-pin": i.pin, - "k-i-unpin": i.unpin - }, function(n, u) { - if (r.hasClass(n)) return t.preventDefault(), u.call(i), !1 - }) - }, - _modals: function() { - var t = this; - return n(a).filter(function() { - var i = n(this), - r = t._object(i).options; - return r.modal && r.visible && i.is(y) - }).sort(function(t, i) { - return +n(t).css("zIndex") - +n(i).css("zIndex") - }) - }, - _object: function(n) { - var t = n.children(v); - return t.data("kendoWindow") || t.data("kendo" + this.options.name) - }, - center: function() { - var t = this, - e = t.options.position, - r = t.wrapper, - i = n(window), - o = 0, - s = 0, - u, f; - return t.options.isMaximized ? t : (t.options.pinned || (o = i.scrollTop(), s = i.scrollLeft()), f = s + Math.max(0, (i.width() - r.width()) / 2), u = o + Math.max(0, (i.height() - r.height()) / 2), r.css({ - left: f, - top: u - }), e.top = u, e.left = f, t) - }, - title: function(n) { - var i = this, - r = i.wrapper, - s = i.options, - t = r.children(e), - f = t.children(ft), - o = t.outerHeight(); - return arguments.length ? (n === !1 ? (r.addClass("k-window-titleless"), t.remove()) : (t.length || r.prepend(u.titlebar(l(u, s))), r.css("padding-top", o), t.css("margin-top", -o)), f.text(n), i.options.title = n, i) : f.text() - }, - content: function(n) { - var t = this.wrapper.children(v), - r = t.children(".km-scroll-container"); - return (t = r[0] ? r : t, !rt(n)) ? t.html() : (i.destroy(this.element.children()), t.html(n), this) - }, - open: function() { - var t = this, - f = t.wrapper, - r = t.options, - e = r.animation.open, - s = f.children(v), - h = s.css(c), - u, o; - return t.trigger(et) || (t._closing && f.kendoStop(!0, !0), t._closing = !1, t.toFront(), r.autoFocus && t.element.focus(), r.visible = !0, r.modal && (u = t._overlay(!1), u.kendoStop(!0, !0), e.duration && i.effects.Fade ? (o = i.fx(u).fadeIn(), o.duration(e.duration || 0), o.endValue(.5), o.play()) : u.css("opacity", .5), u.show()), f.is(y) || (s.css(c, tt), f.show().kendoStop().kendoAnimate({ - effects: e.effects, - duration: e.duration, - complete: function() { - r.autoFocus && t.element.focus(); - t.trigger(ot); - s.css(c, h) - } - }))), r.isMaximized && (t._documentScrollTop = n(document).scrollTop(), n("html, body").css(c, tt)), t - }, - _removeOverlay: function(r) { - var f = this._modals(), - e = this.options, - s = e.modal && !f.length, - h = e.modal ? this._overlay(!0) : n(t), - o = e.animation.close, - u; - s ? !r && o.duration && i.effects.Fade ? (u = i.fx(h).fadeOut(), u.duration(o.duration || 0), u.startValue(.5), u.play()) : this._overlay(!1).remove() : f.length && this._object(f.last())._overlay(!0) - }, - _close: function(t) { - var i = this, - r = i.wrapper, - u = i.options, - e = u.animation.open, - f = u.animation.close; - r.is(y) && !i.trigger(wt, { - userTriggered: !!t - }) && (i._closing = !0, u.visible = !1, n(a).each(function(t, i) { - var u = n(i).children(v); - i != r && u.find("> ." + w).length > 0 && u.children(nt).remove() - }), this._removeOverlay(), r.kendoStop().kendoAnimate({ - effects: f.effects || e.effects, - reverse: f.reverse === !0, - duration: f.duration, - complete: function() { - r.hide().css("opacity", ""); - i.trigger(pt); - var n = i._object(i._modals().last()); - n && n.toFront() - } - })); - i.options.isMaximized && (n("html, body").css(c, ""), i._documentScrollTop && i._documentScrollTop > 0 && n(document).scrollTop(i._documentScrollTop)) - }, - close: function() { - return this._close(!1), this - }, - _actionable: function(t) { - return n(t).is(k + "," + k + " .k-icon,:input,a") - }, - _shouldFocus: function(t) { - var r = fi(), - i = this.element; - return this.options.autoFocus && !n(r).is(i) && !this._actionable(t) && (!i.find(r).length || !i.find(t).length) - }, - toFront: function(t) { - var r = this, - i = r.wrapper, - s = i[0], - f = +i.css(b), - h = f, - c = t && t.target || null, - e, o; - return n(a).each(function(t, i) { - var r = n(i), - e = r.css(b), - o = r.children(v); - isNaN(e) || (f = Math.max(+e, f)); - i != s && o.find("> ." + w).length > 0 && o.append(u.overlay) - }), (!i[0].style.zIndex || h < f) && i.css(b, f + 2), r.element.find("> .k-overlay").remove(), r._shouldFocus(c) && (r.element.focus(), e = n(window).scrollTop(), o = parseInt(i.position().top, 10), o > 0 && o < e && (e > 0 ? n(window).scrollTop(o) : i.css("top", e))), r - }, - toggleMaximization: function() { - return this._closing ? this : this[this.options.isMaximized ? "restore" : "maximize"]() - }, - restore: function() { - var t = this, - i = t.options, - u = i.minHeight, - r = t.restoreOptions; - return !i.isMaximized && !i.isMinimized ? t : (u && u != Infinity && t.wrapper.css("min-height", u), t.wrapper.css({ - position: i.pinned ? "fixed" : "absolute", - left: r.left, - top: r.top, - width: r.width, - height: r.height - }).removeClass(yt).find(".k-window-content,.k-resize-handle").show().end().find(".k-window-titlebar .k-i-restore").parent().remove().end().end().find(gt).parent().show().end().end().find(st).parent().show(), t.options.width = r.width, t.options.height = r.height, n("html, body").css(c, ""), this._documentScrollTop && this._documentScrollTop > 0 && n(document).scrollTop(this._documentScrollTop), i.isMaximized = i.isMinimized = !1, t.resize(), t) - }, - maximize: ii("maximize", function() { - var t = this, - i = t.wrapper, - r = i.position(); - l(t.restoreOptions, { - left: r.left, - top: r.top - }); - i.css({ - left: 0, - top: 0, - position: "fixed" - }).addClass(yt); - this._documentScrollTop = n(document).scrollTop(); - n("html, body").css(c, tt); - t.options.isMaximized = !0; - t._onDocumentResize() - }), - minimize: ii("minimize", function() { - var n = this; - n.wrapper.css({ - height: "", - minHeight: "" - }); - n.element.hide(); - n.options.isMinimized = !0 - }), - pin: function(t) { - var i = this, - u = n(window), - r = i.wrapper, - f = parseInt(r.css("top"), 10), - o = parseInt(r.css("left"), 10); - !t && (i.options.pinned || i.options.isMaximized) || (r.css({ - position: "fixed", - top: f - u.scrollTop(), - left: o - u.scrollLeft() - }), r.children(e).find(ni).addClass("k-i-unpin").removeClass("k-i-pin"), i.options.pinned = !0) - }, - unpin: function() { - var t = this, - r = n(window), - i = t.wrapper, - u = parseInt(i.css("top"), 10), - f = parseInt(i.css("left"), 10); - t.options.pinned && !t.options.isMaximized && (i.css({ - position: "", - top: u + r.scrollTop(), - left: f + r.scrollLeft() - }), i.children(e).find(ti).addClass("k-i-pin").removeClass("k-i-unpin"), t.options.pinned = !1) - }, - _onDocumentResize: function() { - var t = this, - u = t.wrapper, - f = n(window), - i, r; - t.options.isMaximized && (i = f.width(), r = f.height() - parseInt(u.css("padding-top"), 10), u.css({ - width: i, - height: r - }), t.options.width = i, t.options.height = r, t.resize()) - }, - refresh: function(t) { - var i = this, - e = i.options, - o = n(i.element), - h, f, c; - if (ct(t) || (t = { - url: t - }), t = l({}, e.content, t), f = rt(e.iframe) ? e.iframe : t.iframe, c = t.url, c) - if (rt(f) || (f = !ei(c)), f) { - h = o.find("." + w)[0]; - h ? h.src = c || h.src : o.html(u.contentFrame(l({}, e, { - content: t - }))); - o.find("." + w).unbind("load" + r).on("load" + r, function() { - i.trigger(it) - }) - } else i._ajaxRequest(t); - else t.template && i.content(s(t.template)({})), i.trigger(it); - return o.toggleClass("k-window-iframecontent", f), i - }, - _ajaxRequest: function(t) { - var i = this, - r = t.template, - u = i.wrapper.find(".k-window-titlebar .k-i-refresh"), - f = setTimeout(function() { - u.addClass(lt) - }, 100); - n.ajax(l({ - type: "GET", - dataType: "html", - cache: !1, - error: function(n, t) { - i.trigger(dt, { - status: t, - xhr: n - }) - }, - complete: function() { - clearTimeout(f); - u.removeClass(lt) - }, - success: function(n) { - r && (n = s(r)(n || {})); - i.content(n); - i.element.prop("scrollTop", 0); - i.trigger(it) - } - }, t)) - }, - destroy: function() { - var t = this.wrapper; - d.fn.destroy.call(this); - i.destroy(t); - this.resizing && this.resizing.destroy(); - this.dragging && this.dragging.destroy(); - this.element.children("iframe").remove(); - t.find(".k-resize-handle,.k-window-titlebar").off(r); - t.remove().off(r); - n(window).off("resize", this._resizeHandler); - this._removeOverlay(!0) - }, - _createWindow: function() { - var e = this, - t = e.element, - f = e.options, - o, r, s = i.support.isRtl(t); - f.scrollable === !1 && t.attr("style", "overflow:hidden;"); - r = n(u.wrapper(f)); - f.title !== !1 && r.append(u.titlebar(l(u, f))); - o = t.find("iframe:not(.k-content)").map(function() { - var n = this.getAttribute("src"); - return this.src = "", n - }); - r.toggleClass("k-rtl", s).appendTo(e.appendTo).append(t).find("iframe:not(.k-content)").each(function(n) { - this.src = o[n] - }); - r.find(".k-window-title").css(s ? "left" : "right", r.find(".k-window-actions").outerWidth() + 10); - t.show(); - t.find("[data-role=editor]").each(function() { - var t = n(this).data("kendoEditor"); - t && t.refresh() - }) - } - }); - u = { - wrapper: s("<div class='k-widget k-window' />"), - action: s("<a role='button' href='\\#' class='k-window-action k-link'><span role='presentation' class='k-icon k-i-#= name.toLowerCase() #'>#= name #<\/span><\/a>"), - titlebar: s("<div class='k-window-titlebar k-header'> <span class='k-window-title'>#= title #<\/span><div class='k-window-actions'># for (var i = 0; i < actions.length; i++) { ##= action({ name: actions[i] }) ## } #<\/div><\/div>"), - overlay: "<div class='k-overlay' />", - contentFrame: s("<iframe frameborder='0' title='#= title #' class='" + w + "' src='#= content.url #'>This page requires frames in order to show content<\/iframe>"), - resizeHandle: s("<div class='k-resize-handle k-resize-#= data #'><\/div>") - }; - ri.prototype = { - dragstart: function(t) { - var r = this, - e = r.owner, - f = e.wrapper; - r.elementPadding = parseInt(e.wrapper.css("padding-top"), 10); - r.initialCursorPosition = i.getOffset(f, "position"); - r.resizeDirection = t.currentTarget.prop("className").replace("k-resize-handle k-resize-", ""); - r.initialSize = { - width: f.width(), - height: f.height() - }; - r.containerOffset = i.getOffset(e.appendTo); - f.append(u.overlay).children(h).not(t.currentTarget).hide(); - n(g).css(p, t.currentTarget.css(p)) - }, - drag: function(n) { - var u = this, - f = u.owner, - e = f.wrapper, - t = f.options, - s = u.resizeDirection, - h = u.containerOffset, - c = u.initialCursorPosition, - v = u.initialSize, - i, r, l, a, y = Math.max(n.x.location, h.left), - p = Math.max(n.y.location, h.top); - s.indexOf("e") >= 0 ? (i = y - c.left, e.width(o(i, t.minWidth, t.maxWidth))) : s.indexOf("w") >= 0 && (a = c.left + v.width, i = o(a - y, t.minWidth, t.maxWidth), e.css({ - left: a - i - h.left, - width: i - })); - s.indexOf("s") >= 0 ? (r = p - c.top - u.elementPadding, e.height(o(r, t.minHeight, t.maxHeight))) : s.indexOf("n") >= 0 && (l = c.top + v.height, r = o(l - p, t.minHeight, t.maxHeight), e.css({ - top: l - r - h.top, - height: r - })); - i && (f.options.width = i + "px"); - r && (f.options.height = r + "px"); - f.resize() - }, - dragend: function(t) { - var i = this, - r = i.owner, - u = r.wrapper; - return u.find(nt).remove().end().children(h).not(t.currentTarget).show(), n(g).css(p, ""), r.touchScroller && r.touchScroller.reset(), t.keyCode == 27 && u.css(i.initialCursorPosition).css(i.initialSize), !1 - }, - destroy: function() { - this._draggable.destroy() - } - }; - ui.prototype = { - dragstart: function(t) { - var r = this.owner, - f = r.element, - e = f.find(".k-window-actions"), - o = i.getOffset(r.appendTo); - r.trigger(bt); - r.initialWindowPosition = i.getOffset(r.wrapper, "position"); - r.startPosition = { - left: t.x.client - r.initialWindowPosition.left, - top: t.y.client - r.initialWindowPosition.top - }; - r.minLeftPosition = e.length > 0 ? e.outerWidth() + parseInt(e.css("right"), 10) - f.outerWidth() : 20 - f.outerWidth(); - r.minLeftPosition -= o.left; - r.minTopPosition = -o.top; - r.wrapper.append(u.overlay).children(h).hide(); - n(g).css(p, t.currentTarget.css(p)) - }, - drag: function(t) { - var i = this.owner, - r = i.options.position, - u = Math.max(t.y.client - i.startPosition.top, i.minTopPosition), - f = Math.max(t.x.client - i.startPosition.left, i.minLeftPosition), - e = { - left: f, - top: u - }; - n(i.wrapper).css(e); - r.top = u; - r.left = f - }, - _finishDrag: function() { - var t = this.owner; - t.wrapper.children(h).toggle(!t.options.isMinimized).end().find(nt).remove(); - n(g).css(p, "") - }, - dragcancel: function(n) { - this._finishDrag(); - n.currentTarget.closest(a).css(this.owner.initialWindowPosition) - }, - dragend: function() { - return this._finishDrag(), this.owner.trigger(kt), !1 - }, - destroy: function() { - this._draggable.destroy() - } - }; - i.ui.plugin(oi) - }(window.kendo.jQuery); -! function(n) { - return n(["./kendo.data.min", "./kendo.combobox.min", "./kendo.multiselect.min", "./kendo.validator.min"], function() { - ! function(n, t) { - function u(t, i, r, u) { - var f = {}; - return t.sort ? (f[this.options.prefix + "sort"] = n.map(t.sort, function(n) { - return n.field + "-" + n.dir - }).join("~"), delete t.sort) : f[this.options.prefix + "sort"] = "", t.page && (f[this.options.prefix + "page"] = t.page, delete t.page), t.pageSize && (f[this.options.prefix + "pageSize"] = t.pageSize, delete t.pageSize), t.group ? (f[this.options.prefix + "group"] = n.map(t.group, function(n) { - return n.field + "-" + n.dir - }).join("~"), delete t.group) : f[this.options.prefix + "group"] = "", t.aggregate && (f[this.options.prefix + "aggregate"] = n.map(t.aggregate, function(n) { - return n.field + "-" + n.aggregate - }).join("~"), delete t.aggregate), t.filter ? (f[this.options.prefix + "filter"] = o(t.filter, r), delete t.filter) : (f[this.options.prefix + "filter"] = "", delete t.filter), delete t.take, delete t.skip, e(f, t, "", u), f - } - - function c(n) { - var t = i.culture().numberFormat[h]; - return ("" + n).replace(h, t) - } - - function l(n, t) { - return n instanceof Date ? n = t ? i.stringify(n).replace(/"/g, "") : i.format("{0:G}", n) : "number" == typeof n && (n = c(n)), n - } - - function f(n, i, r, u, f, o) { - b(i) ? a(n, i, f, o) : k(i) ? e(n, i, f, o) : n[f] === t && (n[f] = r[u] = l(i, o)) - } - - function e(n, t, i, r) { - var u, e, o; - for (u in t) e = i ? i + "." + u : u, o = t[u], f(n, o, t, u, e, r) - } - - function a(n, t, i, r) { - for (var s, o, h, u = 0, e = 0; u < t.length; u++) s = t[u], o = "[" + e + "]", h = i + o, f(n, s, t, o, h, r), e++ - } - - function o(i, r) { - return i.filters ? n.map(i.filters, function(n) { - var i = n.filters && n.filters.length > 1, - t = o(n, r); - return t && i && (t = "(" + t + ")"), t - }).join("~" + i.logic + "~") : i.field ? i.field + "~" + i.operator + "~" + v(i.value, r) : t - } - - function v(n, t) { - if ("string" == typeof n) { - if (!(n.indexOf("Date(") > -1)) return n = n.replace(w, "''"), t && (n = encodeURIComponent(n)), "'" + n + "'"; - n = new Date(parseInt(n.replace(/^\/Date\((.*?)\)\/$/, "$1"), 10)) - } - return n && n.getTime ? "datetime'" + i.format("{0:yyyy-MM-ddTHH-mm-ss}", n) + "'" : n - } - - function s(i) { - return { - value: t !== i.Key ? i.Key : i.value, - field: i.Member || i.field, - hasSubgroups: i.HasSubgroups || i.hasSubgroups || !1, - aggregates: p(i.Aggregates || i.aggregates), - items: i.HasSubgroups ? n.map(i.Items || i.items, s) : i.Items || i.items - } - } - - function y(n) { - var t = {}; - return t[n.AggregateMethodName.toLowerCase()] = n.Value, t - } - - function p(n) { - var t, i, r, u = {}; - for (t in n) { - u = {}; - r = n[t]; - for (i in r) u[i.toLowerCase()] = r[i]; - n[t] = u - } - return n - } - var i = window.kendo, - w = /'/gi, - r = n.extend, - b = n.isArray, - k = n.isPlainObject, - h = "."; - r(!0, i.data, { - schemas: { - "aspnetmvc-ajax": { - groups: function(t) { - return n.map(this.data(t), s) - }, - aggregates: function(n) { - n = n.d || n; - for (var t, u = {}, e = n.AggregateResults || [], i = 0, f = e.length; f > i; i++) t = e[i], u[t.Member] = r(!0, u[t.Member], y(t)); - return u - } - } - } - }); - r(!0, i.data, { - transports: { - "aspnetmvc-ajax": i.data.RemoteTransport.extend({ - init: function(n) { - var t = this, - f = (n || {}).stringifyDates; - i.data.RemoteTransport.fn.init.call(this, r(!0, {}, this.options, n, { - parameterMap: function(n, i) { - return u.call(t, n, i, !1, f) - } - })) - }, - read: function(n) { - var t = this.options.data, - r = this.options.read.url; - t ? (r && (this.options.data = null), !t.Data.length && r ? i.data.RemoteTransport.fn.read.call(this, n) : n.success(t)) : i.data.RemoteTransport.fn.read.call(this, n) - }, - options: { - read: { - type: "POST" - }, - update: { - type: "POST" - }, - create: { - type: "POST" - }, - destroy: { - type: "POST" - }, - parameterMap: u, - prefix: "" - } - }) - } - }); - r(!0, i.data, { - transports: { - "aspnetmvc-server": i.data.RemoteTransport.extend({ - init: function(n) { - var t = this; - i.data.RemoteTransport.fn.init.call(this, r(n, { - parameterMap: function(n, i) { - return u.call(t, n, i, !0) - } - })) - }, - read: function(t) { - var r, i, u = this.options.prefix, - f = [u + "sort", u + "page", u + "pageSize", u + "group", u + "aggregate", u + "filter"], - e = RegExp("(" + f.join("|") + ")=[^&]*&?", "g"); - i = location.search.replace(e, "").replace("?", ""); - i.length && !/&$/.test(i) && (i += "&"); - t = this.setup(t, "read"); - r = t.url; - r.indexOf("?") >= 0 ? (i = i.replace(/(.*?=.*?)&/g, function(n) { - return r.indexOf(n.substr(0, n.indexOf("="))) >= 0 ? "" : n - }), r += "&" + i) : r += "?" + i; - r += n.map(t.data, function(n, t) { - return t + "=" + n - }).join("&"); - location.href = r - } - }) - } - }) - }(window.kendo.jQuery), - function(n) { - var i = window.kendo, - t = i.ui; - t && t.ComboBox && (t.ComboBox.requestData = function(t) { - var i = n(t).data("kendoComboBox"), - u = i.dataSource.filter(), - r = i.input.val(); - return u || (r = ""), { - text: r - } - }) - }(window.kendo.jQuery), - function(n) { - var i = window.kendo, - t = i.ui; - t && t.MultiSelect && (t.MultiSelect.requestData = function(t) { - var i = n(t).data("kendoMultiSelect"), - r = i.input.val(); - return { - text: r !== i.options.placeholder ? r : "" - } - }) - }(window.kendo.jQuery), - function(n) { - var t = window.kendo, - i = (t.ui, n.extend), - r = n.isFunction; - i(!0, t.data, { - schemas: { - "imagebrowser-aspnetmvc": { - data: function(n) { - return n || [] - }, - model: { - id: "name", - fields: { - name: { - field: "Name" - }, - size: { - field: "Size" - }, - type: { - field: "EntryType", - parse: function(n) { - return 0 == n ? "f" : "d" - } - } - } - } - } - } - }); - i(!0, t.data, { - transports: { - "imagebrowser-aspnetmvc": t.data.RemoteTransport.extend({ - init: function(i) { - t.data.RemoteTransport.fn.init.call(this, n.extend(!0, {}, this.options, i)) - }, - _call: function(i, u) { - u.data = n.extend({}, u.data, { - path: this.options.path() - }); - r(this.options[i]) ? this.options[i].call(this, u) : t.data.RemoteTransport.fn[i].call(this, u) - }, - read: function(n) { - this._call("read", n) - }, - create: function(n) { - this._call("create", n) - }, - destroy: function(n) { - this._call("destroy", n) - }, - update: function() {}, - options: { - read: { - type: "POST" - }, - update: { - type: "POST" - }, - create: { - type: "POST" - }, - destroy: { - type: "POST" - }, - parameterMap: function(n, t) { - return "read" != t && (n.EntryType = "f" === n.EntryType ? 0 : 1), n - } - } - }) - } - }) - }(window.kendo.jQuery), - function(n) { - function r() { - var n, i = {}; - for (n in t) i["mvc" + n] = s(n); - return i - } - - function u() { - var n, i = {}; - for (n in t) i["mvc" + n] = h(n); - return i - } - - function f(n, t) { - var u, i, r, f = {}, - e = n.data(), - o = t.length; - for (r in e) i = r.toLowerCase(), u = i.indexOf(t), u > -1 && (i = i.substring(u + o, r.length), i && (f[i] = e[r])); - return f - } - - function e(t) { - for (var u = t.Fields || [], f = {}, i = 0, r = u.length; r > i; i++) n.extend(!0, f, o(u[i])); - return f - } - - function o(n) { - for (var i, f, o = {}, s = {}, u = n.FieldName, r = n.ValidationRules, t = 0, e = r.length; e > t; t++) i = r[t].ValidationType, f = r[t].ValidationParameters, o[u + i] = l(u, i, f), s[u + i] = c(r[t].ErrorMessage); - return { - rules: o, - messages: s - } - } - - function s(n) { - return function(t) { - return t.attr("data-val-" + n) - } - } - - function h(n) { - return function(i) { - return i.filter("[data-val-" + n + "]").length ? t[n](i, f(i, n)) : !0 - } - } - - function c(n) { - return function() { - return n - } - } - - function l(n, i, r) { - return function(u) { - return u.filter("[name=" + n + "]").length ? t[i](u, r) : !0 - } - } - - function a(n, t) { - return "string" == typeof t && (t = RegExp("^(?:" + t + ")$")), t.test(n) - } - var i = /("|\%|'|\[|\]|\$|\.|\,|\:|\;|\+|\*|\&|\!|\#|\(|\)|<|>|\=|\?|\@|\^|\{|\}|\~|\/|\||`)/g, - t = { - required: function(n) { - var f, t, r = n.val(), - u = n.filter("[type=checkbox]"); - return u.length && (f = u[0].name.replace(i, "\\$1"), t = u.next("input:hidden[name='" + f + "']"), r = t.length ? t.val() : "checked" === n.attr("checked")), !("" === r || !r) - }, - number: function(n) { - return "" === n.val() || null !== kendo.parseFloat(n.val()) - }, - regex: function(n, t) { - return "" !== n.val() ? a(n.val(), t.pattern) : !0 - }, - range: function(n, t) { - return "" !== n.val() ? this.min(n, t) && this.max(n, t) : !0 - }, - min: function(n, t) { - var i = parseFloat(t.min) || 0, - r = kendo.parseFloat(n.val()); - return r >= i - }, - max: function(n, t) { - var i = parseFloat(t.max) || 0, - r = kendo.parseFloat(n.val()); - return i >= r - }, - date: function(n) { - return "" === n.val() || null !== kendo.parseDate(n.val()) - }, - length: function(t, i) { - if ("" !== t.val()) { - var r = n.trim(t.val()).length; - return (!i.min || r >= (i.min || 0)) && (!i.max || r <= (i.max || 0)) - } - return !0 - } - }; - n.extend(!0, kendo.ui.validator, { - rules: u(), - messages: r(), - messageLocators: { - mvcLocator: { - locate: function(n, t) { - return t = t.replace(i, "\\$1"), n.find(".field-validation-valid[data-valmsg-for=" + t + "], .field-validation-error[data-valmsg-for=" + t + "]") - }, - decorate: function(n, t) { - n.addClass("field-validation-error").attr("data-valmsg-for", t || "") - } - }, - mvcMetadataLocator: { - locate: function(n, t) { - return t = t.replace(i, "\\$1"), n.find("#" + t + "_validationMessage.field-validation-valid") - }, - decorate: function(n, t) { - n.addClass("field-validation-error").attr("id", t + "_validationMessage") - } - } - }, - ruleResolvers: { - mvcMetaDataResolver: { - resolve: function(t) { - var i, r = window.mvcClientValidationMetadata || []; - if (r.length) - for (t = n(t), i = 0; i < r.length; i++) - if (r[i].FormId == t.attr("id")) return e(r[i]); - return {} - } - } - } - }) - }(window.kendo.jQuery) - }) -}("function" == typeof define && define.amd ? define : function(n, t) { - return t() -}); -! function(n) { - return n([], function() { - ! function(n) { - var t = n.kendo || (n.kendo = { - cultures: {} - }); - t.cultures["pl-PL"] = { - name: "pl-PL", - numberFormat: { - pattern: ["-n"], - decimals: 2, - ",": " ", - ".": ",", - groupSize: [3], - percent: { - pattern: ["-n%", "n%"], - decimals: 2, - ",": " ", - ".": ",", - groupSize: [3], - symbol: "%" - }, - currency: { - pattern: ["-n $", "n $"], - decimals: 2, - ",": " ", - ".": ",", - groupSize: [3], - symbol: "zł" - } - }, - calendars: { - standard: { - days: { - names: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"], - namesAbbr: ["N", "Pn", "Wt", "Śr", "Cz", "Pt", "So"], - namesShort: ["N", "Pn", "Wt", "Śr", "Cz", "Pt", "So"] - }, - months: { - names: ["styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień", ""], - namesAbbr: ["sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paź", "lis", "gru", ""] - }, - AM: [""], - PM: [""], - patterns: { - d: "yyyy-MM-dd", - D: "d MMMM yyyy", - F: "d MMMM yyyy HH:mm:ss", - g: "yyyy-MM-dd HH:mm", - G: "yyyy-MM-dd HH:mm:ss", - m: "d MMMM", - M: "d MMMM", - s: "yyyy'-'MM'-'dd'T'HH':'mm':'ss", - t: "HH:mm", - T: "HH:mm:ss", - u: "yyyy'-'MM'-'dd HH':'mm':'ss'Z'", - y: "MMMM yyyy", - Y: "MMMM yyyy" - }, - "/": "-", - ":": ":", - firstDay: 1 - } - } - } - }(this) - }) -}("function" == typeof define && define.amd ? define : function(n, t) { - return t() -}), -function() { - function n(n) { - return function() { - return n - } - }(function(t) { - var u = this || eval("this"), - r = u.document, - e = u.navigator, - i = u.jQuery, - f = u.JSON; - (function(n) { - "function" == typeof require && "object" == typeof exports && "object" == typeof module ? n(module.exports || exports) : "function" == typeof define && define.amd ? define(["exports"], n) : n(u.ko = {}) - })(function(o) { - function c(n, t, i, r) { - s.d[n] = { - init: function(n) { - return s.a.f.set(n, a, {}), { - controlsDescendantBindings: !0 - } - }, - update: function(n, u, f, e, o) { - f = s.a.f.get(n, a); - u = s.a.c(u()); - e = !i != !u; - var h = !f.fb; - (h || t || e !== f.vb) && (h && (f.fb = s.a.Oa(s.e.childNodes(n), !0)), e ? (h || s.e.P(n, s.a.Oa(f.fb)), s.Ja(r ? r(o, u) : o, n)) : s.e.ba(n), f.vb = e) - } - }; - s.g.S[n] = !1; - s.e.L[n] = !0 - } - - function v(n, t, i) { - i && t !== s.h.n(n) && s.h.W(n, t); - t !== s.h.n(n) && s.q.I(s.a.Ga, null, [n, "change"]) - } - var s = "undefined" != typeof o ? o : {}, - y, h, l, a; - s.b = function(n, t) { - for (var i = n.split("."), r = s, u = 0; u < i.length - 1; u++) r = r[i[u]]; - r[i[i.length - 1]] = t - }; - s.r = function(n, t, i) { - n[t] = i - }; - s.version = "2.3.0"; - s.b("version", s.version); - s.a = function() { - function o(n, t) { - for (var i in n) n.hasOwnProperty(i) && t(i, n[i]) - } - - function h(n, t) { - if ("input" !== s.a.u(n) || !n.type || "click" != t.toLowerCase()) return !1; - var i = n.type; - return "checkbox" == i || "radio" == i - } - var c = {}, - l = {}, - a, n; - return c[e && /Firefox\/2/i.test(e.userAgent) ? "KeyboardEvent" : "UIEvents"] = ["keyup", "keydown", "keypress"], c.MouseEvents = "click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" "), o(c, function(n, t) { - if (t.length) - for (var i = 0, r = t.length; i < r; i++) l[t[i]] = n - }), a = { - propertychange: !0 - }, n = r && function() { - for (var n = 3, i = r.createElement("div"), u = i.getElementsByTagName("i"); i.innerHTML = "<!--[if gt IE " + ++n + "]><i><\/i><![endif]-->", u[0];); - return 4 < n ? n : t - }(), { - Ta: ["authenticity_token", /^__RequestVerificationToken(_.*)?$/], - p: function(n, t) { - for (var i = 0, r = n.length; i < r; i++) t(n[i]) - }, - k: function(n, t) { - if ("function" == typeof Array.prototype.indexOf) return Array.prototype.indexOf.call(n, t); - for (var i = 0, r = n.length; i < r; i++) - if (n[i] === t) return i; - return -1 - }, - La: function(n, t, i) { - for (var r = 0, u = n.length; r < u; r++) - if (t.call(i, n[r])) return n[r]; - return null - }, - ka: function(n, t) { - var i = s.a.k(n, t); - 0 <= i && n.splice(i, 1) - }, - Ma: function(n) { - n = n || []; - for (var i = [], t = 0, r = n.length; t < r; t++) 0 > s.a.k(i, n[t]) && i.push(n[t]); - return i - }, - Z: function(n, t) { - n = n || []; - for (var r = [], i = 0, u = n.length; i < u; i++) r.push(t(n[i])); - return r - }, - Y: function(n, t) { - n = n || []; - for (var r = [], i = 0, u = n.length; i < u; i++) t(n[i]) && r.push(n[i]); - return r - }, - R: function(n, t) { - if (t instanceof Array) n.push.apply(n, t); - else - for (var i = 0, r = t.length; i < r; i++) n.push(t[i]); - return n - }, - ja: function(n, t, i) { - var r = n.indexOf ? n.indexOf(t) : s.a.k(n, t); - 0 > r ? i && n.push(t) : i || n.splice(r, 1) - }, - extend: function(n, t) { - if (t) - for (var i in t) t.hasOwnProperty(i) && (n[i] = t[i]); - return n - }, - w: o, - oa: function(n) { - for (; n.firstChild;) s.removeNode(n.firstChild) - }, - Mb: function(n) { - n = s.a.N(n); - for (var i = r.createElement("div"), t = 0, u = n.length; t < u; t++) i.appendChild(s.H(n[t])); - return i - }, - Oa: function(n, t) { - for (var r, i = 0, f = n.length, u = []; i < f; i++) r = n[i].cloneNode(!0), u.push(t ? s.H(r) : r); - return u - }, - P: function(n, t) { - if (s.a.oa(n), t) - for (var i = 0, r = t.length; i < r; i++) n.appendChild(t[i]) - }, - eb: function(n, t) { - var r = n.nodeType ? [n] : n; - if (0 < r.length) { - for (var f = r[0], e = f.parentNode, i = 0, u = t.length; i < u; i++) e.insertBefore(t[i], f); - for (i = 0, u = r.length; i < u; i++) s.removeNode(r[i]) - } - }, - hb: function(t, i) { - 7 > n ? t.setAttribute("selected", i) : t.selected = i - }, - F: function(n) { - return null === n || n === t ? "" : n.trim ? n.trim() : n.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g, "") - }, - Wb: function(n, t) { - for (var r, u = [], f = (n || "").split(t), i = 0, e = f.length; i < e; i++) r = s.a.F(f[i]), "" !== r && u.push(r); - return u - }, - Tb: function(n, t) { - return n = n || "", t.length > n.length ? !1 : n.substring(0, t.length) === t - }, - yb: function(n, t) { - if (t.compareDocumentPosition) return 16 == (t.compareDocumentPosition(n) & 16); - for (; null != n;) { - if (n == t) return !0; - n = n.parentNode - } - return !1 - }, - aa: function(n) { - return s.a.yb(n, n.ownerDocument) - }, - pb: function(n) { - return !!s.a.La(n, s.a.aa) - }, - u: function(n) { - return n && n.tagName && n.tagName.toLowerCase() - }, - o: function(t, r, u) { - var o = n && a[r], - f, e, c; - if (o || "undefined" == typeof i) - if (o || "function" != typeof t.addEventListener) - if ("undefined" != typeof t.attachEvent) f = function(n) { - u.call(t, n) - }, e = "on" + r, t.attachEvent(e, f), s.a.C.ia(t, function() { - t.detachEvent(e, f) - }); - else throw Error("Browser doesn't support addEventListener or attachEvent"); - else t.addEventListener(r, u, !1); - else h(t, r) && (c = u, u = function(n, t) { - var i = this.checked; - t && (this.checked = !0 !== t.sb); - c.call(this, n); - this.checked = i - }), i(t).bind(r, u) - }, - Ga: function(n, t) { - if (!n || !n.nodeType) throw Error("element must be a DOM node when calling triggerEvent"); - if ("undefined" != typeof i) { - var f = []; - h(n, t) && f.push({ - sb: n.checked - }); - i(n).trigger(t, f) - } else if ("function" == typeof r.createEvent) - if ("function" == typeof n.dispatchEvent) f = r.createEvent(l[t] || "HTMLEvents"), f.initEvent(t, !0, !0, u, 0, 0, 0, 0, 0, !1, !1, !1, !1, 0, n), n.dispatchEvent(f); - else throw Error("The supplied element doesn't support dispatchEvent"); - else if ("undefined" != typeof n.fireEvent) h(n, t) && (n.checked = !0 !== n.checked), n.fireEvent("on" + t); - else throw Error("Browser doesn't support triggering events"); - }, - c: function(n) { - return s.T(n) ? n() : n - }, - ya: function(n) { - return s.T(n) ? n.t() : n - }, - ga: function(n, t, i) { - if (t) { - var r = /\S+/g, - u = n.className.match(r) || []; - s.a.p(t.match(r), function(n) { - s.a.ja(u, n, i) - }); - n.className = u.join(" ") - } - }, - ib: function(n, i) { - var u = s.a.c(i), - f; - (null === u || u === t) && (u = ""); - f = s.e.firstChild(n); - !f || 3 != f.nodeType || s.e.nextSibling(f) ? s.e.P(n, [r.createTextNode(u)]) : f.data = u; - s.a.Bb(n) - }, - gb: function(t, i) { - if (t.name = i, 7 >= n) try { - t.mergeAttributes(r.createElement("<input name='" + t.name + "'/>"), !1) - } catch (u) {} - }, - Bb: function(t) { - 9 <= n && (t = 1 == t.nodeType ? t : t.parentNode, t.style && (t.style.zoom = t.style.zoom)) - }, - zb: function(t) { - if (n) { - var i = t.style.width; - t.style.width = 0; - t.style.width = i - } - }, - Qb: function(n, t) { - n = s.a.c(n); - t = s.a.c(t); - for (var r = [], i = n; i <= t; i++) r.push(i); - return r - }, - N: function(n) { - for (var i = [], t = 0, r = n.length; t < r; t++) i.push(n[t]); - return i - }, - Ub: 6 === n, - Vb: 7 === n, - ca: n, - Ua: function(n, t) { - for (var r = s.a.N(n.getElementsByTagName("input")).concat(s.a.N(n.getElementsByTagName("textarea"))), f = "string" == typeof t ? function(n) { - return n.name === t - } : function(n) { - return t.test(n.name) - }, u = [], i = r.length - 1; 0 <= i; i--) f(r[i]) && u.push(r[i]); - return u - }, - Nb: function(n) { - return "string" == typeof n && (n = s.a.F(n)) ? f && f.parse ? f.parse(n) : new Function("return " + n)() : null - }, - Ca: function(n, t, i) { - if (!f || !f.stringify) throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js"); - return f.stringify(s.a.c(n), t, i) - }, - Ob: function(n, t, i) { - var v, e, h, f, u, c; - i = i || {}; - var l = i.params || {}, - a = i.includeFields || this.Ta, - v = n; - if ("object" == typeof n && "form" === s.a.u(n)) - for (v = n.action, e = a.length - 1; 0 <= e; e--) - for (h = s.a.Ua(n, a[e]), f = h.length - 1; 0 <= f; f--) l[h[f].name] = h[f].value; - t = s.a.c(t); - u = r.createElement("form"); - u.style.display = "none"; - u.action = v; - u.method = "post"; - for (c in t) n = r.createElement("input"), n.name = c, n.value = s.a.Ca(s.a.c(t[c])), u.appendChild(n); - o(l, function(n, t) { - var i = r.createElement("input"); - i.name = n; - i.value = t; - u.appendChild(i) - }); - r.body.appendChild(u); - i.submitter ? i.submitter(u) : u.submit(); - setTimeout(function() { - u.parentNode.removeChild(u) - }, 0) - } - } - }(); - s.b("utils", s.a); - s.b("utils.arrayForEach", s.a.p); - s.b("utils.arrayFirst", s.a.La); - s.b("utils.arrayFilter", s.a.Y); - s.b("utils.arrayGetDistinctValues", s.a.Ma); - s.b("utils.arrayIndexOf", s.a.k); - s.b("utils.arrayMap", s.a.Z); - s.b("utils.arrayPushAll", s.a.R); - s.b("utils.arrayRemoveItem", s.a.ka); - s.b("utils.extend", s.a.extend); - s.b("utils.fieldsIncludedWithJsonPost", s.a.Ta); - s.b("utils.getFormFields", s.a.Ua); - s.b("utils.peekObservable", s.a.ya); - s.b("utils.postJson", s.a.Ob); - s.b("utils.parseJson", s.a.Nb); - s.b("utils.registerEventHandler", s.a.o); - s.b("utils.stringifyJson", s.a.Ca); - s.b("utils.range", s.a.Qb); - s.b("utils.toggleDomNodeCssClass", s.a.ga); - s.b("utils.triggerEvent", s.a.Ga); - s.b("utils.unwrapObservable", s.a.c); - s.b("utils.objectForEach", s.a.w); - s.b("utils.addOrRemoveItem", s.a.ja); - s.b("unwrap", s.a.c); - Function.prototype.bind || (Function.prototype.bind = function(n) { - var i = this, - t = Array.prototype.slice.call(arguments); - return n = t.shift(), - function() { - return i.apply(n, t.concat(Array.prototype.slice.call(arguments))) - } - }); - s.a.f = new function() { - var r = 0, - n = "__ko__" + (new Date).getTime(), - i = {}; - return { - get: function(n, i) { - var r = s.a.f.pa(n, !1); - return r === t ? t : r[i] - }, - set: function(n, i, r) { - (r !== t || s.a.f.pa(n, !1) !== t) && (s.a.f.pa(n, !0)[i] = r) - }, - pa: function(u, f) { - var e = u[n]; - if (!e || "null" === e || !i[e]) { - if (!f) return t; - e = u[n] = "ko" + r++; - i[e] = {} - } - return i[e] - }, - clear: function(t) { - var r = t[n]; - return r ? (delete i[r], t[n] = null, !0) : !1 - } - } - }; - s.b("utils.domData", s.a.f); - s.b("utils.domData.clear", s.a.f.clear); - s.a.C = new function() { - function n(n, i) { - var r = s.a.f.get(n, u); - return r === t && i && (r = [], s.a.f.set(n, u, r)), r - } - - function r(t) { - var u = n(t, !1), - e; - if (u) - for (u = u.slice(0), e = 0; e < u.length; e++) u[e](t); - if (s.a.f.clear(t), "function" == typeof i && "function" == typeof i.cleanData && i.cleanData([t]), f[t.nodeType]) - for (u = t.firstChild; t = u;) u = t.nextSibling, 8 === t.nodeType && r(t) - } - var u = "__ko_domNodeDisposal__" + (new Date).getTime(), - e = { - 1: !0, - 8: !0, - 9: !0 - }, - f = { - 1: !0, - 9: !0 - }; - return { - ia: function(t, i) { - if ("function" != typeof i) throw Error("Callback must be a function"); - n(t, !0).push(i) - }, - cb: function(i, r) { - var f = n(i, !1); - f && (s.a.ka(f, r), 0 == f.length && s.a.f.set(i, u, t)) - }, - H: function(n) { - var t, i, u; - if (e[n.nodeType] && (r(n), f[n.nodeType])) - for (t = [], s.a.R(t, n.getElementsByTagName("*")), i = 0, u = t.length; i < u; i++) r(t[i]); - return n - }, - removeNode: function(n) { - s.H(n); - n.parentNode && n.parentNode.removeChild(n) - } - } - }; - s.H = s.a.C.H; - s.removeNode = s.a.C.removeNode; - s.b("cleanNode", s.H); - s.b("removeNode", s.removeNode); - s.b("utils.domNodeDisposal", s.a.C); - s.b("utils.domNodeDisposal.addDisposeCallback", s.a.C.ia); - s.b("utils.domNodeDisposal.removeDisposeCallback", s.a.C.cb), - function() { - s.a.xa = function(n) { - var t, f; - if ("undefined" != typeof i) { - if (i.parseHTML) t = i.parseHTML(n) || []; - else if ((t = i.clean([n])) && t[0]) { - for (n = t[0]; n.parentNode && 11 !== n.parentNode.nodeType;) n = n.parentNode; - n.parentNode && n.parentNode.removeChild(n) - } - } else { - for (f = s.a.F(n).toLowerCase(), t = r.createElement("div"), f = f.match(/^<(thead|tbody|tfoot)/) && [1, "<table>", "<\/table>"] || !f.indexOf("<tr") && [2, "<table><tbody>", "<\/tbody><\/table>"] || (!f.indexOf("<td") || !f.indexOf("<th")) && [3, "<table><tbody><tr>", "<\/tr><\/tbody><\/table>"] || [0, "", ""], n = "ignored<div>" + f[1] + n + f[2] + "<\/div>", "function" == typeof u.innerShiv ? t.appendChild(u.innerShiv(n)) : t.innerHTML = n; f[0]--;) t = t.lastChild; - t = s.a.N(t.lastChild.childNodes) - } - return t - }; - s.a.fa = function(n, r) { - if (s.a.oa(n), r = s.a.c(r), null !== r && r !== t) - if ("string" != typeof r && (r = r.toString()), "undefined" != typeof i) i(n).html(r); - else - for (var f = s.a.xa(r), u = 0; u < f.length; u++) n.appendChild(f[u]) - } - }(); - s.b("utils.parseHtmlFragment", s.a.xa); - s.b("utils.setHtml", s.a.fa); - s.s = function() { - function i(n, t) { - var r; - if (n) - if (8 == n.nodeType) r = s.s.$a(n.nodeValue), null != r && t.push({ - xb: n, - Kb: r - }); - else if (1 == n.nodeType) - for (var r = 0, u = n.childNodes, f = u.length; r < f; r++) i(u[r], t) - } - var n = {}; - return { - va: function(t) { - if ("function" != typeof t) throw Error("You can only pass a function to ko.memoization.memoize()"); - var i = (4294967296 * (1 + Math.random()) | 0).toString(16).substring(1) + (4294967296 * (1 + Math.random()) | 0).toString(16).substring(1); - return n[i] = t, "<!--[ko_memo:" + i + "]-->" - }, - mb: function(i, r) { - var u = n[i]; - if (u === t) throw Error("Couldn't find any memo with ID " + i + ". Perhaps it's already been unmemoized."); - try { - return u.apply(null, r || []), !0 - } finally { - delete n[i] - } - }, - nb: function(n, t) { - var f = [], - u, o, r, e; - for (i(n, f), u = 0, o = f.length; u < o; u++) r = f[u].xb, e = [r], t && s.a.R(e, t), s.s.mb(f[u].Kb, e), r.nodeValue = "", r.parentNode && r.parentNode.removeChild(r) - }, - $a: function(n) { - return (n = n.match(/^\[ko_memo\:(.*?)\]$/)) ? n[1] : null - } - } - }(); - s.b("memoization", s.s); - s.b("memoization.memoize", s.s.va); - s.b("memoization.unmemoize", s.s.mb); - s.b("memoization.parseMemoText", s.s.$a); - s.b("memoization.unmemoizeDomNodeAndDescendants", s.s.nb); - s.Sa = { - throttle: function(n, t) { - n.throttleEvaluation = t; - var i = null; - return s.j({ - read: n, - write: function(r) { - clearTimeout(i); - i = setTimeout(function() { - n(r) - }, t) - } - }) - }, - notify: function(t, i) { - return t.equalityComparer = "always" == i ? n(!1) : s.m.fn.equalityComparer, t - } - }; - s.b("extenders", s.Sa); - s.kb = function(n, t, i) { - this.target = n; - this.la = t; - this.wb = i; - s.r(this, "dispose", this.B) - }; - s.kb.prototype.B = function() { - this.Hb = !0; - this.wb() - }; - s.V = function() { - this.G = {}; - s.a.extend(this, s.V.fn); - s.r(this, "subscribe", this.Da); - s.r(this, "extend", this.extend); - s.r(this, "getSubscriptionsCount", this.Db) - }; - s.V.fn = { - Da: function(n, t, i) { - i = i || "change"; - var r = new s.kb(this, t ? n.bind(t) : n, function() { - s.a.ka(this.G[i], r) - }.bind(this)); - return this.G[i] || (this.G[i] = []), this.G[i].push(r), r - }, - notifySubscribers: function(n, t) { - t = t || "change"; - this.G[t] && s.q.I(function() { - s.a.p(this.G[t].slice(0), function(t) { - t && !0 !== t.Hb && t.la(n) - }) - }, this) - }, - Db: function() { - var n = 0; - return s.a.w(this.G, function(t, i) { - n += i.length - }), n - }, - extend: function(n) { - var t = this; - return n && s.a.w(n, function(n, i) { - var r = s.Sa[n]; - "function" == typeof r && (t = r(t, i)) - }), t - } - }; - s.Wa = function(n) { - return null != n && "function" == typeof n.Da && "function" == typeof n.notifySubscribers - }; - s.b("subscribable", s.V); - s.b("isSubscribable", s.Wa); - s.q = function() { - var n = []; - return { - rb: function(t) { - n.push({ - la: t, - Ra: [] - }) - }, - end: function() { - n.pop() - }, - bb: function(t) { - if (!s.Wa(t)) throw Error("Only subscribable things can act as dependencies"); - if (0 < n.length) { - var i = n[n.length - 1]; - !i || 0 <= s.a.k(i.Ra, t) || (i.Ra.push(t), i.la(t)) - } - }, - I: function(t, i, r) { - try { - return n.push(null), t.apply(i, r || []) - } finally { - n.pop() - } - } - } - }(); - y = { - undefined: !0, - boolean: !0, - number: !0, - string: !0 - }; - s.m = function(n) { - function t() { - return 0 < arguments.length ? (t.equalityComparer && t.equalityComparer(i, arguments[0]) || (t.K(), i = arguments[0], t.J()), this) : (s.q.bb(t), i) - } - var i = n; - return s.V.call(t), t.t = function() { - return i - }, t.J = function() { - t.notifySubscribers(i) - }, t.K = function() { - t.notifySubscribers(i, "beforeChange") - }, s.a.extend(t, s.m.fn), s.r(t, "peek", t.t), s.r(t, "valueHasMutated", t.J), s.r(t, "valueWillMutate", t.K), t - }; - s.m.fn = { - equalityComparer: function(n, t) { - return null === n || typeof n in y ? n === t : !1 - } - }; - h = s.m.Pb = "__ko_proto__"; - s.m.fn[h] = s.m; - s.qa = function(n, i) { - return null === n || n === t || n[h] === t ? !1 : n[h] === i ? !0 : s.qa(n[h], i) - }; - s.T = function(n) { - return s.qa(n, s.m) - }; - s.Xa = function(n) { - return "function" == typeof n && n[h] === s.m || "function" == typeof n && n[h] === s.j && n.Eb ? !0 : !1 - }; - s.b("observable", s.m); - s.b("isObservable", s.T); - s.b("isWriteableObservable", s.Xa); - s.U = function(n) { - if (n = n || [], "object" != typeof n || !("length" in n)) throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined."); - return n = s.m(n), s.a.extend(n, s.U.fn), n - }; - s.U.fn = { - remove: function(n) { - for (var u, r = this.t(), i = [], f = "function" == typeof n ? n : function(t) { - return t === n - }, t = 0; t < r.length; t++) u = r[t], f(u) && (0 === i.length && this.K(), i.push(u), r.splice(t, 1), t--); - return i.length && this.J(), i - }, - removeAll: function(n) { - if (n === t) { - var i = this.t(), - r = i.slice(0); - return this.K(), i.splice(0, i.length), this.J(), r - } - return n ? this.remove(function(t) { - return 0 <= s.a.k(n, t) - }) : [] - }, - destroy: function(n) { - var i = this.t(), - r = "function" == typeof n ? n : function(t) { - return t === n - }, - t; - for (this.K(), t = i.length - 1; 0 <= t; t--) r(i[t]) && (i[t]._destroy = !0); - this.J() - }, - destroyAll: function(i) { - return i === t ? this.destroy(n(!0)) : i ? this.destroy(function(n) { - return 0 <= s.a.k(i, n) - }) : [] - }, - indexOf: function(n) { - var t = this(); - return s.a.k(t, n) - }, - replace: function(n, t) { - var i = this.indexOf(n); - 0 <= i && (this.K(), this.t()[i] = t, this.J()) - } - }; - s.a.p("pop push reverse shift sort splice unshift".split(" "), function(n) { - s.U.fn[n] = function() { - var t = this.t(); - return this.K(), t = t[n].apply(t, arguments), this.J(), t - } - }); - s.a.p(["slice"], function(n) { - s.U.fn[n] = function() { - var t = this(); - return t[n].apply(t, arguments) - } - }); - s.b("observableArray", s.U); - s.j = function(i, r, u) { - function w() { - s.a.p(o, function(n) { - n.B() - }); - o = [] - } - - function nt() { - var n = f.throttleEvaluation; - n && 0 <= n ? (clearTimeout(d), d = setTimeout(c, n)) : c() - } - - function c() { - var n, u, i; - if (!y) - if (a && p()) h(); - else { - y = !0; - try { - for (n = s.a.Z(o, function(n) { - return n.target - }), s.q.rb(function(i) { - var r; - 0 <= (r = s.a.k(n, i)) ? n[r] = t : o.push(i.Da(nt)) - }), u = e.call(r), i = n.length - 1; 0 <= i; i--) n[i] && o.splice(i, 1)[0].B(); - a = !0; - f.notifySubscribers(l, "beforeChange"); - l = u; - f.notifySubscribers(l) - } finally { - s.q.end(); - y = !1 - } - o.length || h() - } - } - - function f() { - if (0 < arguments.length) { - if ("function" == typeof k) k.apply(r, arguments); - else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters."); - return this - } - return a || c(), s.q.bb(f), l - } - - function b() { - return !a || 0 < o.length - } - var l, a = !1, - y = !1, - e = i, - g, p; - if (e && "object" == typeof e ? (u = e, e = u.read) : (u = u || {}, e || (e = u.read)), "function" != typeof e) throw Error("Pass a function that returns the value of the ko.computed"); - var k = u.write, - v = u.disposeWhenNodeIsRemoved || u.$ || null, - p = u.disposeWhen || u.Qa || n(!1), - h = w, - o = [], - d = null; - return r || (r = u.owner), f.t = function() { - return a || c(), l - }, f.Cb = function() { - return o.length - }, f.Eb = "function" == typeof u.write, f.B = function() { - h() - }, f.ta = b, s.V.call(f), s.a.extend(f, s.j.fn), s.r(f, "peek", f.t), s.r(f, "dispose", f.B), s.r(f, "isActive", f.ta), s.r(f, "getDependenciesCount", f.Cb), !0 !== u.deferEvaluation && c(), v && b() && (h = function() { - s.a.C.cb(v, h); - w() - }, s.a.C.ia(v, h), g = p, p = function() { - return !s.a.aa(v) || g() - }), f - }; - s.Gb = function(n) { - return s.qa(n, s.j) - }; - o = s.m.Pb; - s.j[o] = s.m; - s.j.fn = {}; - s.j.fn[o] = s.j; - s.b("dependentObservable", s.j); - s.b("computed", s.j); - s.b("isComputed", s.Gb), - function() { - function n(u, f, e) { - if (e = e || new i, u = f(u), "object" != typeof u || null === u || u === t || u instanceof Date || u instanceof String || u instanceof Number || u instanceof Boolean) return u; - var o = u instanceof Array ? [] : {}; - return e.save(u, o), r(u, function(i) { - var r = f(u[i]), - s; - switch (typeof r) { - case "boolean": - case "number": - case "string": - case "function": - o[i] = r; - break; - case "object": - case "undefined": - s = e.get(r); - o[i] = s !== t ? s : n(r, f, e) - } - }), o - } - - function r(n, t) { - if (n instanceof Array) { - for (var i = 0; i < n.length; i++) t(i); - "function" == typeof n.toJSON && t("toJSON") - } else - for (i in n) t(i) - } - - function i() { - this.keys = []; - this.Ha = [] - } - s.lb = function(t) { - if (0 == arguments.length) throw Error("When calling ko.toJS, pass the object you want to convert."); - return n(t, function(n) { - for (var t = 0; s.T(n) && 10 > t; t++) n = n(); - return n - }) - }; - s.toJSON = function(n, t, i) { - return n = s.lb(n), s.a.Ca(n, t, i) - }; - i.prototype = { - save: function(n, t) { - var i = s.a.k(this.keys, n); - 0 <= i ? this.Ha[i] = t : (this.keys.push(n), this.Ha.push(t)) - }, - get: function(n) { - return n = s.a.k(this.keys, n), 0 <= n ? this.Ha[n] : t - } - } - }(); - s.b("toJS", s.lb); - s.b("toJSON", s.toJSON), - function() { - s.h = { - n: function(n) { - switch (s.a.u(n)) { - case "option": - return !0 === n.__ko__hasDomDataOptionValue__ ? s.a.f.get(n, s.d.options.wa) : 7 >= s.a.ca ? n.getAttributeNode("value") && n.getAttributeNode("value").specified ? n.value : n.text : n.value; - case "select": - return 0 <= n.selectedIndex ? s.h.n(n.options[n.selectedIndex]) : t; - default: - return n.value - } - }, - W: function(n, i) { - switch (s.a.u(n)) { - case "option": - switch (typeof i) { - case "string": - s.a.f.set(n, s.d.options.wa, t); - "__ko__hasDomDataOptionValue__" in n && delete n.__ko__hasDomDataOptionValue__; - n.value = i; - break; - default: - s.a.f.set(n, s.d.options.wa, i); - n.__ko__hasDomDataOptionValue__ = !0; - n.value = "number" == typeof i ? i : "" - } - break; - case "select": - "" === i && (i = t); - (null === i || i === t) && (n.selectedIndex = -1); - for (var r = n.options.length - 1; 0 <= r; r--) - if (s.h.n(n.options[r]) == i) { - n.selectedIndex = r; - break - } - 1 < n.size || -1 !== n.selectedIndex || (n.selectedIndex = 0); - break; - default: - (null === i || i === t) && (i = ""); - n.value = i - } - } - } - }(); - s.b("selectExtensions", s.h); - s.b("selectExtensions.readValue", s.h.n); - s.b("selectExtensions.writeValue", s.h.W); - s.g = function() { - function n(n, i) { - for (var r = null; n != r;) r = n, n = n.replace(t, function(n, t) { - return i[t] - }); - return n - } - var t = /\@ko_token_(\d+)\@/g, - i = ["true", "false", "null", "undefined"], - r = /^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i; - return { - S: [], - da: function(t) { - var i = s.a.F(t), - f, e, r, u; - if (3 > i.length) return []; - for ("{" === i.charAt(0) && (i = i.substring(1, i.length - 1)), t = [], f = null, r = 0; r < i.length; r++) - if (u = i.charAt(r), null === f) switch (u) { - case '"': - case "'": - case "/": - f = r; - e = u - } else if (u == e && "\\" !== i.charAt(r - 1)) { - u = i.substring(f, r + 1); - t.push(u); - var c = "@ko_token_" + (t.length - 1) + "@", - i = i.substring(0, f) + c + i.substring(r + 1), - r = r - (u.length - c.length), - f = null - } - e = f = null; - for (var o = 0, h = null, r = 0; r < i.length; r++) { - if (u = i.charAt(r), null === f) switch (u) { - case "{": - f = r; - h = u; - e = "}"; - break; - case "(": - f = r; - h = u; - e = ")"; - break; - case "[": - f = r; - h = u; - e = "]" - } - u === h ? o++ : u === e && (o--, 0 === o && (u = i.substring(f, r + 1), t.push(u), c = "@ko_token_" + (t.length - 1) + "@", i = i.substring(0, f) + c + i.substring(r + 1), r -= u.length - c.length, f = null)) - } - for (e = [], i = i.split(","), f = 0, r = i.length; f < r; f++) o = i[f], h = o.indexOf(":"), 0 < h && h < o.length - 1 ? (u = o.substring(h + 1), e.push({ - key: n(o.substring(0, h), t), - value: n(u, t) - })) : e.push({ - unknown: n(o, t) - }); - return e - }, - ea: function(n) { - var e = "string" == typeof n ? s.g.da(n) : n, - f = [], - t, h, o, u; - for (n = [], h = 0; t = e[h]; h++) - if (0 < f.length && f.push(","), t.key) { - n: { - o = t.key;u = s.a.F(o); - switch (u.length && u.charAt(0)) { - case "'": - case '"': - break n; - default: - o = "'" + u + "'" - } - } - t = t.value;f.push(o);f.push(":");f.push(t);t = s.a.F(t);0 <= s.a.k(i, s.a.F(t).toLowerCase()) ? t = !1 : (u = t.match(r), t = null === u ? !1 : u[1] ? "Object(" + u[1] + ")" + u[2] : t);t && (0 < n.length && n.push(", "), n.push(o + " : function(__ko_value) { " + t + " = __ko_value; }")) - } - else t.unknown && f.push(t.unknown); - return e = f.join(""), 0 < n.length && (e = e + ", '_ko_property_writers' : { " + n.join("") + " } "), e - }, - Jb: function(n, t) { - for (var i = 0; i < n.length; i++) - if (s.a.F(n[i].key) == t) return !0; - return !1 - }, - ha: function(n, t, i, r, u) { - n && s.T(n) ? !s.Xa(n) || u && n.t() === r || n(r) : (n = t()._ko_property_writers) && n[i] && n[i](r) - } - } - }(); - s.b("expressionRewriting", s.g); - s.b("expressionRewriting.bindingRewriteValidators", s.g.S); - s.b("expressionRewriting.parseObjectLiteral", s.g.da); - s.b("expressionRewriting.preProcessBindings", s.g.ea); - s.b("jsonExpressionRewriting", s.g); - s.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson", s.g.ea), - function() { - function n(n) { - return 8 == n.nodeType && (i ? n.text : n.nodeValue).match(e) - } - - function t(n) { - return 8 == n.nodeType && (i ? n.text : n.nodeValue).match(o) - } - - function u(i, r) { - for (var u = i, f = 1, e = []; u = u.nextSibling;) { - if (t(u) && (f--, 0 === f)) return e; - e.push(u); - n(u) && f++ - } - if (!r) throw Error("Cannot find closing comment tag to match: " + i.nodeValue); - return null - } - - function f(n, t) { - var i = u(n, t); - return i ? 0 < i.length ? i[i.length - 1].nextSibling : n.nextSibling : null - } - var i = r && "<!--test-->" === r.createComment("test").text, - e = i ? /^\x3c!--\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*--\x3e$/ : /^\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*$/, - o = i ? /^\x3c!--\s*\/ko\s*--\x3e$/ : /^\s*\/ko\s*$/, - h = { - ul: !0, - ol: !0 - }; - s.e = { - L: {}, - childNodes: function(t) { - return n(t) ? u(t) : t.childNodes - }, - ba: function(t) { - if (n(t)) { - t = s.e.childNodes(t); - for (var i = 0, r = t.length; i < r; i++) s.removeNode(t[i]) - } else s.a.oa(t) - }, - P: function(t, i) { - if (n(t)) { - s.e.ba(t); - for (var u = t.nextSibling, r = 0, f = i.length; r < f; r++) u.parentNode.insertBefore(i[r], u) - } else s.a.P(t, i) - }, - ab: function(t, i) { - n(t) ? t.parentNode.insertBefore(i, t.nextSibling) : t.firstChild ? t.insertBefore(i, t.firstChild) : t.appendChild(i) - }, - Va: function(t, i, r) { - r ? n(t) ? t.parentNode.insertBefore(i, r.nextSibling) : r.nextSibling ? t.insertBefore(i, r.nextSibling) : t.appendChild(i) : s.e.ab(t, i) - }, - firstChild: function(i) { - return n(i) ? !i.nextSibling || t(i.nextSibling) ? null : i.nextSibling : i.firstChild - }, - nextSibling: function(i) { - return n(i) && (i = f(i)), i.nextSibling && t(i.nextSibling) ? null : i.nextSibling - }, - ob: function(t) { - return (t = n(t)) ? t[1] : null - }, - Za: function(i) { - var o, r, u, e; - if (h[s.a.u(i)] && (o = i.firstChild, o)) - do - if (1 === o.nodeType) { - if (r = o.firstChild, u = null, r) - do u ? u.push(r) : n(r) ? (e = f(r, !0), e ? r = e : u = [r]) : t(r) && (u = [r]); while (r = r.nextSibling); - if (r = u) - for (u = o.nextSibling, e = 0; e < r.length; e++) u ? i.insertBefore(r[e], u) : i.appendChild(r[e]) - } - while (o = o.nextSibling) - } - } - }(); - s.b("virtualElements", s.e); - s.b("virtualElements.allowedBindings", s.e.L); - s.b("virtualElements.emptyNode", s.e.ba); - s.b("virtualElements.insertAfter", s.e.Va); - s.b("virtualElements.prepend", s.e.ab); - s.b("virtualElements.setDomNodeChildren", s.e.P), - function() { - s.M = function() { - this.Na = {} - }; - s.a.extend(s.M.prototype, { - nodeHasBindings: function(n) { - switch (n.nodeType) { - case 1: - return null != n.getAttribute("data-bind"); - case 8: - return null != s.e.ob(n); - default: - return !1 - } - }, - getBindings: function(n, t) { - var i = this.getBindingsString(n, t); - return i ? this.parseBindingsString(i, t, n) : null - }, - getBindingsString: function(n) { - switch (n.nodeType) { - case 1: - return n.getAttribute("data-bind"); - case 8: - return s.e.ob(n); - default: - return null - } - }, - parseBindingsString: function(n, t, i) { - var r, f, e, o; - try { - return (r = this.Na[n]) || (f = this.Na, o = "with($context){with($data||{}){return{" + s.g.ea(n) + "}}}", e = new Function("$context", "$element", o), r = f[n] = e), r(t, i) - } catch (u) { - throw u.message = "Unable to parse bindings.\nBindings value: " + n + "\nMessage: " + u.message, u; - } - } - }); - s.M.instance = new s.M - }(); - s.b("bindingProvider", s.M), - function() { - function n(n, t, r) { - for (var u = s.e.firstChild(t); t = u;) u = s.e.nextSibling(t), i(n, t, r) - } - - function i(t, i, u) { - var e = !0, - f = 1 === i.nodeType; - f && s.e.Za(i); - (f && u || s.M.instance.nodeHasBindings(i)) && (e = r(i, null, t, u).Sb); - e && n(t, i, !f) - } - - function r(n, i, r, u) { - function c(n) { - return function() { - return e[n] - } - } - - function l() { - return e - } - var o = 0, - e, h, a = s.a.f.get(n, f); - if (!i) { - if (a) throw Error("You cannot apply bindings multiple times to the same element."); - s.a.f.set(n, f, !0) - } - return s.j(function() { - var f = r && r instanceof s.A ? r : new s.A(s.a.c(r)), - v = f.$data; - !a && u && s.jb(n, f); - (e = ("function" == typeof i ? i(f, n) : i) || s.M.instance.getBindings(n, f)) && (0 === o && (o = 1, s.a.w(e, function(i) { - var r = s.d[i]; - if (r && 8 === n.nodeType && !s.e.L[i]) throw Error("The binding '" + i + "' cannot be used with virtual elements"); - if (r && "function" == typeof r.init && (r = r.init(n, c(i), l, v, f)) && r.controlsDescendantBindings) { - if (h !== t) throw Error("Multiple bindings (" + h + " and " + i + ") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element."); - h = i - } - }), o = 2), 2 === o && s.a.w(e, function(t) { - var i = s.d[t]; - i && "function" == typeof i.update && i.update(n, c(t), l, v, f) - })) - }, null, { - $: n - }), { - Sb: h === t - } - } - s.d = {}; - s.A = function(n, t, i) { - t ? (s.a.extend(this, t), this.$parentContext = t, this.$parent = t.$data, this.$parents = (t.$parents || []).slice(0), this.$parents.unshift(this.$parent)) : (this.$parents = [], this.$root = n, this.ko = s); - this.$data = n; - i && (this[i] = n) - }; - s.A.prototype.createChildContext = function(n, t) { - return new s.A(n, this, t) - }; - s.A.prototype.extend = function(n) { - var t = s.a.extend(new s.A, this); - return s.a.extend(t, n) - }; - var f = "__ko_boundElement"; - s.jb = function(n, t) { - if (2 == arguments.length) s.a.f.set(n, "__ko_bindingContext__", t); - else return s.a.f.get(n, "__ko_bindingContext__") - }; - s.Ka = function(n, t, i) { - return 1 === n.nodeType && s.e.Za(n), r(n, t, i, !0) - }; - s.Ja = function(t, i) { - 1 !== i.nodeType && 8 !== i.nodeType || n(t, i, !0) - }; - s.Ia = function(n, t) { - if (t && 1 !== t.nodeType && 8 !== t.nodeType) throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node"); - t = t || u.document.body; - i(n, t, !0) - }; - s.na = function(n) { - switch (n.nodeType) { - case 1: - case 8: - var i = s.jb(n); - if (i) return i; - if (n.parentNode) return s.na(n.parentNode) - } - return t - }; - s.ub = function(n) { - return (n = s.na(n)) ? n.$data : t - }; - s.b("bindingHandlers", s.d); - s.b("applyBindings", s.Ia); - s.b("applyBindingsToDescendants", s.Ja); - s.b("applyBindingsToNode", s.Ka); - s.b("contextFor", s.na); - s.b("dataFor", s.ub) - }(); - l = { - "class": "className", - "for": "htmlFor" - }; - s.d.attr = { - update: function(n, i) { - var r = s.a.c(i()) || {}; - s.a.w(r, function(i, r) { - r = s.a.c(r); - var u = !1 === r || null === r || r === t; - u && n.removeAttribute(i); - 8 >= s.a.ca && i in l ? (i = l[i], u ? n.removeAttribute(i) : n[i] = r) : u || n.setAttribute(i, r.toString()); - "name" === i && s.a.gb(n, u ? "" : r.toString()) - }) - } - }; - s.d.checked = { - init: function(t, i, r) { - s.a.o(t, "click", function() { - var u, n, f; - if ("checkbox" == t.type) u = t.checked; - else if ("radio" == t.type && t.checked) u = t.value; - else return; - n = i(); - f = s.a.c(n); - "checkbox" == t.type && f instanceof Array ? s.a.ja(n, t.value, t.checked) : s.g.ha(n, r, "checked", u, !0) - }); - "radio" != t.type || t.name || s.d.uniqueName.init(t, n(!0)) - }, - update: function(n, t) { - var i = s.a.c(t()); - "checkbox" == n.type ? n.checked = i instanceof Array ? 0 <= s.a.k(i, n.value) : i : "radio" == n.type && (n.checked = n.value == i) - } - }; - s.d.css = { - update: function(n, t) { - var i = s.a.c(t()); - "object" == typeof i ? s.a.w(i, function(t, i) { - i = s.a.c(i); - s.a.ga(n, t, i) - }) : (i = String(i || ""), s.a.ga(n, n.__ko__cssValue, !1), n.__ko__cssValue = i, s.a.ga(n, i, !0)) - } - }; - s.d.enable = { - update: function(n, t) { - var i = s.a.c(t()); - i && n.disabled ? n.removeAttribute("disabled") : i || n.disabled || (n.disabled = !0) - } - }; - s.d.disable = { - update: function(n, t) { - s.d.enable.update(n, function() { - return !s.a.c(t()) - }) - } - }; - s.d.event = { - init: function(n, t, i, r) { - var u = t() || {}; - s.a.w(u, function(u) { - "string" == typeof u && s.a.o(n, u, function(n) { - var e, o = t()[u], - h, f; - if (o) { - h = i(); - try { - f = s.a.N(arguments); - f.unshift(r); - e = o.apply(r, f) - } finally { - !0 !== e && (n.preventDefault ? n.preventDefault() : n.returnValue = !1) - }!1 === h[u + "Bubble"] && (n.cancelBubble = !0, n.stopPropagation && n.stopPropagation()) - } - }) - }) - } - }; - s.d.foreach = { - Ya: function(n) { - return function() { - var i = n(), - t = s.a.ya(i); - return !t || "number" == typeof t.length ? { - foreach: i, - templateEngine: s.D.sa - } : (s.a.c(i), { - foreach: t.data, - as: t.as, - includeDestroyed: t.includeDestroyed, - afterAdd: t.afterAdd, - beforeRemove: t.beforeRemove, - afterRender: t.afterRender, - beforeMove: t.beforeMove, - afterMove: t.afterMove, - templateEngine: s.D.sa - }) - } - }, - init: function(n, t) { - return s.d.template.init(n, s.d.foreach.Ya(t)) - }, - update: function(n, t, i, r, u) { - return s.d.template.update(n, s.d.foreach.Ya(t), i, r, u) - } - }; - s.g.S.foreach = !1; - s.e.L.foreach = !0; - s.d.hasfocus = { - init: function(n, t, i) { - function r(r) { - var u, f; - if (n.__ko_hasfocusUpdating = !0, u = n.ownerDocument, "activeElement" in u) { - try { - f = u.activeElement - } catch (e) { - f = u.body - } - r = f === n - } - u = t(); - s.g.ha(u, i, "hasfocus", r, !0); - n.__ko_hasfocusLastValue = r; - n.__ko_hasfocusUpdating = !1 - } - var u = r.bind(null, !0), - f = r.bind(null, !1); - s.a.o(n, "focus", u); - s.a.o(n, "focusin", u); - s.a.o(n, "blur", f); - s.a.o(n, "focusout", f) - }, - update: function(n, t) { - var i = !!s.a.c(t()); - n.__ko_hasfocusUpdating || n.__ko_hasfocusLastValue === i || (i ? n.focus() : n.blur(), s.q.I(s.a.Ga, null, [n, i ? "focusin" : "focusout"])) - } - }; - s.d.hasFocus = s.d.hasfocus; - s.d.html = { - init: function() { - return { - controlsDescendantBindings: !0 - } - }, - update: function(n, t) { - s.a.fa(n, t()) - } - }; - a = "__ko_withIfBindingData"; - c("if"); - c("ifnot", !1, !0); - c("with", !0, !1, function(n, t) { - return n.createChildContext(t) - }); - s.d.options = { - init: function(n) { - if ("select" !== s.a.u(n)) throw Error("options binding applies only to SELECT elements"); - for (; 0 < n.length;) n.remove(0); - return { - controlsDescendantBindings: !0 - } - }, - update: function(n, i, u) { - function a(n, t, i) { - var r = typeof t; - return "function" == r ? t(n) : "string" == r ? n[t] : i - } - - function y(n, t) { - if (e) { - var i = 0 <= s.a.k(e, s.h.n(t[0])); - s.a.hb(t[0], i) - } - } - var p = 0 == n.length, - h = !p && n.multiple ? n.scrollTop : null, - l; - i = s.a.c(i()); - var f = u(), - w = f.optionsIncludeDestroyed, - c = {}, - o, e; - n.multiple ? e = s.a.Z(n.selectedOptions || s.a.Y(n.childNodes, function(n) { - return n.tagName && "option" === s.a.u(n) && n.selected - }), function(n) { - return s.h.n(n) - }) : 0 <= n.selectedIndex && (e = [s.h.n(n.options[n.selectedIndex])]); - i ? ("undefined" == typeof i.length && (i = [i]), l = s.a.Y(i, function(n) { - return w || n === t || null === n || !s.a.c(n._destroy) - }), "optionsCaption" in f && (o = s.a.c(f.optionsCaption), null !== o && o !== t && l.unshift(c))) : i = []; - u = y; - f.optionsAfterRender && (u = function(n, i) { - y(0, i); - s.q.I(f.optionsAfterRender, null, [i[0], n !== c ? n : t]) - }); - s.a.Aa(n, l, function(n, i, u) { - return u.length && (e = u[0].selected && [s.h.n(u[0])]), i = r.createElement("option"), n === c ? (s.a.fa(i, o), s.h.W(i, t)) : (u = a(n, f.optionsValue, n), s.h.W(i, s.a.c(u)), n = a(n, f.optionsText, u), s.a.ib(i, n)), [i] - }, null, u); - e = null; - p && "value" in f && v(n, s.a.ya(f.value), !0); - s.a.zb(n); - h && 20 < Math.abs(h - n.scrollTop) && (n.scrollTop = h) - } - }; - s.d.options.wa = "__ko.optionValueDomData__"; - s.d.selectedOptions = { - init: function(n, t, i) { - s.a.o(n, "change", function() { - var u = t(), - r = []; - s.a.p(n.getElementsByTagName("option"), function(n) { - n.selected && r.push(s.h.n(n)) - }); - s.g.ha(u, i, "selectedOptions", r) - }) - }, - update: function(n, t) { - if ("select" != s.a.u(n)) throw Error("values binding applies only to SELECT elements"); - var i = s.a.c(t()); - i && "number" == typeof i.length && s.a.p(n.getElementsByTagName("option"), function(n) { - var t = 0 <= s.a.k(i, s.h.n(n)); - s.a.hb(n, t) - }) - } - }; - s.d.style = { - update: function(n, t) { - var i = s.a.c(t() || {}); - s.a.w(i, function(t, i) { - i = s.a.c(i); - n.style[t] = i || "" - }) - } - }; - s.d.submit = { - init: function(n, t, i, r) { - if ("function" != typeof t()) throw Error("The value for a submit binding must be a function"); - s.a.o(n, "submit", function(i) { - var u, f = t(); - try { - u = f.call(r, n) - } finally { - !0 !== u && (i.preventDefault ? i.preventDefault() : i.returnValue = !1) - } - }) - } - }; - s.d.text = { - update: function(n, t) { - s.a.ib(n, t()) - } - }; - s.e.L.text = !0; - s.d.uniqueName = { - init: function(n, t) { - if (t()) { - var i = "ko_unique_" + ++s.d.uniqueName.tb; - s.a.gb(n, i) - } - } - }; - s.d.uniqueName.tb = 0; - s.d.value = { - init: function(n, t, i) { - function f() { - e = !1; - var r = t(), - u = s.h.n(n); - s.g.ha(r, i, "value", u) - } - var r = ["change"], - u = i().valueUpdate, - e = !1; - u && ("string" == typeof u && (u = [u]), s.a.R(r, u), r = s.a.Ma(r)); - !s.a.ca || "input" != n.tagName.toLowerCase() || "text" != n.type || "off" == n.autocomplete || n.form && "off" == n.form.autocomplete || -1 != s.a.k(r, "propertychange") || (s.a.o(n, "propertychange", function() { - e = !0 - }), s.a.o(n, "blur", function() { - e && f() - })); - s.a.p(r, function(t) { - var i = f; - s.a.Tb(t, "after") && (i = function() { - setTimeout(f, 0) - }, t = t.substring(5)); - s.a.o(n, t, i) - }) - }, - update: function(n, t) { - var u = "select" === s.a.u(n), - r = s.a.c(t()), - i = s.h.n(n); - r !== i && (i = function() { - s.h.W(n, r) - }, i(), u && setTimeout(i, 0)); - u && 0 < n.length && v(n, r, !1) - } - }; - s.d.visible = { - update: function(n, t) { - var i = s.a.c(t()), - r = "none" != n.style.display; - i && !r ? n.style.display = "" : !i && r && (n.style.display = "none") - } - }, - function(n) { - s.d[n] = { - init: function(t, i, r, u) { - return s.d.event.init.call(this, t, function() { - var t = {}; - return t[n] = i(), t - }, r, u) - } - } - }("click"); - s.v = function() {}; - s.v.prototype.renderTemplateSource = function() { - throw Error("Override renderTemplateSource"); - }; - s.v.prototype.createJavaScriptEvaluatorBlock = function() { - throw Error("Override createJavaScriptEvaluatorBlock"); - }; - s.v.prototype.makeTemplateSource = function(n, t) { - if ("string" == typeof n) { - t = t || r; - var i = t.getElementById(n); - if (!i) throw Error("Cannot find template with ID " + n); - return new s.l.i(i) - } - if (1 == n.nodeType || 8 == n.nodeType) return new s.l.Q(n); - throw Error("Unknown template type: " + n); - }; - s.v.prototype.renderTemplate = function(n, t, i, r) { - return n = this.makeTemplateSource(n, r), this.renderTemplateSource(n, t, i) - }; - s.v.prototype.isTemplateRewritten = function(n, t) { - return !1 === this.allowTemplateRewriting ? !0 : this.makeTemplateSource(n, t).data("isRewritten") - }; - s.v.prototype.rewriteTemplate = function(n, t, i) { - n = this.makeTemplateSource(n, i); - t = t(n.text()); - n.text(t); - n.data("isRewritten", !0) - }; - s.b("templateEngine", s.v); - s.Ea = function() { - function n(n, t, i, r) { - var o, f, u, e; - for (n = s.g.da(n), o = s.g.S, f = 0; f < n.length; f++) - if (u = n[f].key, o.hasOwnProperty(u)) - if (e = o[u], "function" == typeof e) { - if (u = e(n[f].value)) throw Error(u); - } else if (!e) throw Error("This template engine does not support the '" + u + "' binding within its templates"); - return i = "ko.__tr_ambtns(function($context,$element){return(function(){return{ " + s.g.ea(n) + " } })()},'" + i.toLowerCase() + "')", r.createJavaScriptEvaluatorBlock(i) + t - } - var t = /(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi, - i = /\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g; - return { - Ab: function(n, t, i) { - t.isTemplateRewritten(n, i) || t.rewriteTemplate(n, function(n) { - return s.Ea.Lb(n, t) - }, i) - }, - Lb: function(r, u) { - return r.replace(t, function(t, i, r, f, e) { - return n(e, i, r, u) - }).replace(i, function(t, i) { - return n(i, "<!-- ko -->", "#comment", u) - }) - }, - qb: function(n, t) { - return s.s.va(function(i, r) { - var u = i.nextSibling; - u && u.nodeName.toLowerCase() === t && s.Ka(u, n, r) - }) - } - } - }(); - s.b("__tr_ambtns", s.Ea.qb), - function() { - s.l = {}; - s.l.i = function(n) { - this.i = n - }; - s.l.i.prototype.text = function() { - var n = s.a.u(this.i), - n = "script" === n ? "text" : "textarea" === n ? "value" : "innerHTML", - t; - if (0 == arguments.length) return this.i[n]; - t = arguments[0]; - "innerHTML" === n ? s.a.fa(this.i, t) : this.i[n] = t - }; - s.l.i.prototype.data = function(n) { - if (1 === arguments.length) return s.a.f.get(this.i, "templateSourceData_" + n); - s.a.f.set(this.i, "templateSourceData_" + n, arguments[1]) - }; - s.l.Q = function(n) { - this.i = n - }; - s.l.Q.prototype = new s.l.i; - s.l.Q.prototype.text = function() { - if (0 == arguments.length) { - var n = s.a.f.get(this.i, "__ko_anon_template__") || {}; - return n.Fa === t && n.ma && (n.Fa = n.ma.innerHTML), n.Fa - } - s.a.f.set(this.i, "__ko_anon_template__", { - Fa: arguments[0] - }) - }; - s.l.i.prototype.nodes = function() { - if (0 == arguments.length) return (s.a.f.get(this.i, "__ko_anon_template__") || {}).ma; - s.a.f.set(this.i, "__ko_anon_template__", { - ma: arguments[0] - }) - }; - s.b("templateSources", s.l); - s.b("templateSources.domElement", s.l.i); - s.b("templateSources.anonymousTemplate", s.l.Q) - }(), - function() { - function r(n, t, i) { - var r; - for (t = s.e.nextSibling(t); n && (r = n) !== t;) n = s.e.nextSibling(r), 1 !== r.nodeType && 8 !== r.nodeType || i(r) - } - - function u(n, t) { - if (n.length) { - var i = n[0], - u = n[n.length - 1]; - r(i, u, function(n) { - s.Ia(t, n) - }); - r(i, u, function(n) { - s.s.nb(n, [t]) - }) - } - } - - function n(n) { - return n.nodeType ? n : 0 < n.length ? n[0] : null - } - - function f(t, r, f, e, o) { - o = o || {}; - var h = t && n(t), - h = h && h.ownerDocument, - c = o.templateEngine || i; - if (s.Ea.Ab(f, c, h), f = c.renderTemplate(f, e, o, h), "number" != typeof f.length || 0 < f.length && "number" != typeof f[0].nodeType) throw Error("Template engine must return an array of DOM nodes"); - h = !1; - switch (r) { - case "replaceChildren": - s.e.P(t, f); - h = !0; - break; - case "replaceNode": - s.a.eb(t, f); - h = !0; - break; - case "ignoreTargetNode": - break; - default: - throw Error("Unknown renderMode: " + r); - } - return h && (u(f, e), o.afterRender && s.q.I(o.afterRender, null, [f, e.$data])), f - } - var i; - s.Ba = function(n) { - if (n != t && !(n instanceof s.v)) throw Error("templateEngine must inherit from ko.templateEngine"); - i = n - }; - s.za = function(r, u, e, o, h) { - if (e = e || {}, (e.templateEngine || i) == t) throw Error("Set a template engine before calling renderTemplate"); - if (h = h || "replaceChildren", o) { - var c = n(o); - return s.j(function() { - var t = u && u instanceof s.A ? u : new s.A(s.a.c(u)), - i = "function" == typeof r ? r(t.$data, t) : r, - t = f(o, h, i, t, e); - "replaceNode" == h && (o = t, c = n(o)) - }, null, { - Qa: function() { - return !c || !s.a.aa(c) - }, - $: c && "replaceNode" == h ? c.parentNode : c - }) - } - return s.s.va(function(n) { - s.za(r, u, e, n, "replaceNode") - }) - }; - s.Rb = function(n, i, r, e, o) { - function c(n, t) { - u(t, h); - r.afterRender && r.afterRender(t, n) - } - - function l(t, i) { - h = o.createChildContext(s.a.c(t), r.as); - h.$index = i; - var u = "function" == typeof n ? n(t, h) : n; - return f(null, "ignoreTargetNode", u, h, r) - } - var h; - return s.j(function() { - var n = s.a.c(i) || []; - "undefined" == typeof n.length && (n = [n]); - n = s.a.Y(n, function(n) { - return r.includeDestroyed || n === t || null === n || !s.a.c(n._destroy) - }); - s.q.I(s.a.Aa, null, [e, n, l, r, c]) - }, null, { - $: e - }) - }; - s.d.template = { - init: function(n, t) { - var i = s.a.c(t()); - return "string" == typeof i || i.name || 1 != n.nodeType && 8 != n.nodeType || (i = 1 == n.nodeType ? n.childNodes : s.e.childNodes(n), i = s.a.Mb(i), new s.l.Q(n).nodes(i)), { - controlsDescendantBindings: !0 - } - }, - update: function(n, i, r, u, f) { - i = s.a.c(i()); - r = {}; - u = !0; - var e, o = null; - "string" != typeof i && (r = i, i = s.a.c(r.name), "if" in r && (u = s.a.c(r["if"])), u && "ifnot" in r && (u = !s.a.c(r.ifnot)), e = s.a.c(r.data)); - "foreach" in r ? o = s.Rb(i || n, u && r.foreach || [], r, n, f) : u ? (f = "data" in r ? f.createChildContext(e, r.as) : f, o = s.za(i || n, f, r, n)) : s.e.ba(n); - f = o; - (e = s.a.f.get(n, "__ko__templateComputedDomDataKey__")) && "function" == typeof e.B && e.B(); - s.a.f.set(n, "__ko__templateComputedDomDataKey__", f && f.ta() ? f : t) - } - }; - s.g.S.template = function(n) { - return n = s.g.da(n), 1 == n.length && n[0].unknown || s.g.Jb(n, "name") ? null : "This template engine does not support anonymous templates nested within its templates" - }; - s.e.L.template = !0 - }(); - s.b("setTemplateEngine", s.Ba); - s.b("renderTemplate", s.za); - s.a.Pa = function() { - function n(n, t, i, r, u) { - for (var o = Math.min, l = Math.max, s = [], a = n.length, f, h = t.length, c = h - a || 1, w = a + h + 1, v, p, b, y, e = 0; e <= a; e++) - for (p = v, s.push(v = []), b = o(h, e + c), f = l(0, e - 1); f <= b; f++) v[f] = f ? e ? n[e - 1] === t[f - 1] ? p[f - 1] : o(p[f] || w, v[f - 1] || w) + 1 : f + 1 : e + 1; - for (o = [], l = [], c = [], e = a, f = h; e || f;) h = s[e][f] - 1, f && h === s[e][f - 1] ? l.push(o[o.length] = { - status: i, - value: t[--f], - index: f - }) : e && h === s[e - 1][f] ? c.push(o[o.length] = { - status: r, - value: n[--e], - index: e - }) : (o.push({ - status: "retained", - value: t[--f] - }), --e); - if (l.length && c.length) - for (n = 10 * a, t = i = 0; - (u || t < n) && (y = l[i]); i++) { - for (r = 0; s = c[r]; r++) - if (y.value === s.value) { - y.moved = s.index; - s.moved = y.index; - c.splice(r, 1); - t = r = 0; - break - } - t += r - } - return o.reverse() - } - return function(t, i, r) { - return t = t || [], i = i || [], t.length <= i.length ? n(t, i, "added", "deleted", r) : n(i, t, "deleted", "added", r) - } - }(); - s.b("utils.compareArrays", s.a.Pa), - function() { - function n(n) { - for (; n.length && !s.a.aa(n[0]);) n.splice(0, 1); - if (1 < n.length) { - for (var t = n[0], r = n[n.length - 1], i = [t]; t !== r;) { - if (t = t.nextSibling, !t) return; - i.push(t) - } - Array.prototype.splice.apply(n, [0, n.length].concat(i)) - } - return n - } - - function i(i, r, u, f, e) { - var o = []; - return i = s.j(function() { - var t = r(u, e, n(o)) || []; - 0 < o.length && (s.a.eb(o, t), f && s.q.I(f, null, [u, t, e])); - o.splice(0, o.length); - s.a.R(o, t) - }, null, { - $: i, - Qa: function() { - return !s.a.pb(o) - } - }), { - O: o, - j: i.ta() ? i : t - } - } - s.a.Aa = function(r, u, f, e, o) { - function rt(t, i) { - h = k[i]; - nt !== i && (it[t] = h); - h.ra(nt++); - n(h.O); - g.push(h); - p.push(h) - } - - function v(n, t) { - if (n) - for (var i = 0, r = t.length; i < r; i++) t[i] && s.a.p(t[i].O, function(r) { - n(r, i, t[i].X) - }) - } - var c, y, ut; - u = u || []; - e = e || {}; - var y = s.a.f.get(r, "setDomNodeChildrenFromArrayMapping_lastMappingResult") === t, - k = s.a.f.get(r, "setDomNodeChildrenFromArrayMapping_lastMappingResult") || [], - d = s.a.Z(k, function(n) { - return n.X - }), - l = s.a.Pa(d, u, e.dontLimitMoves), - g = [], - a = 0, - nt = 0, - tt = [], - p = []; - u = []; - for (var it = [], d = [], h, c = 0, w, b; w = l[c]; c++) switch (b = w.moved, w.status) { - case "deleted": - b === t && (h = k[a], h.j && h.j.B(), tt.push.apply(tt, n(h.O)), e.beforeRemove && (u[c] = h, p.push(h))); - a++; - break; - case "retained": - rt(c, a++); - break; - case "added": - b !== t ? rt(c, b) : (h = { - X: w.value, - ra: s.m(nt++) - }, g.push(h), p.push(h), y || (d[c] = h)) - } - for (v(e.beforeMove, it), s.a.p(tt, e.beforeRemove ? s.H : s.removeNode), c = 0, y = s.e.firstChild(r); h = p[c]; c++) { - for (h.O || s.a.extend(h, i(r, f, h.X, o, h.ra)), a = 0; l = h.O[a]; y = l.nextSibling, ut = l, a++) l !== y && s.e.Va(r, l, ut); - !h.Fb && o && (o(h.X, h.O, h.ra), h.Fb = !0) - } - v(e.beforeRemove, u); - v(e.afterMove, it); - v(e.afterAdd, d); - s.a.f.set(r, "setDomNodeChildrenFromArrayMapping_lastMappingResult", g) - } - }(); - s.b("utils.setDomNodeChildrenFromArrayMapping", s.a.Aa); - s.D = function() { - this.allowTemplateRewriting = !1 - }; - s.D.prototype = new s.v; - s.D.prototype.renderTemplateSource = function(n) { - var t = (9 > s.a.ca ? 0 : n.nodes) ? n.nodes() : null; - return t ? s.a.N(t.cloneNode(!0).childNodes) : (n = n.text(), s.a.xa(n)) - }; - s.D.sa = new s.D; - s.Ba(s.D.sa); - s.b("nativeTemplateEngine", s.D), - function() { - s.ua = function() { - var n = this.Ib = function() { - if ("undefined" == typeof i || !i.tmpl) return 0; - try { - if (0 <= i.tmpl.tag.tmpl.open.toString().indexOf("__")) return 2 - } catch (n) {} - return 1 - }(); - this.renderTemplateSource = function(t, u, f) { - if (f = f || {}, 2 > n) throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later."); - var e = t.data("precompiled"); - return e || (e = t.text() || "", e = i.template(null, "{{ko_with $item.koBindingContext}}" + e + "{{/ko_with}}"), t.data("precompiled", e)), t = [u.$data], u = i.extend({ - koBindingContext: u - }, f.templateOptions), u = i.tmpl(e, t, u), u.appendTo(r.createElement("div")), i.fragments = {}, u - }; - this.createJavaScriptEvaluatorBlock = function(n) { - return "{{ko_code ((function() { return " + n + " })()) }}" - }; - this.addTemplate = function(n, t) { - r.write("<script type='text/html' id='" + n + "'>" + t + "<\/script>") - }; - 0 < n && (i.tmpl.tag.ko_code = { - open: "__.push($1 || '');" - }, i.tmpl.tag.ko_with = { - open: "with($1) {", - close: "} " - }) - }; - s.ua.prototype = new s.v; - var n = new s.ua; - 0 < n.Ib && s.Ba(n); - s.b("jqueryTmplTemplateEngine", s.ua) - }() - }) - })() -}(); -! function(n) { - "function" == typeof require && "object" == typeof exports && "object" == typeof module ? n(require("knockout"), require("jquery"), require("kendo")) : "function" == typeof define && define.amd ? define(["knockout", "jquery", "kendo"], n) : n(window.ko, window.jQuery, window.kendo) -}(function(n, t, i, r) { - var y; - i = i || window.kendo; - n.kendo = n.kendo || {}; - n.kendo.BindingFactory = function() { - var u = this, - f; - this.createBinding = function(i) { - if (t()[i.parent || i.name]) { - var r = {}; - r.init = function(n, t, f, e, o) { - var s = u.buildOptions(i, t); - return s.async === !0 || i.async === !0 && s.async !== !1 ? (setTimeout(function() { - r.setup(n, s, o) - }, 0), void 0) : (r.setup(n, s, o), s && s.useKOTemplates ? { - controlsDescendantBindings: !0 - } : void 0) - }; - r.setup = function(r, f, e) { - var o, s = t(r); - u.setupTemplates(i.templates, f, r, e); - o = u.getWidget(i, f, s); - u.handleEvents(f, i, r, o, e); - u.watchValues(o, f, i, r); - o.destroy && n.utils.domNodeDisposal.addDisposeCallback(r, function() { - o.destroy() - }) - }; - r.options = {}; - r.widgetConfig = i; - n.bindingHandlers[i.bindingName || i.name] = r - } - }; - this.buildOptions = function(t, r) { - var f = t.defaultOption, - e = n.utils.extend({}, n.bindingHandlers[t.name].options), - u = n.utils.unwrapObservable(r()); - return u instanceof i.data.DataSource || "object" != typeof u || null === u || f && !(f in u) ? e[f] = r() : n.utils.extend(e, u), e - }; - f = function(t, i) { - return function(r) { - return n.renderTemplate(t, i.createChildContext(r._raw && r._raw() || r)) - } - }; - this.setupTemplates = function(t, i, r, u) { - var e, h, o, s; - if (t && i && i.useKOTemplates) { - for (e = 0, h = t.length; h > e; e++) o = t[e], i[o] && (i[o] = f(i[o], u)); - s = i.dataBound; - i.dataBound = function() { - n.memoization.unmemoizeDomNodeAndDescendants(r); - s && s.apply(this, arguments) - } - } - }; - this.unwrapOneLevel = function(t) { - var r, u = {}; - if (t) - if (t instanceof i.data.DataSource) u = t; - else if ("object" == typeof t) - for (r in t) u[r] = n.utils.unwrapObservable(t[r]); - return u - }; - this.getWidget = function(t, i, r) { - var u, f; - return t.parent ? (f = r.closest("[data-bind*='" + t.parent + ":']"), u = f.length ? f.data(t.parent) : null) : u = r[t.name](this.unwrapOneLevel(i)).data(t.name), n.isObservable(i.widget) && i.widget(u), u - }; - this.watchValues = function(n, t, i, r) { - var f, e = i.watch; - if (e) - for (f in e) e.hasOwnProperty(f) && u.watchOneValue(f, n, t, i, r) - }; - this.watchOneValue = function(i, u, f, e, o) { - var s = n.computed({ - read: function() { - var a, l, s = e.watch[i], - h = n.utils.unwrapObservable(f[i]), - c = e.parent ? [o] : []; - t.isArray(s) ? s = u[h ? s[0] : s[1]] : "string" == typeof s ? s = u[s] : l = !0; - s && f[i] !== r && (l ? c.push(h, f) : (a = s.apply(u, c), c.push(h)), (l || a !== h) && s.apply(u, c)) - }, - disposeWhenNodeIsRemoved: o - }).extend({ - throttle: f.throttle || 0 === f.throttle ? f.throttle : 1 - }); - n.isObservable(f[i]) || s.dispose() - }; - this.handleEvents = function(n, t, i, r, f) { - var o, e, s = t.events; - if (s) - for (o in s) s.hasOwnProperty(o) && (e = s[o], "string" == typeof e && (e = { - value: e, - writeTo: e - }), u.handleOneEvent(o, e, n, i, r, t.childProp, f)) - }; - this.handleOneEvent = function(t, i, r, u, f, e, o) { - var s = "function" == typeof i ? i : r[i.call]; - "function" == typeof i ? s = s.bind(o.$data, r) : i.call && "function" == typeof r[i.call] ? s = r[i.call].bind(o.$data, o.$data) : i.writeTo && n.isWriteableObservable(r[i.writeTo]) && (s = function(n) { - var t, f; - e && n[e] && n[e] !== u || (t = i.value, f = "string" == typeof t && this[t] ? this[t](e && u) : t, r[i.writeTo](f)) - }); - s && f.bind(t, s) - } - }; - n.kendo.bindingFactory = new n.kendo.BindingFactory; - n.kendo.setDataSource = function(t, r, u) { - var f, e; - return r instanceof i.data.DataSource ? (t.setDataSource(r), void 0) : (u && u.useKOTemplates || (f = n.mapping && r && r.__ko_mapping__, e = r && f ? n.mapping.toJS(r) : n.toJS(r)), t.dataSource.data(e || r), void 0) - }, - function() { - var n = i.data.ObservableArray.fn.wrap; - i.data.ObservableArray.fn.wrap = function(t) { - var i = n.apply(this, arguments); - return i._raw = function() { - return t - }, i - } - }(); - var c = function(t) { - return function(i) { - i && (n.utils.extend(this.options[t], i), this.redraw(), this.value(.001 + this.value())) - } - }, - f = n.kendo.bindingFactory.createBinding.bind(n.kendo.bindingFactory), - d = "clicked", - s = "close", - p = "collapse", - g = "content", - w = "data", - e = "enable", - b = "expand", - l = "expanded", - rt = "error", - ut = "info", - o = "isOpen", - a = "max", - v = "min", - h = "open", - nt = "search", - tt = "selected", - ft = "success", - it = "size", - u = "value", - k = "values", - et = "warning"; - f({ - name: "kendoAutoComplete", - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - search: [nt, s], - data: function(t) { - n.kendo.setDataSource(this, t) - }, - value: u - } - }); - f({ - name: "kendoButton", - defaultOption: d, - events: { - click: { - call: d - } - }, - watch: { - enabled: e - } - }); - f({ - name: "kendoCalendar", - defaultOption: u, - events: { - change: u - }, - watch: { - max: a, - min: v, - value: u - } - }); - f({ - name: "kendoColorPicker", - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - value: u, - color: u, - palette: "palette" - } - }); - f({ - name: "kendoComboBox", - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - isOpen: [h, s], - data: function(t) { - n.kendo.setDataSource(this, t) - }, - value: u - } - }); - f({ - name: "kendoDatePicker", - defaultOption: u, - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - max: a, - min: v, - value: u, - isOpen: [h, s] - } - }); - f({ - name: "kendoDateTimePicker", - defaultOption: u, - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - max: a, - min: v, - value: u, - isOpen: [h, s] - } - }); - f({ - name: "kendoDropDownList", - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - isOpen: [h, s], - data: function(t) { - n.kendo.setDataSource(this, t); - t.length && this.options.optionLabel && this.select() < 0 && this.select(0) - }, - value: u - } - }); - f({ - name: "kendoEditor", - defaultOption: u, - events: { - change: u - }, - watch: { - enabled: e, - value: u - } - }); - f({ - name: "kendoGrid", - defaultOption: w, - watch: { - data: function(t, i) { - n.kendo.setDataSource(this, t, i) - } - }, - templates: ["rowTemplate", "altRowTemplate"] - }); - f({ - name: "kendoListView", - defaultOption: w, - watch: { - data: function(t, i) { - n.kendo.setDataSource(this, t, i) - } - }, - templates: ["template"] - }); - f({ - name: "kendoMaskedTextBox", - defaultOption: u, - events: { - change: u - }, - watch: { - enabled: e, - isReadOnly: "readonly", - value: u - } - }); - f({ - name: "kendoMenu", - async: !0 - }); - f({ - name: "kendoMenuItem", - parent: "kendoMenu", - watch: { - enabled: e, - isOpen: [h, s] - }, - async: !0 - }); - f({ - name: "kendoMultiSelect", - events: { - change: u, - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - enabled: e, - search: [nt, s], - data: function(t) { - n.kendo.setDataSource(this, t) - }, - value: u - } - }); - y = function(n, t) { - t || 0 === t ? this.show(t, n) : this.hide() - }; - f({ - name: "kendoNotification", - watch: { - error: function(n) { - y.call(this, rt, n) - }, - info: function(n) { - y.call(this, ut, n) - }, - success: function(n) { - y.call(this, ft, n) - }, - warning: function(n) { - y.call(this, et, n) - } - } - }); - f({ - name: "kendoNumericTextBox", - defaultOption: u, - events: { - change: u - }, - watch: { - enabled: e, - value: u, - max: function(n) { - this.options.max = n; - var t = this.value(); - (t || 0 === t) && t > n && this.value(n) - }, - min: function(n) { - this.options.min = n; - var t = this.value(); - (t || 0 === t) && n > t && this.value(n) - } - } - }); - f({ - name: "kendoPanelBar", - async: !0 - }); - f({ - name: "kendoPanelItem", - parent: "kendoPanelBar", - watch: { - enabled: e, - expanded: [b, p], - selected: ["select"] - }, - childProp: "item", - events: { - expand: { - writeTo: l, - value: !0 - }, - collapse: { - writeTo: l, - value: !1 - }, - select: { - writeTo: tt, - value: u - } - }, - async: !0 - }); - f({ - name: "kendoProgressBar", - defaultOption: u, - events: { - change: u - }, - watch: { - enabled: e, - value: u - } - }); - f({ - name: "kendoRangeSlider", - defaultOption: k, - events: { - change: k - }, - watch: { - values: k, - enabled: e - } - }); - f({ - async: !0, - name: "kendoScheduler", - watch: { - data: function(t, i) { - n.kendo.setDataSource(this, t, i) - } - } - }); - f({ - name: "kendoSlider", - defaultOption: u, - events: { - change: u - }, - watch: { - value: u, - enabled: e - } - }); - f({ - name: "kendoSortable", - defaultOption: w, - events: { - end: function(i, r) { - var u = "__ko_kendo_sortable_data__", - f = "receive" !== r.action ? n.dataFor(r.item[0]) : r.draggableEvent[u], - o = i.data, - e = i.data; - ("sort" === r.action || "remove" === r.action) && (e.splice(r.oldIndex, 1), "remove" === r.action && (r.draggableEvent[u] = f)); - ("sort" === r.action || "receive" === r.action) && (e.splice(r.newIndex, 0, f), delete r.draggableEvent[u], t(r.draggableEvent.target).hide(), r.preventDefault()); - o.valueHasMutated() - } - } - }); - f({ - name: "kendoSplitter", - async: !0 - }); - f({ - name: "kendoSplitterPane", - parent: "kendoSplitter", - watch: { - max: a, - min: v, - size: it, - expanded: [b, p] - }, - childProp: "pane", - events: { - collapse: { - writeTo: l, - value: !1 - }, - expand: { - writeTo: l, - value: !0 - }, - resize: it - }, - async: !0 - }); - f({ - name: "kendoTabStrip", - async: !0 - }); - f({ - name: "kendoTab", - parent: "kendoTabStrip", - watch: { - enabled: e - }, - childProp: "item", - async: !0 - }); - f({ - name: "kendoTooltip", - events: {}, - watch: { - content: g, - filter: "filter" - } - }); - f({ - name: "kendoTimePicker", - defaultOption: u, - events: { - change: u - }, - watch: { - max: a, - min: v, - value: u, - enabled: e, - isOpen: [h, s] - } - }); - f({ - name: "kendoTreeView", - async: !0 - }); - f({ - name: "kendoTreeItem", - parent: "kendoTreeView", - watch: { - enabled: e, - expanded: [b, p], - selected: function(n, t) { - t ? this.select(n) : this.select()[0] == n && this.select(null) - } - }, - childProp: "node", - events: { - collapse: { - writeTo: l, - value: !1 - }, - expand: { - writeTo: l, - value: !0 - }, - select: { - writeTo: tt, - value: !0 - } - }, - async: !0 - }); - f({ - name: "kendoUpload", - watch: { - enabled: e - } - }); - f({ - async: !0, - name: "kendoWindow", - events: { - open: { - writeTo: o, - value: !0 - }, - close: { - writeTo: o, - value: !1 - } - }, - watch: { - content: g, - title: "title", - isOpen: [h, s] - } - }); - f({ - name: "kendoChart", - watch: { - data: function(t) { - n.kendo.setDataSource(this, t) - } - } - }); - f({ - name: "kendoLinearGauge", - defaultOption: u, - watch: { - value: u, - gaugeArea: c("gaugeArea"), - pointer: c("pointer"), - scale: c("scale") - } - }); - f({ - name: "kendoRadialGauge", - defaultOption: u, - watch: { - value: u, - gaugeArea: c("gaugeArea"), - pointer: c("pointer"), - scale: c("scale") - } - }) -}); -Raphael = function() { - function n() { - var r; - if (n.is(arguments[0], et)) { - for (var i = arguments[0], f = rr[b](n, i.splice(0, 3 + n.is(i[0], nt))), e = f.set(), u = 0, o = i[t]; u < o; u++) r = i[u] || {}, ku.test(r.type) && e[a](f[r.type]().attr(r)); - return e - } - return rr[b](n, arguments) - } - - function y() {} - - function si(t) { - var u, i; - return n.vml ? (u = /^\s+|\s+$/g, si = ut(function(n) { - var f, t, i; - n = (n + r)[w](u, r); - try { - t = new st.ActiveXObject("htmlfile"); - t.write("<body>"); - t.close(); - f = t.body - } catch (e) { - f = st.createPopup().document.body - } - t = f.createTextRange(); - try { - return f.style.color = n, i = t.queryCommandValue("ForeColor"), i = (i & 255) << 16 | i & 65280 | (i & 16711680) >>> 16, "#" + ("000000" + i[d](16)).slice(-6) - } catch (o) { - return "none" - } - })) : (i = c.createElement("i"), i.title = "Raphaël Colour Picker", i.style.display = "none", c.body[o](i), si = ut(function(n) { - return i.style.color = n, c.defaultView.getComputedStyle(i, r).getPropertyValue("color") - })), si(t) - } - - function nf() { - return "hsb(" + [this.h, this.s, this.b] + ")" - } - - function tf() { - return this.hex - } - - function ut(n, r, u) { - function f() { - var c = Array[i].slice.call(arguments, 0), - e = c[tt]("►"), - o = f.cache = f.cache || {}, - h = f.count = f.count || []; - return o[s](e) ? u ? u(o[e]) : o[e] : (h[t] >= 1e3 && delete o[h.shift()], h[a](e), o[e] = n[b](r, c), u ? u(o[e]) : o[e]) - } - return f - } - - function ci(i) { - var f = [], - r, e, u, o; - for (n.is(i, et) && n.is(i && i[0], et) || (i = n.parsePathString(i)), r = 0, e = i[t]; r < e; r++) - for (f[r] = [], u = 0, o = i[r][t]; u < o; u++) f[r][u] = i[r][u]; - return f[d] = n._path2string, f - } - - function li(n, t, i, r) { - return [n, t, i, r, i, r] - } - - function vr(n, t, i, r, u, f) { - var e = 1 / 3, - o = 2 / 3; - return [e * n + o * i, e * t + o * r, e * u + o * i, e * f + o * r, u, f] - } - - function yr(n, i, r, u, f, o, s, h, c, l) { - var y = e.PI, - it = y * 120 / 180, - g = y / 180 * (+f || 0), - b = [], - a, nt = ut(function(n, t, i) { - var r = n * e.cos(i) - t * e.sin(i); - return n = n * e.sin(i) + t * e.cos(i), { - x: r, - y: n - } - }), - d, w, v; - if (l ? (v = l[0], a = l[1], o = l[2], w = l[3]) : (a = nt(n, i, -g), n = a.x, i = a.y, a = nt(h, c, -g), h = a.x, c = a.y, e.cos(y / 180 * f), e.sin(y / 180 * f), a = (n - h) / 2, v = (i - c) / 2, w = a * a / (r * r) + v * v / (u * u), w > 1 && (w = e.sqrt(w), r = w * r, u = w * u), w = r * r, d = u * u, w = (o == s ? -1 : 1) * e.sqrt(e.abs((w * d - w * v * v - d * a * a) / (w * v * v + d * a * a))), o = w * r * v / u + (n + h) / 2, w = w * -u * a / r + (i + c) / 2, v = e.asin(((i - w) / u).toFixed(7)), a = e.asin(((c - w) / u).toFixed(7)), v = n < o ? y - v : v, a = h < o ? y - a : a, v < 0 && (v = y * 2 + v), a < 0 && (a = y * 2 + a), s && v > a && (v -= y * 2), !s && a > v && (a -= y * 2)), y = a - v, e.abs(y) > it && (b = a, y = h, d = c, a = v + it * (s && a > v ? 1 : -1), h = o + r * e.cos(a), c = w + u * e.sin(a), b = yr(h, c, r, u, f, 0, s, y, d, [a, b, o, w])), y = a - v, f = e.cos(v), o = e.sin(v), s = e.cos(a), a = e.sin(a), y = e.tan(y / 4), r = 4 / 3 * r * y, y = 4 / 3 * u * y, u = [n, i], n = [n + r * o, i - y * f], i = [h + r * a, c - y * s], h = [h, c], n[0] = 2 * u[0] - n[0], n[1] = 2 * u[1] - n[1], l) return [n, i, h][k](b); - for (b = [n, i, h][k](b)[tt]()[p](","), l = [], h = 0, c = b[t]; h < c; h++) l[h] = h % 2 ? nt(b[h - 1], b[h], g).y : nt(b[h], b[h + 1], g).x; - return l - } - - function ii(n, t, i, r, u, f, e, o, s) { - var h = 1 - s; - return { - x: l(h, 3) * n + l(h, 2) * 3 * s * i + h * 3 * s * s * u + l(s, 3) * e, - y: l(h, 3) * t + l(h, 2) * 3 * s * r + h * 3 * s * s * f + l(s, 3) * o - } - } - - function wr(t, i, r, u) { - if (n.is(t, wt) || n.is(t, "object")) { - if (t = n.is(t, wt) ? c.getElementById(t) : t, t.tagName) return i == null ? { - container: t, - width: t.style.pixelWidth || t.offsetWidth, - height: t.style.pixelHeight || t.offsetHeight - } : { - container: t, - width: i, - height: r - } - } else return { - container: 1, - x: t, - y: i, - width: r, - height: u - } - } - - function nr(n, t) { - var r = this; - for (var i in t) - if (t[s](i) && !(i in n)) switch (typeof t[i]) { - case "function": - (function(t) { - n[i] = n === r ? t : function() { - return t[b](r, arguments) - } - })(t[i]); - break; - case "object": - n[i] = n[i] || {}; - nr.call(this, n[i], t[i]); - break; - default: - n[i] = t[i] - } - } - - function gt(n, t) { - n == t.top && (t.top = n.prev); - n == t.bottom && (t.bottom = n.next); - n.next && (n.next.prev = n.prev); - n.prev && (n.prev.next = n.next) - } - - function br(n, t) { - t.top !== n && (gt(n, t), n.next = null, n.prev = t.top, t.top.next = n, t.top = n) - } - - function kr(n, t) { - t.bottom !== n && (gt(n, t), n.next = t.bottom, n.prev = null, t.bottom.prev = n, t.bottom = n) - } - - function dr(n, t, i) { - gt(n, i); - t == i.top && (i.top = n); - t.next && (t.next.prev = n); - n.next = t.next; - n.prev = t; - t.next = n - } - - function gr(n, t, i) { - gt(n, i); - t == i.bottom && (i.bottom = n); - t.prev && (t.prev.next = n); - n.prev = t.prev; - t.prev = n; - n.next = t - } - - function nu(n) { - return function() { - throw new Error("Raphaël: you are calling to method “" + n + "” of removed object"); - } - } - - function cf() { - this.returnValue = !1 - } - - function lf() { - return this.originalEvent.preventDefault() - } - - function af() { - this.cancelBubble = !0 - } - - function vf() { - return this.originalEvent.stopPropagation() - } - - function vu() { - return this.x + g + this.y - } - - function fr(t, i) { - return function(r, u, f) { - r = ai(r); - for (var o, s, e, l, h = "", a = {}, c = 0, v = 0, y = r.length; v < y; v++) { - if (e = r[v], e[0] == "M") o = +e[1], s = +e[2]; - else { - if (l = yf(o, s, e[1], e[2], e[3], e[4], e[5], e[6]), c + l > u) { - if (i && !a.start) { - if (o = ur(o, s, e[1], e[2], e[3], e[4], e[5], e[6], u - c), h += ["C", o.start.x, o.start.y, o.m.x, o.m.y, o.x, o.y], f) return h; - a.start = h; - h = ["M", o.x, o.y + "C", o.n.x, o.n.y, o.end.x, o.end.y, e[5], e[6]][tt](); - c += l; - o = +e[5]; - s = +e[6]; - continue - } - if (!t && !i) return o = ur(o, s, e[1], e[2], e[3], e[4], e[5], e[6], u - c), { - x: o.x, - y: o.y, - alpha: o.alpha - } - } - c += l; - o = +e[5]; - s = +e[6] - } - h += e - } - return a.end = h, o = t ? c : i ? a : n.findDotsAtSegment(o, s, e[1], e[2], e[3], e[4], e[5], e[6], 1), o.alpha && (o = { - x: o.x, - y: o.y, - alpha: o.alpha - }), o - } - } - - function pu() { - var et = +new Date, - p, l, i, ut, k, ft; - for (p in rt) - if (p != "length" && rt[s](p)) - if (l = rt[p], l.stop || l.el.removed) delete rt[p], rt[t]--; - else { - var w = et - l.start, - a = l.ms, - u = l.easing, - o = l.from, - f = l.diff, - h = l.to, - b = l.t, - d = l.prev || 0, - c = l.el, - y = l.callback, - it = {}, - e; - if (w < a) { - y = n.easing_formulas[u] ? n.easing_formulas[u](w / a) : w / a; - for (i in o) - if (o[s](i)) { - switch (di[i]) { - case "along": - e = y * a * f[i]; - h.back && (e = h.len - e); - u = vi(h[i], e); - c.translate(f.sx - f.x || 0, f.sy - f.y || 0); - f.x = u.x; - f.y = u.y; - c.translate(u.x - f.sx, u.y - f.sy); - h.rot && c.rotate(f.r + u.alpha, u.x, u.y); - break; - case nt: - e = +o[i] + y * a * f[i]; - break; - case "colour": - e = "rgb(" + [or(v(o[i].r + y * a * f[i].r)), or(v(o[i].g + y * a * f[i].g)), or(v(o[i].b + y * a * f[i].b))][tt](",") + ")"; - break; - case "path": - for (e = [], u = 0, ut = o[i][t]; u < ut; u++) { - for (e[u] = [o[i][u][0]], k = 1, ft = o[i][u][t]; k < ft; k++) e[u][k] = +o[i][u][k] + y * a * f[i][u][k]; - e[u] = e[u][tt](g) - } - e = e[tt](g); - break; - case "csv": - switch (i) { - case "translation": - e = f[i][0] * (w - d); - u = f[i][1] * (w - d); - b.x += e; - b.y += u; - e = e + g + u; - break; - case "rotation": - e = +o[i][0] + y * a * f[i][0]; - o[i][1] && (e += "," + o[i][1] + "," + o[i][2]); - break; - case "scale": - e = [+o[i][0] + y * a * f[i][0], +o[i][1] + y * a * f[i][1], 2 in h[i] ? h[i][2] : r, 3 in h[i] ? h[i][3] : r][tt](g); - break; - case "clip-rect": - for (e = [], u = 4; u--;) e[u] = +o[i][u] + y * a * f[i][u] - } - } - it[i] = e - } - c.attr(it); - c._run && c._run.call(c) - } else h.along && (u = vi(h.along, h.len * !h.back), c.translate(f.sx - (f.x || 0) + u.x - f.sx, f.sy - (f.y || 0) + u.y - f.sy), h.rot && c.rotate(f.r + u.alpha, u.x, u.y)), (b.x || b.y) && c.translate(-b.x, -b.y), h.scale && (h.scale += r), c.attr(h), delete rt[p], rt[t]--, c.in_animation = null, n.is(y, "function") && y.call(c); - l.prev = w - } - n.svg && c && c.paper && c.paper.safari(); - rt[t] && st.setTimeout(pu) - } - - function or(n) { - return ht(lt(n, 255), 0) - } - - function yi(n, t) { - if (n == null) return { - x: this._.tx, - y: this._.ty, - toString: vu - }; - this._.tx += +n; - this._.ty += +t; - switch (this.type) { - case "circle": - case "ellipse": - this.attr({ - cx: +n + this.attrs.cx, - cy: +t + this.attrs.cy - }); - break; - case "rect": - case "image": - case "text": - this.attr({ - x: +n + this.attrs.x, - y: +t + this.attrs.y - }); - break; - case "path": - var i = gi(this.attrs.path); - i[0][1] += +n; - i[0][2] += +t; - this.attr({ - path: i - }) - } - return this - } - - function wu(t) { - return function(i, r, f, e) { - var o = { - back: t - }; - return n.is(f, "function") ? e = f : o.rot = f, i && i.constructor == u && (i = i.attrs.path), i && (o.along = i), this.animate(o, r, e) - } - } - - function ct(n) { - if (this.items = [], this[t] = 0, this.type = "set", n) - for (var i = 0, r = n[t]; i < r; i++) n[i] && (n[i].constructor == u || n[i].constructor == ct) && (this[this.items[t]] = this.items[this.items[t]] = n[i], this[t]++) - } - var bt, lr, ar, ti, gi, dt, tr, f, cu, it, au, ur, rt, pi, bu; - n.version = "1.4.3"; - var ft = /[, ]+/, - ku = /^(circle|rect|path|ellipse|text|image)$/, - i = "prototype", - s = "hasOwnProperty", - c = document, - st = window, - sr = { - was: Object[i][s].call(st, "Raphael"), - is: st.Raphael - }; - var o = "appendChild", - b = "apply", - k = "concat", - wi = "createTouch" in c, - r = "", - g = " ", - p = "split", - hr = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend" [p](g), - bi = { - mousedown: "touchstart", - mousemove: "touchmove", - mouseup: "touchend" - }, - tt = "join", - t = "length", - yt = String[i].toLowerCase, - e = Math, - ht = e.max, - lt = e.min, - nt = "number", - wt = "string", - et = "array", - d = "toString", - at = "fill", - du = Object[i][d], - l = e.pow, - a = "push", - kt = /^(?=[\da-f]$)/, - cr = /^url\(['"]?([^\)]+?)['"]?\)$/i, - gu = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+(?:\s*,\s*[\d\.]+)?)\s*\)|rgba?\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%(?:\s*,\s*[\d\.]+%))\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i, - v = e.round, - ot = "setAttribute", - h = parseFloat, - pt = parseInt, - ki = " progid:DXImageTransform.Microsoft", - ei = String[i].toUpperCase, - oi = { - blur: 0, - "clip-rect": "0 0 1e9 1e9", - cursor: "default", - cx: 0, - cy: 0, - fill: "#fff", - "fill-opacity": 1, - font: '10px "Arial"', - "font-family": '"Arial"', - "font-size": "10", - "font-style": "normal", - "font-weight": 400, - gradient: 0, - height: 0, - href: "http://raphaeljs.com/", - opacity: 1, - path: "M0,0", - r: 0, - rotation: 0, - rx: 0, - ry: 0, - scale: "1 1", - src: "", - stroke: "#000", - "stroke-dasharray": "", - "stroke-linecap": "butt", - "stroke-linejoin": "butt", - "stroke-miterlimit": 0, - "stroke-opacity": 1, - "stroke-width": 1, - target: "_blank", - "text-anchor": "middle", - title: "Raphael", - translation: "0 0", - width: 0, - x: 0, - y: 0 - }, - di = { - along: "along", - blur: nt, - "clip-rect": "csv", - cx: nt, - cy: nt, - fill: "colour", - "fill-opacity": nt, - "font-size": nt, - height: nt, - opacity: nt, - path: "path", - r: nt, - rotation: "csv", - rx: nt, - ry: nt, - scale: "csv", - stroke: "colour", - "stroke-opacity": nt, - "stroke-width": nt, - translation: "csv", - width: nt, - x: nt, - y: nt - }, - w = "replace"; - if (n.type = st.SVGAngle || c.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML", n.type == "VML") { - if (bt = c.createElement("div"), bt.innerHTML = "<!--[if vml]><br><br><![endif]-->", bt.childNodes[t] != 2) return n.type = null; - bt = null - } - n.svg = !(n.vml = n.type == "VML"); - y[i] = n[i]; - n._id = 0; - n._oid = 0; - n.fn = {}; - n.is = function(n, t) { - return t = yt.call(t), t == "object" && n === Object(n) || t == "undefined" && typeof n == t || t == "null" && n == null || yt.call(du.call(n).slice(8, -1)) == t - }; - n.setWindow = function(n) { - st = n; - c = st.document - }; - n.hsb2rgb = ut(function(t, i, r) { - var u; - if (n.is(t, "object") && "h" in t && "s" in t && "b" in t && (r = t.b, i = t.s, t = t.h), r == 0) return { - r: 0, - g: 0, - b: 0, - hex: "#000" - }; - (t > 1 || i > 1 || r > 1) && (t /= 255, i /= 255, r /= 255); - u = ~~(t * 6); - t = t * 6 - u; - var f = r * (1 - i), - o = r * (1 - i * t), - e = r * (1 - i * (1 - t)); - return t = [r, o, f, f, e, r, r][u], i = [e, r, r, o, f, f, e][u], u = [f, f, e, r, r, o, f][u], t *= 255, i *= 255, u *= 255, r = { - r: t, - g: i, - b: u, - toString: tf - }, t = (~~t)[d](16), i = (~~i)[d](16), u = (~~u)[d](16), t = t[w](kt, "0"), i = i[w](kt, "0"), u = u[w](kt, "0"), r.hex = "#" + t + i + u, r - }, n); - n.rgb2hsb = ut(function(t, i, r) { - var f, u, e, o; - return (n.is(t, "object") && "r" in t && "g" in t && "b" in t && (r = t.b, i = t.g, t = t.r), n.is(t, wt) && (f = n.getRGB(t), t = f.r, i = f.g, r = f.b), (t > 1 || i > 1 || r > 1) && (t /= 255, i /= 255, r /= 255), u = ht(t, i, r), e = lt(t, i, r), f = u, e == u) ? { - h: 0, - s: 0, - b: u - } : (o = u - e, e = o / u, t = t == u ? (i - r) / o : i == u ? 2 + (r - t) / o : 4 + (t - i) / o, t /= 6, t < 0 && t++, t > 1 && t--, { - h: t, - s: e, - b: f, - toString: nf - }) - }, n); - var rf = /,?([achlmqrstvxz]),?/gi, - hi = /\s*,\s*/, - uf = { - hs: 1, - rg: 1 - }; - n._path2string = function() { - return this.join(",")[w](rf, "$1") - }; - n.getRGB = ut(function(t) { - if (!t || (t += r).indexOf("-") + 1) return { - r: -1, - g: -1, - b: -1, - hex: "none", - error: 1 - }; - if (t == "none") return { - r: -1, - g: -1, - b: -1, - hex: "none" - }; - uf[s](t.substring(0, 2)) || t.charAt() == "#" || (t = si(t)); - var i, u, f, o, e; - return (t = t.match(gu)) ? (t[2] && (f = pt(t[2].substring(5), 16), u = pt(t[2].substring(3, 5), 16), i = pt(t[2].substring(1, 3), 16)), t[3] && (f = pt((e = t[3].charAt(3)) + e, 16), u = pt((e = t[3].charAt(2)) + e, 16), i = pt((e = t[3].charAt(1)) + e, 16)), t[4] && (t = t[4][p](hi), i = h(t[0]), u = h(t[1]), f = h(t[2]), o = h(t[3])), t[5] && (t = t[5][p](hi), i = h(t[0]) * 2.55, u = h(t[1]) * 2.55, f = h(t[2]) * 2.55, o = h(t[3])), t[6]) ? (t = t[6][p](hi), i = h(t[0]), u = h(t[1]), f = h(t[2]), n.hsb2rgb(i, u, f)) : t[7] ? (t = t[7][p](hi), i = h(t[0]) * 2.55, u = h(t[1]) * 2.55, f = h(t[2]) * 2.55, n.hsb2rgb(i, u, f)) : (t = { - r: i, - g: u, - b: f - }, i = (~~i)[d](16), u = (~~u)[d](16), f = (~~f)[d](16), i = i[w](kt, "0"), u = u[w](kt, "0"), f = f[w](kt, "0"), t.hex = "#" + i + u + f, isFinite(h(o)) && (t.o = o), t) : { - r: -1, - g: -1, - b: -1, - hex: "none", - error: 1 - } - }, n); - n.getColor = function(n) { - n = this.getColor.start = this.getColor.start || { - h: 0, - s: 1, - b: n || .75 - }; - var t = this.hsb2rgb(n.h, n.s, n.b); - return n.h += .075, n.h > 1 && (n.h = 0, n.s -= .2, n.s <= 0 && (this.getColor.start = { - h: 0, - s: 1, - b: n.b - })), t.hex - }; - n.getColor.reset = function() { - delete this.start - }; - lr = /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig; - ar = /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig; - n.parsePathString = ut(function(i) { - if (!i) return null; - var f = { - a: 7, - c: 6, - h: 1, - l: 2, - m: 2, - q: 4, - s: 4, - t: 2, - v: 1, - z: 0 - }, - u = []; - return n.is(i, et) && n.is(i[0], et) && (u = ci(i)), u[t] || (i + r)[w](lr, function(n, i, r) { - var e = []; - for (n = yt.call(i), r[w](ar, function(n, t) { - t && e[a](+t) - }), n == "m" && e[t] > 2 && (u[a]([i][k](e.splice(0, 2))), n = "l", i = i == "m" ? "l" : "L"); e[t] >= f[n];) - if (u[a]([i][k](e.splice(0, f[n]))), !f[n]) break - }), u[d] = n._path2string, u - }); - n.findDotsAtSegment = function(n, t, i, r, u, f, o, s, h) { - var c = 1 - h, - w = l(c, 3) * n + l(c, 2) * 3 * h * i + c * 3 * h * h * u + l(h, 3) * o; - c = l(c, 3) * t + l(c, 2) * 3 * h * r + c * 3 * h * h * f + l(h, 3) * s; - var a = n + 2 * h * (i - n) + h * h * (u - 2 * i + n), - v = t + 2 * h * (r - t) + h * h * (f - 2 * r + t), - y = i + 2 * h * (u - i) + h * h * (o - 2 * u + i), - p = r + 2 * h * (f - r) + h * h * (s - 2 * f + r); - return n = (1 - h) * n + h * i, t = (1 - h) * t + h * r, u = (1 - h) * u + h * o, f = (1 - h) * f + h * s, s = 90 - e.atan((a - y) / (v - p)) * 180 / e.PI, (a > y || v < p) && (s += 180), { - x: w, - y: c, - m: { - x: a, - y: v - }, - n: { - x: y, - y: p - }, - start: { - x: n, - y: t - }, - end: { - x: u, - y: f - }, - alpha: s - } - }; - ti = ut(function(n) { - if (!n) return { - x: 0, - y: 0, - width: 0, - height: 0 - }; - n = ai(n); - for (var r = 0, e = 0, u = [], f = [], i, o = 0, s = n[t]; o < s; o++) i = n[o], i[0] == "M" ? (r = i[1], e = i[2], u[a](r), f[a](e)) : (r = ff(r, e, i[1], i[2], i[3], i[4], i[5], i[6]), u = u[k](r.min.x, r.max.x), f = f[k](r.min.y, r.max.y), r = i[5], e = i[6]); - return n = lt[b](0, u), i = lt[b](0, f), { - x: n, - y: i, - width: ht[b](0, u) - n, - height: ht[b](0, f) - i - } - }); - gi = ut(function(i) { - var v, u, r, h, y; - n.is(i, et) && n.is(i && i[0], et) || (i = n.parsePathString(i)); - var e = [], - s = 0, - o = 0, - c = 0, - l = 0, - f = 0; - for (i[0][0] == "M" && (s = i[0][1], o = i[0][2], c = s, l = o, f++, e[a](["M", s, o])), f = f, v = i[t]; f < v; f++) { - if (u = e[f] = [], r = i[f], r[0] != yt.call(r[0])) { - u[0] = yt.call(r[0]); - switch (u[0]) { - case "a": - u[1] = r[1]; - u[2] = r[2]; - u[3] = r[3]; - u[4] = r[4]; - u[5] = r[5]; - u[6] = +(r[6] - s).toFixed(3); - u[7] = +(r[7] - o).toFixed(3); - break; - case "v": - u[1] = +(r[1] - o).toFixed(3); - break; - case "m": - c = r[1]; - l = r[2]; - default: - for (h = 1, y = r[t]; h < y; h++) u[h] = +(r[h] - (h % 2 ? s : o)).toFixed(3) - } - } else - for (e[f] = [], r[0] == "m" && (c = r[1] + s, l = r[2] + o), u = 0, h = r[t]; u < h; u++) e[f][u] = r[u]; - r = e[f][t]; - switch (e[f][0]) { - case "z": - s = c; - o = l; - break; - case "h": - s += +e[f][r - 1]; - break; - case "v": - o += +e[f][r - 1]; - break; - default: - s += +e[f][r - 2]; - o += +e[f][r - 1] - } - } - return e[d] = n._path2string, e - }, 0, ci); - dt = ut(function(i) { - var v, u, r, e, c; - n.is(i, et) && n.is(i && i[0], et) || (i = n.parsePathString(i)); - var h = [], - o = 0, - s = 0, - l = 0, - a = 0, - f = 0; - for (i[0][0] == "M" && (o = +i[0][1], s = +i[0][2], l = o, a = s, f++, h[0] = ["M", o, s]), f = f, v = i[t]; f < v; f++) { - if (u = h[f] = [], r = i[f], r[0] != ei.call(r[0])) { - u[0] = ei.call(r[0]); - switch (u[0]) { - case "A": - u[1] = r[1]; - u[2] = r[2]; - u[3] = r[3]; - u[4] = r[4]; - u[5] = r[5]; - u[6] = +(r[6] + o); - u[7] = +(r[7] + s); - break; - case "V": - u[1] = +r[1] + s; - break; - case "H": - u[1] = +r[1] + o; - break; - case "M": - l = +r[1] + o; - a = +r[2] + s; - default: - for (e = 1, c = r[t]; e < c; e++) u[e] = +r[e] + (e % 2 ? o : s) - } - } else - for (e = 0, c = r[t]; e < c; e++) h[f][e] = r[e]; - switch (u[0]) { - case "Z": - o = l; - s = a; - break; - case "H": - o = u[1]; - break; - case "V": - s = u[1]; - break; - default: - o = h[f][h[f][t] - 2]; - s = h[f][h[f][t] - 1] - } - } - return h[d] = n._path2string, h - }, null, ci); - var ff = ut(function(n, t, i, r, u, f, o, s) { - var c = u - 2 * i + n - (o - 2 * u + i), - l = 2 * (i - n) - 2 * (u - i), - p = n - i, - h = (-l + e.sqrt(l * l - 4 * c * p)) / 2 / c, - v, y; - return c = (-l - e.sqrt(l * l - 4 * c * p)) / 2 / c, v = [t, s], y = [n, o], e.abs(h) > 1e12 && (h = .5), e.abs(c) > 1e12 && (c = .5), h > 0 && h < 1 && (h = ii(n, t, i, r, u, f, o, s, h), y[a](h.x), v[a](h.y)), c > 0 && c < 1 && (h = ii(n, t, i, r, u, f, o, s, c), y[a](h.x), v[a](h.y)), c = f - 2 * r + t - (s - 2 * f + r), l = 2 * (r - t) - 2 * (f - r), p = t - r, h = (-l + e.sqrt(l * l - 4 * c * p)) / 2 / c, c = (-l - e.sqrt(l * l - 4 * c * p)) / 2 / c, e.abs(h) > 1e12 && (h = .5), e.abs(c) > 1e12 && (c = .5), h > 0 && h < 1 && (h = ii(n, t, i, r, u, f, o, s, h), y[a](h.x), v[a](h.y)), c > 0 && c < 1 && (h = ii(n, t, i, r, u, f, o, s, c), y[a](h.x), v[a](h.y)), { - min: { - x: lt[b](0, y), - y: lt[b](0, v) - }, - max: { - x: ht[b](0, y), - y: ht[b](0, v) - } - } - }), - ai = ut(function(n, i) { - function a(n, t) { - var i; - if (!n) return ["C", t.x, t.y, t.x, t.y, t.x, t.y]; - n[0] in { - T: 1, - Q: 1 - } || (t.qx = t.qy = null); - switch (n[0]) { - case "M": - t.X = n[1]; - t.Y = n[2]; - break; - case "A": - n = ["C"][k](yr[b](0, [t.x, t.y][k](n.slice(1)))); - break; - case "S": - i = t.x + (t.x - (t.bx || t.x)); - t = t.y + (t.y - (t.by || t.y)); - n = ["C", i, t][k](n.slice(1)); - break; - case "T": - t.qx = t.x + (t.x - (t.qx || t.x)); - t.qy = t.y + (t.y - (t.qy || t.y)); - n = ["C"][k](vr(t.x, t.y, t.qx, t.qy, n[1], n[2])); - break; - case "Q": - t.qx = n[1]; - t.qy = n[2]; - n = ["C"][k](vr(t.x, t.y, n[1], n[2], n[3], n[4])); - break; - case "L": - n = ["C"][k](li(t.x, t.y, n[1], n[2])); - break; - case "H": - n = ["C"][k](li(t.x, t.y, n[1], t.y)); - break; - case "V": - n = ["C"][k](li(t.x, t.y, t.x, n[1])); - break; - case "Z": - n = ["C"][k](li(t.x, t.y, t.X, t.Y)) - } - return n - } - - function v(n, i) { - if (n[i][t] > 7) { - n[i].shift(); - for (var u = n[i]; u[t];) n.splice(i++, 0, ["C"][k](u.splice(0, 6))); - n.splice(i, 1); - s = ht(f[t], r && r[t] || 0) - } - } - - function y(n, i, u, e, o) { - n && i && n[o][0] == "M" && i[o][0] != "M" && (i.splice(o, 0, ["M", e.x, e.y]), u.bx = 0, u.by = 0, u.x = n[o][1], u.y = n[o][2], s = ht(f[t], r && r[t] || 0)) - } - var f = dt(n), - r = i && dt(i), - u, s; - for (n = { - x: 0, - y: 0, - bx: 0, - by: 0, - X: 0, - Y: 0, - qx: null, - qy: null - }, i = { - x: 0, - y: 0, - bx: 0, - by: 0, - X: 0, - Y: 0, - qx: null, - qy: null - }, u = 0, s = ht(f[t], r && r[t] || 0); u < s; u++) { - f[u] = a(f[u], n); - v(f, u); - r && (r[u] = a(r[u], i)); - r && v(r, u); - y(f, r, n, i, u); - y(r, f, i, n, u); - var e = f[u], - o = r && r[u], - c = e[t], - l = r && o[t]; - n.x = e[c - 2]; - n.y = e[c - 1]; - n.bx = h(e[c - 4]) || n.x; - n.by = h(e[c - 3]) || n.y; - i.bx = r && (h(o[l - 4]) || i.x); - i.by = r && (h(o[l - 3]) || i.y); - i.x = r && o[l - 2]; - i.y = r && o[l - 1] - } - return r ? [f, r] : f - }, null, ci), - pr = ut(function(i) { - for (var r, f, e = [], u = 0, o = i[t]; u < o; u++) { - if (r = {}, f = i[u].match(/^([^:]*):?([\d\.]*)/), r.color = n.getRGB(f[1]), r.color.error) return null; - r.color = r.color.hex; - f[2] && (r.offset = f[2] + "%"); - e[a](r) - } - for (u = 1, o = e[t] - 1; u < o; u++) - if (!e[u].offset) { - for (i = h(e[u - 1].offset || 0), f = 0, r = u + 1; r < o; r++) - if (e[r].offset) { - f = e[r].offset; - break - } - for (f || (f = 100, r = o), f = h(f), f = (f - i) / (r - u + 1); u < r; u++) i += f, e[u].offset = i + "%" - } - return e - }); - if (tr = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/, n.svg) { - y[i].svgns = "http://www.w3.org/2000/svg"; - y[i].xlink = "http://www.w3.org/1999/xlink"; - v = function(n) { - return +n + (~~n === n) * .5 - }; - f = function(n, t) { - if (t) - for (var u in t) t[s](u) && n[ot](u, t[u] + r); - else return n = c.createElementNS(y[i].svgns, n), n.style.webkitTapHighlightColor = "rgba(0,0,0,0)", n - }; - n[d] = function() { - return "Your browser supports SVG.\nYou are running Raphaël " + this.version - }; - var tu = function(n, t) { - var i = f("path"); - return t.canvas && t.canvas[o](i), t = new u(i, t), t.type = "path", vt(t, { - fill: "none", - stroke: "#000", - path: n - }), t - }, - ri = function(i, u, s) { - var b = "linear", - k = .5, - y = .5, - g = i.style, - a, v, nt; - if (u = (u + r)[w](tr, function(n, t, i) { - return b = "radial", t && i && (k = h(t), y = h(i), n = (y > .5) * 2 - 1, l(k - .5, 2) + l(y - .5, 2) > .25 && (y = e.sqrt(.25 - l(k - .5, 2)) * n + .5) && y != .5 && (y = y.toFixed(5) - 1e-5 * n)), r - }), u = u[p](/\s*\-\s*/), b == "linear") { - if (a = u.shift(), a = -h(a), isNaN(a)) return null; - a = [0, 0, e.cos(a * e.PI / 180), e.sin(a * e.PI / 180)]; - v = 1 / (ht(e.abs(a[2]), e.abs(a[3])) || 1); - a[2] *= v; - a[3] *= v; - a[2] < 0 && (a[0] = -a[2], a[2] = 0); - a[3] < 0 && (a[1] = -a[3], a[3] = 0) - } - if (u = pr(u), !u) return null; - for (v = i.getAttribute(at), (v = v.match(/^url\(#(.*)\)$/)) && s.defs.removeChild(c.getElementById(v[1])), v = f(b + "Gradient"), v.id = "r" + (n._id++)[d](36), f(v, b == "radial" ? { - fx: k, - fy: y - } : { - x1: a[0], - y1: a[1], - x2: a[2], - y2: a[3] - }), s.defs[o](v), s = 0, a = u[t]; s < a; s++) nt = f("stop"), f(nt, { - offset: u[s].offset ? u[s].offset : s ? "100%" : "0%", - "stop-color": u[s].color || "#fff" - }), v[o](nt); - return f(i, { - fill: "url(#" + v.id + ")", - opacity: 1, - "fill-opacity": 1 - }), g.fill = r, g.opacity = 1, g.fillOpacity = 1 - }, - ir = function(t) { - var i = t.getBBox(); - f(t.pattern, { - patternTransform: n.format("translate({0},{1})", i.x, i.y) - }) - }, - vt = function(i, u) { - function et(n, i) { - var e, o, r; - if (i = st[yt.call(i)]) { - for (e = n.attrs["stroke-width"] || "1", n = { - round: e, - square: e, - butt: 0 - }[n.attrs["stroke-linecap"] || u["stroke-linecap"]] || 0, o = [], r = i[t]; r--;) o[r] = i[r] * e + (r % 2 ? 1 : -1) * n; - f(l, { - "stroke-dasharray": o[tt](",") - }) - } - } - var st = { - "": [0], - none: [0], - "-": [3, 1], - ".": [1, 1], - "-.": [3, 1, 1, 1], - "-..": [3, 1, 1, 1, 1, 1], - ". ": [1, 3], - "- ": [4, 3], - "--": [8, 3], - "- .": [4, 3, 1, 3], - "--.": [8, 3, 1, 3], - "--..": [8, 3, 1, 3, 1, 3] - }, - l = i.node, - b = i.attrs, - rt = i.rotate(), - k, y, e, a, it, nt, ut; - u[s]("rotation") && (rt = u.rotation); - k = (rt + r)[p](ft); - k.length - 1 ? (k[1] = +k[1], k[2] = +k[2]) : k = null; - h(rt) && i.rotate(0, !0); - for (y in u) - if (u[s](y) && oi[s](y)) { - e = u[y]; - b[y] = e; - switch (y) { - case "blur": - i.blur(e); - break; - case "rotation": - i.rotate(e, !0); - break; - case "href": - case "title": - case "target": - a = l.parentNode; - yt.call(a.tagName) != "a" && (it = f("a"), a.insertBefore(it, l), it[o](l), a = it); - a.setAttributeNS(i.paper.xlink, y, e); - break; - case "cursor": - l.style.cursor = e; - break; - case "clip-rect": - a = (e + r)[p](ft); - a[t] == 4 && (i.clip && i.clip.parentNode.parentNode.removeChild(i.clip.parentNode), nt = f("clipPath"), it = f("rect"), nt.id = "r" + (n._id++)[d](36), f(it, { - x: a[0], - y: a[1], - width: a[2], - height: a[3] - }), nt[o](it), i.paper.defs[o](nt), f(l, { - "clip-path": "url(#" + nt.id + ")" - }), i.clip = it); - e || ((e = c.getElementById(l.getAttribute("clip-path")[w](/(^url\(#|\)$)/g, r))) && e.parentNode.removeChild(e), f(l, { - "clip-path": r - }), delete i.clip); - break; - case "path": - i.type == "path" && f(l, { - d: e ? b.path = dt(e) : "M0,0" - }); - break; - case "width": - if (l[ot](y, e), b.fx) y = "x", e = b.x; - else break; - case "x": - b.fx && (e = -b.x - (b.width || 0)); - case "rx": - if (y == "rx" && i.type == "rect") break; - case "cx": - k && (y == "x" || y == "cx") && (k[1] += e - b[y]); - l[ot](y, v(e)); - i.pattern && ir(i); - break; - case "height": - if (l[ot](y, e), b.fy) y = "y", e = b.y; - else break; - case "y": - b.fy && (e = -b.y - (b.height || 0)); - case "ry": - if (y == "ry" && i.type == "rect") break; - case "cy": - k && (y == "y" || y == "cy") && (k[2] += e - b[y]); - l[ot](y, v(e)); - i.pattern && ir(i); - break; - case "r": - i.type == "rect" ? f(l, { - rx: e, - ry: e - }) : l[ot](y, e); - break; - case "src": - i.type == "image" && l.setAttributeNS(i.paper.xlink, "href", e); - break; - case "stroke-width": - l.style.strokeWidth = e; - l[ot](y, e); - b["stroke-dasharray"] && et(i, b["stroke-dasharray"]); - break; - case "stroke-dasharray": - et(i, e); - break; - case "translation": - e = (e + r)[p](ft); - e[0] = +e[0] || 0; - e[1] = +e[1] || 0; - k && (k[1] += e[0], k[2] += e[1]); - yi.call(i, e[0], e[1]); - break; - case "scale": - e = (e + r)[p](ft); - i.scale(+e[0] || 1, +e[1] || +e[0] || 1, isNaN(h(e[2])) ? null : +e[2], isNaN(h(e[3])) ? null : +e[3]); - break; - case at: - if (a = (e + r).match(cr)) { - nt = f("pattern"); - ut = f("image"); - nt.id = "r" + (n._id++)[d](36); - f(nt, { - x: 0, - y: 0, - patternUnits: "userSpaceOnUse", - height: 1, - width: 1 - }); - f(ut, { - x: 0, - y: 0 - }); - ut.setAttributeNS(i.paper.xlink, "href", a[1]); - nt[o](ut); - e = c.createElement("img"); - e.style.cssText = "position:absolute;left:-9999em;top-9999em"; - e.onload = function() { - f(nt, { - width: this.offsetWidth, - height: this.offsetHeight - }); - f(ut, { - width: this.offsetWidth, - height: this.offsetHeight - }); - c.body.removeChild(this); - i.paper.safari() - }; - c.body[o](e); - e.src = a[1]; - i.paper.defs[o](nt); - l.style.fill = "url(#" + nt.id + ")"; - f(l, { - fill: "url(#" + nt.id + ")" - }); - i.pattern = nt; - i.pattern && ir(i); - break - } - if (a = n.getRGB(e), a.error) { - if (({ - circle: 1, - ellipse: 1 - }[s](i.type) || (e + r).charAt() != "r") && ri(l, e, i.paper)) { - b.gradient = e; - b.fill = "none"; - break - } - } else delete u.gradient, delete b.gradient, !n.is(b.opacity, "undefined") && n.is(u.opacity, "undefined") && f(l, { - opacity: b.opacity - }), !n.is(b["fill-opacity"], "undefined") && n.is(u["fill-opacity"], "undefined") && f(l, { - "fill-opacity": b["fill-opacity"] - }); - a[s]("o") && f(l, { - "fill-opacity": a.o / 100 - }); - case "stroke": - a = n.getRGB(e); - l[ot](y, a.hex); - y == "stroke" && a[s]("o") && f(l, { - "stroke-opacity": a.o / 100 - }); - break; - case "gradient": - ({ - circle: 1, - ellipse: 1 - }[s](i.type) || (e + r).charAt() != "r") && ri(l, e, i.paper); - break; - case "opacity": - case "fill-opacity": - if (b.gradient) { - (a = c.getElementById(l.getAttribute(at)[w](/^url\(#|\)$/g, r))) && (a = a.getElementsByTagName("stop"), a[a[t] - 1][ot]("stop-opacity", e)); - break - } - default: - y == "font-size" && (e = pt(e, 10) + "px"); - a = y[w](/(\-.)/g, function(n) { - return ei.call(n.substring(1)) - }); - l.style[a] = e; - l[ot](y, e) - } - } - ef(i, u); - k ? i.rotate(k.join(g)) : h(rt) && i.rotate(rt, !0) - }, - iu = 1.2, - ef = function(n, i) { - var u, l, a; - if (!(n.type != "text" || !(i[s]("text") || i[s]("font") || i[s]("font-size") || i[s]("x") || i[s]("y")))) { - var h = n.attrs, - e = n.node, - v = e.firstChild ? pt(c.defaultView.getComputedStyle(e.firstChild, r).getPropertyValue("font-size"), 10) : 10; - if (i[s]("text")) { - for (h.text = i.text; e.firstChild;) e.removeChild(e.firstChild); - for (i = (i.text + r)[p]("\n"), u = 0, l = i[t]; u < l; u++) i[u] && (a = f("tspan"), u && f(a, { - dy: v * iu, - x: h.x - }), a[o](c.createTextNode(i[u])), e[o](a)) - } else - for (i = e.getElementsByTagName("tspan"), u = 0, l = i[t]; u < l; u++) u && f(i[u], { - dy: v * iu, - x: h.x - }); - f(e, { - y: h.y - }); - n = n.getBBox(); - (n = h.y - (n.y + n.height / 2)) && isFinite(n) && f(e, { - y: h.y + n - }) - } - }, - u = function(t, i) { - this[0] = t; - this.id = n._oid++; - this.node = t; - t.raphael = this; - this.paper = i; - this.attrs = this.attrs || {}; - this.transformations = []; - this._ = { - tx: 0, - ty: 0, - rt: { - deg: 0, - cx: 0, - cy: 0 - }, - sx: 1, - sy: 1 - }; - i.bottom || (i.bottom = this); - (this.prev = i.top) && (i.top.next = this); - i.top = this; - this.next = null - }; - u[i].rotate = function(i, u, e) { - if (this.removed) return this; - if (i == null) return this._.rt.cx ? [this._.rt.deg, this._.rt.cx, this._.rt.cy][tt](g) : this._.rt.deg; - var o = this.getBBox(); - return i = (i + r)[p](ft), i[t] - 1 && (u = h(i[1]), e = h(i[2])), i = h(i[0]), u != null ? this._.rt.deg = i : this._.rt.deg += i, e == null && (u = null), this._.rt.cx = u, this._.rt.cy = e, u = u == null ? o.x + o.width / 2 : u, e = e == null ? o.y + o.height / 2 : e, this._.rt.deg ? (this.transformations[0] = n.format("rotate({0} {1} {2})", this._.rt.deg, u, e), this.clip && f(this.clip, { - transform: n.format("rotate({0} {1} {2})", -this._.rt.deg, u, e) - })) : (this.transformations[0] = r, this.clip && f(this.clip, { - transform: r - })), f(this.node, { - transform: this.transformations[tt](g) - }), this - }; - u[i].hide = function() { - return this.removed || (this.node.style.display = "none"), this - }; - u[i].show = function() { - return this.removed || (this.node.style.display = ""), this - }; - u[i].remove = function() { - if (!this.removed) { - gt(this, this.paper); - this.node.parentNode.removeChild(this.node); - for (var n in this) delete this[n]; - this.removed = !0 - } - }; - u[i].getBBox = function() { - var r, n, i, u, t; - if (this.removed) return this; - if (this.type == "path") return ti(this.attrs.path); - this.node.style.display == "none" && (this.show(), r = !0); - n = {}; - try { - n = this.node.getBBox() - } catch (f) {} finally { - n = n || {} - } - if (this.type == "text") - for (n = { - x: n.x, - y: Infinity, - width: 0, - height: 0 - }, i = 0, u = this.node.getNumberOfChars(); i < u; i++) t = this.node.getExtentOfChar(i), t.y < n.y && (n.y = t.y), t.y + t.height - n.y > n.height && (n.height = t.y + t.height - n.y), t.x + t.width - n.x > n.width && (n.width = t.x + t.width - n.x); - return r && this.hide(), n - }; - u[i].attr = function(t, i) { - var r, u; - if (this.removed) return this; - if (t == null) { - t = {}; - for (r in this.attrs) this.attrs[s](r) && (t[r] = this.attrs[r]); - return this._.rt.deg && (t.rotation = this.rotate()), (this._.sx != 1 || this._.sy != 1) && (t.scale = this.scale()), t.gradient && t.fill == "none" && (t.fill = t.gradient) && delete t.gradient, t - } - if (i == null && n.is(t, wt)) return t == "translation" ? yi.call(this) : t == "rotation" ? this.rotate() : t == "scale" ? this.scale() : t == at && this.attrs.fill == "none" && this.attrs.gradient ? this.attrs.gradient : this.attrs[t]; - if (i == null && n.is(t, et)) { - for (i = {}, r = 0, u = t.length; r < u; r++) i[t[r]] = this.attr(t[r]); - return i - } - return i != null ? (r = {}, r[t] = i, vt(this, r)) : t != null && n.is(t, "object") && vt(this, t), this - }; - u[i].toFront = function() { - if (this.removed) return this; - this.node.parentNode[o](this.node); - var n = this.paper; - return n.top != this && br(this, n), this - }; - u[i].toBack = function() { - return this.removed ? this : (this.node.parentNode.firstChild != this.node && (this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild), kr(this, this.paper)), this) - }; - u[i].insertAfter = function(n) { - if (this.removed) return this; - var t = n.node; - return t.nextSibling ? t.parentNode.insertBefore(this.node, t.nextSibling) : t.parentNode[o](this.node), dr(this, n, this.paper), this - }; - u[i].insertBefore = function(n) { - if (this.removed) return this; - var t = n.node; - return t.parentNode.insertBefore(this.node, t), gr(this, n, this.paper), this - }; - u[i].blur = function(t) { - var i = this, - r, u; + t != 0 ? (r = f("filter"), u = f("feGaussianBlur"), i.attrs.blur = t, r.id = "r" + (n._id++)[d](36), f(u, { - stdDeviation: +t || 1.5 - }), r.appendChild(u), i.paper.defs.appendChild(r), i._blur = r, f(i.node, { - filter: "url(#" + r.id + ")" - })) : (i._blur && (i._blur.parentNode.removeChild(i._blur), delete i._blur, delete i.attrs.blur), i.node.removeAttribute("filter")) - }; - var ru = function(n, t, i, r) { - t = v(t); - i = v(i); - var e = f("circle"); - return n.canvas && n.canvas[o](e), n = new u(e, n), n.attrs = { - cx: t, - cy: i, - r: r, - fill: "none", - stroke: "#000" - }, n.type = "circle", f(e, n.attrs), n - }, - uu = function(n, t, i, r, e, s) { - t = v(t); - i = v(i); - var h = f("rect"); - return n.canvas && n.canvas[o](h), n = new u(h, n), n.attrs = { - x: t, - y: i, - width: r, - height: e, - r: s || 0, - rx: s || 0, - ry: s || 0, - fill: "none", - stroke: "#000" - }, n.type = "rect", f(h, n.attrs), n - }, - fu = function(n, t, i, r, e) { - t = v(t); - i = v(i); - var s = f("ellipse"); - return n.canvas && n.canvas[o](s), n = new u(s, n), n.attrs = { - cx: t, - cy: i, - rx: r, - ry: e, - fill: "none", - stroke: "#000" - }, n.type = "ellipse", f(s, n.attrs), n - }, - eu = function(n, t, i, r, e, s) { - var h = f("image"); - return f(h, { - x: i, - y: r, - width: e, - height: s, - preserveAspectRatio: "none" - }), h.setAttributeNS(n.xlink, "href", t), n.canvas && n.canvas[o](h), n = new u(h, n), n.attrs = { - x: i, - y: r, - width: e, - height: s, - src: t - }, n.type = "image", n - }, - ou = function(n, t, i, r) { - var e = f("text"); - return f(e, { - x: t, - y: i, - "text-anchor": "middle" - }), n.canvas && n.canvas[o](e), n = new u(e, n), n.attrs = { - x: t, - y: i, - "text-anchor": "middle", - text: r, - font: oi.font, - stroke: "none", - fill: "#000" - }, n.type = "text", vt(n, n.attrs), n - }, - su = function(n, t) { - return this.width = n || this.width, this.height = t || this.height, this.canvas[ot]("width", this.width), this.canvas[ot]("height", this.height), this - }, - rr = function() { - var i = wr[b](0, arguments), - t = i && i.container, - e = i.x, - s = i.y, - u = i.width, - r; - if (i = i.height, !t) throw new Error("SVG container not found."); - return r = f("svg"), e = e || 0, s = s || 0, u = u || 512, i = i || 342, f(r, { - xmlns: "http://www.w3.org/2000/svg", - version: 1.1, - width: u, - height: i - }), t == 1 ? (r.style.cssText = "position:absolute;left:" + e + "px;top:" + s + "px", c.body[o](r)) : t.firstChild ? t.insertBefore(r, t.firstChild) : t[o](r), t = new y, t.width = u, t.height = i, t.canvas = r, nr.call(t, t, n.fn), t.clear(), t - }; - y[i].clear = function() { - for (var n = this.canvas; n.firstChild;) n.removeChild(n.firstChild); - this.bottom = this.top = null; - (this.desc = f("desc"))[o](c.createTextNode("Created with Raphaël")); - n[o](this.desc); - n[o](this.defs = f("defs")) - }; - y[i].remove = function() { - this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas); - for (var n in this) this[n] = nu(n) - } - } - if (n.vml) { - var hu = { - M: "m", - L: "l", - C: "c", - Z: "x", - m: "t", - l: "r", - c: "v", - z: "x" - }, - of = /([clmz]),?([^clmz]*)/gi, - sf = /-?[^,\s-]+/g, - ui = 1e3 + g + 1e3, - ni = 10, - fi = { - path: 1, - rect: 1 - }, - hf = function(n) { - var i = /[ahqstv]/ig, - u = dt, - f, e, h, o, s; - if ((n + r).match(i) && (u = ai), i = /[clmz]/g, u == dt && !(n + r).match(i)) return (n + r)[w]( of , function(n, i, r) { - var u = [], - e = yt.call(i) == "m", - f = hu[i]; - return r[w](sf, function(n) { - e && u[t] == 2 && (f += u + hu[i == "m" ? "l" : "L"], u = []); - u[a](v(n * ni)) - }), f + u - }); - for (i = u(n), n = [], e = 0, h = i[t]; e < h; e++) { - for (u = i[e], f = yt.call(i[e][0]), f == "z" && (f = "x"), o = 1, s = u[t]; o < s; o++) f += v(u[o] * ni) + (o != s - 1 ? "," : r); - n[a](f) - } - return n[tt](g) - }; - n[d] = function() { - return "Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël " + this.version - }; - tu = function(n, t) { - var f = it("group"), - i, e; - return f.style.cssText = "position:absolute;left:0;top:0;width:" + t.width + "px;height:" + t.height + "px", f.coordsize = t.coordsize, f.coordorigin = t.coordorigin, i = it("shape"), e = i.style, e.width = t.width + "px", e.height = t.height + "px", i.coordsize = ui, i.coordorigin = t.coordorigin, f[o](i), i = new u(i, f, t), e = { - fill: "none", - stroke: "#000" - }, n && (e.path = n), i.isAbsolute = !0, i.type = "path", i.path = [], i.Path = r, vt(i, e), t.canvas[o](f), i - }; - vt = function(i, u) { - var y, b, k, d; - i.attrs = i.attrs || {}; - var a = i.node, - e = i.attrs, - f = a.style, - l; - l = (u.x != e.x || u.y != e.y || u.width != e.width || u.height != e.height || u.r != e.r) && i.type == "rect"; - y = i; - for (b in u) u[s](b) && (e[b] = u[b]); - if (l && (e.path = lu(e.x, e.y, e.width, e.height, e.r), i.X = e.x, i.Y = e.y, i.W = e.width, i.H = e.height), u.href && (a.href = u.href), u.title && (a.title = u.title), u.target && (a.target = u.target), u.cursor && (f.cursor = u.cursor), "blur" in u && i.blur(u.blur), (u.path && i.type == "path" || l) && (a.path = hf(e.path)), u.rotation != null && i.rotate(u.rotation, !0), u.translation && (l = (u.translation + r)[p](ft), yi.call(i, l[0], l[1]), i._.rt.cx != null && (i._.rt.cx += +l[0], i._.rt.cy += +l[1], i.setBox(i.attrs, l[0], l[1]))), u.scale && (l = (u.scale + r)[p](ft), i.scale(+l[0] || 1, +l[1] || +l[0] || 1, +l[2] || null, +l[3] || null)), "clip-rect" in u && (l = (u["clip-rect"] + r)[p](ft), l[t] == 4 && (l[2] = +l[2] + +l[0], l[3] = +l[3] + +l[1], b = a.clipRect || c.createElement("div"), k = b.style, d = a.parentNode, k.clip = n.format("rect({1}px {2}px {3}px {0}px)", l), a.clipRect || (k.position = "absolute", k.top = 0, k.left = 0, k.width = i.paper.width + "px", k.height = i.paper.height + "px", d.parentNode.insertBefore(b, d), b[o](d), a.clipRect = b)), u["clip-rect"] || a.clipRect && (a.clipRect.style.clip = r)), i.type == "image" && u.src && (a.src = u.src), i.type == "image" && u.opacity && (a.filterOpacity = ki + ".Alpha(opacity=" + u.opacity * 100 + ")", f.filter = (a.filterMatrix || r) + (a.filterOpacity || r)), u.font && (f.font = u.font), u["font-family"] && (f.fontFamily = '"' + u["font-family"][p](",")[0][w](/^['"]+|['"]+$/g, r) + '"'), u["font-size"] && (f.fontSize = u["font-size"]), u["font-weight"] && (f.fontWeight = u["font-weight"]), u["font-style"] && (f.fontStyle = u["font-style"]), (u.opacity != null || u["stroke-width"] != null || u.fill != null || u.stroke != null || u["stroke-width"] != null || u["stroke-opacity"] != null || u["fill-opacity"] != null || u["stroke-dasharray"] != null || u["stroke-miterlimit"] != null || u["stroke-linejoin"] != null || u["stroke-linecap"] != null) && (a = i.shape || a, f = a.getElementsByTagName(at) && a.getElementsByTagName(at)[0], l = !1, f || (l = f = it(at)), ("fill-opacity" in u || "opacity" in u) && (i = ((+e["fill-opacity"] + 1 || 2) - 1) * ((+e.opacity + 1 || 2) - 1) * ((+n.getRGB(u.fill).o + 1 || 2) - 1), i < 0 && (i = 0), i > 1 && (i = 1), f.opacity = i), u.fill && (f.on = !0), (f.on == null || u.fill == "none") && (f.on = !1), f.on && u.fill && ((i = u.fill.match(cr)) ? (f.src = i[1], f.type = "tile") : (f.color = n.getRGB(u.fill).hex, f.src = r, f.type = "solid", n.getRGB(u.fill).error && (y.type in { - circle: 1, - ellipse: 1 - } || (u.fill + r).charAt() != "r") && ri(y, u.fill) && (e.fill = "none", e.gradient = u.fill))), l && a[o](f), f = a.getElementsByTagName("stroke") && a.getElementsByTagName("stroke")[0], l = !1, f || (l = f = it("stroke")), (u.stroke && u.stroke != "none" || u["stroke-width"] || u["stroke-opacity"] != null || u["stroke-dasharray"] || u["stroke-miterlimit"] || u["stroke-linejoin"] || u["stroke-linecap"]) && (f.on = !0), (u.stroke == "none" || f.on == null || u.stroke == 0 || u["stroke-width"] == 0) && (f.on = !1), i = n.getRGB(u.stroke), f.on && u.stroke && (f.color = i.hex), i = ((+e["stroke-opacity"] + 1 || 2) - 1) * ((+e.opacity + 1 || 2) - 1) * ((+i.o + 1 || 2) - 1), b = (h(u["stroke-width"]) || 1) * .75, i < 0 && (i = 0), i > 1 && (i = 1), u["stroke-width"] == null && (b = e["stroke-width"]), u["stroke-width"] && (f.weight = b), b && b < 1 && (i *= b) && (f.weight = 1), f.opacity = i, u["stroke-linejoin"] && (f.joinstyle = u["stroke-linejoin"] || "miter"), f.miterlimit = u["stroke-miterlimit"] || 8, u["stroke-linecap"] && (f.endcap = u["stroke-linecap"] == "butt" ? "flat" : u["stroke-linecap"] == "square" ? "square" : "round"), u["stroke-dasharray"] && (i = { - "-": "shortdash", - ".": "shortdot", - "-.": "shortdashdot", - "-..": "shortdashdotdot", - ". ": "dot", - "- ": "dash", - "--": "longdash", - "- .": "dashdot", - "--.": "longdashdot", - "--..": "longdashdotdot" - }, f.dashstyle = i[s](u["stroke-dasharray"]) ? i[u["stroke-dasharray"]] : r), l && a[o](f)), y.type == "text") { - f = y.paper.span.style; - e.font && (f.font = e.font); - e["font-family"] && (f.fontFamily = e["font-family"]); - e["font-size"] && (f.fontSize = e["font-size"]); - e["font-weight"] && (f.fontWeight = e["font-weight"]); - e["font-style"] && (f.fontStyle = e["font-style"]); - y.node.string && (y.paper.span.innerHTML = (y.node.string + r)[w](/</g, "<")[w](/&/g, "&")[w](/\n/g, "<br>")); - y.W = e.w = y.paper.span.offsetWidth; - y.H = e.h = y.paper.span.offsetHeight; - y.X = e.x; - y.Y = e.y + v(y.H / 2); - switch (e["text-anchor"]) { - case "start": - y.node.style["v-text-align"] = "left"; - y.bbx = v(y.W / 2); - break; - case "end": - y.node.style["v-text-align"] = "right"; - y.bbx = -v(y.W / 2); - break; - default: - y.node.style["v-text-align"] = "center" - } - } - }; - ri = function(n, i) { - var s, c, o, u, f, v; - if ((n.attrs = n.attrs || {}, s = "linear", c = ".5 .5", n.attrs.gradient = i, i = (i + r)[w](tr, function(n, t, i) { - return s = "radial", t && i && (t = h(t), i = h(i), l(t - .5, 2) + l(i - .5, 2) > .25 && (i = e.sqrt(.25 - l(t - .5, 2)) * ((i > .5) * 2 - 1) + .5), c = t + g + i), r - }), i = i[p](/\s*\-\s*/), s == "linear" && (o = i.shift(), o = -h(o), isNaN(o))) || (u = pr(i), !u)) return null; - if (n = n.shape || n.node, i = n.getElementsByTagName(at)[0] || it(at), i.parentNode || n.appendChild(i), u[t]) { - for (i.on = !0, i.method = "none", i.color = u[0].color, i.color2 = u[u[t] - 1].color, n = [], f = 0, v = u[t]; f < v; f++) u[f].offset && n[a](u[f].offset + g + u[f].color); - i.colors && (i.colors.value = n[t] ? n[tt]() : "0% " + i.color); - s == "radial" ? (i.type = "gradientradial", i.focus = "100%", i.focussize = c, i.focusposition = c) : (i.type = "gradient", i.angle = (270 - o) % 360) - } - return 1 - }; - u = function(t, i, r) { - this[0] = t; - this.id = n._oid++; - this.node = t; - t.raphael = this; - this.Y = this.X = 0; - this.attrs = {}; - this.Group = i; - this.paper = r; - this._ = { - tx: 0, - ty: 0, - rt: { - deg: 0 - }, - sx: 1, - sy: 1 - }; - r.bottom || (r.bottom = this); - (this.prev = r.top) && (r.top.next = this); - r.top = this; - this.next = null - }; - u[i].rotate = function(n, i, u) { - return this.removed ? this : n == null ? this._.rt.cx ? [this._.rt.deg, this._.rt.cx, this._.rt.cy][tt](g) : this._.rt.deg : (n = (n + r)[p](ft), n[t] - 1 && (i = h(n[1]), u = h(n[2])), n = h(n[0]), i != null ? this._.rt.deg = n : this._.rt.deg += n, u == null && (i = null), this._.rt.cx = i, this._.rt.cy = u, this.setBox(this.attrs, i, u), this.Group.style.rotation = this._.rt.deg, this) - }; - u[i].setBox = function(n, t, i) { - var c, e, o, u, h, f; - if (this.removed) return this; - c = this.Group.style; - e = this.shape && this.shape.style || this.node.style; - n = n || {}; - for (o in n) n[s](o) && (this.attrs[o] = n[o]); - t = t || this._.rt.cx; - i = i || this._.rt.cy; - u = this.attrs; - switch (this.type) { - case "circle": - n = u.cx - u.r; - o = u.cy - u.r; - h = u = u.r * 2; - break; - case "ellipse": - n = u.cx - u.rx; - o = u.cy - u.ry; - h = u.rx * 2; - u = u.ry * 2; - break; - case "image": - n = +u.x; - o = +u.y; - h = u.width || 0; - u = u.height || 0; - break; - case "text": - this.textpath.v = ["m", v(u.x), ", ", v(u.y - 2), "l", v(u.x) + 1, ", ", v(u.y - 2)][tt](r); - n = u.x - v(this.W / 2); - o = u.y - this.H / 2; - h = this.W; - u = this.H; - break; - case "rect": - case "path": - this.attrs.path ? (u = ti(this.attrs.path), n = u.x, o = u.y, h = u.width, u = u.height) : (o = n = 0, h = this.paper.width, u = this.paper.height); - break; - default: - o = n = 0; - h = this.paper.width; - u = this.paper.height - } - t = t == null ? n + h / 2 : t; - i = i == null ? o + u / 2 : i; - t = t - this.paper.width / 2; - i = i - this.paper.height / 2; - c.left != (f = t + "px") && (c.left = f); - c.top != (f = i + "px") && (c.top = f); - this.X = fi[s](this.type) ? -t : n; - this.Y = fi[s](this.type) ? -i : o; - this.W = h; - this.H = u; - fi[s](this.type) ? (e.left != (f = -t * ni + "px") && (e.left = f), e.top != (f = -i * ni + "px") && (e.top = f)) : this.type == "text" ? (e.left != (f = -t + "px") && (e.left = f), e.top != (f = -i + "px") && (e.top = f)) : (c.width != (f = this.paper.width + "px") && (c.width = f), c.height != (f = this.paper.height + "px") && (c.height = f), e.left != (f = n - t + "px") && (e.left = f), e.top != (f = o - i + "px") && (e.top = f), e.width != (f = h + "px") && (e.width = f), e.height != (f = u + "px") && (e.height = f)) - }; - u[i].hide = function() { - return this.removed || (this.Group.style.display = "none"), this - }; - u[i].show = function() { - return this.removed || (this.Group.style.display = "block"), this - }; - u[i].getBBox = function() { - return this.removed ? this : fi[s](this.type) ? ti(this.attrs.path) : { - x: this.X + (this.bbx || 0), - y: this.Y, - width: this.W, - height: this.H - } - }; - u[i].remove = function() { - if (!this.removed) { - gt(this, this.paper); - this.node.parentNode.removeChild(this.node); - this.Group.parentNode.removeChild(this.Group); - this.shape && this.shape.parentNode.removeChild(this.shape); - for (var n in this) delete this[n]; - this.removed = !0 - } - }; - u[i].attr = function(i, u) { - var e, f; - if (this.removed) return this; - if (i == null) { - i = {}; - for (e in this.attrs) this.attrs[s](e) && (i[e] = this.attrs[e]); - return this._.rt.deg && (i.rotation = this.rotate()), (this._.sx != 1 || this._.sy != 1) && (i.scale = this.scale()), i.gradient && i.fill == "none" && (i.fill = i.gradient) && delete i.gradient, i - } - if (u == null && n.is(i, wt)) return i == "translation" ? yi.call(this) : i == "rotation" ? this.rotate() : i == "scale" ? this.scale() : i == at && this.attrs.fill == "none" && this.attrs.gradient ? this.attrs.gradient : this.attrs[i]; - if (this.attrs && u == null && n.is(i, et)) { - for (f = {}, e = 0, u = i[t]; e < u; e++) f[i[e]] = this.attr(i[e]); - return f - } - return u != null && (f = {}, f[i] = u), u == null && n.is(i, "object") && (f = i), f && (f.text && this.type == "text" && (this.node.string = f.text), vt(this, f), f.gradient && ({ - circle: 1, - ellipse: 1 - }[s](this.type) || (f.gradient + r).charAt() != "r") && ri(this, f.gradient), (!fi[s](this.type) || this._.rt.deg) && this.setBox(this.attrs)), this - }; - u[i].toFront = function() { - return this.removed || this.Group.parentNode[o](this.Group), this.paper.top != this && br(this, this.paper), this - }; - u[i].toBack = function() { - return this.removed ? this : (this.Group.parentNode.firstChild != this.Group && (this.Group.parentNode.insertBefore(this.Group, this.Group.parentNode.firstChild), kr(this, this.paper)), this) - }; - u[i].insertAfter = function(n) { - return this.removed ? this : (n.Group.nextSibling ? n.Group.parentNode.insertBefore(this.Group, n.Group.nextSibling) : n.Group.parentNode[o](this.Group), dr(this, n, this.paper), this) - }; - u[i].insertBefore = function(n) { - return this.removed ? this : (n.Group.parentNode.insertBefore(this.Group, n.Group), gr(this, n, this.paper), this) - }; - cu = / progid:\S+Blur\([^\)]+\)/g; - u[i].blur = function(n) { - var t = this.node.style, - i = t.filter; - i = i.replace(cu, ""); + n != 0 ? (this.attrs.blur = n, t.filter = i + ki + ".Blur(pixelradius=" + (+n || 1.5) + ")", t.margin = Raphael.format("-{0}px 0 0 -{0}px", Math.round(+n || 1.5))) : (t.filter = i, t.margin = 0, delete this.attrs.blur) - }; - ru = function(n, t, i, r) { - var e = it("group"), - f = it("oval"); - return e.style.cssText = "position:absolute;left:0;top:0;width:" + n.width + "px;height:" + n.height + "px", e.coordsize = ui, e.coordorigin = n.coordorigin, e[o](f), f = new u(f, e, n), f.type = "circle", vt(f, { - stroke: "#000", - fill: "none" - }), f.attrs.cx = t, f.attrs.cy = i, f.attrs.r = r, f.setBox({ - x: t - r, - y: i - r, - width: r * 2, - height: r * 2 - }), n.canvas[o](e), f - }; - - function lu(t, i, r, u, f) { - return f ? n.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z", t + f, i, r - f * 2, f, -f, u - f * 2, f * 2 - r, f * 2 - u) : n.format("M{0},{1}l{2},0,0,{3},{4},0z", t, i, r, u, -r) - } - uu = function(n, t, i, r, u, f) { - var o = lu(t, i, r, u, f), - e; - return n = n.path(o), e = n.attrs, n.X = e.x = t, n.Y = e.y = i, n.W = e.width = r, n.H = e.height = u, e.r = f, e.path = o, n.type = "rect", n - }; - fu = function(n, t, i, r, f) { - var s = it("group"), - e = it("oval"); - return s.style.cssText = "position:absolute;left:0;top:0;width:" + n.width + "px;height:" + n.height + "px", s.coordsize = ui, s.coordorigin = n.coordorigin, s[o](e), e = new u(e, s, n), e.type = "ellipse", vt(e, { - stroke: "#000" - }), e.attrs.cx = t, e.attrs.cy = i, e.attrs.rx = r, e.attrs.ry = f, e.setBox({ - x: t - r, - y: i - f, - width: r * 2, - height: f * 2 - }), n.canvas[o](s), e - }; - eu = function(n, t, i, r, f, e) { - var h = it("group"), - s = it("image"); - return h.style.cssText = "position:absolute;left:0;top:0;width:" + n.width + "px;height:" + n.height + "px", h.coordsize = ui, h.coordorigin = n.coordorigin, s.src = t, h[o](s), s = new u(s, h, n), s.type = "image", s.attrs.src = t, s.attrs.x = i, s.attrs.y = r, s.attrs.w = f, s.attrs.h = e, s.setBox({ - x: i, - y: r, - width: f, - height: e - }), n.canvas[o](h), s - }; - ou = function(t, i, f, e) { - var h = it("group"), - c = it("shape"), - s = c.style, - l = it("path"), - a = it("textpath"); - return h.style.cssText = "position:absolute;left:0;top:0;width:" + t.width + "px;height:" + t.height + "px", h.coordsize = ui, h.coordorigin = t.coordorigin, l.v = n.format("m{0},{1}l{2},{1}", v(i * 10), v(f * 10), v(i * 10) + 1), l.textpathok = !0, s.width = t.width, s.height = t.height, a.string = e + r, a.on = !0, c[o](a), c[o](l), h[o](c), s = new u(a, h, t), s.shape = c, s.textpath = l, s.type = "text", s.attrs.text = e, s.attrs.x = i, s.attrs.y = f, s.attrs.w = 1, s.attrs.h = 1, vt(s, { - font: oi.font, - stroke: "none", - fill: "#000" - }), s.setBox(), t.canvas[o](h), s - }; - su = function(n, t) { - var i = this.canvas.style; - return n == +n && (n += "px"), t == +t && (t += "px"), i.width = n, i.height = t, i.clip = "rect(0 " + n + " " + t + " 0)", this - }; - c.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)"); - try { - c.namespaces.rvml || c.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"); - it = function(n) { - return c.createElement("<rvml:" + n + ' class="rvml">') - } - } catch (pf) { - it = function(n) { - return c.createElement("<" + n + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">') - } - } - rr = function() { - var i = wr[b](0, arguments), - r = i.container, - u = i.height, - f = i.width, - h = i.x; - if (i = i.y, !r) throw new Error("VML container not found."); - var t = new y, - e = t.canvas = c.createElement("div"), - s = e.style; - return h = h || 0, i = i || 0, f = f || 512, u = u || 342, f == +f && (f += "px"), u == +u && (u += "px"), t.width = 1e3, t.height = 1e3, t.coordsize = ni * 1e3 + g + ni * 1e3, t.coordorigin = "0 0", t.span = c.createElement("span"), t.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;", e[o](t.span), s.cssText = n.format("width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", f, u), r == 1 ? (c.body[o](e), s.left = h + "px", s.top = i + "px", s.position = "absolute") : r.firstChild ? r.insertBefore(e, r.firstChild) : r[o](e), nr.call(t, t, n.fn), t - }; - y[i].clear = function() { - this.canvas.innerHTML = r; - this.span = c.createElement("span"); - this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;"; - this.canvas[o](this.span); - this.bottom = this.top = null - }; - y[i].remove = function() { - this.canvas.parentNode.removeChild(this.canvas); - for (var n in this) this[n] = nu(n); - return !0 - } - } - for (y[i].safari = /^Apple|^Google/.test(st.navigator.vendor) && (!(st.navigator.userAgent.indexOf("Version/4.0") + 1) || st.navigator.platform.slice(0, 2) == "iP") ? function() { - var n = this.rect(-99, -99, this.width + 99, this.height + 99); - st.setTimeout(function() { - n.remove() - }) - } : function() {}, au = function() { - return c.addEventListener ? function(n, t, i, r) { - function f(u) { - if (wi && bi[s](t)) - for (var f = 0, e = u.targetTouches && u.targetTouches.length; f < e; f++) - if (u.targetTouches[f].target == n) { - e = u; - u = u.targetTouches[f]; - u.originalEvent = e; - u.preventDefault = lf; - u.stopPropagation = vf; - break - } - return i.call(r, u) - } - var u = wi && bi[t] ? bi[t] : t; - return n.addEventListener(u, f, !1), - function() { - return n.removeEventListener(u, f, !1), !0 - } - } : c.attachEvent ? function(n, t, i, r) { - function u(n) { - return n = n || st.event, n.preventDefault = n.preventDefault || cf, n.stopPropagation = n.stopPropagation || af, i.call(r, n) - } - - function f() { - return n.detachEvent("on" + t, u), !0 - } - return n.attachEvent("on" + t, u), f - } : void 0 - }(), bt = hr[t]; bt--;)(function(r) { - n[r] = u[i][r] = function(t) { - return n.is(t, "function") && (this.events = this.events || [], this.events.push({ - name: r, - f: t, - unbind: au(this.shape || this.node || c, r, t, this) - })), this - }; - n["un" + r] = u[i]["un" + r] = function(n) { - for (var i = this.events, u = i[t]; u--;) - if (i[u].name == r && i[u].f == n) return i[u].unbind(), i.splice(u, 1), i.length || delete this.events, this; - return this - } - })(hr[bt]); - u[i].hover = function(n, t) { - return this.mouseover(n).mouseout(t) - }; - u[i].unhover = function(n, t) { - return this.unmouseover(n).unmouseout(t) - }; - u[i].drag = function(n, t, i) { - function u(t) { - var u = t.clientX, - f = t.clientY, - e, i; - if (wi) { - for (e = t.touches.length; e--;) - if (i = t.touches[e], i.identifier == r._drag.id) { - u = i.clientX; - f = i.clientY; - (t.originalEvent ? t.originalEvent : t).preventDefault(); - break - } - } else t.preventDefault(); - n && n.call(r, u - r._drag.x, f - r._drag.y, u, f) - } - - function f() { - r._drag = {}; - Raphael.unmousemove(u).unmouseup(f); - i && i.call(r) - } - this._drag = {}; - var r = this.mousedown(function(n) { - (n.originalEvent ? n.originalEvent : n).preventDefault(); - this._drag.x = n.clientX; - this._drag.y = n.clientY; - this._drag.id = n.identifier; - t && t.call(this, n.clientX, n.clientY); - Raphael.mousemove(u).mouseup(f) - }); - return this - }; - y[i].circle = function(n, t, i) { - return ru(this, n || 0, t || 0, i || 0) - }; - y[i].rect = function(n, t, i, r, u) { - return uu(this, n || 0, t || 0, i || 0, r || 0, u || 0) - }; - y[i].ellipse = function(n, t, i, r) { - return fu(this, n || 0, t || 0, i || 0, r || 0) - }; - y[i].path = function(t) { - return !t || n.is(t, wt) || n.is(t[0], et) || (t += r), tu(n.format[b](n, arguments), this) - }; - y[i].image = function(n, t, i, r, u) { - return eu(this, n || "about:blank", t || 0, i || 0, r || 0, u || 0) - }; - y[i].text = function(n, t, i) { - return ou(this, n || 0, t || 0, i || r) - }; - y[i].set = function(n) { - return arguments[t] > 1 && (n = Array[i].splice.call(arguments, 0, arguments[t])), new ct(n) - }; - y[i].setSize = su; - y[i].top = y[i].bottom = null; - y[i].raphael = n; - u[i].resetScale = function() { - if (this.removed) return this; - this._.sx = 1; - this._.sy = 1; - this.attrs.scale = "1 1" - }; - u[i].scale = function(n, i, u, f) { - var a, o, h, nt, it, l, s, w; - if (this.removed) return this; - if (n == null && i == null) return { - x: this._.sx, - y: this._.sy, - toString: vu - }; - if (i = i || n, +i || (i = n), h = this.attrs, n != 0) { - var c = this.getBBox(), - v = c.x + c.width / 2, - p = c.y + c.height / 2; - a = n / this._.sx; - o = i / this._.sy; - u = +u || u == 0 ? u : v; - f = +f || f == 0 ? f : p; - c = ~~(n / e.abs(n)); - var y = ~~(i / e.abs(i)), - rt = this.node.style, - d = u + (v - u) * a; - p = f + (p - f) * o; - switch (this.type) { - case "rect": - case "image": - nt = h.width * c * a; - it = h.height * y * o; - this.attr({ - height: it, - r: h.r * lt(c * a, y * o), - width: nt, - x: d - nt / 2, - y: p - it / 2 - }); - break; - case "circle": - case "ellipse": - this.attr({ - rx: h.rx * c * a, - ry: h.ry * y * o, - r: h.r * lt(c * a, y * o), - cx: d, - cy: p - }); - break; - case "text": - this.attr({ - x: d, - y: p - }); - break; - case "path": - v = gi(h.path); - for (var ut = !0, b = 0, ft = v[t]; b < ft; b++) - if (l = v[b], s = ei.call(l[0]), !(s == "M" && ut)) - if (ut = !1, s == "A") l[v[b][t] - 2] *= a, l[v[b][t] - 1] *= o, l[1] *= c * a, l[2] *= y * o, l[5] = +!(c + y ? !+l[5] : +l[5]); - else if (s == "H") - for (s = 1, w = l[t]; s < w; s++) l[s] *= a; - else if (s == "V") - for (s = 1, w = l[t]; s < w; s++) l[s] *= o; - else - for (s = 1, w = l[t]; s < w; s++) l[s] *= s % 2 ? a : o; - o = ti(v); - a = d - o.x - o.width / 2; - o = p - o.y - o.height / 2; - v[0][1] += a; - v[0][2] += o; - this.attr({ - path: v - }) - } - this.type in { - text: 1, - image: 1 - } && (c != 1 || y != 1) ? this.transformations ? (this.transformations[2] = "scale(" [k](c, ",", y, ")"), this.node[ot]("transform", this.transformations[tt](g)), a = c == -1 ? -h.x - (nt || 0) : h.x, o = y == -1 ? -h.y - (it || 0) : h.y, this.attr({ - x: a, - y: o - }), h.fx = c - 1, h.fy = y - 1) : (this.node.filterMatrix = ki + ".Matrix(M11=" [k](c, ", M12=0, M21=0, M22=", y, ", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')"), rt.filter = (this.node.filterMatrix || r) + (this.node.filterOpacity || r)) : this.transformations ? (this.transformations[2] = r, this.node[ot]("transform", this.transformations[tt](g)), h.fx = 0, h.fy = 0) : (this.node.filterMatrix = r, rt.filter = (this.node.filterMatrix || r) + (this.node.filterOpacity || r)); - h.scale = [n, i, u, f][tt](g); - this._.sx = n; - this._.sy = i - } - return this - }; - u[i].clone = function() { - if (this.removed) return null; - var n = this.attr(); - return delete n.scale, delete n.translation, this.paper[this.type]().attr(n) - }; - ur = ut(function(t, i, r, u, f, e, o, s, h) { - for (var y, a, v = 0, c = 0; c < 1.001; c += .001) { - if (a = n.findDotsAtSegment(t, i, r, u, f, e, o, s, c), c && (v += l(l(y.x - a.x, 2) + l(y.y - a.y, 2), .5)), v >= h) return a; - y = a - } - }); - var yf = ut(function(n, t, i, r, u, f, e, o) { - for (var h, c = { - x: 0, - y: 0 - }, a = 0, s = 0; s < 1.01; s += .01) h = ii(n, t, i, r, u, f, e, o, s), s && (a += l(l(c.x - h.x, 2) + l(c.y - h.y, 2), .5)), c = h; - return a - }), - yu = fr(1), - vi = fr(), - er = fr(0, 1); - u[i].getTotalLength = function() { - if (this.type == "path") return this.node.getTotalLength ? this.node.getTotalLength() : yu(this.attrs.path) - }; - u[i].getPointAtLength = function(n) { - if (this.type == "path") return vi(this.attrs.path, n) - }; - u[i].getSubpath = function(n, t) { - if (this.type == "path") return e.abs(this.getTotalLength() - t) < 1e-6 ? er(this.attrs.path, n).end : (t = er(this.attrs.path, t, 1), n ? er(t, n).end : t) - }; - n.easing_formulas = { - linear: function(n) { - return n - }, - "<": function(n) { - return l(n, 3) - }, - ">": function(n) { - return l(n - 1, 3) + 1 - }, - "<>": function(n) { - return (n *= 2, n < 1) ? l(n, 3) / 2 : (n -= 2, (l(n, 3) + 2) / 2) - }, - backIn: function(n) { - var t = 1.70158; - return n * n * ((t + 1) * n - t) - }, - backOut: function(n) { - n -= 1; - var t = 1.70158; - return n * n * ((t + 1) * n + t) + 1 - }, - elastic: function(n) { - if (n == 0 || n == 1) return n; - var t = .3, - i = t / 4; - return l(2, -10 * n) * e.sin((n - i) * 2 * e.PI / t) + 1 - }, - bounce: function(n) { - var i = 7.5625, - t = 2.75; - return n < 1 / t ? n = i * n * n : n < 2 / t ? (n -= 1.5 / t, n = i * n * n + .75) : n < 2.5 / t ? (n -= 2.25 / t, n = i * n * n + .9375) : (n -= 2.625 / t, n = i * n * n + .984375), n - } - }; - rt = { - length: 0 - }; - u[i].animateWith = function(n, t, i, r, u) { - return rt[n.id] && (t.start = rt[n.id].start), this.animate(t, i, r, u) - }; - u[i].animateAlong = wu(); - u[i].animateAlongBack = wu(1); - u[i].onAnimation = function(n) { - return this._run = n || 0, this - }; - u[i].animate = function(i, u, f, e) { - var o, w, k; - (n.is(f, "function") || !f) && (e = f || null); - var l = {}, - y = {}, - a = {}; - for (o in i) - if (i[s](o) && di[s](o)) { - l[o] = this.attr(o); - l[o] == null && (l[o] = oi[o]); - y[o] = i[o]; - switch (di[o]) { - case "along": - var c = yu(i[o]), - v = vi(i[o], c * !!i.back), - b = this.getBBox(); - a[o] = c / u; - a.tx = b.x; - a.ty = b.y; - a.sx = v.x; - a.sy = v.y; - y.rot = i.rot; - y.back = i.back; - y.len = c; - i.rot && (a.r = h(this.rotate()) || 0); - break; - case nt: - a[o] = (y[o] - l[o]) / u; - break; - case "colour": - l[o] = n.getRGB(l[o]); - c = n.getRGB(y[o]); - a[o] = { - r: (c.r - l[o].r) / u, - g: (c.g - l[o].g) / u, - b: (c.b - l[o].b) / u - }; - break; - case "path": - for (c = ai(l[o], y[o]), l[o] = c[0], v = c[1], a[o] = [], c = 0, b = l[o][t]; c < b; c++) - for (a[o][c] = [0], w = 1, k = l[o][c][t]; w < k; w++) a[o][c][w] = (v[c][w] - l[o][c][w]) / u; - break; - case "csv": - v = (i[o] + r)[p](ft); - c = (l[o] + r)[p](ft); - switch (o) { - case "translation": - l[o] = [0, 0]; - a[o] = [v[0] / u, v[1] / u]; - break; - case "rotation": - l[o] = c[1] == v[1] && c[2] == v[2] ? c : [0, v[1], v[2]]; - a[o] = [(v[0] - l[o][0]) / u, 0, 0]; - break; - case "scale": - i[o] = v; - l[o] = (l[o] + r)[p](ft); - a[o] = [(v[0] - l[o][0]) / u, (v[1] - l[o][1]) / u, 0, 0]; - break; - case "clip-rect": - for (l[o] = (l[o] + r)[p](ft), a[o] = [], c = 4; c--;) a[o][c] = (v[c] - l[o][c]) / u - } - y[o] = v - } - } - return this.stop(), this.in_animation = 1, rt[this.id] = { - start: i.start || +new Date, - ms: u, - easing: f, - from: l, - diff: a, - to: y, - el: this, - callback: e, - t: { - x: 0, - y: 0 - } - }, ++rt[t] == 1 && pu(), this - }; - u[i].stop = function() { - return rt[this.id] && rt[t]--, delete rt[this.id], this - }; - u[i].translate = function(n, t) { - return this.attr({ - translation: n + " " + t - }) - }; - u[i][d] = function() { - return "Raphaël’s object" - }; - n.ae = rt; - ct[i][a] = function() { - for (var n, i, r = 0, f = arguments[t]; r < f; r++)(n = arguments[r]) && (n.constructor == u || n.constructor == ct) && (i = this.items[t], this[i] = this.items[i] = n, this[t]++); - return this - }; - ct[i].pop = function() { - return delete this[this[t]--], this.items.pop() - }; - for (pi in u[i]) u[i][s](pi) && (ct[i][pi] = function(n) { - return function() { - for (var i = 0, r = this.items[t]; i < r; i++) this.items[i][n][b](this.items[i], arguments); - return this - } - }(pi)); - return ct[i].attr = function(i, r) { - var u, f; - if (i && n.is(i, et) && n.is(i[0], "object")) - for (r = 0, u = i[t]; r < u; r++) this.items[r].attr(i[r]); - else - for (u = 0, f = this.items[t]; u < f; u++) this.items[u].attr(i, r); - return this - }, ct[i].animate = function(i, r, u, f) { - (n.is(u, "function") || !u) && (f = u || null); - var s = this.items[t], - o = s, - h, c = this, - e; - for (f && (e = function() { - --s || f.call(c) - }), u = n.is(u, wt) ? u : e, h = this.items[--o].animate(i, r, u, e); o--;) this.items[o].animateWith(h, i, r, u, e); - return this - }, ct[i].insertAfter = function(n) { - for (var i = this.items[t]; i--;) this.items[i].insertAfter(n); - return this - }, ct[i].getBBox = function() { - for (var n, i = [], r = [], u = [], f = [], e = this.items[t]; e--;) n = this.items[e].getBBox(), i[a](n.x), r[a](n.y), u[a](n.x + n.width), f[a](n.y + n.height); - return i = lt[b](0, i), r = lt[b](0, r), { - x: i, - y: r, - width: ht[b](0, u) - i, - height: ht[b](0, f) - r - } - }, ct[i].clone = function(n) { - n = new ct; - for (var i = 0, r = this.items[t]; i < r; i++) n[a](this.items[i].clone()); - return n - }, n.registerFont = function(n) { - var i, t, u, r, f; - if (!n.face) return n; - this.fonts = this.fonts || {}; - i = { - w: n.w, - face: {}, - glyphs: {} - }; - t = n.face["font-family"]; - for (u in n.face) n.face[s](u) && (i.face[u] = n.face[u]); - if (this.fonts[t] ? this.fonts[t][a](i) : this.fonts[t] = [i], !n.svg) { - i.face["units-per-em"] = pt(n.face["units-per-em"], 10); - for (r in n.glyphs) - if (n.glyphs[s](r) && (t = n.glyphs[r], i.glyphs[r] = { - w: t.w, - k: {}, - d: t.d && "M" + t.d[w](/[mlcxtrv]/g, function(n) { - return { - l: "L", - c: "C", - x: "z", - t: "m", - r: "l", - v: "c" - }[n] || "M" - }) + "z" - }, t.k)) - for (f in t.k) t[s](f) && (i.glyphs[r].k[f] = t.k[f]) - } - return n - }, y[i].getFont = function(i, u, f, e) { - var h, o, c; - if (e = e || "normal", f = f || "normal", u = +u || { - normal: 400, - bold: 700, - lighter: 300, - bolder: 800 - }[u] || 400, n.fonts) { - if (h = n.fonts[i], !h) { - i = new RegExp("(^|\\s)" + i[w](/[^\w\d\s+!~.:_-]/g, r) + "(\\s|$)", "i"); - for (o in n.fonts) - if (n.fonts[s](o) && i.test(o)) { - h = n.fonts[o]; - break - } - } - if (h) - for (o = 0, i = h[t]; o < i; o++) - if (c = h[o], c.face["font-weight"] == u && (c.face["font-style"] == f || !c.face["font-style"]) && c.face["font-stretch"] == e) break; - return c - } - }, y[i].print = function(i, u, f, e, o, s) { - var h, b, l, v; - s = s || "middle"; - var y = this.set(), - c = (f + r)[p](r), - w = 0; - if (n.is(e, f) && (e = this.getFont(e)), e) { - for (f = (o || 16) / e.face["units-per-em"], h = e.face.bbox.split(ft), o = +h[0], s = +h[1] + (s == "baseline" ? h[3] - h[1] + +e.face.descent : (h[3] - h[1]) / 2), h = 0, b = c[t]; h < b; h++) l = h && e.glyphs[c[h - 1]] || {}, v = e.glyphs[c[h]], w += h ? (l.w || e.w) + (l.k && l.k[c[h]] || 0) : 0, v && v.d && y[a](this.path(v.d).attr({ - fill: "#000", - stroke: "none", - translation: [w, 0] - })); - y.scale(f, f, o, s).translate(i - o, u - s) - } - return y - }, bu = /\{(\d+)\}/g, n.format = function(i, u) { - var f = n.is(u, et) ? [0][k](u) : arguments; - return i && n.is(i, wt) && f[t] - 1 && (i = i[w](bu, function(n, t) { - return f[++t] == null ? r : f[t] - })), i || r - }, n.ninja = function() { - return sr.was ? Raphael = sr.is : delete Raphael, n - }, n.el = u[i], n -}(); -dateTimeFromServer = new Date; -dateTimeFromClient = new Date; -$(document).ready(function() { - function n(n) { - return n < 10 ? "0" + n.toString() : n.toString() - } - $(".multiMenu").hover(function() { - mouse_is_inside = !0 - }, function() { - mouse_is_inside = !1 - }); - $("body").mouseup(function() { - mouse_is_inside || $(".multiMenu .layer").slideUp(function() { - $(this).parent("div").removeClass("active") - }) - }); - try { - $.ajax({ - url: "/Home/BiezacaDataGodzina", - type: "GET", - async: !1, - cache: !1, - success: function(n) { - dateTimeFromServer = new Date(parseInt(n.substr(6))); - dateTimeFromClient = new Date - } - }) - } catch (t) {} - setInterval(function() { - var u = dateTimeFromServer - dateTimeFromClient, - f = (new Date).getTime(), - r = new Date, - t, i; - r.setTime(f + u); - t = r; - t.setDate(t.getDate()); - var e = t.getDate(), - o = t.getMonth() + 1, - s = t.getFullYear(), - h = n(e) + " - " + n(o) + " - " + s; - $("#date").html(h); - i = r; - i.setDate(i.getDate()); - var c = i.getHours(), - l = i.getMinutes(), - a = n(c) + ":" + n(l); - $("#time").html(a) - }, 1e3); - $(".showDetails").click(function() { - $(this).prev(".details").slideToggle(); - $(this).find(".gui").toggleClass("icoDArrDown icoDArrUp"); - $(this).toggleClass("act") - }); - indirectStation() -}); -mouse_is_inside = !1, - function(n) { - n.cookies = { - render: function(t) { - var i = ""; - i += '<div id="cookiesBar"><div id="cookiesBarWrap"><p>' + C_Cookie_Tekst_1; - i += t.privacyPolicy ? ' <a href="' + t.cookiesPageURL + '" title="' + C_Cookie_PolitykaPrywatnosciTitle + '">' + C_Cookie_PolitykaPrywatnosci + "<\/a>.<\/p>" : ' <a href="' + t.cookiesPageURL + '" title="' + C_Cookie_RegulaminSerwisu + '">' + C_Cookie_RegulaminSerwisu + "<\/a>.<\/p>"; - i += "<p>" + C_Cookie_Tekst_2 + '<\/p><a id="cookiesBarClose" href="#" title="' + C_Cookie_Zamknij + '">' + C_Cookie_Zamknij + "<\/a><\/div><\/div>"; - n.cookie("cookie") || (n("body").append(i), n.fn.delegate ? n("#cookiesBar").delegate("#cookiesBarClose", "click", function(t) { - n.cookies.closeCallback(t) - }) : n("#cookiesBarClose").bind("click", function(t) { - n.cookies.closeCallback(t) - })) - }, - closeCallback: function(t) { - return n("#cookiesBar").fadeOut(), n.cookie("cookie") || n.cookie("cookie", !0, { - path: "/", - expires: 30 - }), t.preventDefault(), !1 - } - } - }(jQuery); -String.prototype.replaceAll = function(n, t) { - return this.split(n).join(t) -}; -$.ajaxSetup({ - headers: { - "X-Kendo-Ui-Version": "r3-2016-sp2" - } -}); -! function(n) { - function i() { - var i = document.createElement("smartbanner"), - n = { - WebkitTransition: "webkitTransitionEnd", - MozTransition: "transitionend", - OTransition: "oTransitionEnd otransitionend", - transition: "transitionend" - }; - for (var t in n) - if (i.style[t] !== undefined) return { - end: n[t] - }; - return !1 - } - var t = function(t) { - var f, i, r, u; - if ((this.origHtmlMargin = parseFloat(n("html").css("margin-top")), this.options = n.extend({}, n.smartbanner.defaults, t), f = navigator.standalone, i = navigator.userAgent, this.options.force ? this.type = this.options.force : i.match(/Windows Phone 8/i) != null && i.match(/Touch/i) !== null ? this.type = "windows" : i.match(/iPhone|iPod/i) != null || i.match(/iPad/) && this.options.iOSUniversalApp ? i.match(/Safari/i) != null && (i.match(/CriOS/i) != null || window.Number(i.substr(i.indexOf("OS ") + 3, 3).replace("_", ".")) < 6) && (this.type = "ios") : i.match(/\bSilk\/(.*\bMobile Safari\b)?/) || i.match(/\bKF\w/) || i.match("Kindle Fire") ? this.type = "kindle" : i.match(/Android/i) != null && (this.type = "android"), this.type && !f && !this.getCookie("sb-closed") && !this.getCookie("sb-installed")) && (this.scale = this.options.scale == "auto" ? n(window).width() / window.screen.width : this.options.scale, this.scale < 1 && (this.scale = 1), r = n(this.type == "android" ? 'meta[name="google-play-app"]' : this.type == "ios" ? 'meta[name="apple-itunes-app"]' : this.type == "kindle" ? 'meta[name="kindle-fire-app"]' : 'meta[name="msApplication-ID"]'), r.length != 0)) { - if (this.type == "windows") this.appId = n('meta[name="msApplication-PackageFamilyName"]').attr("content"); - else if (u = /app-id=([^\s,]+)/.exec(r.attr("content")), u) this.appId = u[1]; - else return; - this.title = this.options.title ? this.options.title : r.data("title") || n("title").text().replace(/\s*[|\-·].*$/, ""); - this.author = this.options.author ? this.options.author : r.data("author") || (n('meta[name="author"]').length ? n('meta[name="author"]').attr("content") : window.location.hostname); - this.iconUrl = r.data("icon-url"); - this.price = r.data("price"); - this.create(); - this.show(); - this.listen() - } - }; - (t.prototype = { - constructor: t, - create: function() { - var t, i = this.options.url ? this.options.url : (this.type == "windows" ? "ms-windows-store:navigate?appid=" : this.type == "android" ? "market://details?id=" : this.type == "kindle" ? "amzn://apps/android?asin=" : "https://itunes.apple.com/" + this.options.appStoreLanguage + "/app/id") + this.appId, - u = this.price || this.options.price, - e = u ? u + " - " + (this.type == "android" ? this.options.inGooglePlay : this.type == "kindle" ? this.options.inAmazonAppStore : this.type == "ios" ? this.options.inAppStore : this.options.inWindowsStore) : "", - f = this.options.iconGloss === null ? this.type == "ios" : this.options.iconGloss, - r; - this.type == "android" && this.options.GooglePlayParams && (i = i + "&referrer=" + this.options.GooglePlayParams); - r = '<div id="smartbanner" class="' + this.type + '"><div class="sb-container"><a href="#" class="sb-close">×<\/a><span class="sb-icon"><\/span><div class="sb-info"><strong>' + this.title + "<\/strong><span>" + this.author + "<\/span><span>" + e + '<\/span><\/div><a href="' + i + '" class="sb-button"><span>' + this.options.button + "<\/span><\/a><\/div><\/div>"; - this.options.layer ? n(this.options.appendToSelector).append(r) : n(this.options.appendToSelector).prepend(r); - this.options.icon ? t = this.options.icon : this.iconUrl ? t = this.iconUrl : n('link[rel="apple-touch-icon-precomposed"]').length > 0 ? (t = n('link[rel="apple-touch-icon-precomposed"]').attr("href"), this.options.iconGloss === null && (f = !1)) : n('link[rel="apple-touch-icon"]').length > 0 ? t = n('link[rel="apple-touch-icon"]').attr("href") : n('meta[name="msApplication-TileImage"]').length > 0 ? t = n('meta[name="msApplication-TileImage"]').attr("content") : n('meta[name="msapplication-TileImage"]').length > 0 && (t = n('meta[name="msapplication-TileImage"]').attr("content")); - t ? (n("#smartbanner .sb-icon").css("background-image", "url(" + t + ")"), f && n("#smartbanner .sb-icon").addClass("gloss")) : n("#smartbanner").addClass("no-icon"); - this.bannerHeight = n("#smartbanner").outerHeight() + 2; - this.scale > 1 && (n("#smartbanner").css("top", parseFloat(n("#smartbanner").css("top")) * this.scale).css("height", parseFloat(n("#smartbanner").css("height")) * this.scale).hide(), n("#smartbanner .sb-container").css("-webkit-transform", "scale(" + this.scale + ")").css("-msie-transform", "scale(" + this.scale + ")").css("-moz-transform", "scale(" + this.scale + ")").css("width", n(window).width() / this.scale)); - n("#smartbanner").css("position", this.options.layer ? "absolute" : "static") - }, - listen: function() { - n("#smartbanner .sb-close").on("click", n.proxy(this.close, this)); - n("#smartbanner .sb-button").on("click", n.proxy(this.install, this)) - }, - show: function(t) { - var i = n("#smartbanner"), - r; - i.stop(); - this.options.layer ? (i.animate({ - top: 0, - display: "block" - }, this.options.speedIn).addClass("shown").show(), n(this.pushSelector).animate({ - paddingTop: this.origHtmlMargin + this.bannerHeight * this.scale - }, this.options.speedIn, "swing", t)) : n.support.transition ? (i.animate({ - top: 0 - }, this.options.speedIn).addClass("shown"), r = function() { - n("html").removeClass("sb-animation"); - t && t() - }, n(this.pushSelector).addClass("sb-animation").one(n.support.transition.end, r).emulateTransitionEnd(this.options.speedIn).css("margin-top", this.origHtmlMargin + this.bannerHeight * this.scale)) : i.slideDown(this.options.speedIn).addClass("shown") - }, - hide: function(t) { - var i = n("#smartbanner"), - r; - i.stop(); - this.options.layer ? (i.animate({ - top: -1 * this.bannerHeight * this.scale, - display: "block" - }, this.options.speedIn).removeClass("shown"), n(this.pushSelector).animate({ - paddingTop: this.origHtmlMargin - }, this.options.speedIn, "swing", t)) : n.support.transition ? (this.type !== "android" ? i.css("top", -1 * this.bannerHeight * this.scale).removeClass("shown") : i.css({ - display: "none" - }).removeClass("shown"), r = function() { - n("html").removeClass("sb-animation"); - t && t() - }, n(this.pushSelector).addClass("sb-animation").one(n.support.transition.end, r).emulateTransitionEnd(this.options.speedOut).css("margin-top", this.origHtmlMargin)) : i.slideUp(this.options.speedOut).removeClass("shown") - }, - close: function(n) { - n.preventDefault(); - this.hide(); - this.setCookie("sb-closed", "true", this.options.daysHidden) - }, - install: function() { - this.options.hideOnInstall && this.hide(); - this.setCookie("sb-installed", "true", this.options.daysReminder) - }, - setCookie: function(n, t, i) { - var r = new Date; - r.setDate(r.getDate() + i); - t = encodeURI(t) + (i == null ? "" : "; expires=" + r.toUTCString()); - document.cookie = n + "=" + t + "; path=/;" - }, - getCookie: function(n) { - for (var r, u, i = document.cookie.split(";"), t = 0; t < i.length; t++) - if (r = i[t].substr(0, i[t].indexOf("=")), u = i[t].substr(i[t].indexOf("=") + 1), r = r.replace(/^\s+|\s+$/g, ""), r == n) return decodeURI(u); - return null - }, - switchType: function() { - var t = this; - this.hide(function() { - t.type = t.type == "android" ? "ios" : "android"; - var i = n(t.type == "android" ? 'meta[name="google-play-app"]' : 'meta[name="apple-itunes-app"]').attr("content"); - t.appId = /app-id=([^\s,]+)/.exec(i)[1]; - n("#smartbanner").detach(); - t.create(); - t.show() - }) - } - }, n.smartbanner = function(i) { - var u = n(window), - r = u.data("smartbanner"), - f = typeof i == "object" && i; - r || u.data("smartbanner", r = new t(f)); - typeof i == "string" && r[i]() - }, n.smartbanner.defaults = { - title: null, - author: null, - price: "FREE", - appStoreLanguage: "us", - inAppStore: "On the App Store", - inGooglePlay: "In Google Play", - inAmazonAppStore: "In the Amazon Appstore", - inWindowsStore: "In the Windows Store", - GooglePlayParams: null, - icon: null, - iconGloss: null, - button: "VIEW", - url: null, - scale: "auto", - speedIn: 300, - speedOut: 400, - daysHidden: 15, - daysReminder: 90, - force: null, - hideOnInstall: !0, - layer: !1, - iOSUniversalApp: !0, - appendToSelector: "body", - pushSelector: "html" - }, n.smartbanner.Constructor = t, n.support.transition === undefined) && (n.fn.emulateTransitionEnd = function(t) { - var i = !1, - u = this, - r; - n(this).one(n.support.transition.end, function() { - i = !0 - }); - return r = function() { - i || n(u).trigger(n.support.transition.end) - }, setTimeout(r, t), this - }, n(function() { - n.support.transition = i() - }):) -}(window.jQuery) diff --git a/research/Specyfikacja-GTFS-07.12.2017.pdf b/research/Specyfikacja-GTFS-07.12.2017.pdf deleted file mode 100644 index 0655f1a852018ad8d5a55c9aaa09360f3097e118..0000000000000000000000000000000000000000 Binary files a/research/Specyfikacja-GTFS-07.12.2017.pdf and /dev/null differ diff --git a/research/datasources.md b/research/datasources.md deleted file mode 100644 index 80149196a6eed388c865b5e4a69baef698bdef38..0000000000000000000000000000000000000000 --- a/research/datasources.md +++ /dev/null @@ -1,17 +0,0 @@ -# Poznań API - -* bicycles: http://egov.psnc.pl/node/29#stacje-rowerow-miejskich -* tickets: http://egov.psnc.pl/node/29#punkty-sprzedazy-biletow & http://egov.psnc.pl/node/29#biletomaty -* car park automats: http://egov.psnc.pl/node/29#parkomaty -* real-time timetable: http://egov.psnc.pl/node/29#przystanki -* wireless: http://egov.psnc.pl/node/29#wireless_poznan -* tourism: http://egov.psnc.pl/node/29#turystyka -* P&R: https://www.peka.poznan.pl/SOP/parkings/getAvailableSpaces.jspb -* accidents: https://mympk.mpk.poznan.pl/web/menu -* -* news: -* https://mympk.mpk.poznan.pl/web/categories/aktualnosci [json/html] -* https://ztm.poznan.pl/aktualnosci/rss [rss/html] -* accidents: -* https://mympk.mpk.poznan.pl/web/categories/zdarzenia-komunikacyjne [json/html] -* https://ztm.poznan.pl/komunikaty/rss [rss/html] diff --git a/research/peka-vm-api.md b/research/peka-vm-api.md deleted file mode 100644 index d459a9f1fead3f2bf7e1c98bc8c50f18d19eb012..0000000000000000000000000000000000000000 --- a/research/peka-vm-api.md +++ /dev/null @@ -1,524 +0,0 @@ -# Ostrzeżenie - -Autor tego dokumentu nie jest w jakikolwiek sposób powiązany z ZTM, a informacje służące do jego napisania zostały pozyskane przez analizę kodu wykorzystywanego przez stronę http://www.peka.poznan.pl/vm oraz pakietów wymienianych między serwerem i klientem podczas korzystania z niej. - -# Zapytanie - -Zapytanie wykonywane jest przez HTTP do hosta www.peka.poznan.pl i zasobu `/vm/method.vm` , z parametrem `ts` przekazywanym przez `GET` i zawierającym wynik javascriptowej `new Date().getTime()`. `Content-Type` zapytania musi być ustawione na `application/x-www-form-urlencoded; charset=UTF-8`, w przeciwnym razie znaki spoza standardowego zakresu ASCII nie będą działały poprawnie. - -Wszystkie znaki kodowane są jako UTF-8. - -Dane `POST` zapytania instruują serwer odnośnie funkcji, którą ma on wykonać. Nazwa funkcji mieści się w parametrze `method`, natomiast jej parametry jako JSON w `p0`. Implementacja przepuszcza jeszcze to, co idzie do `p0` przez `Object.toJSON`, ale serwer nie zdaje się zwracać na to uwagi. - -Wygląda na to, że serwer zawsze zwraca 200 OK, nawet gdy wywoła się funkcję, której nie posiada : jako wynik zapytania jest wtedy zwracany pusty JSON. - -Podanie niepoprawnych parametrów do funkcji kończy się zwróceniem obiektu JSON zawierającego komunikat błędu w atrybucie `failure`, np. : -```javascript -{ - "failure":"error: java.lang.reflect.InvocationTargetException" -} -``` - -Poprawne wywołanie funkcji kończy się przesłaniem obiektu zawierającego w sobie obiekt `success`, którego znaczenie jest uzależnione od wywołanej funkcji. Obiekt ten jest pomijany w tym dokumencie w opisie wyjścia danej funkcji. - -W przykładach wykorzystywana jest funkcja `peka_vm_get`, której definicja w Bashu wygląda następująco : -```bash -peka_vm_get() -{ - curl -H 'Content-Type:application/x-www-form-urlencoded; charset=UTF-8' \ - http://www.peka.poznan.pl/vm/method.vm?ts=$(($(date +'%s') * 1000)) \ - -d "method=$1" \ - -d "p0=$2" -} -``` - -Jeśli parametr wejściowy jakiejś funkcji jest "wzorcem", należy go rozumieć jak wyszukiwanie z glob-gwiazdkami po obu stronach wzorca. Wielkość liter jest ignorowana. Powinno być to widoczne w przykładach. - -# Słowniczek -* *bollard* - coś, co najwygodniej chyba wytłumaczyć jako "słupek". Jest to fizyczne miejsce, w którym zatrzymują się pojazdy. Na jeden przystanek może przypadać więcej niż jeden bollard : jeden dla pojazdów jadących w jednym kierunku, a drugi - w drugim. Dochodzą do tego jeszcze osobne punkty przystankowe dla linii nocnych. Przystanek AWF ma na przykład aż siedem takich punktów : dwa tramwajowe na Królowej Jadwigi, jeden tramwajowy na Garbarach, i autobusowe rozrzucone w różnych miejscach. - -# Funkcje -## `getStopPoints` -Pobiera listę przystanków o nazwie pasującej do zadanego wzorca. -### Wejście -* `pattern` - wzorzec, według którego serwer ma szukać przystanku. - -### Wyjście -Tablica zawierająca obiekty, w których mamy : -* `symbol` - identyfikator przystanku używany do późniejszych zapytań -* `name` - pełna nazwa przystanku. - -### Przykład -``` -peka_vm_get getStopPoints '{"pattern":"Pół"}' -``` -```javascript -{ - "success":[ - { - "symbol":"BOZSZ", - "name":"Bolechowo-Os./Zespół Szkół" - }, - { - "symbol":"PRPLN", - "name":"Promnice/Północna" - }, - { - "symbol":"POLW", - "name":"Półwiejska" - } - ] -} -``` - -## `getBollards` -Chyba nieużywana. Dla pustego obiektu przesłanego w zapytaniu pobiera wszystkie bollardy. - -## `getBollardsByStopPoint` -Zwraca listę bollardów dla danego przystanku i listę linii odjeżdżających z niego. - -### Wejście -* `name` : nazwa przystanku, zwrócona w `getStopPoints` - -### Wyjście -Obiekt `bollards`, będący tablicą obiektów `bollard` (opisanym w `getTimes`) i `directions`, który sam jest tablicą obiektów zawierających : -* `returnVariant` : jakiś bool, z tego co widziałem prawie zawsze false. -* `lineName` : nazwa linii odjeżdżającej z danego punktu, -* `direction` : kierunek tejże linii. - -### Przykład -``` -peka_vm_get getBollardsByStopPoint '{"name":"Termy Maltańskie"}' -``` -```javascript -{ - "success":{ - "bollards":[ - { - "directions":[ - { - "returnVariant":false, - "direction":"Rondo Rataje", - "lineName":"84" - }, - { - "returnVariant":false, - "direction":"Termy Maltańskie", - "lineName":"84" - }, - { - "returnVariant":false, - "direction":"Rondo Śródka", - "lineName":"84" - }, - { - "returnVariant":false, - "direction":"Nowe ZOO", - "lineName":"84" - } - ], - "bollard":{ - "symbol":"TEMA22", - "tag":"TEMA01", - "name":"Termy Maltańskie", - "mainBollard":false - } - } - ] - } -} -``` - -## `getBollardsByStreet` -Zwraca listę bollardów znajdujących się przy zadanej ulicy. - -### Wejście -* `name` : nazwa ulicy - -### Wyjście -To samo, co przy `getBollardsByStopPoint`. - -### Przykład -``` -peka_vm_get getBollardsByStreet '{"name":"Lutycka"}' -``` -```javascript -{ - "success":{ - "bollards":[ - { - "directions":[ - { - "returnVariant":false, - "direction":"Szarych Szeregów", - "lineName":"83" - } - ], - "bollard":{ - "symbol":"LU I21", - "tag":"LU I01", - "name":"Lutycka I n/ż", - "mainBollard":false - } - }, - { - "directions":[ - { - "returnVariant":false, - "direction":"Szarych Szeregów", - "lineName":"83" - } - ], - "bollard":{ - "symbol":"LUII21", - "tag":"LUII01", - "name":"Lutycka II n/ż", - "mainBollard":false - } - }, - { - "directions":[ - { - "returnVariant":false, - "direction":"Rondo Śródka", - "lineName":"83" - } - ], - "bollard":{ - "symbol":"LUII22", - "tag":"LUII02", - "name":"Lutycka II n/ż", - "mainBollard":false - } - }, - { - "directions":[ - { - "returnVariant":false, - "direction":"Rondo Śródka", - "lineName":"83" - } - ], - "bollard":{ - "symbol":"LU I22", - "tag":"LU I02", - "name":"Lutycka I n/ż", - "mainBollard":false - } - }, - { - "directions":[ - { - "returnVariant":false, - "direction":"Poznań Główny", - "lineName":"236" - } - ], - "bollard":{ - "symbol":"ROOB22", - "tag":"ROOB02", - "name":"Rondo Obornicka", - "mainBollard":false - } - }, - { - "directions":[ - { - "returnVariant":false, - "direction":"Poznań Główny", - "lineName":"246" - } - ], - "bollard":{ - "symbol":"ROOB21", - "tag":"ROOB01", - "name":"Rondo Obornicka", - "mainBollard":false - } - } - ] - } -} -``` - -## `getBollardsByLine` -Zwraca bollardy, przy których zatrzymuje się dana linia, włącznie z jej wariacjami wynikającymi z wyjazdami/zjazdami z/do zajezdni. - -### Wejście -* `name` : nazwa linii - -### Wyjście -Obiekt `directions`, będący tablicą obiektów zawierających w sobie obiekt `direction` i `bollards`. `direction` zawiera : -* `returnVariant` - chyba `true` dla "powracającego", chociaż trudno mi się domyślić, jakie to ma naprawdę znaczenie. -* `direction` - kierunek jazdy -* `lineName` - nazwę linii. - -`bollards` to natomiast tablica obiektów zawierających wszystkie bollardy, przy których zatrzymuje się dana wariacja linii. Każdy z tych obiektów zawiera to samo, co `bollard` znajdujący się w wyniku `getBollardsByStopPoint`, ale z dodanym `orderNo`, czyli - chyba - kolejny numer przystanku dla linii. Atrybut ten pewnie być użyty do zrekonstruowania trasy danej linii i jej wariacji, ale nie udało mi się znaleźć na to jakiegoś algorytmu. - -### Przykład -Pominięty ze względu na zbyt duży rozmiar. - -## `getLines` -Pobiera linie komunikacji pasujące do zadanego wzorca. - -### Wejście -* `pattern` - -### Wyjście -Tablica zawierająca obiekty, których `name` zawiera pełną nazwę linii. - -### Przykład -``` -peka_vm_get getLines '{"pattern":"16"}' -``` -```javascript -{ - "success":[ - { - "name":"16" - }, - { - "name":"616" - }, - { - "name":"716" - } - ] -} -``` -## `getStreets` -Pobiera listę ulic razem z ich identyfikatorami, pasującymi do zadanego wzorca. - -### Wejście -* `pattern` : wzorzec. - -### Wyjście -Tablica obiektów zawierających `id` ulicy do użycia w późniejszych zapytaniach, oraz `name`, czyli ich pełną nazwę. - -### Przykład -``` -peka_vm_get getStreets '{"pattern":"Gło"}' -``` -```javascript -{ - "success":[ - { - "id":3, - "name":"Głogowska" - }, - { - "id":159, - "name":"Koziegłowy/Gdyńska" - }, - { - "id":270, - "name":"Koziegłowy/Piaskowa" - }, - { - "id":167, - "name":"Koziegłowy/Piłsudskiego" - }, - { - "id":166, - "name":"Koziegłowy/Poznańska" - }, - { - "id":165, - "name":"Koziegłowy/Taczaka" - }, - { - "id":319, - "name":"Kórnik/pl. Niepodległości" - }, - { - "id":277, - "name":"Luboń/Niepodległości" - }, - { - "id":143, - "name":"al. Niepodległości" - }, - { - "id":6, - "name":"zajezdnia Głogowska" - } - ] -} -``` - -## `getTimes` -Pobiera szacowane czasy przyjazdu kolejnych pojazdów na zadany bollard. - -### Wejście -* `symbol` : `tag` bollarda (niestety nie `symbol`, jak mogłoby się wydawać) wyciągnięty przez którąś z wariacji funkcji `getBollards`, dla którego pobrać listę przyjazdów. - -### Wyjście -Dwa obiekty : `bollard` opisujący bollarda i zawierający : - * `symbol` - identyfikator bollarda w systemie, - * `tag` - alternatywny identyfikator?, - * `name` - nazwę przystanku, do którego należy bollard, - * `mainBollard` - na razie widziałem tutaj tylko `false`, ale domyślam się, że może to być `true` dla "jednobollardowych" przystanków. - -Oraz obiekt `times` będący tablicą obiektów zawierających : -* `realTime` - czy przyjazd jest podany w oparciu o położenie pojazdu na podstawie odczytu jego lokalizacji, -* `minutes` - ile minut zostało do przyjazdu, -* `direction` - kierunek trasy, -* `onStopPoint` - czy pojazd aktualnie znajduje się na bollardzie, -* `departure` - szacowany czas odjazdu podany jako `yyyy-MM-dd'T'HH:mm:ss.SSS'Z'`. **Nie** jest to ISO 8601, ponieważ końcowe `Z` sugerowałoby wtedy, że jest on podany w UTC. Tak się jednak nie dzieje : godzina podawana jest w czasie lokalnym , czyli CET albo CEST. -* `line` - linia, którą obsługuje pojazd. - -### Przykład -``` -peka_vm_get getTimes '{"symbol":"AWF03"}' -``` -```javascript -{ - "success":{ - "bollard":{ - "symbol":"AWF03", - "tag":"AWF21", - "name":"AWF", - "mainBollard":false - }, - "times":[ - { - "realTime":true, - "minutes":0, - "direction":"Os. Orła Białego", - "onStopPoint":true, - "departure":"2016-11-25T21:48:00.000Z", - "line":"74" - }, - { - "realTime":true, - "minutes":20, - "direction":"Os. Orła Białego", - "onStopPoint":false, - "departure":"2016-11-25T22:08:00.000Z", - "line":"74" - } - ] - } -} -``` - -## `getTimesForAllBollards` -Pobiera czasy przyjazdu na wszystkich bollardach przypisanych do danego przystanku. Swoiste połączenie `getBollardsByStopPoint` i `getTimes`. - -### Wejście -* `name` : nazwa przystanku. - -### Wyjście -Obiekt `bollardsWithTimes`, będący tablicą struktur opisanych w `getTimes`. - -### Przykład -``` -peka_vm_get getTimesForAllBollards '{"name":"Katowicka"}' -``` -```javascript -{ - "success":{ - "bollardsWithTimes":[ - { - "bollard":{ - "symbol":"KATO22", - "tag":"KATO02", - "name":"Katowicka", - "mainBollard":false - }, - "times":[ - { - "realTime":true, - "minutes":8, - "direction":"Rondo Śródka", - "onStopPoint":false, - "departure":"2016-11-25T22:48:00.000Z", - "line":"57" - }, - { - "realTime":true, - "minutes":13, - "direction":"Termy Maltańskie", - "onStopPoint":false, - "departure":"2016-11-25T22:53:00.000Z", - "line":"84" - } - ] - }, - { - "bollard":{ - "symbol":"KATO21", - "tag":"KATO01", - "name":"Katowicka", - "mainBollard":false - }, - "times":[ - { - "realTime":false, - "minutes":13, - "direction":"Rondo Rataje", - "onStopPoint":false, - "departure":"2016-11-25T22:53:00.000Z", - "line":"84" - }, - { - "realTime":false, - "minutes":24, - "direction":"Mogileńska", - "onStopPoint":false, - "departure":"2016-11-25T23:04:00.000Z", - "line":"57" - } - ] - } - ] - } -} -``` - -## `getServerTime` -Pobiera aktualny czas na serwerze jako coś, co wygląda na liczbę milisekund od 1. stycznia 1970. Na wejściu pusty obiekt. - -### Przykład -``` -peka_vm_get getServerTime '{}' -``` -```javascript -{"success":1480110116917} -``` - -## `findMessagesForBollard` -Zwraca wiadomości zapisane przez administrację serwisu, skojarzone z danym bollardem. Z reguły wykorzystywane do zakomunikowania czasowych zmian w rozkładzie. - -### Wejście -* `symbol` : identyfikator bollarda - -### Wyjście -Tablica obiektów zawierających następujące pola : -* `content` : wiadomość, która ma zostać wyświetlona, jako HTML, -* `startHour`, `stopsGroups` i `endHour` : przeznaczenie nieznane, nie są używane w ogóle przez kod renderujący oficjalną stronę, -* `startDate` : data oznaczająca początek okresu, kiedy komunikat ma zacząć zostać wyświetlany, -* `endDate` : j.w., ale oznaczająca koniec tego okresu. - -Format daty jest taki sam jak ten używany przez pole `departure` w `getTimes`. - -### Przykład -``` -peka_vm_get findMessagesForBollard '{"symbol":"RJEZ04"}' -``` -```javascript -{ - "success":[ - { - "content":"INFO: Od 9 kwietnia, w związku z remontem torowiska na ul. 28 Czerwca 1956 r., zmianie ulegną trasy linii tramwajowych nr 2, 9, 10 i 11. Uruchomiona zostanie komunikacja zastępcza. Szczegóły na stronie <a href=\"http://tiny.pl/g5dss\">www.ztm.poznan.pl<\/a>.", - "startDate":"2017-04-06T01:00:00.000Z", - "stopsGroups":[ - - ], - "startHour":60, - "endDate":"2017-04-11T23:00:00.000Z", - "endHour":1380 - } - ] -} -``` diff --git a/research/pkp b/research/pkp deleted file mode 100644 index 230f97e801f615336f910c6647a0500d61df3088..0000000000000000000000000000000000000000 --- a/research/pkp +++ /dev/null @@ -1,37 +0,0 @@ -https://github.com/bartekmp/infopasazer - -stacja: -curl 'https://portalpasazera.pl/WyszukiwaniePolaczen/StacjeFiltrRead?wprowadzonyTekst=Warszawa' \ --XGET \ --H '387693: 764f49' \ --H 'Referer: https://portalpasazera.pl/WyszukiwaniePolaczen/' \ --H 'Accept: */*' \ --H 'Connection: Keep-Alive' \ --H 'Accept-Encoding: gzip, deflate' \ --H 'Accept-Language: en-gb, en;q=0.90' \ --H 'DNT: 1' \ --H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1 (KHTML, like Gecko) Version/11.0 Safari/605.1 Epiphany/3.26.5.1' \ --H 'Cookie: ASP.NET_SessionId=d4pkbz3xwzewshdm5dqvjxyi; __RequestVerificationToken=XiuyWQvHFRmudTBK2Ke_484x-LZC91Q-1fOwP_AzGT3szmmvdCUVDmNJNpMP6z_HrxjXBy_duOm1l1FP2Asg6Tz1DttmvE8rJc_X0XwOtfY1' \ --H 'aa7cbb: 7d52cc' \ --H 'X-Requested-With: XMLHttpRequest' \ --H 'X-Kendo-Ui-Version: r3-2016-sp2' - -połączenie: -curl 'https://portalpasazera.pl/WyszukiwaniePolaczen/WyszukajPolaczenia' \ --XPOST \ --H 'Referer: https://portalpasazera.pl/WyszukiwaniePolaczen/' \ --H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \ --H 'Origin: https://portalpasazera.pl' \ --H 'Accept: */*' \ --H 'Connection: Keep-Alive' \ --H 'Accept-Encoding: gzip, deflate' \ --H 'Accept-Language: en-gb, en;q=0.90' \ --H 'DNT: 1' \ --H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1 (KHTML, like Gecko) Version/11.0 Safari/605.1 Epiphany/3.26.5.1' \ --H 'Cookie: Section_WP_ThroughStations=1; ASP.NET_SessionId=q43u4zrurf2oh12fcy2td1no; __RequestVerificationToken=6V9CETnBIOhA61_KpfNlmxazzjfjEqk1ZHTKpZQkjn24rtLDqnFpJbCVNi7ariHdA38gslZhTpziDp6kC9EcLLZnHj0vn9BcA1WIEdjGrsk1; cookie=true' \ # Proste do uzyskania Podaje przy dowolnym połączeniu (można zrobić GET / >/dev/null) --H 'Content-Length: 1058' \ --H 'c2e09f: 44952b' \ # to i następna linia musi się zgadzać ze stacjami (jest deterministyczne, zależne od stacji można sprawdzić wszystkie interesujące stacje i zahardcodować (nie wiem, może to się jakoś ma do wyniku StacjeFiltrRead?) --H 'aa7cbb: 7d52cc' \ # To jest poznań Główny --H 'X-Requested-With: XMLHttpRequest' \ --H 'X-Kendo-Ui-Version: r3-2016-sp2' \ ---data 'sort=&group=&filter=&kryteria=%7B%22IdStacjiPoczatkowej%22%3A%22356503%22%2C%22NazwaStacjiPoczatkowej%22%3A%22Lubo%C5%84+ko%C5%82o+Poznania%22%2C%22StacjePosrednie%22%3A%5B%5D%2C%22IdStacjiKoncowej%22%3A%22356701%22%2C%22NazwaStacjiKoncowej%22%3A%22Pozna%C5%84+G%C5%82%C3%B3wny%22%2C%22KategorieSzybkosci%22%3A%5B%22SZ%22%2C%22DA%22%2C%22LO%22%2C%22AG%22%5D%2C%22Uslugi%22%3A%5B%5D%2C%22PolaczenieBezposrednie%22%3Afalse%2C%22GlobalneParametryPolaczenia%22%3Atrue%2C%22Data%22%3A%222018-02-07%22%2C%22Czas%22%3A%2220%3A51%22%2C%22PociagCzynnosc%22%3A%22Odjazd%22%2C%22Przewoznicy%22%3A%5B%22KM%22%2C%22PR%22%2C%22KM%C5%81%22%2C%22%C5%81KA%22%2C%22IC%22%2C%22AR%22%2C%22KD%22%2C%22KS%22%2C%22KW%22%2C%22LEO%22%2C%22ODEG%22%2C%22CARGO%22%2C%22SKMT%22%2C%22SKPL%22%2C%22SKM%22%5D%2C%22MinimalnyCzasNaPrzesiadke%22%3A%2200%3A10%22%2C%22grc%22%3A%22%22%2C%22p%22%3A%22ok%22%7D&rodzaj=NoweWyszukiwanie&zapamietanePolaczenia=null&__RequestVerificationToken=arWI_CJhi7iighRQMaB7eWLKYMUMvW5kA2ObVpS0KjEslYMd1fSBSkrY4Ipi978ZUEktfFvHurtV6XWxk5zF0PORcxv_q0XZp3K6SGYKOnM1' diff --git a/research/svg/departure_timetable.svg b/research/svg/departure_timetable.svg deleted file mode 100644 index 6029c7740978a518e1d4acdd31de22fabd2986a5..0000000000000000000000000000000000000000 --- a/research/svg/departure_timetable.svg +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - fill="#000000" - height="24" - viewBox="0 0 24 24" - width="24" - version="1.1" - id="svg6"> - <metadata - id="metadata12"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs10" /> - <path - d="M0 0h24v24H0z" - fill="none" - id="path2" /> - <path - d="M 19,3 C 12,2.4802944 12,2.481597 5,3 3.89,3 3.01,3.9 3.01,5 L 3,19 c 0,1.1 0.89,2 2,2 h 14 c 1.1,0 2,-0.9 2,-2 V 5 C 21,3.9 20.1,3 19,3 Z m 0,16 H 5 V 8 h 14 z" - id="path4" /> - <path - id="path2-6" - d="m 17,12 h -5 v 5 h 5 z" /> -</svg> diff --git a/research/svg/download.svg b/research/svg/download.svg deleted file mode 100644 index 6e3674ba7937318b725e8eaf6f4d24ca9e570366..0000000000000000000000000000000000000000 --- a/research/svg/download.svg +++ /dev/null @@ -1,4 +0,0 @@ -<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> - <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/> - <path d="M0 0h24v24H0z" fill="none"/> -</svg> \ No newline at end of file diff --git a/research/svg/favourite.svg b/research/svg/favourite.svg deleted file mode 100644 index 742e71af5c709a7bae7e5f54190ee88a5cbc90fb..0000000000000000000000000000000000000000 --- a/research/svg/favourite.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> - <path d="M0 0h24v24H0z" fill="none"/> - <path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/> - <path d="M0 0h24v24H0z" fill="none"/> -</svg> \ No newline at end of file diff --git a/research/svg/info.svg b/research/svg/info.svg deleted file mode 100644 index 5c09d08bd5bd7c3fde49fa77d2878ba4362b21d9..0000000000000000000000000000000000000000 --- a/research/svg/info.svg +++ /dev/null @@ -1,4 +0,0 @@ -<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> - <path d="M0 0h24v24H0z" fill="none"/> - <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/> -</svg> \ No newline at end of file diff --git a/research/svg/more.svg b/research/svg/more.svg deleted file mode 100644 index eba41f0af5c5d918f21ca4f9dd456c684c6bcebc..0000000000000000000000000000000000000000 --- a/research/svg/more.svg +++ /dev/null @@ -1,4 +0,0 @@ -<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"> - <path d="M0 0h24v24H0z" fill="none"/> - <path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/> -</svg> \ No newline at end of file diff --git a/research/svg/nodb.svg b/research/svg/nodb.svg deleted file mode 100644 index 2473baef81e7aad05f75eb66fa272c1d0e321717..0000000000000000000000000000000000000000 --- a/research/svg/nodb.svg +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - id="svg8" - version="1.1" - viewBox="0 0 285.74999 508.00001" - height="1920" - width="1080"> - <defs - id="defs2" /> - <metadata - id="metadata5"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - transform="translate(0,211.00002)" - id="layer1"> - <rect - y="-211.00002" - x="0" - height="508" - width="285.75" - id="rect4485" - style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2.96499991;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <rect - y="130.19077" - x="136.12813" - height="166.80922" - width="13.49375" - id="rect4495" - style="opacity:1;fill:#aaaaaa;fill-opacity:1;stroke:none;stroke-width:5.5416379;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> - <g - id="g5093" - transform="matrix(0.28222223,0,0,0.28222223,100.54167,47.749918)"> - <circle - id="blauwe_cirkel" - cx="150" - cy="150" - r="150" - style="fill:#0e518d;stroke:none" /> - <g - id="symbool_voetpad" /> - <path - style="fill:#ffffff;stroke:none" - id="tram_zwart" - d="m 110.21944,84.81961 -38.897406,26.63158 32.087416,21.98037 H 45.043711 l 1.079393,6.82962 L 40,163.6742 v 29.88939 h 18.545941 l 1.609278,-7.2025 h 62.663691 l 1.60927,7.2025 h 51.14363 l 1.60928,-7.2025 h 62.66369 l 1.60928,7.2025 H 260 V 163.6742 l -6.12311,-23.41302 1.09902,-6.82962 H 117.02943 l 32.0678,-21.98037 z m 0,6.12311 29.90901,20.48884 v 0.0589 l -29.90901,20.50847 -29.909003,-20.50847 v -0.0589 z M 49.891168,140.26118 H 66.454951 V 163.6742 H 43.78769 Z m 20.900982,0 H 98.876004 V 163.6742 H 70.79215 Z m 32.40142,0 h 28.08385 v 23.41302 h -28.08385 z m 32.40143,0 h 28.80999 V 163.6742 H 135.595 Z m 33.12757,0 h 28.08385 v 23.41302 h -28.08385 z m 32.42105,0 h 28.08385 v 23.41302 h -28.08385 z m 32.40143,0 h 16.56378 l 6.10348,23.41302 H 233.54505 Z M 65.885816,191.03192 v 2.45316 c 0,5.35876 4.336163,9.69492 9.694915,9.69492 4.304046,0 7.956129,-2.80368 9.223907,-6.69224 h 13.541476 c 1.26777,3.88856 4.919856,6.69224 9.223906,6.69224 5.35874,0 9.69491,-4.33616 9.69491,-9.69492 l -0.0392,-2.45316 H 65.885867 Z m 116.888494,0 -0.0393,2.45316 c 0,5.35876 4.33617,9.69492 9.69492,9.69492 4.30405,0 7.95613,-2.80368 9.22391,-6.69224 h 13.54148 c 1.26778,3.88856 4.91986,6.69224 9.2239,6.69224 5.35876,0 9.69492,-4.33616 9.69492,-9.69492 v -2.45316 h -51.33987 z" /> - <circle - id="circle3774" - cx="150" - cy="150" - r="141.942" - style="fill:none;stroke:#f7fbf5;stroke-width:6.73600006" /> - </g> - </g> -</svg> diff --git a/research/svg/textHandle_left.svg b/research/svg/textHandle_left.svg deleted file mode 100644 index e929f21ce40749c272b2386ffcb847e25d98f78d..0000000000000000000000000000000000000000 --- a/research/svg/textHandle_left.svg +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 176 88" - height="88" - width="176" - id="svg2" - version="1.1"> - <metadata - id="metadata8"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs6" /> - <path - id="path817" - d="M 88,0 A 44,44 0 0 0 44,44 44,44 0 0 0 88,88 44,44 0 0 0 132,44 V 0 Z" - style="opacity:1;fill:#54af39;fill-opacity:1;stroke:none;stroke-width:0.01982322;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> -</svg> diff --git a/research/svg/textHandle_middle.svg b/research/svg/textHandle_middle.svg deleted file mode 100644 index 4e8b5c388a1d204b1f2f0c44766b611759e23728..0000000000000000000000000000000000000000 --- a/research/svg/textHandle_middle.svg +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 87.999999 87.999998" - height="88" - width="88" - id="svg2" - version="1.1"> - <metadata - id="metadata8"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs6" /> - <path - id="path817" - d="m 69.774698,25.774604 a 36.450926,36.45079 0 0 1 0,51.549207 36.450926,36.45079 0 0 1 -51.549395,0 36.450926,36.45079 0 0 1 0,-51.549207 L 44,0 Z" - style="opacity:1;fill:#54af39;fill-opacity:1;stroke:none;stroke-width:0.01642212;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> -</svg> diff --git a/research/svg/textHandle_right.svg b/research/svg/textHandle_right.svg deleted file mode 100644 index 6db4aeec1cbb7dc1696d4d3db08884a2708e7873..0000000000000000000000000000000000000000 --- a/research/svg/textHandle_right.svg +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 176 88" - height="88" - width="176" - id="svg2" - version="1.1"> - <metadata - id="metadata8"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs6" /> - <path - id="path817" - d="M 88,0 A 44,44 0 0 1 132,44 44,44 0 0 1 88,88 44,44 0 0 1 44,44 V 0 Z" - style="opacity:1;fill:#54af39;fill-opacity:1;stroke:none;stroke-width:0.01982322;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> -</svg> diff --git a/research/svg/timetable_full.svg b/research/svg/timetable_full.svg deleted file mode 100644 index 426d183ff1bf2bb4135985e6d2a9826fea215d52..0000000000000000000000000000000000000000 --- a/research/svg/timetable_full.svg +++ /dev/null @@ -1,35 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - id="svg6" - version="1.1" - width="24" - viewBox="0 0 24 24" - height="24" - fill="#000000"> - <metadata - id="metadata12"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs10" /> - <path - id="path2" - fill="none" - d="M0 0h24v24H0z" /> - <path - id="path4" - d="M 17,10 H 7 v 2 H 17 Z M 19,3 C 12,2.4802944 12,2.481597 5,3 3.89,3 3.01,3.9 3.01,5 L 3,19 c 0,1.1 0.89,2 2,2 h 14 c 1.1,0 2,-0.9 2,-2 V 5 C 21,3.9 20.1,3 19,3 Z m 0,16 H 5 V 8 H 19 Z M 14,14 H 7 v 2 h 7 z" /> -</svg> diff --git a/research/svg/vm.svg b/research/svg/vm.svg deleted file mode 100644 index e22fcf65b5ff9e600b9354f88bfdaa59d09e04c3..0000000000000000000000000000000000000000 --- a/research/svg/vm.svg +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - id="svg6" - version="1.1" - width="24" - viewBox="0 0 24 24" - height="24" - fill="#000000" - sodipodi:docname="vm.svg" - inkscape:version="0.92.1 r"> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1368" - inkscape:window-height="744" - id="namedview64" - showgrid="false" - inkscape:zoom="21.166667" - inkscape:cx="12" - inkscape:cy="12" - inkscape:window-x="0" - inkscape:window-y="24" - inkscape:window-maximized="0" - inkscape:current-layer="svg6" /> - <metadata - id="metadata12"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs10" /> - <path - id="path2" - fill="none" - d="M0 0h24v24H0z" /> - <path - d="M 12 4 C 9.11 4 6.5996094 5.6390625 5.3496094 8.0390625 C 2.3396094 8.3590625 -1.1842379e-15 10.91 0 14 C 0 17.31 2.69 20 6 20 L 19 20 C 21.76 20 24 17.76 24 15 C 24 12.36 21.949609 10.219062 19.349609 10.039062 C 18.669609 6.5890625 15.64 4 12 4 z M 4.4042969 10.652344 L 5.921875 10.652344 L 7.4179688 15.642578 L 8.921875 10.652344 L 10.443359 10.652344 L 8.1328125 17.289062 L 6.7070312 17.289062 L 4.4042969 10.652344 z M 11.072266 10.652344 L 12.859375 10.652344 L 14.5625 15.464844 L 16.257812 10.652344 L 18.054688 10.652344 L 18.054688 17.289062 L 16.681641 17.289062 L 16.681641 15.474609 L 16.818359 12.34375 L 15.027344 17.289062 L 14.089844 17.289062 L 12.302734 12.347656 L 12.439453 15.474609 L 12.439453 17.289062 L 11.072266 17.289062 L 11.072266 10.652344 z " - id="path4" /> -</svg> diff --git a/settings.gradle b/settings.gradle index e7b4def49cb53d9aa04228dd3edb14c9e635e003..65d6741bf7ac4b9016dfb6c839a41deb33027086 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,18 @@ +pluginManagement { + repositories { + gradlePluginPortal() + google() + mavenCentral() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + maven { url "https://jitpack.io" } + } +} +rootProject.name = "Bimba" include ':app' +include ':fruchtfleisch' diff --git a/todo b/todo deleted file mode 100644 index 5c7be496093f80354c8a4ec93be87fcd0494c742..0000000000000000000000000000000000000000 --- a/todo +++ /dev/null @@ -1,19 +0,0 @@ -- acra: https://stackoverflow.com/questions/601503/how-do-i-obtain-crash-data-from-my-android-application -v empty search result -- search results loading [?] -- search results history [?] -v shed loading -v departures loading -v departures empty -- search result retry -- shed retry -- departures retry -x search results flickering -- favourite cache -v in a moment -v departures sort (timeTill, onStop) : StopActivity -v sort and limit search results -T PEKA info -- check update (only in APK builds) -- settings day/night -- ‘no conn…’ only w/o timetable