JSDM

HTML

126
1
<svg class='svg' id="intro" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="669.2px" height="200.2px" viewBox="0 0 669.2 200.2" enable-background="new 0 0 669.2 200.2" xml:space="preserve">
2
        <g class='text-chinese'>
3
        <path data-start="0" data-duration="10" fill="white" d="M282.4,108.2h-3.8l8.1,7h-15.4l-15.7-14.9L235,115.1h-15.101l10.2-7h-9l3.5-19.801H291.4l-2.5,13.9   C288.2,106.2,286.101,108.2,282.4,108.2z M240.8,87.2h-16l1.8-2h-1.5l0.7-4.1h6.1l0.301-1.7H226.1l0.601-3.5h6.1l0.3-1.5H227   l0.7-3.8h6.1l0.3-1.7H248l-0.3,1.7h26.7l0.3-1.7h13.9l-0.301,1.7h6.101l-0.7,3.8h-6.1l-0.301,1.5h6.101l-0.601,3.5h-6.1l-0.3,1.7   h6.1l-0.7,4.1h-1.699l1.399,2h-16.3l-1.1-2h-31.4L240.8,87.2z M240.899,66.6l-0.199,0.9h-12.5l1-5.5H255.6l-0.5-2H269l0.2,2h26.7   l-1,5.5h-12.3l0.199-0.9H240.899z M275.9,105.2l2.2-12.5H236.3l-2.2,12.2l15.4-11.3h15.4l-7.4,5.5h11.9L275.9,105.2z M246.2,79.4   l-0.301,1.7h26.701l0.3-1.7H246.2z M247.1,74.5l-0.3,1.5h26.7l0.3-1.5H247.1z" style="stroke-dasharray: 849px, 851px; stroke-dashoffset: 0px;"></path>
4
        </g>
5
        <g class='text-chinese'>
6
        <path data-start="0" data-duration="10" fill="white" d="M303,65.5l1-5.5h66.8l-1,5.5h-9.6l-2,11.299l10.1-2.899l-1.5,8.399l-10.1,2.9l-4.4,25h9.601l-0.9,4.9h-66.8   l0.9-4.9H305l4.3-24.4l-9.3-3.5l1.5-8.399l9.2,3.8l2.2-12.199H303L303,65.5z M328.3,65.5L320.4,110.2H337l3.601-20.6l-4.301,1.199   l1.4-8.1L342,81.5l2.8-16H328.3z" style="stroke-dasharray: 459px, 461px; stroke-dashoffset: 0px;"></path>
7
        </g>
8
        <g class='text-chinese'>
9
        <path data-start="0" data-duration="10" fill="white" d="M371.2,115.1l8.5-48.2l-2.7,0.3l1-5.5L393.4,60l-9.7,55.199h-12.5V115.1z M427.101,59.9l-0.5,2.899h18   l-1,5.5h-2.9l-5.3,46.801h-11.3l5.3-46.801h-3.8l-6.2,35.4h4.899l-1,5.5H418.4c-0.4,4.5-3.101,6.4-8,5.801h-7l1-5.801h-6.7   L396.4,115h-11.3L396.3,68.2H393.4l1-5.5h18.3l0.5-2.9h13.9V59.9z M405.4,103.799l6.2-35.399h-4l-8.301,35.399H405.4z" style="stroke-dasharray: 554px, 556px; stroke-dashoffset: 0px;"></path>
10
        </g>
11
        <g class='text-chinese'>
12
        <path data-start="0" data-duration="10" fill="white" d="M459.7,107.299l1.2-7L444.8,104.1l1.2-6.7l16-3.5l1.101-6.101h-15.4l3.4-19.5h11l-2.5,13.9H475l-4.899,27.9   c-0.301,3.699-2.4,5.3-6.4,4.9h-16.8l0.899-4.9h8.4C458.4,110.4,459.5,109.4,459.7,107.299z M464.3,79.4l2.5-13.899h-15.1l1-5.5   h26.4l-3.4,19.5h-11.4V79.4z M504.5,82.299h11l-6.399,27.9h1.5l-0.9,4.9h-38.9l0.9-4.9h26.4L504.5,82.299z M486.2,82.299l-3.2,26.4   h-9.899l3.5-26.4H486.2z M477.101,79.4l1-5.5H517l-1,5.5H477.101z M483.2,59.9h33.4l0.8,12.2h-11l-0.3-6.7h-13.9l-2.6,6.7h-11   L483.2,59.9z M499,82.299l-3.2,26.4h-9.6l3.2-26.4H499z" style="stroke-dasharray: 782px, 784px; stroke-dashoffset: 0px;"></path>
13
        </g>
14
        <g class='text-chinese'>
15
        <path data-start="0" data-duration="10" fill="white" d="M537.601,75.6l0.5-2.6h-13.4l1-5.5h13.4l0.399-2h-13.399l1-5.5H557l-1,5.5h-3.2l-0.399,2h3.2l-1,5.5h-3.2   l-0.5,2.6h2.899l-1,5.5H549.9l-5.9,33.4h-13.4l5.9-33.4h-0.6c-1.7-0.2-2.601,0.4-2.601,1.699l-5.6,31.701h-10.5l5.9-33.4   c0.1-4.1,2.699-5.9,7.699-5.5H537.601L537.601,75.6z M587.4,96.5l-1,5.5l-1.8,0.299L582.3,115.1H568.4l2-11.301l-21,2l1-5.5l21-2   l2.2-12.5l-19.7-2l1-5.799l19.7,2l1.5-8.701l-19.4-2l1-5.799l19.4,2l1-5.5H592L585.5,96.9L587.4,96.5z" style="stroke-dasharray: 568px, 570px; stroke-dashoffset: 0px;"></path>
16
        </g>
17
        <g class='text-chinese'>
18
        <path data-start="0" data-duration="10" fill="white" d="M623.601,75.6l-1,5.8l-3,0.601l-5,28.199c-0.301,3.7-2.4,5.301-6.4,4.9h-16.8l0.899-4.9h5.801   c2.1,0.4,3.1-0.6,3.1-2.9l3.8-21.5l-8.8,2l1-5.799l8.8-2l2-11.601h-8.399l1-5.5H609L609.5,60h13.9l-0.5,2.899h2.899l-1,5.5H621.9   l-1.4,7.8L623.601,75.6z M666.7,68.4h-13.4l-0.7,4.101H666l-0.6,3.199c-0.2,1.9-1,3.7-2.7,5.2l-8.6,10.7l4.3,23.5h-14.5L640.8,98   l-9.1,17.1h-14.5l12.3-23.5l-5.2-11.9h14.5l3.7,8.4l6.7-8.4c0.7-0.8,0.3-1.3-1.2-1.5c0.2,0,0.101,0-0.3,0h-23.5l1-5.8h13.4   l0.699-4.101H625.9l1-5.5H640.3l0.5-2.899h13.9l-0.5,2.899h13.4L666.7,68.4z" style="stroke-dasharray: 541px, 543px; stroke-dashoffset: 0px;"></path>
19
        </g>
20
        <g class='text-english'>
21
        <path fill="white" d="M227.899,132.1L224.5,133c-0.2-2.301-1.2-3.5-3.101-3.5c-2.199,0-3.5,0.799-3.8,2.5   c-0.399,1,0.7,1.799,3.3,2.398c4.5,0.9,6.5,3,5.801,6.301c-0.801,3.699-3.4,5.6-7.9,5.699c-4.4,0.201-6.6-1.898-6.7-6.199l3.4-0.9   c0,2.9,1.2,4.301,3.8,4.201c2.4-0.102,3.8-1,4.2-2.9c0.3-1.301-0.9-2.301-3.601-2.9c-4.3-1.1-6.199-3-5.6-5.699   c0.9-3.602,3.4-5.5,7.6-5.602C225.899,126.5,227.899,128.299,227.899,132.1z" style="stroke-dasharray: 99px, 101px; stroke-dashoffset: 0px;"></path>
22
        </g>
23
        <g class='text-english'>
24
        <path fill="white" d="M245.8,126.799l-8.1,11.1l-1.5,8.4h-3.301l1.5-8.299l-4.1-11.201h3.4l2.8,8.5l5.8-8.5H245.8z" style="stroke-dasharray: 73px, 75px; stroke-dashoffset: 0px;"></path>
25
        </g>
26
        <g class='text-english'>
27
        <path fill="white" d="M256.2,146.299l-0.7-4.6h-7l-2.4,4.6h-3.3l10.4-19.5h2.8l3.6,19.5H256.2z M250.1,138.5h4.9l-1.2-7.102   L250.1,138.5z" style="stroke-dasharray: 89px, 91px; stroke-dashoffset: 0px;"></path>
28
        </g>
29
        <g class='text-english'>
30
        <path fill="white" d="M271.9,143.399h8.8l-0.5,2.9H268.1l3.4-19.5h11.7l-0.5,3.1h-8.4l-0.8,4.701h7.7l-0.6,3.199h-7.7   L271.9,143.399z" style="stroke-dasharray: 96px, 98px; stroke-dashoffset: 0px;"></path>
31
        </g>
32
        <g class='text-english'>
33
        <path fill="white" d="M284.3,131.799h3.4l2,4.9l3.6-4.9h3.4L291,139l3.4,7.199h-3.7l-1.8-5l-3.9,5h-3.6l6.2-7.301L284.3,131.799z   " style="stroke-dasharray: 72px, 74px; stroke-dashoffset: 0px;"></path>
34
        </g>
35
        <g class='text-english'>
36
        <path fill="white" d="M298.4,150.399h-3.3l3.3-18.6h3.2l-0.2,1.4c1.2-1.199,2.6-1.801,4.1-1.801c3.5,0.301,4.9,2.9,4.2,7.602   c-0.9,5-3.4,7.5-7.3,7.5c-1.4,0-2.5-0.5-3-1.4L298.4,150.399z M300.4,138.399l-0.3,1.9c-0.301,2.301,0.399,3.5,2.3,3.5   c2.1,0,3.5-1.6,4-4.699c0.5-3-0.3-4.5-2.3-4.6C302.2,134.5,301,135.799,300.4,138.399z" style="stroke-dasharray: 88px, 90px; stroke-dashoffset: 0px;"></path>
37
        </g>
38
        <g class='text-english'>
39
        <path fill="white" d="M319.7,141.2l2.9,0.9c-1.4,3.1-3.601,4.6-6.601,4.5c-3.899-0.1-5.5-2.6-4.8-7.301c1.1-5,3.6-7.6,7.5-7.9   c3.9,0.102,5.4,2.801,4.5,7.9l-0.2,1h-8.7c-0.1,2.301,0.601,3.4,2.2,3.5C317.9,143.899,319,143,319.7,141.2z M314.9,137.399h5.3   c0.3-1.898-0.4-2.898-2-2.898S315.5,135.5,314.9,137.399z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
40
        </g>
41
        <g class='text-english'>
42
        <path fill="white" d="M334.5,132.399l-1.899,3c-0.4-0.398-0.801-0.6-1.301-0.6c-1.399,0-2.3,1.201-2.699,3.701l-1.4,7.799H324   l2.601-14.5h3.199l-0.199,1.301c0.899-1.1,1.8-1.6,2.699-1.6C333.2,131.5,334,131.799,334.5,132.399z" style="stroke-dasharray: 47px, 49px; stroke-dashoffset: 0px;"></path>
43
        </g>
44
        <g class='text-english'>
45
        <path fill="white" d="M336.101,131.799h3.3l-2.601,14.5h-3.199L336.101,131.799z M337,126.799h3.3l-0.7,3.801h-3.3L337,126.799z" style="stroke-dasharray: 51px, 53px; stroke-dashoffset: 0px;"></path>
46
        </g>
47
        <g class='text-english'>
48
        <path fill="white" d="M349,141.2l2.9,0.9c-1.4,3.1-3.601,4.6-6.601,4.5c-3.899-0.1-5.5-2.6-4.8-7.301c1.101-5,3.601-7.6,7.5-7.9   c3.9,0.102,5.4,2.801,4.5,7.9l-0.2,1h-8.699c-0.101,2.301,0.6,3.4,2.199,3.5C347.3,143.899,348.3,143,349,141.2z M344.2,137.399   h5.3c0.3-1.898-0.399-2.898-2-2.898C345.9,134.5,344.8,135.5,344.2,137.399z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
49
        </g>
50
        <g class='text-english'>
51
        <path fill="white" d="M366.8,137.299l-1.6,9h-3.3l1.6-8.9c0.3-1.898-0.2-2.898-1.6-2.898c-2,0.1-3.3,1.199-3.8,3.199l-1.5,8.6   h-3.2l2.6-14.5h3.2L359,133.1c1.3-1.1,2.7-1.701,4.101-1.701C366.101,131.6,367.4,133.6,366.8,137.299z" style="stroke-dasharray: 75px, 77px; stroke-dashoffset: 0px;"></path>
52
        </g>
53
        <g class='text-english'>
54
        <path fill="white" d="M379.7,136.1l-3.2,1c0.101-1.801-0.5-2.6-1.7-2.6c-1.5,0.1-2.6,1.699-3.2,4.699c-0.5,3,0,4.5,1.601,4.5   c1.2,0,2.1-1,2.7-3.1l3,0.799c-1.3,3.602-3.4,5.4-6.3,5.301c-3.601-0.1-5-2.5-4.301-7.301c1-5.1,3.301-7.699,6.9-7.898   C378.2,131.399,379.601,133,379.7,136.1z" style="stroke-dasharray: 64px, 66px; stroke-dashoffset: 0px;"></path>
55
        </g>
56
        <g class='text-english'>
57
        <path fill="white" d="M389.101,141.2l2.899,0.9c-1.399,3.1-3.6,4.6-6.6,4.5c-3.9-0.1-5.5-2.6-4.8-7.301c1.1-5,3.6-7.6,7.5-7.9   c3.899,0.102,5.399,2.801,4.5,7.9l-0.2,1h-8.7c-0.101,2.301,0.6,3.4,2.2,3.5C387.3,143.899,388.4,143,389.101,141.2z    M384.3,137.399h5.301c0.3-1.898-0.4-2.898-2-2.898C386,134.5,384.9,135.5,384.3,137.399z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
58
        </g>
59
        <g class='text-english'>
60
        <path fill="white" d="M411.8,135.6l-3.199,0.9c-0.101-1.4-0.801-2.102-1.9-2.102c-1.3,0.102-2.1,0.5-2.3,1.4   c-0.3,0.801,0.6,1.301,2.399,1.701c3.2,0.6,4.601,2.199,4.2,4.6c-0.6,2.9-2.7,4.4-6.3,4.5c-2.9,0.1-4.5-1.5-4.8-4.701l3.1-0.799   c0.101,1.9,0.9,2.799,2.2,2.699c1.6,0,2.4-0.6,2.6-1.699c0.101-0.801-0.6-1.301-2.199-1.6c-3.5-0.602-4.9-2.201-4.4-4.602   c0.7-2.898,2.6-4.398,5.8-4.5C410.101,131.5,411.601,132.899,411.8,135.6z" style="stroke-dasharray: 72px, 74px; stroke-dashoffset: 0px;"></path>
61
        </g>
62
        <g class='text-english'>
63
        <path fill="white" d="M423.8,136.1l-3.199,1c0.1-1.801-0.5-2.6-1.7-2.6c-1.5,0.1-2.601,1.699-3.2,4.699c-0.5,3,0,4.5,1.6,4.5   c1.2,0,2.101-1,2.7-3.1l3,0.799c-1.3,3.602-3.399,5.4-6.3,5.301c-3.6-0.1-5-2.5-4.3-7.301c1-5.1,3.3-7.699,6.899-7.898   C422.3,131.399,423.7,133,423.8,136.1z" style="stroke-dasharray: 64px, 66px; stroke-dashoffset: 0px;"></path>
64
        </g>
65
        <g class='text-english'>
66
        <path fill="white" d="M426.9,131.799h3.3l-2.601,14.5h-3.3L426.9,131.799z M427.8,126.799h3.301l-0.7,3.801h-3.3L427.8,126.799z" style="stroke-dasharray: 51px, 53px; stroke-dashoffset: 0px;"></path>
67
        </g>
68
        <g class='text-english'>
69
        <path fill="white" d="M439.8,141.2l2.9,0.9c-1.4,3.1-3.6,4.6-6.6,4.5c-3.9-0.1-5.5-2.6-4.801-7.301c1.101-5,3.601-7.6,7.5-7.9   c3.9,0.102,5.4,2.801,4.5,7.9l-0.199,1h-8.7c-0.101,2.301,0.6,3.4,2.2,3.5C438.101,143.899,439.101,143,439.8,141.2z    M435.101,137.399h5.3c0.3-1.898-0.4-2.898-2-2.898C436.7,134.5,435.7,135.5,435.101,137.399z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
70
        </g>
71
        <g class='text-english'>
72
        <path fill="white" d="M457.7,137.299l-1.6,9H452.8l1.601-8.9c0.3-1.898-0.2-2.898-1.601-2.898c-2,0.1-3.3,1.199-3.8,3.199   l-1.5,8.6h-3.2l2.601-14.5h3.2l-0.2,1.301c1.3-1.1,2.7-1.701,4.1-1.701C456.9,131.6,458.2,133.6,457.7,137.299z" style="stroke-dasharray: 75px, 77px; stroke-dashoffset: 0px;"></path>
73
        </g>
74
        <g class='text-english'>
75
        <path fill="white" d="M470.5,136.1l-3.2,1c0.101-1.801-0.5-2.6-1.7-2.6c-1.5,0.1-2.6,1.699-3.199,4.699c-0.5,3,0,4.5,1.6,4.5   c1.2,0,2.1-1,2.7-3.1l3,0.799c-1.3,3.602-3.4,5.4-6.3,5.301c-3.601-0.1-5-2.5-4.3-7.301c1-5.1,3.3-7.699,6.899-7.898   C469,131.399,470.5,133,470.5,136.1z" style="stroke-dasharray: 64px, 66px; stroke-dashoffset: 0px;"></path>
76
        </g>
77
        <g class='text-english'>
78
        <path fill="white" d="M479.9,141.2l2.899,0.9c-1.399,3.1-3.6,4.6-6.6,4.5c-3.9-0.1-5.5-2.6-4.8-7.301c1.1-5,3.6-7.6,7.5-7.9   c3.899,0.102,5.399,2.801,4.5,7.9l-0.2,1h-8.7c-0.1,2.301,0.601,3.4,2.2,3.5C478.101,143.899,479.2,143,479.9,141.2z    M475.101,137.399h5.3c0.3-1.898-0.4-2.898-2-2.898C476.8,134.5,475.7,135.5,475.101,137.399z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
79
        </g>
80
        <g class='text-english'>
81
        <path fill="white" d="M502.101,146.299H498.8c-0.199-0.4-0.399-0.9-0.399-1.5c-1,1.301-2.4,1.801-4,1.801   c-2.7-0.1-3.9-1.4-3.5-4.1c0.5-2.801,2.3-4.4,5.399-4.9c1.4-0.201,2.5-0.5,3.2-0.801c0.2-1.4-0.399-2.199-1.7-2.299   c-1.3,0-2.199,0.799-2.899,2.398L492,136.1c1.4-3.1,3.5-4.6,6.3-4.6c3.4,0.1,4.7,2.1,4.101,6.199l-0.9,4.9   C501.4,144.1,501.5,145.399,502.101,146.299z M498.9,140.5l0.1-0.801c-0.6,0.4-1.5,0.699-2.7,0.9c-1.5,0.299-2.3,0.799-2.399,1.799   c-0.101,0.9,0.399,1.301,1.399,1.4C497.3,143.6,498.4,142.5,498.9,140.5z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
82
        </g>
83
        <g class='text-english'>
84
        <path fill="white" d="M517.7,137.299l-1.6,9H512.8l1.601-8.9c0.3-1.898-0.2-2.898-1.601-2.898c-2,0.1-3.3,1.199-3.8,3.199   l-1.5,8.6h-3.2l2.601-14.5h3.2l-0.2,1.301c1.3-1.1,2.7-1.701,4.1-1.701C517,131.6,518.3,133.6,517.7,137.299z" style="stroke-dasharray: 75px, 77px; stroke-dashoffset: 0px;"></path>
85
        </g>
86
        <g class='text-english'>
87
        <path fill="white" d="M531.101,126.7h3.3l-3.4,19.6h-3.399l0.199-1.199c-0.899,1-2.199,1.5-3.899,1.5c-3.9,0.1-5.4-2.4-4.5-7.301   c1-5.1,3.5-7.699,7.5-7.799c1.399,0,2.5,0.5,3.1,1.6L531.101,126.7z M528.7,139.899L529,138c0.3-2.301-0.5-3.4-2.5-3.5   c-2.1,0.1-3.4,1.6-3.9,4.699s0.2,4.6,2.301,4.6C527,143.799,528.3,142.5,528.7,139.899z" style="stroke-dasharray: 91px, 93px; stroke-dashoffset: 0px;"></path>
88
        </g>
89
        <g class='text-english'>
90
        <path fill="white" d="M547.2,143.6l0.2,2.4c-1.101,0.398-2.101,0.6-3,0.699c-2.5,0.1-3.4-1.1-2.9-3.6l1.5-8.301h-2l0.5-2.9h2   l0.6-3.5l3.601-1.6l-0.9,5.1h2.7l-0.5,2.9h-2.7L544.9,143c-0.2,0.799,0,1.1,0.699,1C545.8,143.899,546.4,143.799,547.2,143.6z" style="stroke-dasharray: 60px, 62px; stroke-dashoffset: 0px;"></path>
91
        </g>
92
        <g class='text-english'>
93
        <path fill="white" d="M558.601,141.2l2.899,0.9c-1.399,3.1-3.6,4.6-6.6,4.5c-3.9-0.1-5.5-2.6-4.8-7.301c1.1-5,3.6-7.6,7.5-7.9   c3.899,0.102,5.399,2.801,4.5,7.9l-0.2,1h-8.7c-0.1,2.301,0.6,3.4,2.2,3.5C556.8,143.899,557.9,143,558.601,141.2z M553.8,137.399   h5.301c0.3-1.898-0.4-2.898-2-2.898C555.5,134.5,554.4,135.5,553.8,137.399z" style="stroke-dasharray: 78px, 80px; stroke-dashoffset: 0px;"></path>
94
        </g>
95
        <g class='text-english'>
96
        <path fill="white" d="M574.601,136.1l-3.2,1c0.1-1.801-0.5-2.6-1.7-2.6c-1.5,0.1-2.6,1.699-3.2,4.699c-0.5,3,0,4.5,1.7,4.5   c1.2,0,2.1-1,2.7-3.1l3,0.799c-1.3,3.602-3.4,5.4-6.3,5.301c-3.601-0.1-5-2.5-4.301-7.301c1-5.1,3.301-7.699,6.9-7.898   C573.101,131.399,574.601,133,574.601,136.1z" style="stroke-dasharray: 64px, 66px; stroke-dashoffset: 0px;"></path>
97
        </g>
98
        <g class='text-english'>
99
        <path fill="white" d="M588.4,137.2l-1.601,9.1h-3.3l1.601-8.9c0.3-1.898-0.2-2.898-1.601-2.898c-1.899,0.1-3.1,1.199-3.6,3.199   l-1.5,8.6h-3.3l3.399-19.5h3.3L580.7,133c1.2-1.102,2.5-1.602,3.9-1.602C587.7,131.5,589,133.399,588.4,137.2z" style="stroke-dasharray: 85px, 87px; stroke-dashoffset: 0px;"></path>
100
        </g>
101
        <g class='text-english'>
102
        <path fill="white" d="M603.101,137.299l-1.601,9h-3.3l1.6-8.9c0.301-1.898-0.199-2.898-1.6-2.898c-2,0.1-3.3,1.199-3.8,3.199   l-1.5,8.6h-3.2l2.6-14.5h3.2l-0.2,1.301c1.301-1.1,2.7-1.701,4.101-1.701C602.3,131.6,603.601,133.6,603.101,137.299z" style="stroke-dasharray: 75px, 77px; stroke-dashoffset: 0px;"></path>
103
        </g>
104
        <g class='text-english'>
105
        <path fill="white" d="M612.8,131.399c4.2,0.201,5.9,2.801,5.2,7.701c-0.899,5-3.6,7.5-8,7.5c-4.2-0.201-5.899-2.6-5.2-7.301   C605.9,134.299,608.5,131.7,612.8,131.399z M610.601,143.899c2.199-0.1,3.6-1.699,4.199-4.6c0.601-3.199-0.199-4.799-2.399-4.9   c-2.2,0.102-3.601,1.801-4.2,4.9C607.7,142.2,608.5,143.7,610.601,143.899z" style="stroke-dasharray: 72px, 74px; stroke-dashoffset: 0px;"></path>
106
        </g>
107
        <g class='text-english'>
108
        <path fill="white" d="M622.7,126.799h3.3l-3.399,19.5H619.3L622.7,126.799z" style="stroke-dasharray: 47px, 49px; stroke-dashoffset: 0px;"></path>
109
        </g>
110
        <g class='text-english'>
111
        <path fill="white" d="M634.101,131.399C638.3,131.6,640,134.2,639.3,139.1c-0.899,5-3.6,7.5-8,7.5   c-4.199-0.201-5.899-2.6-5.199-7.301C627.2,134.299,629.9,131.7,634.101,131.399z M631.9,143.899c2.2-0.1,3.6-1.699,4.2-4.6   c0.6-3.199-0.2-4.799-2.4-4.9c-2.2,0.102-3.6,1.801-4.2,4.9C629,142.2,629.8,143.7,631.9,143.899z" style="stroke-dasharray: 72px, 74px; stroke-dashoffset: 0px;"></path>
112
        </g>
113
        <g class='text-english'>
114
        <path fill="white" d="M651.5,131.7h3.3l-2.199,12.199c-0.7,4.301-3.301,6.4-7.801,6.301c-2,0-3.6-0.801-4.899-2.301l2.1-2.199   c1.2,0.9,2.3,1.4,3.3,1.4c2.3,0,3.5-0.801,3.8-2.4c-0.899,0.801-2.199,1.199-3.8,1.199c-3.6-0.199-5.1-2.5-4.399-7   c1-4.799,3.5-7.398,7.3-7.6c1.399,0,2.5,0.5,3,1.5L651.5,131.7z M650.101,139.7l0.3-1.9c0.3-2.199-0.4-3.4-2.2-3.5   c-2.1,0.1-3.5,1.6-4.1,4.6c-0.4,2.801,0.399,4.201,2.3,4.301C648.4,143.299,649.601,142.1,650.101,139.7z" style="stroke-dasharray: 99px, 101px; stroke-dashoffset: 0px;"></path>
115
        </g>
116
        <g class='text-english'>
117
        <path fill="white" d="M656.3,131.799h3.4l1.5,9.5l4.6-9.5h3.4l-7.8,14.301c-1.4,2.9-3.101,4.299-5.101,4.1   c-0.8,0-1.6-0.301-2.5-0.801L654.9,147c0.1,0,0.2,0,0.3,0.1c0.5,0.199,0.9,0.299,1.4,0.299c0.6,0.102,1.199-0.398,1.699-1.299   l0.7-0.9L656.3,131.799z" style="stroke-dasharray: 75px, 77px; stroke-dashoffset: 0px;"></path>
118
        </g>
119
120
        <g class="circle-container">
121
        <path class="circle" fill="white" d="M0,100.1A100.1,100.1 0,1,1 200.2,100.1A100.1,100.1 0,1,1 0,100.1" style="stroke-dasharray: 630px, 632px; stroke-dashoffset: 0px;"></path>
122
        <path stroke="white" fill="#070001" d="M90,40.1l-1.2,8.1h-42.4l-3,25.9l42.2,0.199l-7.8,54.5H27.3l1.2-8.1h42.899l5.5-38.3L35.2,82.2l5.3-42.1    H90z" style="stroke-dasharray: 448px, 450px; stroke-dashoffset: 0px;"></path>
123
        <path stroke="white" fill="#070001" d="M90.8,121.7l29.2-0.3l6.1-45.601h8.4l-13.9,93.9H85.3l1.4-8.6H113.6l5.101-31.801L81.2,129.1L88.6,75H97    L90.8,121.7z" style="stroke-dasharray: 430px, 432px; stroke-dashoffset: 0px;"></path>
124
        <path stroke="white" fill="#070001" d="M137.5,75.799h42.2L172.1,129.5h-42.3l5.3-37.301l32.7,13.301l2.9-20.201H136.1L137.5,75.799z     M141.5,104.299l-2.3,16.4h26.5l0.899-6.3L141.5,104.299z" style="stroke-dasharray: 353px, 355px; stroke-dashoffset: 0px;"></path>
125
        </g>
126
        </svg>
!

CSS

xxxxxxxxxx
33
 
1
body
2
  background #040000
3
.svg
4
  width 100%
5
  position fixed
6
  margin auto
7
  top 0
8
  bottom 0
9
  left 0
10
  right 0
11
  .circle
12
    transition opacity 1s
13
    opacity 0
14
  for txtc in 1 2 3 4 5 6
15
    .text-chinese:nth-child({txtc})
16
      opacity 0
17
      transform scale(1.5) translate(10px,10px)
18
      transition transform 1s 1s+0.05*txtc,opacity 1s 1s+0.05*txtc
19
  for txte in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
20
    .text-english:nth-child({txte})
21
      opacity 0
22
      transition opacity 1s 2s+0.02*txte
23
  &.active
24
    .circle
25
      opacity 1
26
    .circle-container
27
      transform rotate3d(1,1,0,360deg)
28
      transition transform 1s
29
    .text-chinese
30
      transform scale(1) translate(0,0)
31
      opacity 1
32
    .text-english
33
      opacity 1
!
? ?
? ?
必须是有效的URL
+ 添加另一个资源

JS

10201
 
1
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2
/*!
3
 * jQuery JavaScript Library v2.1.4
4
 * http://jquery.com/
5
 *
6
 * Includes Sizzle.js
7
 * http://sizzlejs.com/
8
 *
9
 * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
10
 * Released under the MIT license
11
 * http://jquery.org/license
12
 *
13
 * Date: 2015-04-28T16:01Z
14
 */
15
16
(function( global, factory ) {
17
18
  if ( typeof module === "object" && typeof module.exports === "object" ) {
19
    // For CommonJS and CommonJS-like environments where a proper `window`
20
    // is present, execute the factory and get jQuery.
21
    // For environments that do not have a `window` with a `document`
22
    // (such as Node.js), expose a factory as module.exports.
23
    // This accentuates the need for the creation of a real `window`.
24
    // e.g. var jQuery = require("jquery")(window);
25
    // See ticket #14549 for more info.
26
    module.exports = global.document ?
27
      factory( global, true ) :
28
      function( w ) {
29
        if ( !w.document ) {
30
          throw new Error( "jQuery requires a window with a document" );
31
        }
32
        return factory( w );
33
      };
34
  } else {
35
    factory( global );
36
  }
37
38
// Pass this if window is not defined yet
39
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
40
41
// Support: Firefox 18+
42
// Can't be in strict mode, several libs including ASP.NET trace
43
// the stack via arguments.caller.callee and Firefox dies if
44
// you try to trace through "use strict" call chains. (#13335)
45
//
46
47
var arr = [];
48
49
var slice = arr.slice;
50
51
var concat = arr.concat;
52
53
var push = arr.push;
54
55
var indexOf = arr.indexOf;
56
57
var class2type = {};
58
59
var toString = class2type.toString;
60
61
var hasOwn = class2type.hasOwnProperty;
62
63
var support = {};
64
65
66
67
var
68
  // Use the correct document accordingly with window argument (sandbox)
69
  document = window.document,
70
71
  version = "2.1.4",
72
73
  // Define a local copy of jQuery
74
  jQuery = function( selector, context ) {
75
    // The jQuery object is actually just the init constructor 'enhanced'
76
    // Need init if jQuery is called (just allow error to be thrown if not included)
77
    return new jQuery.fn.init( selector, context );
78
  },
79
80
  // Support: Android<4.1
81
  // Make sure we trim BOM and NBSP
82
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
83
84
  // Matches dashed string for camelizing
85
  rmsPrefix = /^-ms-/,
86
  rdashAlpha = /-([\da-z])/gi,
87
88
  // Used by jQuery.camelCase as callback to replace()
89
  fcamelCase = function( all, letter ) {
90
    return letter.toUpperCase();
91
  };
92
93
jQuery.fn = jQuery.prototype = {
94
  // The current version of jQuery being used
95
  jquery: version,
96
97
  constructor: jQuery,
98
99
  // Start with an empty selector
100
  selector: "",
101
102
  // The default length of a jQuery object is 0
103
  length: 0,
104
105
  toArray: function() {
106
    return slice.call( this );
107
  },
108
109
  // Get the Nth element in the matched element set OR
110
  // Get the whole matched element set as a clean array
111
  get: function( num ) {
112
    return num != null ?
113
114
      // Return just the one element from the set
115
      ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
116
117
      // Return all the elements in a clean array
118
      slice.call( this );
119
  },
120
121
  // Take an array of elements and push it onto the stack
122
  // (returning the new matched element set)
123
  pushStack: function( elems ) {
124
125
    // Build a new jQuery matched element set
126
    var ret = jQuery.merge( this.constructor(), elems );
127
128
    // Add the old object onto the stack (as a reference)
129
    ret.prevObject = this;
130
    ret.context = this.context;
131
132
    // Return the newly-formed element set
133
    return ret;
134
  },
135
136
  // Execute a callback for every element in the matched set.
137
  // (You can seed the arguments with an array of args, but this is
138
  // only used internally.)
139
  each: function( callback, args ) {
140
    return jQuery.each( this, callback, args );
141
  },
142
143
  map: function( callback ) {
144
    return this.pushStack( jQuery.map(this, function( elem, i ) {
145
      return callback.call( elem, i, elem );
146
    }));
147
  },
148
149
  slice: function() {
150
    return this.pushStack( slice.apply( this, arguments ) );
151
  },
152
153
  first: function() {
154
    return this.eq( 0 );
155
  },
156
157
  last: function() {
158
    return this.eq( -1 );
159
  },
160
161
  eq: function( i ) {
162
    var len = this.length,
163
      j = +i + ( i < 0 ? len : 0 );
164
    return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
165
  },
166
167
  end: function() {
168
    return this.prevObject || this.constructor(null);
169
  },
170
171
  // For internal use only.
172
  // Behaves like an Array's method, not like a jQuery method.
173
  push: push,
174
  sort: arr.sort,
175
  splice: arr.splice
176
};
177
178
jQuery.extend = jQuery.fn.extend = function() {
179
  var options, name, src, copy, copyIsArray, clone,
180
    target = arguments[0] || {},
181
    i = 1,
182
    length = arguments.length,
183
    deep = false;
184
185
  // Handle a deep copy situation
186
  if ( typeof target === "boolean" ) {
187
    deep = target;
188
189
    // Skip the boolean and the target
190
    target = arguments[ i ] || {};
191
    i++;
192
  }
193
194
  // Handle case when target is a string or something (possible in deep copy)
195
  if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
196
    target = {};
197
  }
198
199
  // Extend jQuery itself if only one argument is passed
200
  if ( i === length ) {
201
    target = this;
202
    i--;
203
  }
204
205
  for ( ; i < length; i++ ) {
206
    // Only deal with non-null/undefined values
207
    if ( (options = arguments[ i ]) != null ) {
208
      // Extend the base object
209
      for ( name in options ) {
210
        src = target[ name ];
211
        copy = options[ name ];
212
213
        // Prevent never-ending loop
214
        if ( target === copy ) {
215
          continue;
216
        }
217
218
        // Recurse if we're merging plain objects or arrays
219
        if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
220
          if ( copyIsArray ) {
221
            copyIsArray = false;
222
            clone = src && jQuery.isArray(src) ? src : [];
223
224
          } else {
225
            clone = src && jQuery.isPlainObject(src) ? src : {};
226
          }
227
228
          // Never move original objects, clone them
229
          target[ name ] = jQuery.extend( deep, clone, copy );
230
231
        // Don't bring in undefined values
232
        } else if ( copy !== undefined ) {
233
          target[ name ] = copy;
234
        }
235
      }
236
    }
237
  }
238
239
  // Return the modified object
240
  return target;
241
};
242
243
jQuery.extend({
244
  // Unique for each copy of jQuery on the page
245
  expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
246
247
  // Assume jQuery is ready without the ready module
248
  isReady: true,
249
250
  error: function( msg ) {
251
    throw new Error( msg );
252
  },
253
254
  noop: function() {},
255
256
  isFunction: function( obj ) {
257
    return jQuery.type(obj) === "function";
258
  },
259
260
  isArray: Array.isArray,
261
262
  isWindow: function( obj ) {
263
    return obj != null && obj === obj.window;
264
  },
265
266
  isNumeric: function( obj ) {
267
    // parseFloat NaNs numeric-cast false positives (null|true|false|"")
268
    // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
269
    // subtraction forces infinities to NaN
270
    // adding 1 corrects loss of precision from parseFloat (#15100)
271
    return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
272
  },
273
274
  isPlainObject: function( obj ) {
275
    // Not plain objects:
276
    // - Any object or value whose internal [[Class]] property is not "[object Object]"
277
    // - DOM nodes
278
    // - window
279
    if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
280
      return false;
281
    }
282
283
    if ( obj.constructor &&
284
        !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
285
      return false;
286
    }
287
288
    // If the function hasn't returned already, we're confident that
289
    // |obj| is a plain object, created by {} or constructed with new Object
290
    return true;
291
  },
292
293
  isEmptyObject: function( obj ) {
294
    var name;
295
    for ( name in obj ) {
296
      return false;
297
    }
298
    return true;
299
  },
300
301
  type: function( obj ) {
302
    if ( obj == null ) {
303
      return obj + "";
304
    }
305
    // Support: Android<4.0, iOS<6 (functionish RegExp)
306
    return typeof obj === "object" || typeof obj === "function" ?
307
      class2type[ toString.call(obj) ] || "object" :
308
      typeof obj;
309
  },
310
311
  // Evaluates a script in a global context
312
  globalEval: function( code ) {
313
    var script,
314
      indirect = eval;
315
316
    code = jQuery.trim( code );
317
318
    if ( code ) {
319
      // If the code includes a valid, prologue position
320
      // strict mode pragma, execute code by injecting a
321
      // script tag into the document.
322
      if ( code.indexOf("use strict") === 1 ) {
323
        script = document.createElement("script");
324
        script.text = code;
325
        document.head.appendChild( script ).parentNode.removeChild( script );
326
      } else {
327
      // Otherwise, avoid the DOM node creation, insertion
328
      // and removal by using an indirect global eval
329
        indirect( code );
330
      }
331
    }
332
  },
333
334
  // Convert dashed to camelCase; used by the css and data modules
335
  // Support: IE9-11+
336
  // Microsoft forgot to hump their vendor prefix (#9572)
337
  camelCase: function( string ) {
338
    return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
339
  },
340
341
  nodeName: function( elem, name ) {
342
    return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
343
  },
344
345
  // args is for internal usage only
346
  each: function( obj, callback, args ) {
347
    var value,
348
      i = 0,
349
      length = obj.length,
350
      isArray = isArraylike( obj );
351
352
    if ( args ) {
353
      if ( isArray ) {
354
        for ( ; i < length; i++ ) {
355
          value = callback.apply( obj[ i ], args );
356
357
          if ( value === false ) {
358
            break;
359
          }
360
        }
361
      } else {
362
        for ( i in obj ) {
363
          value = callback.apply( obj[ i ], args );
364
365
          if ( value === false ) {
366
            break;
367
          }
368
        }
369
      }
370
371
    // A special, fast, case for the most common use of each
372
    } else {
373
      if ( isArray ) {
374
        for ( ; i < length; i++ ) {
375
          value = callback.call( obj[ i ], i, obj[ i ] );
376
377
          if ( value === false ) {
378
            break;
379
          }
380
        }
381
      } else {
382
        for ( i in obj ) {
383
          value = callback.call( obj[ i ], i, obj[ i ] );
384
385
          if ( value === false ) {
386
            break;
387
          }
388
        }
389
      }
390
    }
391
392
    return obj;
393
  },
394
395
  // Support: Android<4.1
396
  trim: function( text ) {
397
    return text == null ?
398
      "" :
399
      ( text + "" ).replace( rtrim, "" );
400
  },
401
402
  // results is for internal usage only
403
  makeArray: function( arr, results ) {
404
    var ret = results || [];
405
406
    if ( arr != null ) {
407
      if ( isArraylike( Object(arr) ) ) {
408
        jQuery.merge( ret,
409
          typeof arr === "string" ?
410
          [ arr ] : arr
411
        );
412
      } else {
413
        push.call( ret, arr );
414
      }
415
    }
416
417
    return ret;
418
  },
419
420
  inArray: function( elem, arr, i ) {
421
    return arr == null ? -1 : indexOf.call( arr, elem, i );
422
  },
423
424
  merge: function( first, second ) {
425
    var len = +second.length,
426
      j = 0,
427
      i = first.length;
428
429
    for ( ; j < len; j++ ) {
430
      first[ i++ ] = second[ j ];
431
    }
432
433
    first.length = i;
434
435
    return first;
436
  },
437
438
  grep: function( elems, callback, invert ) {
439
    var callbackInverse,
440
      matches = [],
441
      i = 0,
442
      length = elems.length,
443
      callbackExpect = !invert;
444
445
    // Go through the array, only saving the items
446
    // that pass the validator function
447
    for ( ; i < length; i++ ) {
448
      callbackInverse = !callback( elems[ i ], i );
449
      if ( callbackInverse !== callbackExpect ) {
450
        matches.push( elems[ i ] );
451
      }
452
    }
453
454
    return matches;
455
  },
456
457
  // arg is for internal usage only
458
  map: function( elems, callback, arg ) {
459
    var value,
460
      i = 0,
461
      length = elems.length,
462
      isArray = isArraylike( elems ),
463
      ret = [];
464
465
    // Go through the array, translating each of the items to their new values
466
    if ( isArray ) {
467
      for ( ; i < length; i++ ) {
468
        value = callback( elems[ i ], i, arg );
469
470
        if ( value != null ) {
471
          ret.push( value );
472
        }
473
      }
474
475
    // Go through every key on the object,
476
    } else {
477
      for ( i in elems ) {
478
        value = callback( elems[ i ], i, arg );
479
480
        if ( value != null ) {
481
          ret.push( value );
482
        }
483
      }
484
    }
485
486
    // Flatten any nested arrays
487
    return concat.apply( [], ret );
488
  },
489
490
  // A global GUID counter for objects
491
  guid: 1,
492
493
  // Bind a function to a context, optionally partially applying any
494
  // arguments.
495
  proxy: function( fn, context ) {
496
    var tmp, args, proxy;
497
498
    if ( typeof context === "string" ) {
499
      tmp = fn[ context ];
500
      context = fn;
501
      fn = tmp;
502
    }
503
504
    // Quick check to determine if target is callable, in the spec
505
    // this throws a TypeError, but we will just return undefined.
506
    if ( !jQuery.isFunction( fn ) ) {
507
      return undefined;
508
    }
509
510
    // Simulated bind
511
    args = slice.call( arguments, 2 );
512
    proxy = function() {
513
      return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
514
    };
515
516
    // Set the guid of unique handler to the same of original handler, so it can be removed
517
    proxy.guid = fn.guid = fn.guid || jQuery.guid++;
518
519
    return proxy;
520
  },
521
522
  now: Date.now,
523
524
  // jQuery.support is not used in Core but other projects attach their
525
  // properties to it so it needs to exist.
526
  support: support
527
});
528
529
// Populate the class2type map
530
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
531
  class2type[ "[object " + name + "]" ] = name.toLowerCase();
532
});
533
534
function isArraylike( obj ) {
535
536
  // Support: iOS 8.2 (not reproducible in simulator)
537
  // `in` check used to prevent JIT error (gh-2145)
538
  // hasOwn isn't used here due to false negatives
539
  // regarding Nodelist length in IE
540
  var length = "length" in obj && obj.length,
541
    type = jQuery.type( obj );
542
543
  if ( type === "function" || jQuery.isWindow( obj ) ) {
544
    return false;
545
  }
546
547
  if ( obj.nodeType === 1 && length ) {
548
    return true;
549
  }
550
551
  return type === "array" || length === 0 ||
552
    typeof length === "number" && length > 0 && ( length - 1 ) in obj;
553
}
554
var Sizzle =
555
/*!
556
 * Sizzle CSS Selector Engine v2.2.0-pre
557
 * http://sizzlejs.com/
558
 *
559
 * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
560
 * Released under the MIT license
561
 * http://jquery.org/license
562
 *
563
 * Date: 2014-12-16
564
 */
565
(function( window ) {
566
567
var i,
568
  support,
569
  Expr,
570
  getText,
571
  isXML,
572
  tokenize,
573
  compile,
574
  select,
575
  outermostContext,
576
  sortInput,
577
  hasDuplicate,
578
579
  // Local document vars
580
  setDocument,
581
  document,
582
  docElem,
583
  documentIsHTML,
584
  rbuggyQSA,
585
  rbuggyMatches,
586
  matches,
587
  contains,
588
589
  // Instance-specific data
590
  expando = "sizzle" + 1 * new Date(),
591
  preferredDoc = window.document,
592
  dirruns = 0,
593
  done = 0,
594
  classCache = createCache(),
595
  tokenCache = createCache(),
596
  compilerCache = createCache(),
597
  sortOrder = function( a, b ) {
598
    if ( a === b ) {
599
      hasDuplicate = true;
600
    }
601
    return 0;
602
  },
603
604
  // General-purpose constants
605
  MAX_NEGATIVE = 1 << 31,
606
607
  // Instance methods
608
  hasOwn = ({}).hasOwnProperty,
609
  arr = [],
610
  pop = arr.pop,
611
  push_native = arr.push,
612
  push = arr.push,
613
  slice = arr.slice,
614
  // Use a stripped-down indexOf as it's faster than native
615
  // http://jsperf.com/thor-indexof-vs-for/5
616
  indexOf = function( list, elem ) {
617
    var i = 0,
618
      len = list.length;
619
    for ( ; i < len; i++ ) {
620
      if ( list[i] === elem ) {
621
        return i;
622
      }
623
    }
624
    return -1;
625
  },
626
627
  booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
628
629
  // Regular expressions
630
631
  // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
632
  whitespace = "[\\x20\\t\\r\\n\\f]",
633
  // http://www.w3.org/TR/css3-syntax/#characters
634
  characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
635
636
  // Loosely modeled on CSS identifier characters
637
  // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
638
  // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
639
  identifier = characterEncoding.replace( "w", "w#" ),
640
641
  // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
642
  attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
643
    // Operator (capture 2)
644
    "*([*^$|!~]?=)" + whitespace +
645
    // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
646
    "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
647
    "*\\]",
648
649
  pseudos = ":(" + characterEncoding + ")(?:\\((" +
650
    // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
651
    // 1. quoted (capture 3; capture 4 or capture 5)
652
    "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
653
    // 2. simple (capture 6)
654
    "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
655
    // 3. anything else (capture 2)
656
    ".*" +
657
    ")\\)|)",
658
659
  // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
660
  rwhitespace = new RegExp( whitespace + "+", "g" ),
661
  rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
662
663
  rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
664
  rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
665
666
  rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
667
668
  rpseudo = new RegExp( pseudos ),
669
  ridentifier = new RegExp( "^" + identifier + "$" ),
670
671
  matchExpr = {
672
    "ID": new RegExp( "^#(" + characterEncoding + ")" ),
673
    "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
674
    "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
675
    "ATTR": new RegExp( "^" + attributes ),
676
    "PSEUDO": new RegExp( "^" + pseudos ),
677
    "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
678
      "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
679
      "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
680
    "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
681
    // For use in libraries implementing .is()
682
    // We use this for POS matching in `select`
683
    "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
684
      whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
685
  },
686
687
  rinputs = /^(?:input|select|textarea|button)$/i,
688
  rheader = /^h\d$/i,
689
690
  rnative = /^[^{]+\{\s*\[native \w/,
691
692
  // Easily-parseable/retrievable ID or TAG or CLASS selectors
693
  rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
694
695
  rsibling = /[+~]/,
696
  rescape = /'|\\/g,
697
698
  // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
699
  runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
700
  funescape = function( _, escaped, escapedWhitespace ) {
701
    var high = "0x" + escaped - 0x10000;
702
    // NaN means non-codepoint
703
    // Support: Firefox<24
704
    // Workaround erroneous numeric interpretation of +"0x"
705
    return high !== high || escapedWhitespace ?
706
      escaped :
707
      high < 0 ?
708
        // BMP codepoint
709
        String.fromCharCode( high + 0x10000 ) :
710
        // Supplemental Plane codepoint (surrogate pair)
711
        String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
712
  },
713
714
  // Used for iframes
715
  // See setDocument()
716
  // Removing the function wrapper causes a "Permission Denied"
717
  // error in IE
718
  unloadHandler = function() {
719
    setDocument();
720
  };
721
722
// Optimize for push.apply( _, NodeList )
723
try {
724
  push.apply(
725
    (arr = slice.call( preferredDoc.childNodes )),
726
    preferredDoc.childNodes
727
  );
728
  // Support: Android<4.0
729
  // Detect silently failing push.apply
730
  arr[ preferredDoc.childNodes.length ].nodeType;
731
} catch ( e ) {
732
  push = { apply: arr.length ?
733
734
    // Leverage slice if possible
735
    function( target, els ) {
736
      push_native.apply( target, slice.call(els) );
737
    } :
738
739
    // Support: IE<9
740
    // Otherwise append directly
741
    function( target, els ) {
742
      var j = target.length,
743
        i = 0;
744
      // Can't trust NodeList.length
745
      while ( (target[j++] = els[i++]) ) {}
746
      target.length = j - 1;
747
    }
748
  };
749
}
750
751
function Sizzle( selector, context, results, seed ) {
752
  var match, elem, m, nodeType,
753
    // QSA vars
754
    i, groups, old, nid, newContext, newSelector;
755
756
  if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
757
    setDocument( context );
758
  }
759
760
  context = context || document;
761
  results = results || [];
762
  nodeType = context.nodeType;
763
764
  if ( typeof selector !== "string" || !selector ||
765
    nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
766
767
    return results;
768
  }
769
770
  if ( !seed && documentIsHTML ) {
771
772
    // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
773
    if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
774
      // Speed-up: Sizzle("#ID")
775
      if ( (m = match[1]) ) {
776
        if ( nodeType === 9 ) {
777
          elem = context.getElementById( m );
778
          // Check parentNode to catch when Blackberry 4.6 returns
779
          // nodes that are no longer in the document (jQuery #6963)
780
          if ( elem && elem.parentNode ) {
781
            // Handle the case where IE, Opera, and Webkit return items
782
            // by name instead of ID
783
            if ( elem.id === m ) {
784
              results.push( elem );
785
              return results;
786
            }
787
          } else {
788
            return results;
789
          }
790
        } else {
791
          // Context is not a document
792
          if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
793
            contains( context, elem ) && elem.id === m ) {
794
            results.push( elem );
795
            return results;
796
          }
797
        }
798
799
      // Speed-up: Sizzle("TAG")
800
      } else if ( match[2] ) {
801
        push.apply( results, context.getElementsByTagName( selector ) );
802
        return results;
803
804
      // Speed-up: Sizzle(".CLASS")
805
      } else if ( (m = match[3]) && support.getElementsByClassName ) {
806
        push.apply( results, context.getElementsByClassName( m ) );
807
        return results;
808
      }
809
    }
810
811
    // QSA path
812
    if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
813
      nid = old = expando;
814
      newContext = context;
815
      newSelector = nodeType !== 1 && selector;
816
817
      // qSA works strangely on Element-rooted queries
818
      // We can work around this by specifying an extra ID on the root
819
      // and working up from there (Thanks to Andrew Dupont for the technique)
820
      // IE 8 doesn't work on object elements
821
      if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
822
        groups = tokenize( selector );
823
824
        if ( (old = context.getAttribute("id")) ) {
825
          nid = old.replace( rescape, "\\$&" );
826
        } else {
827
          context.setAttribute( "id", nid );
828
        }
829
        nid = "[id='" + nid + "'] ";
830
831
        i = groups.length;
832
        while ( i-- ) {
833
          groups[i] = nid + toSelector( groups[i] );
834
        }
835
        newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
836
        newSelector = groups.join(",");
837
      }
838
839
      if ( newSelector ) {
840
        try {
841
          push.apply( results,
842
            newContext.querySelectorAll( newSelector )
843
          );
844
          return results;
845
        } catch(qsaError) {
846
        } finally {
847
          if ( !old ) {
848
            context.removeAttribute("id");
849
          }
850
        }
851
      }
852
    }
853
  }
854
855
  // All others
856
  return select( selector.replace( rtrim, "$1" ), context, results, seed );
857
}
858
859
/**
860
 * Create key-value caches of limited size
861
 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
862
 *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
863
 *  deleting the oldest entry
864
 */
865
function createCache() {
866
  var keys = [];
867
868
  function cache( key, value ) {
869
    // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
870
    if ( keys.push( key + " " ) > Expr.cacheLength ) {
871
      // Only keep the most recent entries
872
      delete cache[ keys.shift() ];
873
    }
874
    return (cache[ key + " " ] = value);
875
  }
876
  return cache;
877
}
878
879
/**
880
 * Mark a function for special use by Sizzle
881
 * @param {Function} fn The function to mark
882
 */
883
function markFunction( fn ) {
884
  fn[ expando ] = true;
885
  return fn;
886
}
887
888
/**
889
 * Support testing using an element
890
 * @param {Function} fn Passed the created div and expects a boolean result
891
 */
892
function assert( fn ) {
893
  var div = document.createElement("div");
894
895
  try {
896
    return !!fn( div );
897
  } catch (e) {
898
    return false;
899
  } finally {
900
    // Remove from its parent by default
901
    if ( div.parentNode ) {
902
      div.parentNode.removeChild( div );
903
    }
904
    // release memory in IE
905
    div = null;
906
  }
907
}
908
909
/**
910
 * Adds the same handler for all of the specified attrs
911
 * @param {String} attrs Pipe-separated list of attributes
912
 * @param {Function} handler The method that will be applied
913
 */
914
function addHandle( attrs, handler ) {
915
  var arr = attrs.split("|"),
916
    i = attrs.length;
917
918
  while ( i-- ) {
919
    Expr.attrHandle[ arr[i] ] = handler;
920
  }
921
}
922
923
/**
924
 * Checks document order of two siblings
925
 * @param {Element} a
926
 * @param {Element} b
927
 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
928
 */
929
function siblingCheck( a, b ) {
930
  var cur = b && a,
931
    diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
932
      ( ~b.sourceIndex || MAX_NEGATIVE ) -
933
      ( ~a.sourceIndex || MAX_NEGATIVE );
934
935
  // Use IE sourceIndex if available on both nodes
936
  if ( diff ) {
937
    return diff;
938
  }
939
940
  // Check if b follows a
941
  if ( cur ) {
942
    while ( (cur = cur.nextSibling) ) {
943
      if ( cur === b ) {
944
        return -1;
945
      }
946
    }
947
  }
948
949
  return a ? 1 : -1;
950
}
951
952
/**
953
 * Returns a function to use in pseudos for input types
954
 * @param {String} type
955
 */
956
function createInputPseudo( type ) {
957
  return function( elem ) {
958
    var name = elem.nodeName.toLowerCase();
959
    return name === "input" && elem.type === type;
960
  };
961
}
962
963
/**
964
 * Returns a function to use in pseudos for buttons
965
 * @param {String} type
966
 */
967
function createButtonPseudo( type ) {
968
  return function( elem ) {
969
    var name = elem.nodeName.toLowerCase();
970
    return (name === "input" || name === "button") && elem.type === type;
971
  };
972
}
973
974
/**
975
 * Returns a function to use in pseudos for positionals
976
 * @param {Function} fn
977
 */
978
function createPositionalPseudo( fn ) {
979
  return markFunction(function( argument ) {
980
    argument = +argument;
981
    return markFunction(function( seed, matches ) {
982
      var j,
983
        matchIndexes = fn( [], seed.length, argument ),
984
        i = matchIndexes.length;
985
986
      // Match elements found at the specified indexes
987
      while ( i-- ) {
988
        if ( seed[ (j = matchIndexes[i]) ] ) {
989
          seed[j] = !(matches[j] = seed[j]);
990
        }
991
      }
992
    });
993
  });
994
}
995
996
/**
997
 * Checks a node for validity as a Sizzle context
998
 * @param {Element|Object=} context
999
 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1000
 */
1001
function testContext( context ) {
1002
  return context && typeof context.getElementsByTagName !== "undefined" && context;
1003
}
1004
1005
// Expose support vars for convenience
1006
support = Sizzle.support = {};
1007
1008
/**
1009
 * Detects XML nodes
1010
 * @param {Element|Object} elem An element or a document
1011
 * @returns {Boolean} True iff elem is a non-HTML XML node
1012
 */
1013
isXML = Sizzle.isXML = function( elem ) {
1014
  // documentElement is verified for cases where it doesn't yet exist
1015
  // (such as loading iframes in IE - #4833)
1016
  var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1017
  return documentElement ? documentElement.nodeName !== "HTML" : false;
1018
};
1019
1020
/**
1021
 * Sets document-related variables once based on the current document
1022
 * @param {Element|Object} [doc] An element or document object to use to set the document
1023
 * @returns {Object} Returns the current document
1024
 */
1025
setDocument = Sizzle.setDocument = function( node ) {
1026
  var hasCompare, parent,
1027
    doc = node ? node.ownerDocument || node : preferredDoc;
1028
1029
  // If no document and documentElement is available, return
1030
  if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1031
    return document;
1032
  }
1033
1034
  // Set our document
1035
  document = doc;
1036
  docElem = doc.documentElement;
1037
  parent = doc.defaultView;
1038
1039
  // Support: IE>8
1040
  // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1041
  // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1042
  // IE6-8 do not support the defaultView property so parent will be undefined
1043
  if ( parent && parent !== parent.top ) {
1044
    // IE11 does not have attachEvent, so all must suffer
1045
    if ( parent.addEventListener ) {
1046
      parent.addEventListener( "unload", unloadHandler, false );
1047
    } else if ( parent.attachEvent ) {
1048
      parent.attachEvent( "onunload", unloadHandler );
1049
    }
1050
  }
1051
1052
  /* Support tests
1053
  ---------------------------------------------------------------------- */
1054
  documentIsHTML = !isXML( doc );
1055
1056
  /* Attributes
1057
  ---------------------------------------------------------------------- */
1058
1059
  // Support: IE<8
1060
  // Verify that getAttribute really returns attributes and not properties
1061
  // (excepting IE8 booleans)
1062
  support.attributes = assert(function( div ) {
1063
    div.className = "i";
1064
    return !div.getAttribute("className");
1065
  });
1066
1067
  /* getElement(s)By*
1068
  ---------------------------------------------------------------------- */
1069
1070
  // Check if getElementsByTagName("*") returns only elements
1071
  support.getElementsByTagName = assert(function( div ) {
1072
    div.appendChild( doc.createComment("") );
1073
    return !div.getElementsByTagName("*").length;
1074
  });
1075
1076
  // Support: IE<9
1077
  support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
1078
1079
  // Support: IE<10
1080
  // Check if getElementById returns elements by name
1081
  // The broken getElementById methods don't pick up programatically-set names,
1082
  // so use a roundabout getElementsByName test
1083
  support.getById = assert(function( div ) {
1084
    docElem.appendChild( div ).id = expando;
1085
    return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1086
  });
1087
1088
  // ID find and filter
1089
  if ( support.getById ) {
1090
    Expr.find["ID"] = function( id, context ) {
1091
      if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1092
        var m = context.getElementById( id );
1093
        // Check parentNode to catch when Blackberry 4.6 returns
1094
        // nodes that are no longer in the document #6963
1095
        return m && m.parentNode ? [ m ] : [];
1096
      }
1097
    };
1098
    Expr.filter["ID"] = function( id ) {
1099
      var attrId = id.replace( runescape, funescape );
1100
      return function( elem ) {
1101
        return elem.getAttribute("id") === attrId;
1102
      };
1103
    };
1104
  } else {
1105
    // Support: IE6/7
1106
    // getElementById is not reliable as a find shortcut
1107
    delete Expr.find["ID"];
1108
1109
    Expr.filter["ID"] =  function( id ) {
1110
      var attrId = id.replace( runescape, funescape );
1111
      return function( elem ) {
1112
        var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1113
        return node && node.value === attrId;
1114
      };
1115
    };
1116
  }
1117
1118
  // Tag
1119
  Expr.find["TAG"] = support.getElementsByTagName ?
1120
    function( tag, context ) {
1121
      if ( typeof context.getElementsByTagName !== "undefined" ) {
1122
        return context.getElementsByTagName( tag );
1123
1124
      // DocumentFragment nodes don't have gEBTN
1125
      } else if ( support.qsa ) {
1126
        return context.querySelectorAll( tag );
1127
      }
1128
    } :
1129
1130
    function( tag, context ) {
1131
      var elem,
1132
        tmp = [],
1133
        i = 0,
1134
        // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1135
        results = context.getElementsByTagName( tag );
1136
1137
      // Filter out possible comments
1138
      if ( tag === "*" ) {
1139
        while ( (elem = results[i++]) ) {
1140
          if ( elem.nodeType === 1 ) {
1141
            tmp.push( elem );
1142
          }
1143
        }
1144
1145
        return tmp;
1146
      }
1147
      return results;
1148
    };
1149
1150
  // Class
1151
  Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1152
    if ( documentIsHTML ) {
1153
      return context.getElementsByClassName( className );
1154
    }
1155
  };
1156
1157
  /* QSA/matchesSelector
1158
  ---------------------------------------------------------------------- */
1159
1160
  // QSA and matchesSelector support
1161
1162
  // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1163
  rbuggyMatches = [];
1164
1165
  // qSa(:focus) reports false when true (Chrome 21)
1166
  // We allow this because of a bug in IE8/9 that throws an error
1167
  // whenever `document.activeElement` is accessed on an iframe
1168
  // So, we allow :focus to pass through QSA all the time to avoid the IE error
1169
  // See http://bugs.jquery.com/ticket/13378
1170
  rbuggyQSA = [];
1171
1172
  if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1173
    // Build QSA regex
1174
    // Regex strategy adopted from Diego Perini
1175
    assert(function( div ) {
1176
      // Select is set to empty string on purpose
1177
      // This is to test IE's treatment of not explicitly
1178
      // setting a boolean content attribute,
1179
      // since its presence should be enough
1180
      // http://bugs.jquery.com/ticket/12359
1181
      docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1182
        "<select id='" + expando + "-\f]' msallowcapture=''>" +
1183
        "<option selected=''></option></select>";
1184
1185
      // Support: IE8, Opera 11-12.16
1186
      // Nothing should be selected when empty strings follow ^= or $= or *=
1187
      // The test attribute must be unknown in Opera but "safe" for WinRT
1188
      // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1189
      if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1190
        rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1191
      }
1192
1193
      // Support: IE8
1194
      // Boolean attributes and "value" are not treated correctly
1195
      if ( !div.querySelectorAll("[selected]").length ) {
1196
        rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1197
      }
1198
1199
      // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
1200
      if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1201
        rbuggyQSA.push("~=");
1202
      }
1203
1204
      // Webkit/Opera - :checked should return selected option elements
1205
      // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1206
      // IE8 throws error here and will not see later tests
1207
      if ( !div.querySelectorAll(":checked").length ) {
1208
        rbuggyQSA.push(":checked");
1209
      }
1210
1211
      // Support: Safari 8+, iOS 8+
1212
      // https://bugs.webkit.org/show_bug.cgi?id=136851
1213
      // In-page `selector#id sibing-combinator selector` fails
1214
      if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1215
        rbuggyQSA.push(".#.+[+~]");
1216
      }
1217
    });
1218
1219
    assert(function( div ) {
1220
      // Support: Windows 8 Native Apps
1221
      // The type and name attributes are restricted during .innerHTML assignment
1222
      var input = doc.createElement("input");
1223
      input.setAttribute( "type", "hidden" );
1224
      div.appendChild( input ).setAttribute( "name", "D" );
1225
1226
      // Support: IE8
1227
      // Enforce case-sensitivity of name attribute
1228
      if ( div.querySelectorAll("[name=d]").length ) {
1229
        rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1230
      }
1231
1232
      // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1233
      // IE8 throws error here and will not see later tests
1234
      if ( !div.querySelectorAll(":enabled").length ) {
1235
        rbuggyQSA.push( ":enabled", ":disabled" );
1236
      }
1237
1238
      // Opera 10-11 does not throw on post-comma invalid pseudos
1239
      div.querySelectorAll("*,:x");
1240
      rbuggyQSA.push(",.*:");
1241
    });
1242
  }
1243
1244
  if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1245
    docElem.webkitMatchesSelector ||
1246
    docElem.mozMatchesSelector ||
1247
    docElem.oMatchesSelector ||
1248
    docElem.msMatchesSelector) )) ) {
1249
1250
    assert(function( div ) {
1251
      // Check to see if it's possible to do matchesSelector
1252
      // on a disconnected node (IE 9)
1253
      support.disconnectedMatch = matches.call( div, "div" );
1254
1255
      // This should fail with an exception
1256
      // Gecko does not error, returns false instead
1257
      matches.call( div, "[s!='']:x" );
1258
      rbuggyMatches.push( "!=", pseudos );
1259
    });
1260
  }
1261
1262
  rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1263
  rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1264
1265
  /* Contains
1266
  ---------------------------------------------------------------------- */
1267
  hasCompare = rnative.test( docElem.compareDocumentPosition );
1268
1269
  // Element contains another
1270
  // Purposefully does not implement inclusive descendent
1271
  // As in, an element does not contain itself
1272
  contains = hasCompare || rnative.test( docElem.contains ) ?
1273
    function( a, b ) {
1274
      var adown = a.nodeType === 9 ? a.documentElement : a,
1275
        bup = b && b.parentNode;
1276
      return a === bup || !!( bup && bup.nodeType === 1 && (
1277
        adown.contains ?
1278
          adown.contains( bup ) :
1279
          a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1280
      ));
1281
    } :
1282
    function( a, b ) {
1283
      if ( b ) {
1284
        while ( (b = b.parentNode) ) {
1285
          if ( b === a ) {
1286
            return true;
1287
          }
1288
        }
1289
      }
1290
      return false;
1291
    };
1292
1293
  /* Sorting
1294
  ---------------------------------------------------------------------- */
1295
1296
  // Document order sorting
1297
  sortOrder = hasCompare ?
1298
  function( a, b ) {
1299
1300
    // Flag for duplicate removal
1301
    if ( a === b ) {
1302
      hasDuplicate = true;
1303
      return 0;
1304
    }
1305
1306
    // Sort on method existence if only one input has compareDocumentPosition
1307
    var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1308
    if ( compare ) {
1309
      return compare;
1310
    }
1311
1312
    // Calculate position if both inputs belong to the same document
1313
    compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1314
      a.compareDocumentPosition( b ) :
1315
1316
      // Otherwise we know they are disconnected
1317
      1;
1318
1319
    // Disconnected nodes
1320
    if ( compare & 1 ||
1321
      (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1322
1323
      // Choose the first element that is related to our preferred document
1324
      if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1325
        return -1;
1326
      }
1327
      if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1328
        return 1;
1329
      }
1330
1331
      // Maintain original order
1332
      return sortInput ?
1333
        ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1334
        0;
1335
    }
1336
1337
    return compare & 4 ? -1 : 1;
1338
  } :
1339
  function( a, b ) {
1340
    // Exit early if the nodes are identical
1341
    if ( a === b ) {
1342
      hasDuplicate = true;
1343
      return 0;
1344
    }
1345
1346
    var cur,
1347
      i = 0,
1348
      aup = a.parentNode,
1349
      bup = b.parentNode,
1350
      ap = [ a ],
1351
      bp = [ b ];
1352
1353
    // Parentless nodes are either documents or disconnected
1354
    if ( !aup || !bup ) {
1355
      return a === doc ? -1 :
1356
        b === doc ? 1 :
1357
        aup ? -1 :
1358
        bup ? 1 :
1359
        sortInput ?
1360
        ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1361
        0;
1362
1363
    // If the nodes are siblings, we can do a quick check
1364
    } else if ( aup === bup ) {
1365
      return siblingCheck( a, b );
1366
    }
1367
1368
    // Otherwise we need full lists of their ancestors for comparison
1369
    cur = a;
1370
    while ( (cur = cur.parentNode) ) {
1371
      ap.unshift( cur );
1372
    }
1373
    cur = b;
1374
    while ( (cur = cur.parentNode) ) {
1375
      bp.unshift( cur );
1376
    }
1377
1378
    // Walk down the tree looking for a discrepancy
1379
    while ( ap[i] === bp[i] ) {
1380
      i++;
1381
    }
1382
1383
    return i ?
1384
      // Do a sibling check if the nodes have a common ancestor
1385
      siblingCheck( ap[i], bp[i] ) :
1386
1387
      // Otherwise nodes in our document sort first
1388
      ap[i] === preferredDoc ? -1 :
1389
      bp[i] === preferredDoc ? 1 :
1390
      0;
1391
  };
1392
1393
  return doc;
1394
};
1395
1396
Sizzle.matches = function( expr, elements ) {
1397
  return Sizzle( expr, null, null, elements );
1398
};
1399
1400
Sizzle.matchesSelector = function( elem, expr ) {
1401
  // Set document vars if needed
1402
  if ( ( elem.ownerDocument || elem ) !== document ) {
1403
    setDocument( elem );
1404
  }
1405
1406
  // Make sure that attribute selectors are quoted
1407
  expr = expr.replace( rattributeQuotes, "='$1']" );
1408
1409
  if ( support.matchesSelector && documentIsHTML &&
1410
    ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1411
    ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1412
1413
    try {
1414
      var ret = matches.call( elem, expr );
1415
1416
      // IE 9's matchesSelector returns false on disconnected nodes
1417
      if ( ret || support.disconnectedMatch ||
1418
          // As well, disconnected nodes are said to be in a document
1419
          // fragment in IE 9
1420
          elem.document && elem.document.nodeType !== 11 ) {
1421
        return ret;
1422
      }
1423
    } catch (e) {}
1424
  }
1425
1426
  return Sizzle( expr, document, null, [ elem ] ).length > 0;
1427
};
1428
1429
Sizzle.contains = function( context, elem ) {
1430
  // Set document vars if needed
1431
  if ( ( context.ownerDocument || context ) !== document ) {
1432
    setDocument( context );
1433
  }
1434
  return contains( context, elem );
1435
};
1436
1437
Sizzle.attr = function( elem, name ) {
1438
  // Set document vars if needed
1439
  if ( ( elem.ownerDocument || elem ) !== document ) {
1440
    setDocument( elem );
1441
  }
1442
1443
  var fn = Expr.attrHandle[ name.toLowerCase() ],
1444
    // Don't get fooled by Object.prototype properties (jQuery #13807)
1445
    val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1446
      fn( elem, name, !documentIsHTML ) :
1447
      undefined;
1448
1449
  return val !== undefined ?
1450
    val :
1451
    support.attributes || !documentIsHTML ?
1452
      elem.getAttribute( name ) :
1453
      (val = elem.getAttributeNode(name)) && val.specified ?
1454
        val.value :
1455
        null;
1456
};
1457
1458
Sizzle.error = function( msg ) {
1459
  throw new Error( "Syntax error, unrecognized expression: " + msg );
1460
};
1461
1462
/**
1463
 * Document sorting and removing duplicates
1464
 * @param {ArrayLike} results
1465
 */
1466
Sizzle.uniqueSort = function( results ) {
1467
  var elem,
1468
    duplicates = [],
1469
    j = 0,
1470
    i = 0;
1471
1472
  // Unless we *know* we can detect duplicates, assume their presence
1473
  hasDuplicate = !support.detectDuplicates;
1474
  sortInput = !support.sortStable && results.slice( 0 );
1475
  results.sort( sortOrder );
1476
1477
  if ( hasDuplicate ) {
1478
    while ( (elem = results[i++]) ) {
1479
      if ( elem === results[ i ] ) {
1480
        j = duplicates.push( i );
1481
      }
1482
    }
1483
    while ( j-- ) {
1484
      results.splice( duplicates[ j ], 1 );
1485
    }
1486
  }
1487
1488
  // Clear input after sorting to release objects
1489
  // See https://github.com/jquery/sizzle/pull/225
1490
  sortInput = null;
1491
1492
  return results;
1493
};
1494
1495
/**
1496
 * Utility function for retrieving the text value of an array of DOM nodes
1497
 * @param {Array|Element} elem
1498
 */
1499
getText = Sizzle.getText = function( elem ) {
1500
  var node,
1501
    ret = "",
1502
    i = 0,
1503
    nodeType = elem.nodeType;
1504
1505
  if ( !nodeType ) {
1506
    // If no nodeType, this is expected to be an array
1507
    while ( (node = elem[i++]) ) {
1508
      // Do not traverse comment nodes
1509
      ret += getText( node );
1510
    }
1511
  } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1512
    // Use textContent for elements
1513
    // innerText usage removed for consistency of new lines (jQuery #11153)
1514
    if ( typeof elem.textContent === "string" ) {
1515
      return elem.textContent;
1516
    } else {
1517
      // Traverse its children
1518
      for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1519
        ret += getText( elem );
1520
      }
1521
    }
1522
  } else if ( nodeType === 3 || nodeType === 4 ) {
1523
    return elem.nodeValue;
1524
  }
1525
  // Do not include comment or processing instruction nodes
1526
1527
  return ret;
1528
};
1529
1530
Expr = Sizzle.selectors = {
1531
1532
  // Can be adjusted by the user
1533
  cacheLength: 50,
1534
1535
  createPseudo: markFunction,
1536
1537
  match: matchExpr,
1538
1539
  attrHandle: {},
1540
1541
  find: {},
1542
1543
  relative: {
1544
    ">": { dir: "parentNode", first: true },
1545
    " ": { dir: "parentNode" },
1546
    "+": { dir: "previousSibling", first: true },
1547
    "~": { dir: "previousSibling" }
1548
  },
1549
1550
  preFilter: {
1551
    "ATTR": function( match ) {
1552
      match[1] = match[1].replace( runescape, funescape );
1553
1554
      // Move the given value to match[3] whether quoted or unquoted
1555
      match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1556
1557
      if ( match[2] === "~=" ) {
1558
        match[3] = " " + match[3] + " ";
1559
      }
1560
1561
      return match.slice( 0, 4 );
1562
    },
1563
1564
    "CHILD": function( match ) {
1565
      /* matches from matchExpr["CHILD"]
1566
        1 type (only|nth|...)
1567
        2 what (child|of-type)
1568
        3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1569
        4 xn-component of xn+y argument ([+-]?\d*n|)
1570
        5 sign of xn-component
1571
        6 x of xn-component
1572
        7 sign of y-component
1573
        8 y of y-component
1574
      */
1575
      match[1] = match[1].toLowerCase();
1576
1577
      if ( match[1].slice( 0, 3 ) === "nth" ) {
1578
        // nth-* requires argument
1579
        if ( !match[3] ) {
1580
          Sizzle.error( match[0] );
1581
        }
1582
1583
        // numeric x and y parameters for Expr.filter.CHILD
1584
        // remember that false/true cast respectively to 0/1
1585
        match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1586
        match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1587
1588
      // other types prohibit arguments
1589
      } else if ( match[3] ) {
1590
        Sizzle.error( match[0] );
1591
      }
1592
1593
      return match;
1594
    },
1595
1596
    "PSEUDO": function( match ) {
1597
      var excess,
1598
        unquoted = !match[6] && match[2];
1599
1600
      if ( matchExpr["CHILD"].test( match[0] ) ) {
1601
        return null;
1602
      }
1603
1604
      // Accept quoted arguments as-is
1605
      if ( match[3] ) {
1606
        match[2] = match[4] || match[5] || "";
1607
1608
      // Strip excess characters from unquoted arguments
1609
      } else if ( unquoted && rpseudo.test( unquoted ) &&
1610
        // Get excess from tokenize (recursively)
1611
        (excess = tokenize( unquoted, true )) &&
1612
        // advance to the next closing parenthesis
1613
        (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1614
1615
        // excess is a negative index
1616
        match[0] = match[0].slice( 0, excess );
1617
        match[2] = unquoted.slice( 0, excess );
1618
      }
1619
1620
      // Return only captures needed by the pseudo filter method (type and argument)
1621
      return match.slice( 0, 3 );
1622
    }
1623
  },
1624
1625
  filter: {
1626
1627
    "TAG": function( nodeNameSelector ) {
1628
      var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1629
      return nodeNameSelector === "*" ?
1630
        function() { return true; } :
1631
        function( elem ) {
1632
          return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1633
        };
1634
    },
1635
1636
    "CLASS": function( className ) {
1637
      var pattern = classCache[ className + " " ];
1638
1639
      return pattern ||
1640
        (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1641
        classCache( className, function( elem ) {
1642
          return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1643
        });
1644
    },
1645
1646
    "ATTR": function( name, operator, check ) {
1647
      return function( elem ) {
1648
        var result = Sizzle.attr( elem, name );
1649
1650
        if ( result == null ) {
1651
          return operator === "!=";
1652
        }
1653
        if ( !operator ) {
1654
          return true;
1655
        }
1656
1657
        result += "";
1658
1659
        return operator === "=" ? result === check :
1660
          operator === "!=" ? result !== check :
1661
          operator === "^=" ? check && result.indexOf( check ) === 0 :
1662
          operator === "*=" ? check && result.indexOf( check ) > -1 :
1663
          operator === "$=" ? check && result.slice( -check.length ) === check :
1664
          operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1665
          operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1666
          false;
1667
      };
1668
    },
1669
1670
    "CHILD": function( type, what, argument, first, last ) {
1671
      var simple = type.slice( 0, 3 ) !== "nth",
1672
        forward = type.slice( -4 ) !== "last",
1673
        ofType = what === "of-type";
1674
1675
      return first === 1 && last === 0 ?
1676
1677
        // Shortcut for :nth-*(n)
1678
        function( elem ) {
1679
          return !!elem.parentNode;
1680
        } :
1681
1682
        function( elem, context, xml ) {
1683
          var cache, outerCache, node, diff, nodeIndex, start,
1684
            dir = simple !== forward ? "nextSibling" : "previousSibling",
1685
            parent = elem.parentNode,
1686
            name = ofType && elem.nodeName.toLowerCase(),
1687
            useCache = !xml && !ofType;
1688
1689
          if ( parent ) {
1690
1691
            // :(first|last|only)-(child|of-type)
1692
            if ( simple ) {
1693
              while ( dir ) {
1694
                node = elem;
1695
                while ( (node = node[ dir ]) ) {
1696
                  if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1697
                    return false;
1698
                  }
1699
                }
1700
                // Reverse direction for :only-* (if we haven't yet done so)
1701
                start = dir = type === "only" && !start && "nextSibling";
1702
              }
1703
              return true;
1704
            }
1705
1706
            start = [ forward ? parent.firstChild : parent.lastChild ];
1707
1708
            // non-xml :nth-child(...) stores cache data on `parent`
1709
            if ( forward && useCache ) {
1710
              // Seek `elem` from a previously-cached index
1711
              outerCache = parent[ expando ] || (parent[ expando ] = {});
1712
              cache = outerCache[ type ] || [];
1713
              nodeIndex = cache[0] === dirruns && cache[1];
1714
              diff = cache[0] === dirruns && cache[2];
1715
              node = nodeIndex && parent.childNodes[ nodeIndex ];
1716
1717
              while ( (node = ++nodeIndex && node && node[ dir ] ||
1718
1719
                // Fallback to seeking `elem` from the start
1720
                (diff = nodeIndex = 0) || start.pop()) ) {
1721
1722
                // When found, cache indexes on `parent` and break
1723
                if ( node.nodeType === 1 && ++diff && node === elem ) {
1724
                  outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1725
                  break;
1726
                }
1727
              }
1728
1729
            // Use previously-cached element index if available
1730
            } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1731
              diff = cache[1];
1732
1733
            // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1734
            } else {
1735
              // Use the same loop as above to seek `elem` from the start
1736
              while ( (node = ++nodeIndex && node && node[ dir ] ||
1737
                (diff = nodeIndex = 0) || start.pop()) ) {
1738
1739
                if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1740
                  // Cache the index of each encountered element
1741
                  if ( useCache ) {
1742
                    (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1743
                  }
1744
1745
                  if ( node === elem ) {
1746
                    break;
1747
                  }
1748
                }
1749
              }
1750
            }
1751
1752
            // Incorporate the offset, then check against cycle size
1753
            diff -= last;
1754
            return diff === first || ( diff % first === 0 && diff / first >= 0 );
1755
          }
1756
        };
1757
    },
1758
1759
    "PSEUDO": function( pseudo, argument ) {
1760
      // pseudo-class names are case-insensitive
1761
      // http://www.w3.org/TR/selectors/#pseudo-classes
1762
      // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1763
      // Remember that setFilters inherits from pseudos
1764
      var args,
1765
        fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1766
          Sizzle.error( "unsupported pseudo: " + pseudo );
1767
1768
      // The user may use createPseudo to indicate that
1769
      // arguments are needed to create the filter function
1770
      // just as Sizzle does
1771
      if ( fn[ expando ] ) {
1772
        return fn( argument );
1773
      }
1774
1775
      // But maintain support for old signatures
1776
      if ( fn.length > 1 ) {
1777
        args = [ pseudo, pseudo, "", argument ];
1778
        return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1779
          markFunction(function( seed, matches ) {
1780
            var idx,
1781
              matched = fn( seed, argument ),
1782
              i = matched.length;
1783
            while ( i-- ) {
1784
              idx = indexOf( seed, matched[i] );
1785
              seed[ idx ] = !( matches[ idx ] = matched[i] );
1786
            }
1787
          }) :
1788
          function( elem ) {
1789
            return fn( elem, 0, args );
1790
          };
1791
      }
1792
1793
      return fn;
1794
    }
1795
  },
1796
1797
  pseudos: {
1798
    // Potentially complex pseudos
1799
    "not": markFunction(function( selector ) {
1800
      // Trim the selector passed to compile
1801
      // to avoid treating leading and trailing
1802
      // spaces as combinators
1803
      var input = [],
1804
        results = [],
1805
        matcher = compile( selector.replace( rtrim, "$1" ) );
1806
1807
      return matcher[ expando ] ?
1808
        markFunction(function( seed, matches, context, xml ) {
1809
          var elem,
1810
            unmatched = matcher( seed, null, xml, [] ),
1811
            i = seed.length;
1812
1813
          // Match elements unmatched by `matcher`
1814
          while ( i-- ) {
1815
            if ( (elem = unmatched[i]) ) {
1816
              seed[i] = !(matches[i] = elem);
1817
            }
1818
          }
1819
        }) :
1820
        function( elem, context, xml ) {
1821
          input[0] = elem;
1822
          matcher( input, null, xml, results );
1823
          // Don't keep the element (issue #299)
1824
          input[0] = null;
1825
          return !results.pop();
1826
        };
1827
    }),
1828
1829
    "has": markFunction(function( selector ) {
1830
      return function( elem ) {
1831
        return Sizzle( selector, elem ).length > 0;
1832
      };
1833
    }),
1834
1835
    "contains": markFunction(function( text ) {
1836
      text = text.replace( runescape, funescape );
1837
      return function( elem ) {
1838
        return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1839
      };
1840
    }),
1841
1842
    // "Whether an element is represented by a :lang() selector
1843
    // is based solely on the element's language value
1844
    // being equal to the identifier C,
1845
    // or beginning with the identifier C immediately followed by "-".
1846
    // The matching of C against the element's language value is performed case-insensitively.
1847
    // The identifier C does not have to be a valid language name."
1848
    // http://www.w3.org/TR/selectors/#lang-pseudo
1849
    "lang": markFunction( function( lang ) {
1850
      // lang value must be a valid identifier
1851
      if ( !ridentifier.test(lang || "") ) {
1852
        Sizzle.error( "unsupported lang: " + lang );
1853
      }
1854
      lang = lang.replace( runescape, funescape ).toLowerCase();
1855
      return function( elem ) {
1856
        var elemLang;
1857
        do {
1858
          if ( (elemLang = documentIsHTML ?
1859
            elem.lang :
1860
            elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1861
1862
            elemLang = elemLang.toLowerCase();
1863
            return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1864
          }
1865
        } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1866
        return false;
1867
      };
1868
    }),
1869
1870
    // Miscellaneous
1871
    "target": function( elem ) {
1872
      var hash = window.location && window.location.hash;
1873
      return hash && hash.slice( 1 ) === elem.id;
1874
    },
1875
1876
    "root": function( elem ) {
1877
      return elem === docElem;
1878
    },
1879
1880
    "focus": function( elem ) {
1881
      return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1882
    },
1883
1884
    // Boolean properties
1885
    "enabled": function( elem ) {
1886
      return elem.disabled === false;
1887
    },
1888
1889
    "disabled": function( elem ) {
1890
      return elem.disabled === true;
1891
    },
1892
1893
    "checked": function( elem ) {
1894
      // In CSS3, :checked should return both checked and selected elements
1895
      // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1896
      var nodeName = elem.nodeName.toLowerCase();
1897
      return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1898
    },
1899
1900
    "selected": function( elem ) {
1901
      // Accessing this property makes selected-by-default
1902
      // options in Safari work properly
1903
      if ( elem.parentNode ) {
1904
        elem.parentNode.selectedIndex;
1905
      }
1906
1907
      return elem.selected === true;
1908
    },
1909
1910
    // Contents
1911
    "empty": function( elem ) {
1912
      // http://www.w3.org/TR/selectors/#empty-pseudo
1913
      // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1914
      //   but not by others (comment: 8; processing instruction: 7; etc.)
1915
      // nodeType < 6 works because attributes (2) do not appear as children
1916
      for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1917
        if ( elem.nodeType < 6 ) {
1918
          return false;
1919
        }
1920
      }
1921
      return true;
1922
    },
1923
1924
    "parent": function( elem ) {
1925
      return !Expr.pseudos["empty"]( elem );
1926
    },
1927
1928
    // Element/input types
1929
    "header": function( elem ) {
1930
      return rheader.test( elem.nodeName );
1931
    },
1932
1933
    "input": function( elem ) {
1934
      return rinputs.test( elem.nodeName );
1935
    },
1936
1937
    "button": function( elem ) {
1938
      var name = elem.nodeName.toLowerCase();
1939
      return name === "input" && elem.type === "button" || name === "button";
1940
    },
1941
1942
    "text": function( elem ) {
1943
      var attr;
1944
      return elem.nodeName.toLowerCase() === "input" &&
1945
        elem.type === "text" &&
1946
1947
        // Support: IE<8
1948
        // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1949
        ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1950
    },
1951
1952
    // Position-in-collection
1953
    "first": createPositionalPseudo(function() {
1954
      return [ 0 ];
1955
    }),
1956
1957
    "last": createPositionalPseudo(function( matchIndexes, length ) {
1958
      return [ length - 1 ];
1959
    }),
1960
1961
    "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
1962
      return [ argument < 0 ? argument + length : argument ];
1963
    }),
1964
1965
    "even": createPositionalPseudo(function( matchIndexes, length ) {
1966
      var i = 0;
1967
      for ( ; i < length; i += 2 ) {
1968
        matchIndexes.push( i );
1969
      }
1970
      return matchIndexes;
1971
    }),
1972
1973
    "odd": createPositionalPseudo(function( matchIndexes, length ) {
1974
      var i = 1;
1975
      for ( ; i < length; i += 2 ) {
1976
        matchIndexes.push( i );
1977
      }
1978
      return matchIndexes;
1979
    }),
1980
1981
    "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1982
      var i = argument < 0 ? argument + length : argument;
1983
      for ( ; --i >= 0; ) {
1984
        matchIndexes.push( i );
1985
      }
1986
      return matchIndexes;
1987
    }),
1988
1989
    "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
1990
      var i = argument < 0 ? argument + length : argument;
1991
      for ( ; ++i < length; ) {
1992
        matchIndexes.push( i );
1993
      }
1994
      return matchIndexes;
1995
    })
1996
  }
1997
};
1998
1999
Expr.pseudos["nth"] = Expr.pseudos["eq"];
2000
2001
// Add button/input type pseudos
2002
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2003
  Expr.pseudos[ i ] = createInputPseudo( i );
2004
}
2005
for ( i in { submit: true, reset: true } ) {
2006
  Expr.pseudos[ i ] = createButtonPseudo( i );
2007
}
2008
2009
// Easy API for creating new setFilters
2010
function setFilters() {}
2011
setFilters.prototype = Expr.filters = Expr.pseudos;
2012
Expr.setFilters = new setFilters();
2013
2014
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2015
  var matched, match, tokens, type,
2016
    soFar, groups, preFilters,
2017
    cached = tokenCache[ selector + " " ];
2018
2019
  if ( cached ) {
2020
    return parseOnly ? 0 : cached.slice( 0 );
2021
  }
2022
2023
  soFar = selector;
2024
  groups = [];
2025
  preFilters = Expr.preFilter;
2026
2027
  while ( soFar ) {
2028
2029
    // Comma and first run
2030
    if ( !matched || (match = rcomma.exec( soFar )) ) {
2031
      if ( match ) {
2032
        // Don't consume trailing commas as valid
2033
        soFar = soFar.slice( match[0].length ) || soFar;
2034
      }
2035
      groups.push( (tokens = []) );
2036
    }
2037
2038
    matched = false;
2039
2040
    // Combinators
2041
    if ( (match = rcombinators.exec( soFar )) ) {
2042
      matched = match.shift();
2043
      tokens.push({
2044
        value: matched,
2045
        // Cast descendant combinators to space
2046
        type: match[0].replace( rtrim, " " )
2047
      });
2048
      soFar = soFar.slice( matched.length );
2049
    }
2050
2051
    // Filters
2052
    for ( type in Expr.filter ) {
2053
      if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2054
        (match = preFilters[ type ]( match ))) ) {
2055
        matched = match.shift();
2056
        tokens.push({
2057
          value: matched,
2058
          type: type,
2059
          matches: match
2060
        });
2061
        soFar = soFar.slice( matched.length );
2062
      }
2063
    }
2064
2065
    if ( !matched ) {
2066
      break;
2067
    }
2068
  }
2069
2070
  // Return the length of the invalid excess
2071
  // if we're just parsing
2072
  // Otherwise, throw an error or return tokens
2073
  return parseOnly ?
2074
    soFar.length :
2075
    soFar ?
2076
      Sizzle.error( selector ) :
2077
      // Cache the tokens
2078
      tokenCache( selector, groups ).slice( 0 );
2079
};
2080
2081
function toSelector( tokens ) {
2082
  var i = 0,
2083
    len = tokens.length,
2084
    selector = "";
2085
  for ( ; i < len; i++ ) {
2086
    selector += tokens[i].value;
2087
  }
2088
  return selector;
2089
}
2090
2091
function addCombinator( matcher, combinator, base ) {
2092
  var dir = combinator.dir,
2093
    checkNonElements = base && dir === "parentNode",
2094
    doneName = done++;
2095
2096
  return combinator.first ?
2097
    // Check against closest ancestor/preceding element
2098
    function( elem, context, xml ) {
2099
      while ( (elem = elem[ dir ]) ) {
2100
        if ( elem.nodeType === 1 || checkNonElements ) {
2101
          return matcher( elem, context, xml );
2102
        }
2103
      }
2104
    } :
2105
2106
    // Check against all ancestor/preceding elements
2107
    function( elem, context, xml ) {
2108
      var oldCache, outerCache,
2109
        newCache = [ dirruns, doneName ];
2110
2111
      // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2112
      if ( xml ) {
2113
        while ( (elem = elem[ dir ]) ) {
2114
          if ( elem.nodeType === 1 || checkNonElements ) {
2115
            if ( matcher( elem, context, xml ) ) {
2116
              return true;
2117
            }
2118
          }
2119
        }
2120
      } else {
2121
        while ( (elem = elem[ dir ]) ) {
2122
          if ( elem.nodeType === 1 || checkNonElements ) {
2123
            outerCache = elem[ expando ] || (elem[ expando ] = {});
2124
            if ( (oldCache = outerCache[ dir ]) &&
2125
              oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2126
2127
              // Assign to newCache so results back-propagate to previous elements
2128
              return (newCache[ 2 ] = oldCache[ 2 ]);
2129
            } else {
2130
              // Reuse newcache so results back-propagate to previous elements
2131
              outerCache[ dir ] = newCache;
2132
2133
              // A match means we're done; a fail means we have to keep checking
2134
              if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2135
                return true;
2136
              }
2137
            }
2138
          }
2139
        }
2140
      }
2141
    };
2142
}
2143
2144
function elementMatcher( matchers ) {
2145
  return matchers.length > 1 ?
2146
    function( elem, context, xml ) {
2147
      var i = matchers.length;
2148
      while ( i-- ) {
2149
        if ( !matchers[i]( elem, context, xml ) ) {
2150
          return false;
2151
        }
2152
      }
2153
      return true;
2154
    } :
2155
    matchers[0];
2156
}
2157
2158
function multipleContexts( selector, contexts, results ) {
2159
  var i = 0,
2160
    len = contexts.length;
2161
  for ( ; i < len; i++ ) {
2162
    Sizzle( selector, contexts[i], results );
2163
  }
2164
  return results;
2165
}
2166
2167
function condense( unmatched, map, filter, context, xml ) {
2168
  var elem,
2169
    newUnmatched = [],
2170
    i = 0,
2171
    len = unmatched.length,
2172
    mapped = map != null;
2173
2174
  for ( ; i < len; i++ ) {
2175
    if ( (elem = unmatched[i]) ) {
2176
      if ( !filter || filter( elem, context, xml ) ) {
2177
        newUnmatched.push( elem );
2178
        if ( mapped ) {
2179
          map.push( i );
2180
        }
2181
      }
2182
    }
2183
  }
2184
2185
  return newUnmatched;
2186
}
2187
2188
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2189
  if ( postFilter && !postFilter[ expando ] ) {
2190
    postFilter = setMatcher( postFilter );
2191
  }
2192
  if ( postFinder && !postFinder[ expando ] ) {
2193
    postFinder = setMatcher( postFinder, postSelector );
2194
  }
2195
  return markFunction(function( seed, results, context, xml ) {
2196
    var temp, i, elem,
2197
      preMap = [],
2198
      postMap = [],
2199
      preexisting = results.length,
2200
2201
      // Get initial elements from seed or context
2202
      elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2203
2204
      // Prefilter to get matcher input, preserving a map for seed-results synchronization
2205
      matcherIn = preFilter && ( seed || !selector ) ?
2206
        condense( elems, preMap, preFilter, context, xml ) :
2207
        elems,
2208
2209
      matcherOut = matcher ?
2210
        // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2211
        postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2212
2213
          // ...intermediate processing is necessary
2214
          [] :
2215
2216
          // ...otherwise use results directly
2217
          results :
2218
        matcherIn;
2219
2220
    // Find primary matches
2221
    if ( matcher ) {
2222
      matcher( matcherIn, matcherOut, context, xml );
2223
    }
2224
2225
    // Apply postFilter
2226
    if ( postFilter ) {
2227
      temp = condense( matcherOut, postMap );
2228
      postFilter( temp, [], context, xml );
2229
2230
      // Un-match failing elements by moving them back to matcherIn
2231
      i = temp.length;
2232
      while ( i-- ) {
2233
        if ( (elem = temp[i]) ) {
2234
          matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2235
        }
2236
      }
2237
    }
2238
2239
    if ( seed ) {
2240
      if ( postFinder || preFilter ) {
2241
        if ( postFinder ) {
2242
          // Get the final matcherOut by condensing this intermediate into postFinder contexts
2243
          temp = [];
2244
          i = matcherOut.length;
2245
          while ( i-- ) {
2246
            if ( (elem = matcherOut[i]) ) {
2247
              // Restore matcherIn since elem is not yet a final match
2248
              temp.push( (matcherIn[i] = elem) );
2249
            }
2250
          }
2251
          postFinder( null, (matcherOut = []), temp, xml );
2252
        }
2253
2254
        // Move matched elements from seed to results to keep them synchronized
2255
        i = matcherOut.length;
2256
        while ( i-- ) {
2257
          if ( (elem = matcherOut[i]) &&
2258
            (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2259
2260
            seed[temp] = !(results[temp] = elem);
2261
          }
2262
        }
2263
      }
2264
2265
    // Add elements to results, through postFinder if defined
2266
    } else {
2267
      matcherOut = condense(
2268
        matcherOut === results ?
2269
          matcherOut.splice( preexisting, matcherOut.length ) :
2270
          matcherOut
2271
      );
2272
      if ( postFinder ) {
2273
        postFinder( null, results, matcherOut, xml );
2274
      } else {
2275
        push.apply( results, matcherOut );
2276
      }
2277
    }
2278
  });
2279
}
2280
2281
function matcherFromTokens( tokens ) {
2282
  var checkContext, matcher, j,
2283
    len = tokens.length,
2284
    leadingRelative = Expr.relative[ tokens[0].type ],
2285
    implicitRelative = leadingRelative || Expr.relative[" "],
2286
    i = leadingRelative ? 1 : 0,
2287
2288
    // The foundational matcher ensures that elements are reachable from top-level context(s)
2289
    matchContext = addCombinator( function( elem ) {
2290
      return elem === checkContext;
2291
    }, implicitRelative, true ),
2292
    matchAnyContext = addCombinator( function( elem ) {
2293
      return indexOf( checkContext, elem ) > -1;
2294
    }, implicitRelative, true ),
2295
    matchers = [ function( elem, context, xml ) {
2296
      var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2297
        (checkContext = context).nodeType ?
2298
          matchContext( elem, context, xml ) :
2299
          matchAnyContext( elem, context, xml ) );
2300
      // Avoid hanging onto element (issue #299)
2301
      checkContext = null;
2302
      return ret;
2303
    } ];
2304
2305
  for ( ; i < len; i++ ) {
2306
    if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2307
      matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2308
    } else {
2309
      matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2310
2311
      // Return special upon seeing a positional matcher
2312
      if ( matcher[ expando ] ) {
2313
        // Find the next relative operator (if any) for proper handling
2314
        j = ++i;
2315
        for ( ; j < len; j++ ) {
2316
          if ( Expr.relative[ tokens[j].type ] ) {
2317
            break;
2318
          }
2319
        }
2320
        return setMatcher(
2321
          i > 1 && elementMatcher( matchers ),
2322
          i > 1 && toSelector(
2323
            // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2324
            tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2325
          ).replace( rtrim, "$1" ),
2326
          matcher,
2327
          i < j && matcherFromTokens( tokens.slice( i, j ) ),
2328
          j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2329
          j < len && toSelector( tokens )
2330
        );
2331
      }
2332
      matchers.push( matcher );
2333
    }
2334
  }
2335
2336
  return elementMatcher( matchers );
2337
}
2338
2339
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2340
  var bySet = setMatchers.length > 0,
2341
    byElement = elementMatchers.length > 0,
2342
    superMatcher = function( seed, context, xml, results, outermost ) {
2343
      var elem, j, matcher,
2344
        matchedCount = 0,
2345
        i = "0",
2346
        unmatched = seed && [],
2347
        setMatched = [],
2348
        contextBackup = outermostContext,
2349
        // We must always have either seed elements or outermost context
2350
        elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2351
        // Use integer dirruns iff this is the outermost matcher
2352
        dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2353
        len = elems.length;
2354
2355
      if ( outermost ) {
2356
        outermostContext = context !== document && context;
2357
      }
2358
2359
      // Add elements passing elementMatchers directly to results
2360
      // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2361
      // Support: IE<9, Safari
2362
      // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2363
      for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2364
        if ( byElement && elem ) {
2365
          j = 0;
2366
          while ( (matcher = elementMatchers[j++]) ) {
2367
            if ( matcher( elem, context, xml ) ) {
2368
              results.push( elem );
2369
              break;
2370
            }
2371
          }
2372
          if ( outermost ) {
2373
            dirruns = dirrunsUnique;
2374
          }
2375
        }
2376
2377
        // Track unmatched elements for set filters
2378
        if ( bySet ) {
2379
          // They will have gone through all possible matchers
2380
          if ( (elem = !matcher && elem) ) {
2381
            matchedCount--;
2382
          }
2383
2384
          // Lengthen the array for every element, matched or not
2385
          if ( seed ) {
2386
            unmatched.push( elem );
2387
          }
2388
        }
2389
      }
2390
2391
      // Apply set filters to unmatched elements
2392
      matchedCount += i;
2393
      if ( bySet && i !== matchedCount ) {
2394
        j = 0;
2395
        while ( (matcher = setMatchers[j++]) ) {
2396
          matcher( unmatched, setMatched, context, xml );
2397
        }
2398
2399
        if ( seed ) {
2400
          // Reintegrate element matches to eliminate the need for sorting
2401
          if ( matchedCount > 0 ) {
2402
            while ( i-- ) {
2403
              if ( !(unmatched[i] || setMatched[i]) ) {
2404
                setMatched[i] = pop.call( results );
2405
              }
2406
            }
2407
          }
2408
2409
          // Discard index placeholder values to get only actual matches
2410
          setMatched = condense( setMatched );
2411
        }
2412
2413
        // Add matches to results
2414
        push.apply( results, setMatched );
2415
2416
        // Seedless set matches succeeding multiple successful matchers stipulate sorting
2417
        if ( outermost && !seed && setMatched.length > 0 &&
2418
          ( matchedCount + setMatchers.length ) > 1 ) {
2419
2420
          Sizzle.uniqueSort( results );
2421
        }
2422
      }
2423
2424
      // Override manipulation of globals by nested matchers
2425
      if ( outermost ) {
2426
        dirruns = dirrunsUnique;
2427
        outermostContext = contextBackup;
2428
      }
2429
2430
      return unmatched;
2431
    };
2432
2433
  return bySet ?
2434
    markFunction( superMatcher ) :
2435
    superMatcher;
2436
}
2437
2438
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2439
  var i,
2440
    setMatchers = [],
2441
    elementMatchers = [],
2442
    cached = compilerCache[ selector + " " ];
2443
2444
  if ( !cached ) {
2445
    // Generate a function of recursive functions that can be used to check each element
2446
    if ( !match ) {
2447
      match = tokenize( selector );
2448
    }
2449
    i = match.length;
2450
    while ( i-- ) {
2451
      cached = matcherFromTokens( match[i] );
2452
      if ( cached[ expando ] ) {
2453
        setMatchers.push( cached );
2454
      } else {
2455
        elementMatchers.push( cached );
2456
      }
2457
    }
2458
2459
    // Cache the compiled function
2460
    cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2461
2462
    // Save selector and tokenization
2463
    cached.selector = selector;
2464
  }
2465
  return cached;
2466
};
2467
2468
/**
2469
 * A low-level selection function that works with Sizzle's compiled
2470
 *  selector functions
2471
 * @param {String|Function} selector A selector or a pre-compiled
2472
 *  selector function built with Sizzle.compile
2473
 * @param {Element} context
2474
 * @param {Array} [results]
2475
 * @param {Array} [seed] A set of elements to match against
2476
 */
2477
select = Sizzle.select = function( selector, context, results, seed ) {
2478
  var i, tokens, token, type, find,
2479
    compiled = typeof selector === "function" && selector,
2480
    match = !seed && tokenize( (selector = compiled.selector || selector) );
2481
2482
  results = results || [];
2483
2484
  // Try to minimize operations if there is no seed and only one group
2485
  if ( match.length === 1 ) {
2486
2487
    // Take a shortcut and set the context if the root selector is an ID
2488
    tokens = match[0] = match[0].slice( 0 );
2489
    if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2490
        support.getById && context.nodeType === 9 && documentIsHTML &&
2491
        Expr.relative[ tokens[1].type ] ) {
2492
2493
      context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2494
      if ( !context ) {
2495
        return results;
2496
2497
      // Precompiled matchers will still verify ancestry, so step up a level
2498
      } else if ( compiled ) {
2499
        context = context.parentNode;
2500
      }
2501
2502
      selector = selector.slice( tokens.shift().value.length );
2503
    }
2504
2505
    // Fetch a seed set for right-to-left matching
2506
    i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2507
    while ( i-- ) {
2508
      token = tokens[i];
2509
2510
      // Abort if we hit a combinator
2511
      if ( Expr.relative[ (type = token.type) ] ) {
2512
        break;
2513
      }
2514
      if ( (find = Expr.find[ type ]) ) {
2515
        // Search, expanding context for leading sibling combinators
2516
        if ( (seed = find(
2517
          token.matches[0].replace( runescape, funescape ),
2518
          rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2519
        )) ) {
2520
2521
          // If seed is empty or no tokens remain, we can return early
2522
          tokens.splice( i, 1 );
2523
          selector = seed.length && toSelector( tokens );
2524
          if ( !selector ) {
2525
            push.apply( results, seed );
2526
            return results;
2527
          }
2528
2529
          break;
2530
        }
2531
      }
2532
    }
2533
  }
2534
2535
  // Compile and execute a filtering function if one is not provided
2536
  // Provide `match` to avoid retokenization if we modified the selector above
2537
  ( compiled || compile( selector, match ) )(
2538
    seed,
2539
    context,
2540
    !documentIsHTML,
2541
    results,
2542
    rsibling.test( selector ) && testContext( context.parentNode ) || context
2543
  );
2544
  return results;
2545
};
2546
2547
// One-time assignments
2548
2549
// Sort stability
2550
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2551
2552
// Support: Chrome 14-35+
2553
// Always assume duplicates if they aren't passed to the comparison function
2554
support.detectDuplicates = !!hasDuplicate;
2555
2556
// Initialize against the default document
2557
setDocument();
2558
2559
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2560
// Detached nodes confoundingly follow *each other*
2561
support.sortDetached = assert(function( div1 ) {
2562
  // Should return 1, but returns 4 (following)
2563
  return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2564
});
2565
2566
// Support: IE<8
2567
// Prevent attribute/property "interpolation"
2568
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2569
if ( !assert(function( div ) {
2570
  div.innerHTML = "<a href='#'></a>";
2571
  return div.firstChild.getAttribute("href") === "#" ;
2572
}) ) {
2573
  addHandle( "type|href|height|width", function( elem, name, isXML ) {
2574
    if ( !isXML ) {
2575
      return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2576
    }
2577
  });
2578
}
2579
2580
// Support: IE<9
2581
// Use defaultValue in place of getAttribute("value")
2582
if ( !support.attributes || !assert(function( div ) {
2583
  div.innerHTML = "<input/>";
2584
  div.firstChild.setAttribute( "value", "" );
2585
  return div.firstChild.getAttribute( "value" ) === "";
2586
}) ) {
2587
  addHandle( "value", function( elem, name, isXML ) {
2588
    if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2589
      return elem.defaultValue;
2590
    }
2591
  });
2592
}
2593
2594
// Support: IE<9
2595
// Use getAttributeNode to fetch booleans when getAttribute lies
2596
if ( !assert(function( div ) {
2597
  return div.getAttribute("disabled") == null;
2598
}) ) {
2599
  addHandle( booleans, function( elem, name, isXML ) {
2600
    var val;
2601
    if ( !isXML ) {
2602
      return elem[ name ] === true ? name.toLowerCase() :
2603
          (val = elem.getAttributeNode( name )) && val.specified ?
2604
          val.value :
2605
        null;
2606
    }
2607
  });
2608
}
2609
2610
return Sizzle;
2611
2612
})( window );
2613
2614
2615
2616
jQuery.find = Sizzle;
2617
jQuery.expr = Sizzle.selectors;
2618
jQuery.expr[":"] = jQuery.expr.pseudos;
2619
jQuery.unique = Sizzle.uniqueSort;
2620
jQuery.text = Sizzle.getText;
2621
jQuery.isXMLDoc = Sizzle.isXML;
2622
jQuery.contains = Sizzle.contains;
2623
2624
2625
2626
var rneedsContext = jQuery.expr.match.needsContext;
2627
2628
var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
2629
2630
2631
2632
var risSimple = /^.[^:#\[\.,]*$/;
2633
2634
// Implement the identical functionality for filter and not
2635
function winnow( elements, qualifier, not ) {
2636
  if ( jQuery.isFunction( qualifier ) ) {
2637
    return jQuery.grep( elements, function( elem, i ) {
2638
      /* jshint -W018 */
2639
      return !!qualifier.call( elem, i, elem ) !== not;
2640
    });
2641
2642
  }
2643
2644
  if ( qualifier.nodeType ) {
2645
    return jQuery.grep( elements, function( elem ) {
2646
      return ( elem === qualifier ) !== not;
2647
    });
2648
2649
  }
2650
2651
  if ( typeof qualifier === "string" ) {
2652
    if ( risSimple.test( qualifier ) ) {
2653
      return jQuery.filter( qualifier, elements, not );
2654
    }
2655
2656
    qualifier = jQuery.filter( qualifier, elements );
2657
  }
2658
2659
  return jQuery.grep( elements, function( elem ) {
2660
    return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
2661
  });
2662
}
2663
2664
jQuery.filter = function( expr, elems, not ) {
2665
  var elem = elems[ 0 ];
2666
2667
  if ( not ) {
2668
    expr = ":not(" + expr + ")";
2669
  }
2670
2671
  return elems.length === 1 && elem.nodeType === 1 ?
2672
    jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2673
    jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2674
      return elem.nodeType === 1;
2675
    }));
2676
};
2677
2678
jQuery.fn.extend({
2679
  find: function( selector ) {
2680
    var i,
2681
      len = this.length,
2682
      ret = [],
2683
      self = this;
2684
2685
    if ( typeof selector !== "string" ) {
2686
      return this.pushStack( jQuery( selector ).filter(function() {
2687
        for ( i = 0; i < len; i++ ) {
2688
          if ( jQuery.contains( self[ i ], this ) ) {
2689
            return true;
2690
          }
2691
        }
2692
      }) );
2693
    }
2694
2695
    for ( i = 0; i < len; i++ ) {
2696
      jQuery.find( selector, self[ i ], ret );
2697
    }
2698
2699
    // Needed because $( selector, context ) becomes $( context ).find( selector )
2700
    ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2701
    ret.selector = this.selector ? this.selector + " " + selector : selector;
2702
    return ret;
2703
  },
2704
  filter: function( selector ) {
2705
    return this.pushStack( winnow(this, selector || [], false) );
2706
  },
2707
  not: function( selector ) {
2708
    return this.pushStack( winnow(this, selector || [], true) );
2709
  },
2710
  is: function( selector ) {
2711
    return !!winnow(
2712
      this,
2713
2714
      // If this is a positional/relative selector, check membership in the returned set
2715
      // so $("p:first").is("p:last") won't return true for a doc with two "p".
2716
      typeof selector === "string" && rneedsContext.test( selector ) ?
2717
        jQuery( selector ) :
2718
        selector || [],
2719
      false
2720
    ).length;
2721
  }
2722
});
2723
2724
2725
// Initialize a jQuery object
2726
2727
2728
// A central reference to the root jQuery(document)
2729
var rootjQuery,
2730
2731
  // A simple way to check for HTML strings
2732
  // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2733
  // Strict HTML recognition (#11290: must start with <)
2734
  rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2735
2736
  init = jQuery.fn.init = function( selector, context ) {
2737
    var match, elem;
2738
2739
    // HANDLE: $(""), $(null), $(undefined), $(false)
2740
    if ( !selector ) {
2741
      return this;
2742
    }
2743
2744
    // Handle HTML strings
2745
    if ( typeof selector === "string" ) {
2746
      if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
2747
        // Assume that strings that start and end with <> are HTML and skip the regex check
2748
        match = [ null, selector, null ];
2749
2750
      } else {
2751
        match = rquickExpr.exec( selector );
2752
      }
2753
2754
      // Match html or make sure no context is specified for #id
2755
      if ( match && (match[1] || !context) ) {
2756
2757
        // HANDLE: $(html) -> $(array)
2758
        if ( match[1] ) {
2759
          context = context instanceof jQuery ? context[0] : context;
2760
2761
          // Option to run scripts is true for back-compat
2762
          // Intentionally let the error be thrown if parseHTML is not present
2763
          jQuery.merge( this, jQuery.parseHTML(
2764
            match[1],
2765
            context && context.nodeType ? context.ownerDocument || context : document,
2766
            true
2767
          ) );
2768
2769
          // HANDLE: $(html, props)
2770
          if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
2771
            for ( match in context ) {
2772
              // Properties of context are called as methods if possible
2773
              if ( jQuery.isFunction( this[ match ] ) ) {
2774
                this[ match ]( context[ match ] );
2775
2776
              // ...and otherwise set as attributes
2777
              } else {
2778
                this.attr( match, context[ match ] );
2779
              }
2780
            }
2781
          }
2782
2783
          return this;
2784
2785
        // HANDLE: $(#id)
2786
        } else {
2787
          elem = document.getElementById( match[2] );
2788
2789
          // Support: Blackberry 4.6
2790
          // gEBID returns nodes no longer in the document (#6963)
2791
          if ( elem && elem.parentNode ) {
2792
            // Inject the element directly into the jQuery object
2793
            this.length = 1;
2794
            this[0] = elem;
2795
          }
2796
2797
          this.context = document;
2798
          this.selector = selector;
2799
          return this;
2800
        }
2801
2802
      // HANDLE: $(expr, $(...))
2803
      } else if ( !context || context.jquery ) {
2804
        return ( context || rootjQuery ).find( selector );
2805
2806
      // HANDLE: $(expr, context)
2807
      // (which is just equivalent to: $(context).find(expr)
2808
      } else {
2809
        return this.constructor( context ).find( selector );
2810
      }
2811
2812
    // HANDLE: $(DOMElement)
2813
    } else if ( selector.nodeType ) {
2814
      this.context = this[0] = selector;
2815
      this.length = 1;
2816
      return this;
2817
2818
    // HANDLE: $(function)
2819
    // Shortcut for document ready
2820
    } else if ( jQuery.isFunction( selector ) ) {
2821
      return typeof rootjQuery.ready !== "undefined" ?
2822
        rootjQuery.ready( selector ) :
2823
        // Execute immediately if ready is not present
2824
        selector( jQuery );
2825
    }
2826
2827
    if ( selector.selector !== undefined ) {
2828
      this.selector = selector.selector;
2829
      this.context = selector.context;
2830
    }
2831
2832
    return jQuery.makeArray( selector, this );
2833
  };
2834
2835
// Give the init function the jQuery prototype for later instantiation
2836
init.prototype = jQuery.fn;
2837
2838
// Initialize central reference
2839
rootjQuery = jQuery( document );
2840
2841
2842
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2843
  // Methods guaranteed to produce a unique set when starting from a unique set
2844
  guaranteedUnique = {
2845
    children: true,
2846
    contents: true,
2847
    next: true,
2848
    prev: true
2849
  };
2850
2851
jQuery.extend({
2852
  dir: function( elem, dir, until ) {
2853
    var matched = [],
2854
      truncate = until !== undefined;
2855
2856
    while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
2857
      if ( elem.nodeType === 1 ) {
2858
        if ( truncate && jQuery( elem ).is( until ) ) {
2859
          break;
2860
        }
2861
        matched.push( elem );
2862
      }
2863
    }
2864
    return matched;
2865
  },
2866
2867
  sibling: function( n, elem ) {
2868
    var matched = [];
2869
2870
    for ( ; n; n = n.nextSibling ) {
2871
      if ( n.nodeType === 1 && n !== elem ) {
2872
        matched.push( n );
2873
      }
2874
    }
2875
2876
    return matched;
2877
  }
2878
});
2879
2880
jQuery.fn.extend({
2881
  has: function( target ) {
2882
    var targets = jQuery( target, this ),
2883
      l = targets.length;
2884
2885
    return this.filter(function() {
2886
      var i = 0;
2887
      for ( ; i < l; i++ ) {
2888
        if ( jQuery.contains( this, targets[i] ) ) {
2889
          return true;
2890
        }
2891
      }
2892
    });
2893
  },
2894
2895
  closest: function( selectors, context ) {
2896
    var cur,
2897
      i = 0,
2898
      l = this.length,
2899
      matched = [],
2900
      pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2901
        jQuery( selectors, context || this.context ) :
2902
        0;
2903
2904
    for ( ; i < l; i++ ) {
2905
      for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
2906
        // Always skip document fragments
2907
        if ( cur.nodeType < 11 && (pos ?
2908
          pos.index(cur) > -1 :
2909
2910
          // Don't pass non-elements to Sizzle
2911
          cur.nodeType === 1 &&
2912
            jQuery.find.matchesSelector(cur, selectors)) ) {
2913
2914
          matched.push( cur );
2915
          break;
2916
        }
2917
      }
2918
    }
2919
2920
    return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
2921
  },
2922
2923
  // Determine the position of an element within the set
2924
  index: function( elem ) {
2925
2926
    // No argument, return index in parent
2927
    if ( !elem ) {
2928
      return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
2929
    }
2930
2931
    // Index in selector
2932
    if ( typeof elem === "string" ) {
2933
      return indexOf.call( jQuery( elem ), this[ 0 ] );
2934
    }
2935
2936
    // Locate the position of the desired element
2937
    return indexOf.call( this,
2938
2939
      // If it receives a jQuery object, the first element is used
2940
      elem.jquery ? elem[ 0 ] : elem
2941
    );
2942
  },
2943
2944
  add: function( selector, context ) {
2945
    return this.pushStack(
2946
      jQuery.unique(
2947
        jQuery.merge( this.get(), jQuery( selector, context ) )
2948
      )
2949
    );
2950
  },
2951
2952
  addBack: function( selector ) {
2953
    return this.add( selector == null ?
2954
      this.prevObject : this.prevObject.filter(selector)
2955
    );
2956
  }
2957
});
2958
2959
function sibling( cur, dir ) {
2960
  while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
2961
  return cur;
2962
}
2963
2964
jQuery.each({
2965
  parent: function( elem ) {
2966
    var parent = elem.parentNode;
2967
    return parent && parent.nodeType !== 11 ? parent : null;
2968
  },
2969
  parents: function( elem ) {
2970
    return jQuery.dir( elem, "parentNode" );
2971
  },
2972
  parentsUntil: function( elem, i, until ) {
2973
    return jQuery.dir( elem, "parentNode", until );
2974
  },
2975
  next: function( elem ) {
2976
    return sibling( elem, "nextSibling" );
2977
  },
2978
  prev: function( elem ) {
2979
    return sibling( elem, "previousSibling" );
2980
  },
2981
  nextAll: function( elem ) {
2982
    return jQuery.dir( elem, "nextSibling" );
2983
  },
2984
  prevAll: function( elem ) {
2985
    return jQuery.dir( elem, "previousSibling" );
2986
  },
2987
  nextUntil: function( elem, i, until ) {
2988
    return jQuery.dir( elem, "nextSibling", until );
2989
  },
2990
  prevUntil: function( elem, i, until ) {
2991
    return jQuery.dir( elem, "previousSibling", until );
2992
  },
2993
  siblings: function( elem ) {
2994
    return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
2995
  },
2996
  children: function( elem ) {
2997
    return jQuery.sibling( elem.firstChild );
2998
  },
2999
  contents: function( elem ) {
3000
    return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3001
  }
3002
}, function( name, fn ) {
3003
  jQuery.fn[ name ] = function( until, selector ) {
3004
    var matched = jQuery.map( this, fn, until );
3005
3006
    if ( name.slice( -5 ) !== "Until" ) {
3007
      selector = until;
3008
    }
3009
3010
    if ( selector && typeof selector === "string" ) {
3011
      matched = jQuery.filter( selector, matched );
3012
    }
3013
3014
    if ( this.length > 1 ) {
3015
      // Remove duplicates
3016
      if ( !guaranteedUnique[ name ] ) {
3017
        jQuery.unique( matched );
3018
      }
3019
3020
      // Reverse order for parents* and prev-derivatives
3021
      if ( rparentsprev.test( name ) ) {
3022
        matched.reverse();
3023
      }
3024
    }
3025
3026
    return this.pushStack( matched );
3027
  };
3028
});
3029
var rnotwhite = (/\S+/g);
3030
3031
3032
3033
// String to Object options format cache
3034
var optionsCache = {};
3035
3036
// Convert String-formatted options into Object-formatted ones and store in cache
3037
function createOptions( options ) {
3038
  var object = optionsCache[ options ] = {};
3039
  jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3040
    object[ flag ] = true;
3041
  });
3042
  return object;
3043
}
3044
3045
/*
3046
 * Create a callback list using the following parameters:
3047
 *
3048
 *  options: an optional list of space-separated options that will change how
3049
 *      the callback list behaves or a more traditional option object
3050
 *
3051
 * By default a callback list will act like an event callback list and can be
3052
 * "fired" multiple times.
3053
 *
3054
 * Possible options:
3055
 *
3056
 *  once:     will ensure the callback list can only be fired once (like a Deferred)
3057
 *
3058
 *  memory:     will keep track of previous values and will call any callback added
3059
 *          after the list has been fired right away with the latest "memorized"
3060
 *          values (like a Deferred)
3061
 *
3062
 *  unique:     will ensure a callback can only be added once (no duplicate in the list)
3063
 *
3064
 *  stopOnFalse:  interrupt callings when a callback returns false
3065
 *
3066
 */
3067
jQuery.Callbacks = function( options ) {
3068
3069
  // Convert options from String-formatted to Object-formatted if needed
3070
  // (we check in cache first)
3071
  options = typeof options === "string" ?
3072
    ( optionsCache[ options ] || createOptions( options ) ) :
3073
    jQuery.extend( {}, options );
3074
3075
  var // Last fire value (for non-forgettable lists)
3076
    memory,
3077
    // Flag to know if list was already fired
3078
    fired,
3079
    // Flag to know if list is currently firing
3080
    firing,
3081
    // First callback to fire (used internally by add and fireWith)
3082
    firingStart,
3083
    // End of the loop when firing
3084
    firingLength,
3085
    // Index of currently firing callback (modified by remove if needed)
3086
    firingIndex,
3087
    // Actual callback list
3088
    list = [],
3089
    // Stack of fire calls for repeatable lists
3090
    stack = !options.once && [],
3091
    // Fire callbacks
3092
    fire = function( data ) {
3093
      memory = options.memory && data;
3094
      fired = true;
3095
      firingIndex = firingStart || 0;
3096
      firingStart = 0;
3097
      firingLength = list.length;
3098
      firing = true;
3099
      for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3100
        if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3101
          memory = false; // To prevent further calls using add
3102
          break;
3103
        }
3104
      }
3105
      firing = false;
3106
      if ( list ) {
3107
        if ( stack ) {
3108
          if ( stack.length ) {
3109
            fire( stack.shift() );
3110
          }
3111
        } else if ( memory ) {
3112
          list = [];
3113
        } else {
3114
          self.disable();
3115
        }
3116
      }
3117
    },
3118
    // Actual Callbacks object
3119
    self = {
3120
      // Add a callback or a collection of callbacks to the list
3121
      add: function() {
3122
        if ( list ) {
3123
          // First, we save the current length
3124
          var start = list.length;
3125
          (function add( args ) {
3126
            jQuery.each( args, function( _, arg ) {
3127
              var type = jQuery.type( arg );
3128
              if ( type === "function" ) {
3129
                if ( !options.unique || !self.has( arg ) ) {
3130
                  list.push( arg );
3131
                }
3132
              } else if ( arg && arg.length && type !== "string" ) {
3133
                // Inspect recursively
3134
                add( arg );
3135
              }
3136
            });
3137
          })( arguments );
3138
          // Do we need to add the callbacks to the
3139
          // current firing batch?
3140
          if ( firing ) {
3141
            firingLength = list.length;
3142
          // With memory, if we're not firing then
3143
          // we should call right away
3144
          } else if ( memory ) {
3145
            firingStart = start;
3146
            fire( memory );
3147
          }
3148
        }
3149
        return this;
3150
      },
3151
      // Remove a callback from the list
3152
      remove: function() {
3153
        if ( list ) {
3154
          jQuery.each( arguments, function( _, arg ) {
3155
            var index;
3156
            while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3157
              list.splice( index, 1 );
3158
              // Handle firing indexes
3159
              if ( firing ) {
3160
                if ( index <= firingLength ) {
3161
                  firingLength--;
3162
                }
3163
                if ( index <= firingIndex ) {
3164
                  firingIndex--;
3165
                }
3166
              }
3167
            }
3168
          });
3169
        }
3170
        return this;
3171
      },
3172
      // Check if a given callback is in the list.
3173
      // If no argument is given, return whether or not list has callbacks attached.
3174
      has: function( fn ) {
3175
        return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3176
      },
3177
      // Remove all callbacks from the list
3178
      empty: function() {
3179
        list = [];
3180
        firingLength = 0;
3181
        return this;
3182
      },
3183
      // Have the list do nothing anymore
3184
      disable: function() {
3185
        list = stack = memory = undefined;
3186
        return this;
3187
      },
3188
      // Is it disabled?
3189
      disabled: function() {
3190
        return !list;
3191
      },
3192
      // Lock the list in its current state
3193
      lock: function() {
3194
        stack = undefined;
3195
        if ( !memory ) {
3196
          self.disable();
3197
        }
3198
        return this;
3199
      },
3200
      // Is it locked?
3201
      locked: function() {
3202
        return !stack;
3203
      },
3204
      // Call all callbacks with the given context and arguments
3205
      fireWith: function( context, args ) {
3206
        if ( list && ( !fired || stack ) ) {
3207
          args = args || [];
3208
          args = [ context, args.slice ? args.slice() : args ];
3209
          if ( firing ) {
3210
            stack.push( args );
3211
          } else {
3212
            fire( args );
3213
          }
3214
        }
3215
        return this;
3216
      },
3217
      // Call all the callbacks with the given arguments
3218
      fire: function() {
3219
        self.fireWith( this, arguments );
3220
        return this;
3221
      },
3222
      // To know if the callbacks have already been called at least once
3223
      fired: function() {
3224
        return !!fired;
3225
      }
3226
    };
3227
3228
  return self;
3229
};
3230
3231
3232
jQuery.extend({
3233
3234
  Deferred: function( func ) {
3235
    var tuples = [
3236
        // action, add listener, listener list, final state
3237
        [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3238
        [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3239
        [ "notify", "progress", jQuery.Callbacks("memory") ]
3240
      ],
3241
      state = "pending",
3242
      promise = {
3243
        state: function() {
3244
          return state;
3245
        },
3246
        always: function() {
3247
          deferred.done( arguments ).fail( arguments );
3248
          return this;
3249
        },
3250
        then: function( /* fnDone, fnFail, fnProgress */ ) {
3251
          var fns = arguments;
3252
          return jQuery.Deferred(function( newDefer ) {
3253
            jQuery.each( tuples, function( i, tuple ) {
3254
              var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3255
              // deferred[ done | fail | progress ] for forwarding actions to newDefer
3256
              deferred[ tuple[1] ](function() {
3257
                var returned = fn && fn.apply( this, arguments );
3258
                if ( returned && jQuery.isFunction( returned.promise ) ) {
3259
                  returned.promise()
3260
                    .done( newDefer.resolve )
3261
                    .fail( newDefer.reject )
3262
                    .progress( newDefer.notify );
3263
                } else {
3264
                  newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3265
                }
3266
              });
3267
            });
3268
            fns = null;
3269
          }).promise();
3270
        },
3271
        // Get a promise for this deferred
3272
        // If obj is provided, the promise aspect is added to the object
3273
        promise: function( obj ) {
3274
          return obj != null ? jQuery.extend( obj, promise ) : promise;
3275
        }
3276
      },
3277
      deferred = {};
3278
3279
    // Keep pipe for back-compat
3280
    promise.pipe = promise.then;
3281
3282
    // Add list-specific methods
3283
    jQuery.each( tuples, function( i, tuple ) {
3284
      var list = tuple[ 2 ],
3285
        stateString = tuple[ 3 ];
3286
3287
      // promise[ done | fail | progress ] = list.add
3288
      promise[ tuple[1] ] = list.add;
3289
3290
      // Handle state
3291
      if ( stateString ) {
3292
        list.add(function() {
3293
          // state = [ resolved | rejected ]
3294
          state = stateString;
3295
3296
        // [ reject_list | resolve_list ].disable; progress_list.lock
3297
        }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3298
      }
3299
3300
      // deferred[ resolve | reject | notify ]
3301
      deferred[ tuple[0] ] = function() {
3302
        deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3303
        return this;
3304
      };
3305
      deferred[ tuple[0] + "With" ] = list.fireWith;
3306
    });
3307
3308
    // Make the deferred a promise
3309
    promise.promise( deferred );
3310
3311
    // Call given func if any
3312
    if ( func ) {
3313
      func.call( deferred, deferred );
3314
    }
3315
3316
    // All done!
3317
    return deferred;
3318
  },
3319
3320
  // Deferred helper
3321
  when: function( subordinate /* , ..., subordinateN */ ) {
3322
    var i = 0,
3323
      resolveValues = slice.call( arguments ),
3324
      length = resolveValues.length,
3325
3326
      // the count of uncompleted subordinates
3327
      remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3328
3329
      // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3330
      deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3331
3332
      // Update function for both resolve and progress values
3333
      updateFunc = function( i, contexts, values ) {
3334
        return function( value ) {
3335
          contexts[ i ] = this;
3336
          values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3337
          if ( values === progressValues ) {
3338
            deferred.notifyWith( contexts, values );
3339
          } else if ( !( --remaining ) ) {
3340
            deferred.resolveWith( contexts, values );
3341
          }
3342
        };
3343
      },
3344
3345
      progressValues, progressContexts, resolveContexts;
3346
3347
    // Add listeners to Deferred subordinates; treat others as resolved
3348
    if ( length > 1 ) {
3349
      progressValues = new Array( length );
3350
      progressContexts = new Array( length );
3351
      resolveContexts = new Array( length );
3352
      for ( ; i < length; i++ ) {
3353
        if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3354
          resolveValues[ i ].promise()
3355
            .done( updateFunc( i, resolveContexts, resolveValues ) )
3356
            .fail( deferred.reject )
3357
            .progress( updateFunc( i, progressContexts, progressValues ) );
3358
        } else {
3359
          --remaining;
3360
        }
3361
      }
3362
    }
3363
3364
    // If we're not waiting on anything, resolve the master
3365
    if ( !remaining ) {
3366
      deferred.resolveWith( resolveContexts, resolveValues );
3367
    }
3368
3369
    return deferred.promise();
3370
  }
3371
});
3372
3373
3374
// The deferred used on DOM ready
3375
var readyList;
3376
3377
jQuery.fn.ready = function( fn ) {
3378
  // Add the callback
3379
  jQuery.ready.promise().done( fn );
3380
3381
  return this;
3382
};
3383
3384
jQuery.extend({
3385
  // Is the DOM ready to be used? Set to true once it occurs.
3386
  isReady: false,
3387
3388
  // A counter to track how many items to wait for before
3389
  // the ready event fires. See #6781
3390
  readyWait: 1,
3391
3392
  // Hold (or release) the ready event
3393
  holdReady: function( hold ) {
3394
    if ( hold ) {
3395
      jQuery.readyWait++;
3396
    } else {
3397
      jQuery.ready( true );
3398
    }
3399
  },
3400
3401
  // Handle when the DOM is ready
3402
  ready: function( wait ) {
3403
3404
    // Abort if there are pending holds or we're already ready
3405
    if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3406
      return;
3407
    }
3408
3409
    // Remember that the DOM is ready
3410
    jQuery.isReady = true;
3411
3412
    // If a normal DOM Ready event fired, decrement, and wait if need be
3413
    if ( wait !== true && --jQuery.readyWait > 0 ) {
3414
      return;
3415
    }
3416
3417
    // If there are functions bound, to execute
3418
    readyList.resolveWith( document, [ jQuery ] );
3419
3420
    // Trigger any bound ready events
3421
    if ( jQuery.fn.triggerHandler ) {
3422
      jQuery( document ).triggerHandler( "ready" );
3423
      jQuery( document ).off( "ready" );
3424
    }
3425
  }
3426
});
3427
3428
/**
3429
 * The ready event handler and self cleanup method
3430
 */
3431
function completed() {
3432
  document.removeEventListener( "DOMContentLoaded", completed, false );
3433
  window.removeEventListener( "load", completed, false );
3434
  jQuery.ready();
3435
}
3436
3437
jQuery.ready.promise = function( obj ) {
3438
  if ( !readyList ) {
3439
3440
    readyList = jQuery.Deferred();
3441
3442
    // Catch cases where $(document).ready() is called after the browser event has already occurred.
3443
    // We once tried to use readyState "interactive" here, but it caused issues like the one
3444
    // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
3445
    if ( document.readyState === "complete" ) {
3446
      // Handle it asynchronously to allow scripts the opportunity to delay ready
3447
      setTimeout( jQuery.ready );
3448
3449
    } else {
3450
3451
      // Use the handy event callback
3452
      document.addEventListener( "DOMContentLoaded", completed, false );
3453
3454
      // A fallback to window.onload, that will always work
3455
      window.addEventListener( "load", completed, false );
3456
    }
3457
  }
3458
  return readyList.promise( obj );
3459
};
3460
3461
// Kick off the DOM ready check even if the user does not
3462
jQuery.ready.promise();
3463
3464
3465
3466
3467
// Multifunctional method to get and set values of a collection
3468
// The value/s can optionally be executed if it's a function
3469
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3470
  var i = 0,
3471
    len = elems.length,
3472
    bulk = key == null;
3473
3474
  // Sets many values
3475
  if ( jQuery.type( key ) === "object" ) {
3476
    chainable = true;
3477
    for ( i in key ) {
3478
      jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
3479
    }
3480
3481
  // Sets one value
3482
  } else if ( value !== undefined ) {
3483
    chainable = true;
3484
3485
    if ( !jQuery.isFunction( value ) ) {
3486
      raw = true;
3487
    }
3488
3489
    if ( bulk ) {
3490
      // Bulk operations run against the entire set
3491
      if ( raw ) {
3492
        fn.call( elems, value );
3493
        fn = null;
3494
3495
      // ...except when executing function values
3496
      } else {
3497
        bulk = fn;
3498
        fn = function( elem, key, value ) {
3499
          return bulk.call( jQuery( elem ), value );
3500
        };
3501
      }
3502
    }
3503
3504
    if ( fn ) {
3505
      for ( ; i < len; i++ ) {
3506
        fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
3507
      }
3508
    }
3509
  }
3510
3511
  return chainable ?
3512
    elems :
3513
3514
    // Gets
3515
    bulk ?
3516
      fn.call( elems ) :
3517
      len ? fn( elems[0], key ) : emptyGet;
3518
};
3519
3520
3521
/**
3522
 * Determines whether an object can have data
3523
 */
3524
jQuery.acceptData = function( owner ) {
3525
  // Accepts only:
3526
  //  - Node
3527
  //    - Node.ELEMENT_NODE
3528
  //    - Node.DOCUMENT_NODE
3529
  //  - Object
3530
  //    - Any
3531
  /* jshint -W018 */
3532
  return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3533
};
3534
3535
3536
function Data() {
3537
  // Support: Android<4,
3538
  // Old WebKit does not have Object.preventExtensions/freeze method,
3539
  // return new empty object instead with no [[set]] accessor
3540
  Object.defineProperty( this.cache = {}, 0, {
3541
    get: function() {
3542
      return {};
3543
    }
3544
  });
3545
3546
  this.expando = jQuery.expando + Data.uid++;
3547
}
3548
3549
Data.uid = 1;
3550
Data.accepts = jQuery.acceptData;
3551
3552
Data.prototype = {
3553
  key: function( owner ) {
3554
    // We can accept data for non-element nodes in modern browsers,
3555
    // but we should not, see #8335.
3556
    // Always return the key for a frozen object.
3557
    if ( !Data.accepts( owner ) ) {
3558
      return 0;
3559
    }
3560
3561
    var descriptor = {},
3562
      // Check if the owner object already has a cache key
3563
      unlock = owner[ this.expando ];
3564
3565
    // If not, create one
3566
    if ( !unlock ) {
3567
      unlock = Data.uid++;
3568
3569
      // Secure it in a non-enumerable, non-writable property
3570
      try {
3571
        descriptor[ this.expando ] = { value: unlock };
3572
        Object.defineProperties( owner, descriptor );
3573
3574
      // Support: Android<4
3575
      // Fallback to a less secure definition
3576
      } catch ( e ) {
3577
        descriptor[ this.expando ] = unlock;
3578
        jQuery.extend( owner, descriptor );
3579
      }
3580
    }
3581
3582
    // Ensure the cache object
3583
    if ( !this.cache[ unlock ] ) {
3584
      this.cache[ unlock ] = {};
3585
    }
3586
3587
    return unlock;
3588
  },
3589
  set: function( owner, data, value ) {
3590
    var prop,
3591
      // There may be an unlock assigned to this node,
3592
      // if there is no entry for this "owner", create one inline
3593
      // and set the unlock as though an owner entry had always existed
3594
      unlock = this.key( owner ),
3595
      cache = this.cache[ unlock ];
3596
3597
    // Handle: [ owner, key, value ] args
3598
    if ( typeof data === "string" ) {
3599
      cache[ data ] = value;
3600
3601
    // Handle: [ owner, { properties } ] args
3602
    } else {
3603
      // Fresh assignments by object are shallow copied
3604
      if ( jQuery.isEmptyObject( cache ) ) {
3605
        jQuery.extend( this.cache[ unlock ], data );
3606
      // Otherwise, copy the properties one-by-one to the cache object
3607
      } else {
3608
        for ( prop in data ) {
3609
          cache[ prop ] = data[ prop ];
3610
        }
3611
      }
3612
    }
3613
    return cache;
3614
  },
3615
  get: function( owner, key ) {
3616
    // Either a valid cache is found, or will be created.
3617
    // New caches will be created and the unlock returned,
3618
    // allowing direct access to the newly created
3619
    // empty data object. A valid owner object must be provided.
3620
    var cache = this.cache[ this.key( owner ) ];
3621
3622
    return key === undefined ?
3623
      cache : cache[ key ];
3624
  },
3625
  access: function( owner, key, value ) {
3626
    var stored;
3627
    // In cases where either:
3628
    //
3629
    //   1. No key was specified
3630
    //   2. A string key was specified, but no value provided
3631
    //
3632
    // Take the "read" path and allow the get method to determine
3633
    // which value to return, respectively either:
3634
    //
3635
    //   1. The entire cache object
3636
    //   2. The data stored at the key
3637
    //
3638
    if ( key === undefined ||
3639
        ((key && typeof key === "string") && value === undefined) ) {
3640
3641
      stored = this.get( owner, key );
3642
3643
      return stored !== undefined ?
3644
        stored : this.get( owner, jQuery.camelCase(key) );
3645
    }
3646
3647
    // [*]When the key is not a string, or both a key and value
3648
    // are specified, set or extend (existing objects) with either:
3649
    //
3650
    //   1. An object of properties
3651
    //   2. A key and value
3652
    //
3653
    this.set( owner, key, value );
3654
3655
    // Since the "set" path can have two possible entry points
3656
    // return the expected data based on which path was taken[*]
3657
    return value !== undefined ? value : key;
3658
  },
3659
  remove: function( owner, key ) {
3660
    var i, name, camel,
3661
      unlock = this.key( owner ),
3662
      cache = this.cache[ unlock ];
3663
3664
    if ( key === undefined ) {
3665
      this.cache[ unlock ] = {};
3666
3667
    } else {
3668
      // Support array or space separated string of keys
3669
      if ( jQuery.isArray( key ) ) {
3670
        // If "name" is an array of keys...
3671
        // When data is initially created, via ("key", "val") signature,
3672
        // keys will be converted to camelCase.
3673
        // Since there is no way to tell _how_ a key was added, remove
3674
        // both plain key and camelCase key. #12786
3675
        // This will only penalize the array argument path.
3676
        name = key.concat( key.map( jQuery.camelCase ) );
3677
      } else {
3678
        camel = jQuery.camelCase( key );
3679
        // Try the string as a key before any manipulation
3680
        if ( key in cache ) {
3681
          name = [ key, camel ];
3682
        } else {
3683
          // If a key with the spaces exists, use it.
3684
          // Otherwise, create an array by matching non-whitespace
3685
          name = camel;
3686
          name = name in cache ?
3687
            [ name ] : ( name.match( rnotwhite ) || [] );
3688
        }
3689
      }
3690
3691
      i = name.length;
3692
      while ( i-- ) {
3693
        delete cache[ name[ i ] ];
3694
      }
3695
    }
3696
  },
3697
  hasData: function( owner ) {
3698
    return !jQuery.isEmptyObject(
3699
      this.cache[ owner[ this.expando ] ] || {}
3700
    );
3701
  },
3702
  discard: function( owner ) {
3703
    if ( owner[ this.expando ] ) {
3704
      delete this.cache[ owner[ this.expando ] ];
3705
    }
3706
  }
3707
};
3708
var data_priv = new Data();
3709
3710
var data_user = new Data();
3711
3712
3713
3714
//  Implementation Summary
3715
//
3716
//  1. Enforce API surface and semantic compatibility with 1.9.x branch
3717
//  2. Improve the module's maintainability by reducing the storage
3718
//    paths to a single mechanism.
3719
//  3. Use the same single mechanism to support "private" and "user" data.
3720
//  4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3721
//  5. Avoid exposing implementation details on user objects (eg. expando properties)
3722
//  6. Provide a clear path for implementation upgrade to WeakMap in 2014
3723
3724
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3725
  rmultiDash = /([A-Z])/g;
3726
3727
function dataAttr( elem, key, data ) {
3728
  var name;
3729
3730
  // If nothing was found internally, try to fetch any
3731
  // data from the HTML5 data-* attribute
3732
  if ( data === undefined && elem.nodeType === 1 ) {
3733
    name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3734
    data = elem.getAttribute( name );
3735
3736
    if ( typeof data === "string" ) {
3737
      try {
3738
        data = data === "true" ? true :
3739
          data === "false" ? false :
3740
          data === "null" ? null :
3741
          // Only convert to a number if it doesn't change the string
3742
          +data + "" === data ? +data :
3743
          rbrace.test( data ) ? jQuery.parseJSON( data ) :
3744
          data;
3745
      } catch( e ) {}
3746
3747
      // Make sure we set the data so it isn't changed later
3748
      data_user.set( elem, key, data );
3749
    } else {
3750
      data = undefined;
3751
    }
3752
  }
3753
  return data;
3754
}
3755
3756
jQuery.extend({
3757
  hasData: function( elem ) {
3758
    return data_user.hasData( elem ) || data_priv.hasData( elem );
3759
  },
3760
3761
  data: function( elem, name, data ) {
3762
    return data_user.access( elem, name, data );
3763
  },
3764
3765
  removeData: function( elem, name ) {
3766
    data_user.remove( elem, name );
3767
  },
3768
3769
  // TODO: Now that all calls to _data and _removeData have been replaced
3770
  // with direct calls to data_priv methods, these can be deprecated.
3771
  _data: function( elem, name, data ) {
3772
    return data_priv.access( elem, name, data );
3773
  },
3774
3775
  _removeData: function( elem, name ) {
3776
    data_priv.remove( elem, name );
3777
  }
3778
});
3779
3780
jQuery.fn.extend({
3781
  data: function( key, value ) {
3782
    var i, name, data,
3783
      elem = this[ 0 ],
3784
      attrs = elem && elem.attributes;
3785
3786
    // Gets all values
3787
    if ( key === undefined ) {
3788
      if ( this.length ) {
3789
        data = data_user.get( elem );
3790
3791
        if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
3792
          i = attrs.length;
3793
          while ( i-- ) {
3794
3795
            // Support: IE11+
3796
            // The attrs elements can be null (#14894)
3797
            if ( attrs[ i ] ) {
3798
              name = attrs[ i ].name;
3799
              if ( name.indexOf( "data-" ) === 0 ) {
3800
                name = jQuery.camelCase( name.slice(5) );
3801
                dataAttr( elem, name, data[ name ] );
3802
              }
3803
            }
3804
          }
3805
          data_priv.set( elem, "hasDataAttrs", true );
3806
        }
3807
      }
3808
3809
      return data;
3810
    }
3811
3812
    // Sets multiple values
3813
    if ( typeof key === "object" ) {
3814
      return this.each(function() {
3815
        data_user.set( this, key );
3816
      });
3817
    }
3818
3819
    return access( this, function( value ) {
3820
      var data,
3821
        camelKey = jQuery.camelCase( key );
3822
3823
      // The calling jQuery object (element matches) is not empty
3824
      // (and therefore has an element appears at this[ 0 ]) and the
3825
      // `value` parameter was not undefined. An empty jQuery object
3826
      // will result in `undefined` for elem = this[ 0 ] which will
3827
      // throw an exception if an attempt to read a data cache is made.
3828
      if ( elem && value === undefined ) {
3829
        // Attempt to get data from the cache
3830
        // with the key as-is
3831
        data = data_user.get( elem, key );
3832
        if ( data !== undefined ) {
3833
          return data;
3834
        }
3835
3836
        // Attempt to get data from the cache
3837
        // with the key camelized
3838
        data = data_user.get( elem, camelKey );
3839
        if ( data !== undefined ) {
3840
          return data;
3841
        }
3842
3843
        // Attempt to "discover" the data in
3844
        // HTML5 custom data-* attrs
3845
        data = dataAttr( elem, camelKey, undefined );
3846
        if ( data !== undefined ) {
3847
          return data;
3848
        }
3849
3850
        // We tried really hard, but the data doesn't exist.
3851
        return;
3852
      }
3853
3854
      // Set the data...
3855
      this.each(function() {
3856
        // First, attempt to store a copy or reference of any
3857
        // data that might've been store with a camelCased key.
3858
        var data = data_user.get( this, camelKey );
3859
3860
        // For HTML5 data-* attribute interop, we have to
3861
        // store property names with dashes in a camelCase form.
3862
        // This might not apply to all properties...*
3863
        data_user.set( this, camelKey, value );
3864
3865
        // *... In the case of properties that might _actually_
3866
        // have dashes, we need to also store a copy of that
3867
        // unchanged property.
3868
        if ( key.indexOf("-") !== -1 && data !== undefined ) {
3869
          data_user.set( this, key, value );
3870
        }
3871
      });
3872
    }, null, value, arguments.length > 1, null, true );
3873
  },
3874
3875
  removeData: function( key ) {
3876
    return this.each(function() {
3877
      data_user.remove( this, key );
3878
    });
3879
  }
3880
});
3881
3882
3883
jQuery.extend({
3884
  queue: function( elem, type, data ) {
3885
    var queue;
3886
3887
    if ( elem ) {
3888
      type = ( type || "fx" ) + "queue";
3889
      queue = data_priv.get( elem, type );
3890
3891
      // Speed up dequeue by getting out quickly if this is just a lookup
3892
      if ( data ) {
3893
        if ( !queue || jQuery.isArray( data ) ) {
3894
          queue = data_priv.access( elem, type, jQuery.makeArray(data) );
3895
        } else {
3896
          queue.push( data );
3897
        }
3898
      }
3899
      return queue || [];
3900
    }
3901
  },
3902
3903
  dequeue: function( elem, type ) {
3904
    type = type || "fx";
3905
3906
    var queue = jQuery.queue( elem, type ),
3907
      startLength = queue.length,
3908
      fn = queue.shift(),
3909
      hooks = jQuery._queueHooks( elem, type ),
3910
      next = function() {
3911
        jQuery.dequeue( elem, type );
3912
      };
3913
3914
    // If the fx queue is dequeued, always remove the progress sentinel
3915
    if ( fn === "inprogress" ) {
3916
      fn = queue.shift();
3917
      startLength--;
3918
    }
3919
3920
    if ( fn ) {
3921
3922
      // Add a progress sentinel to prevent the fx queue from being
3923
      // automatically dequeued
3924
      if ( type === "fx" ) {
3925
        queue.unshift( "inprogress" );
3926
      }
3927
3928
      // Clear up the last queue stop function
3929
      delete hooks.stop;
3930
      fn.call( elem, next, hooks );
3931
    }
3932
3933
    if ( !startLength && hooks ) {
3934
      hooks.empty.fire();
3935
    }
3936
  },
3937
3938
  // Not public - generate a queueHooks object, or return the current one
3939
  _queueHooks: function( elem, type ) {
3940
    var key = type + "queueHooks";
3941
    return data_priv.get( elem, key ) || data_priv.access( elem, key, {
3942
      empty: jQuery.Callbacks("once memory").add(function() {
3943
        data_priv.remove( elem, [ type + "queue", key ] );
3944
      })
3945
    });
3946
  }
3947
});
3948
3949
jQuery.fn.extend({
3950
  queue: function( type, data ) {
3951
    var setter = 2;
3952
3953
    if ( typeof type !== "string" ) {
3954
      data = type;
3955
      type = "fx";
3956
      setter--;
3957
    }
3958
3959
    if ( arguments.length < setter ) {
3960
      return jQuery.queue( this[0], type );
3961
    }
3962
3963
    return data === undefined ?
3964
      this :
3965
      this.each(function() {
3966
        var queue = jQuery.queue( this, type, data );
3967
3968
        // Ensure a hooks for this queue
3969
        jQuery._queueHooks( this, type );
3970
3971
        if ( type === "fx" && queue[0] !== "inprogress" ) {
3972
          jQuery.dequeue( this, type );
3973
        }
3974
      });
3975
  },
3976
  dequeue: function( type ) {
3977
    return this.each(function() {
3978
      jQuery.dequeue( this, type );
3979
    });
3980
  },
3981
  clearQueue: function( type ) {
3982
    return this.queue( type || "fx", [] );
3983
  },
3984
  // Get a promise resolved when queues of a certain type
3985
  // are emptied (fx is the type by default)
3986
  promise: function( type, obj ) {
3987
    var tmp,
3988
      count = 1,
3989
      defer = jQuery.Deferred(),
3990
      elements = this,
3991
      i = this.length,
3992
      resolve = function() {
3993
        if ( !( --count ) ) {
3994
          defer.resolveWith( elements, [ elements ] );
3995
        }
3996
      };
3997
3998
    if ( typeof type !== "string" ) {
3999
      obj = type;
4000
      type = undefined;
4001
    }
4002
    type = type || "fx";
4003
4004
    while ( i-- ) {
4005
      tmp = data_priv.get( elements[ i ], type + "queueHooks" );
4006
      if ( tmp && tmp.empty ) {
4007
        count++;
4008
        tmp.empty.add( resolve );
4009
      }
4010
    }
4011
    resolve();
4012
    return defer.promise( obj );
4013
  }
4014
});
4015
var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
4016
4017
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4018
4019
var isHidden = function( elem, el ) {
4020
    // isHidden might be called from jQuery#filter function;
4021
    // in that case, element will be second argument
4022
    elem = el || elem;
4023
    return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
4024
  };
4025
4026
var rcheckableType = (/^(?:checkbox|radio)$/i);
4027
4028
4029
4030
(function() {
4031
  var fragment = document.createDocumentFragment(),
4032
    div = fragment.appendChild( document.createElement( "div" ) ),
4033
    input = document.createElement( "input" );
4034
4035
  // Support: Safari<=5.1
4036
  // Check state lost if the name is set (#11217)
4037
  // Support: Windows Web Apps (WWA)
4038
  // `name` and `type` must use .setAttribute for WWA (#14901)
4039
  input.setAttribute( "type", "radio" );
4040
  input.setAttribute( "checked", "checked" );
4041
  input.setAttribute( "name", "t" );
4042
4043
  div.appendChild( input );
4044
4045
  // Support: Safari<=5.1, Android<4.2
4046
  // Older WebKit doesn't clone checked state correctly in fragments
4047
  support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4048
4049
  // Support: IE<=11+
4050
  // Make sure textarea (and checkbox) defaultValue is properly cloned
4051
  div.innerHTML = "<textarea>x</textarea>";
4052
  support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4053
})();
4054
var strundefined = typeof undefined;
4055
4056
4057
4058
support.focusinBubbles = "onfocusin" in window;
4059
4060
4061
var
4062
  rkeyEvent = /^key/,
4063
  rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
4064
  rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4065
  rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4066
4067
function returnTrue() {
4068
  return true;
4069
}
4070
4071
function returnFalse() {
4072
  return false;
4073
}
4074
4075
function safeActiveElement() {
4076
  try {
4077
    return document.activeElement;
4078
  } catch ( err ) { }
4079
}
4080
4081
/*
4082
 * Helper functions for managing events -- not part of the public interface.
4083
 * Props to Dean Edwards' addEvent library for many of the ideas.
4084
 */
4085
jQuery.event = {
4086
4087
  global: {},
4088
4089
  add: function( elem, types, handler, data, selector ) {
4090
4091
    var handleObjIn, eventHandle, tmp,
4092
      events, t, handleObj,
4093
      special, handlers, type, namespaces, origType,
4094
      elemData = data_priv.get( elem );
4095
4096
    // Don't attach events to noData or text/comment nodes (but allow plain objects)
4097
    if ( !elemData ) {
4098
      return;
4099
    }
4100
4101
    // Caller can pass in an object of custom data in lieu of the handler
4102
    if ( handler.handler ) {
4103
      handleObjIn = handler;
4104
      handler = handleObjIn.handler;
4105
      selector = handleObjIn.selector;
4106
    }
4107
4108
    // Make sure that the handler has a unique ID, used to find/remove it later
4109
    if ( !handler.guid ) {
4110
      handler.guid = jQuery.guid++;
4111
    }
4112
4113
    // Init the element's event structure and main handler, if this is the first
4114
    if ( !(events = elemData.events) ) {
4115
      events = elemData.events = {};
4116
    }
4117
    if ( !(eventHandle = elemData.handle) ) {
4118
      eventHandle = elemData.handle = function( e ) {
4119
        // Discard the second event of a jQuery.event.trigger() and
4120
        // when an event is called after a page has unloaded
4121
        return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
4122
          jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4123
      };
4124
    }
4125
4126
    // Handle multiple events separated by a space
4127
    types = ( types || "" ).match( rnotwhite ) || [ "" ];
4128
    t = types.length;
4129
    while ( t-- ) {
4130
      tmp = rtypenamespace.exec( types[t] ) || [];
4131
      type = origType = tmp[1];
4132
      namespaces = ( tmp[2] || "" ).split( "." ).sort();
4133
4134
      // There *must* be a type, no attaching namespace-only handlers
4135
      if ( !type ) {
4136
        continue;
4137
      }
4138
4139
      // If event changes its type, use the special event handlers for the changed type
4140
      special = jQuery.event.special[ type ] || {};
4141
4142
      // If selector defined, determine special event api type, otherwise given type
4143
      type = ( selector ? special.delegateType : special.bindType ) || type;
4144
4145
      // Update special based on newly reset type
4146
      special = jQuery.event.special[ type ] || {};
4147
4148
      // handleObj is passed to all event handlers
4149
      handleObj = jQuery.extend({
4150
        type: type,
4151
        origType: origType,
4152
        data: data,
4153
        handler: handler,
4154
        guid: handler.guid,
4155
        selector: selector,
4156
        needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4157
        namespace: namespaces.join(".")
4158
      }, handleObjIn );
4159
4160
      // Init the event handler queue if we're the first
4161
      if ( !(handlers = events[ type ]) ) {
4162
        handlers = events[ type ] = [];
4163
        handlers.delegateCount = 0;
4164
4165
        // Only use addEventListener if the special events handler returns false
4166
        if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4167
          if ( elem.addEventListener ) {
4168
            elem.addEventListener( type, eventHandle, false );
4169
          }
4170
        }
4171
      }
4172
4173
      if ( special.add ) {
4174
        special.add.call( elem, handleObj );
4175
4176
        if ( !handleObj.handler.guid ) {
4177
          handleObj.handler.guid = handler.guid;
4178
        }
4179
      }
4180
4181
      // Add to the element's handler list, delegates in front
4182
      if ( selector ) {
4183
        handlers.splice( handlers.delegateCount++, 0, handleObj );
4184
      } else {
4185
        handlers.push( handleObj );
4186
      }
4187
4188
      // Keep track of which events have ever been used, for event optimization
4189
      jQuery.event.global[ type ] = true;
4190
    }
4191
4192
  },
4193
4194
  // Detach an event or set of events from an element
4195
  remove: function( elem, types, handler, selector, mappedTypes ) {
4196
4197
    var j, origCount, tmp,
4198
      events, t, handleObj,
4199
      special, handlers, type, namespaces, origType,
4200
      elemData = data_priv.hasData( elem ) && data_priv.get( elem );
4201
4202
    if ( !elemData || !(events = elemData.events) ) {
4203
      return;
4204
    }
4205
4206
    // Once for each type.namespace in types; type may be omitted
4207
    types = ( types || "" ).match( rnotwhite ) || [ "" ];
4208
    t = types.length;
4209
    while ( t-- ) {
4210
      tmp = rtypenamespace.exec( types[t] ) || [];
4211
      type = origType = tmp[1];
4212
      namespaces = ( tmp[2] || "" ).split( "." ).sort();
4213
4214
      // Unbind all events (on this namespace, if provided) for the element
4215
      if ( !type ) {
4216
        for ( type in events ) {
4217
          jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4218
        }
4219
        continue;
4220
      }
4221
4222
      special = jQuery.event.special[ type ] || {};
4223
      type = ( selector ? special.delegateType : special.bindType ) || type;
4224
      handlers = events[ type ] || [];
4225
      tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4226
4227
      // Remove matching events
4228
      origCount = j = handlers.length;
4229
      while ( j-- ) {
4230
        handleObj = handlers[ j ];
4231
4232
        if ( ( mappedTypes || origType === handleObj.origType ) &&
4233
          ( !handler || handler.guid === handleObj.guid ) &&
4234
          ( !tmp || tmp.test( handleObj.namespace ) ) &&
4235
          ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4236
          handlers.splice( j, 1 );
4237
4238
          if ( handleObj.selector ) {
4239
            handlers.delegateCount--;
4240
          }
4241
          if ( special.remove ) {
4242
            special.remove.call( elem, handleObj );
4243
          }
4244
        }
4245
      }
4246
4247
      // Remove generic event handler if we removed something and no more handlers exist
4248
      // (avoids potential for endless recursion during removal of special event handlers)
4249
      if ( origCount && !handlers.length ) {
4250
        if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4251
          jQuery.removeEvent( elem, type, elemData.handle );
4252
        }
4253
4254
        delete events[ type ];
4255
      }
4256
    }
4257
4258
    // Remove the expando if it's no longer used
4259
    if ( jQuery.isEmptyObject( events ) ) {
4260
      delete elemData.handle;
4261
      data_priv.remove( elem, "events" );
4262
    }
4263
  },
4264
4265
  trigger: function( event, data, elem, onlyHandlers ) {
4266
4267
    var i, cur, tmp, bubbleType, ontype, handle, special,
4268
      eventPath = [ elem || document ],
4269
      type = hasOwn.call( event, "type" ) ? event.type : event,
4270
      namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4271
4272
    cur = tmp = elem = elem || document;
4273
4274
    // Don't do events on text and comment nodes
4275
    if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4276
      return;
4277
    }
4278
4279
    // focus/blur morphs to focusin/out; ensure we're not firing them right now
4280
    if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4281
      return;
4282
    }
4283
4284
    if ( type.indexOf(".") >= 0 ) {
4285
      // Namespaced trigger; create a regexp to match event type in handle()
4286
      namespaces = type.split(".");
4287
      type = namespaces.shift();
4288
      namespaces.sort();
4289
    }
4290
    ontype = type.indexOf(":") < 0 && "on" + type;
4291
4292
    // Caller can pass in a jQuery.Event object, Object, or just an event type string
4293
    event = event[ jQuery.expando ] ?
4294
      event :
4295
      new jQuery.Event( type, typeof event === "object" && event );
4296
4297
    // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4298
    event.isTrigger = onlyHandlers ? 2 : 3;
4299
    event.namespace = namespaces.join(".");
4300
    event.namespace_re = event.namespace ?
4301
      new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4302
      null;
4303
4304
    // Clean up the event in case it is being reused
4305
    event.result = undefined;
4306
    if ( !event.target ) {
4307
      event.target = elem;
4308
    }
4309
4310
    // Clone any incoming data and prepend the event, creating the handler arg list
4311
    data = data == null ?
4312
      [ event ] :
4313
      jQuery.makeArray( data, [ event ] );
4314
4315
    // Allow special events to draw outside the lines
4316
    special = jQuery.event.special[ type ] || {};
4317
    if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4318
      return;
4319
    }
4320
4321
    // Determine event propagation path in advance, per W3C events spec (#9951)
4322
    // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4323
    if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4324
4325
      bubbleType = special.delegateType || type;
4326
      if ( !rfocusMorph.test( bubbleType + type ) ) {
4327
        cur = cur.parentNode;
4328
      }
4329
      for ( ; cur; cur = cur.parentNode ) {
4330
        eventPath.push( cur );
4331
        tmp = cur;
4332
      }
4333
4334
      // Only add window if we got to document (e.g., not plain obj or detached DOM)
4335
      if ( tmp === (elem.ownerDocument || document) ) {
4336
        eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4337
      }
4338
    }
4339
4340
    // Fire handlers on the event path
4341
    i = 0;
4342
    while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4343
4344
      event.type = i > 1 ?
4345
        bubbleType :
4346
        special.bindType || type;
4347
4348
      // jQuery handler
4349
      handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
4350
      if ( handle ) {
4351
        handle.apply( cur, data );
4352
      }
4353
4354
      // Native handler
4355
      handle = ontype && cur[ ontype ];
4356
      if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
4357
        event.result = handle.apply( cur, data );
4358
        if ( event.result === false ) {
4359
          event.preventDefault();
4360
        }
4361
      }
4362
    }
4363
    event.type = type;
4364
4365
    // If nobody prevented the default action, do it now
4366
    if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4367
4368
      if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4369
        jQuery.acceptData( elem ) ) {
4370
4371
        // Call a native DOM method on the target with the same name name as the event.
4372
        // Don't do default actions on window, that's where global variables be (#6170)
4373
        if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
4374
4375
          // Don't re-trigger an onFOO event when we call its FOO() method
4376
          tmp = elem[ ontype ];
4377
4378
          if ( tmp ) {
4379
            elem[ ontype ] = null;
4380
          }
4381
4382
          // Prevent re-triggering of the same event, since we already bubbled it above
4383
          jQuery.event.triggered = type;
4384
          elem[ type ]();
4385
          jQuery.event.triggered = undefined;
4386
4387
          if ( tmp ) {
4388
            elem[ ontype ] = tmp;
4389
          }
4390
        }
4391
      }
4392
    }
4393
4394
    return event.result;
4395
  },
4396
4397
  dispatch: function( event ) {
4398
4399
    // Make a writable jQuery.Event from the native event object
4400
    event = jQuery.event.fix( event );
4401
4402
    var i, j, ret, matched, handleObj,
4403
      handlerQueue = [],
4404
      args = slice.call( arguments ),
4405
      handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
4406
      special = jQuery.event.special[ event.type ] || {};
4407
4408
    // Use the fix-ed jQuery.Event rather than the (read-only) native event
4409
    args[0] = event;
4410
    event.delegateTarget = this;
4411
4412
    // Call the preDispatch hook for the mapped type, and let it bail if desired
4413
    if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4414
      return;
4415
    }
4416
4417
    // Determine handlers
4418
    handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4419
4420
    // Run delegates first; they may want to stop propagation beneath us
4421
    i = 0;
4422
    while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4423
      event.currentTarget = matched.elem;
4424
4425
      j = 0;
4426
      while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4427
4428
        // Triggered event must either 1) have no namespace, or 2) have namespace(s)
4429
        // a subset or equal to those in the bound event (both can have no namespace).
4430
        if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4431
4432
          event.handleObj = handleObj;
4433
          event.data = handleObj.data;
4434
4435
          ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4436
              .apply( matched.elem, args );
4437
4438
          if ( ret !== undefined ) {
4439
            if ( (event.result = ret) === false ) {
4440
              event.preventDefault();
4441
              event.stopPropagation();
4442
            }
4443
          }
4444
        }
4445
      }
4446
    }
4447
4448
    // Call the postDispatch hook for the mapped type
4449
    if ( special.postDispatch ) {
4450
      special.postDispatch.call( this, event );
4451
    }
4452
4453
    return event.result;
4454
  },
4455
4456
  handlers: function( event, handlers ) {
4457
    var i, matches, sel, handleObj,
4458
      handlerQueue = [],
4459
      delegateCount = handlers.delegateCount,
4460
      cur = event.target;
4461
4462
    // Find delegate handlers
4463
    // Black-hole SVG <use> instance trees (#13180)
4464
    // Avoid non-left-click bubbling in Firefox (#3861)
4465
    if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4466
4467
      for ( ; cur !== this; cur = cur.parentNode || this ) {
4468
4469
        // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4470
        if ( cur.disabled !== true || event.type !== "click" ) {
4471
          matches = [];
4472
          for ( i = 0; i < delegateCount; i++ ) {
4473
            handleObj = handlers[ i ];
4474
4475
            // Don't conflict with Object.prototype properties (#13203)
4476
            sel = handleObj.selector + " ";
4477
4478
            if ( matches[ sel ] === undefined ) {
4479
              matches[ sel ] = handleObj.needsContext ?
4480
                jQuery( sel, this ).index( cur ) >= 0 :
4481
                jQuery.find( sel, this, null, [ cur ] ).length;
4482
            }
4483
            if ( matches[ sel ] ) {
4484
              matches.push( handleObj );
4485
            }
4486
          }
4487
          if ( matches.length ) {
4488
            handlerQueue.push({ elem: cur, handlers: matches });
4489
          }
4490
        }
4491
      }
4492
    }
4493
4494
    // Add the remaining (directly-bound) handlers
4495
    if ( delegateCount < handlers.length ) {
4496
      handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4497
    }
4498
4499
    return handlerQueue;
4500
  },
4501
4502
  // Includes some event props shared by KeyEvent and MouseEvent
4503
  props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4504
4505
  fixHooks: {},
4506
4507
  keyHooks: {
4508
    props: "char charCode key keyCode".split(" "),
4509
    filter: function( event, original ) {
4510
4511
      // Add which for key events
4512
      if ( event.which == null ) {
4513
        event.which = original.charCode != null ? original.charCode : original.keyCode;
4514
      }
4515
4516
      return event;
4517
    }
4518
  },
4519
4520
  mouseHooks: {
4521
    props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4522
    filter: function( event, original ) {
4523
      var eventDoc, doc, body,
4524
        button = original.button;
4525
4526
      // Calculate pageX/Y if missing and clientX/Y available
4527
      if ( event.pageX == null && original.clientX != null ) {
4528
        eventDoc = event.target.ownerDocument || document;
4529
        doc = eventDoc.documentElement;
4530
        body = eventDoc.body;
4531
4532
        event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4533
        event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
4534
      }
4535
4536
      // Add which for click: 1 === left; 2 === middle; 3 === right
4537
      // Note: button is not normalized, so don't use it
4538
      if ( !event.which && button !== undefined ) {
4539
        event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4540
      }
4541
4542
      return event;
4543
    }
4544
  },
4545
4546
  fix: function( event ) {
4547
    if ( event[ jQuery.expando ] ) {
4548
      return event;
4549
    }
4550
4551
    // Create a writable copy of the event object and normalize some properties
4552
    var i, prop, copy,
4553
      type = event.type,
4554
      originalEvent = event,
4555
      fixHook = this.fixHooks[ type ];
4556
4557
    if ( !fixHook ) {
4558
      this.fixHooks[ type ] = fixHook =
4559
        rmouseEvent.test( type ) ? this.mouseHooks :
4560
        rkeyEvent.test( type ) ? this.keyHooks :
4561
        {};
4562
    }
4563
    copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4564
4565
    event = new jQuery.Event( originalEvent );
4566
4567
    i = copy.length;
4568
    while ( i-- ) {
4569
      prop = copy[ i ];
4570
      event[ prop ] = originalEvent[ prop ];
4571
    }
4572
4573
    // Support: Cordova 2.5 (WebKit) (#13255)
4574
    // All events should have a target; Cordova deviceready doesn't
4575
    if ( !event.target ) {
4576
      event.target = document;
4577
    }
4578
4579
    // Support: Safari 6.0+, Chrome<28
4580
    // Target should not be a text node (#504, #13143)
4581
    if ( event.target.nodeType === 3 ) {
4582
      event.target = event.target.parentNode;
4583
    }
4584
4585
    return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4586
  },
4587
4588
  special: {
4589
    load: {
4590
      // Prevent triggered image.load events from bubbling to window.load
4591
      noBubble: true
4592
    },
4593
    focus: {
4594
      // Fire native event if possible so blur/focus sequence is correct
4595
      trigger: function() {
4596
        if ( this !== safeActiveElement() && this.focus ) {
4597
          this.focus();
4598
          return false;
4599
        }
4600
      },
4601
      delegateType: "focusin"
4602
    },
4603
    blur: {
4604
      trigger: function() {
4605
        if ( this === safeActiveElement() && this.blur ) {
4606
          this.blur();
4607
          return false;
4608
        }
4609
      },
4610
      delegateType: "focusout"
4611
    },
4612
    click: {
4613
      // For checkbox, fire native event so checked state will be right
4614
      trigger: function() {
4615
        if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4616
          this.click();
4617
          return false;
4618
        }
4619
      },
4620
4621
      // For cross-browser consistency, don't fire native .click() on links
4622
      _default: function( event ) {
4623
        return jQuery.nodeName( event.target, "a" );
4624
      }
4625
    },
4626
4627
    beforeunload: {
4628
      postDispatch: function( event ) {
4629
4630
        // Support: Firefox 20+
4631
        // Firefox doesn't alert if the returnValue field is not set.
4632
        if ( event.result !== undefined && event.originalEvent ) {
4633
          event.originalEvent.returnValue = event.result;
4634
        }
4635
      }
4636
    }
4637
  },
4638
4639
  simulate: function( type, elem, event, bubble ) {
4640
    // Piggyback on a donor event to simulate a different one.
4641
    // Fake originalEvent to avoid donor's stopPropagation, but if the
4642
    // simulated event prevents default then we do the same on the donor.
4643
    var e = jQuery.extend(
4644
      new jQuery.Event(),
4645
      event,
4646
      {
4647
        type: type,
4648
        isSimulated: true,
4649
        originalEvent: {}
4650
      }
4651
    );
4652
    if ( bubble ) {
4653
      jQuery.event.trigger( e, null, elem );
4654
    } else {
4655
      jQuery.event.dispatch.call( elem, e );
4656
    }
4657
    if ( e.isDefaultPrevented() ) {
4658
      event.preventDefault();
4659
    }
4660
  }
4661
};
4662
4663
jQuery.removeEvent = function( elem, type, handle ) {
4664
  if ( elem.removeEventListener ) {
4665
    elem.removeEventListener( type, handle, false );
4666
  }
4667
};
4668
4669
jQuery.Event = function( src, props ) {
4670
  // Allow instantiation without the 'new' keyword
4671
  if ( !(this instanceof jQuery.Event) ) {
4672
    return new jQuery.Event( src, props );
4673
  }
4674
4675
  // Event object
4676
  if ( src && src.type ) {
4677
    this.originalEvent = src;
4678
    this.type = src.type;
4679
4680
    // Events bubbling up the document may have been marked as prevented
4681
    // by a handler lower down the tree; reflect the correct value.
4682
    this.isDefaultPrevented = src.defaultPrevented ||
4683
        src.defaultPrevented === undefined &&
4684
        // Support: Android<4.0
4685
        src.returnValue === false ?
4686
      returnTrue :
4687
      returnFalse;
4688
4689
  // Event type
4690
  } else {
4691
    this.type = src;
4692
  }
4693
4694
  // Put explicitly provided properties onto the event object
4695
  if ( props ) {
4696
    jQuery.extend( this, props );
4697
  }
4698
4699
  // Create a timestamp if incoming event doesn't have one
4700
  this.timeStamp = src && src.timeStamp || jQuery.now();
4701
4702
  // Mark it as fixed
4703
  this[ jQuery.expando ] = true;
4704
};
4705
4706
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
4707
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
4708
jQuery.Event.prototype = {
4709
  isDefaultPrevented: returnFalse,
4710
  isPropagationStopped: returnFalse,
4711
  isImmediatePropagationStopped: returnFalse,
4712
4713
  preventDefault: function() {
4714
    var e = this.originalEvent;
4715
4716
    this.isDefaultPrevented = returnTrue;
4717
4718
    if ( e && e.preventDefault ) {
4719
      e.preventDefault();
4720
    }
4721
  },
4722
  stopPropagation: function() {
4723
    var e = this.originalEvent;
4724
4725
    this.isPropagationStopped = returnTrue;
4726
4727
    if ( e && e.stopPropagation ) {
4728
      e.stopPropagation();
4729
    }
4730
  },
4731
  stopImmediatePropagation: function() {
4732
    var e = this.originalEvent;
4733
4734
    this.isImmediatePropagationStopped = returnTrue;
4735
4736
    if ( e && e.stopImmediatePropagation ) {
4737
      e.stopImmediatePropagation();
4738
    }
4739
4740
    this.stopPropagation();
4741
  }
4742
};
4743
4744
// Create mouseenter/leave events using mouseover/out and event-time checks
4745
// Support: Chrome 15+
4746
jQuery.each({
4747
  mouseenter: "mouseover",
4748
  mouseleave: "mouseout",
4749
  pointerenter: "pointerover",
4750
  pointerleave: "pointerout"
4751
}, function( orig, fix ) {
4752
  jQuery.event.special[ orig ] = {
4753
    delegateType: fix,
4754
    bindType: fix,
4755
4756
    handle: function( event ) {
4757
      var ret,
4758
        target = this,
4759
        related = event.relatedTarget,
4760
        handleObj = event.handleObj;
4761
4762
      // For mousenter/leave call the handler if related is outside the target.
4763
      // NB: No relatedTarget if the mouse left/entered the browser window
4764
      if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
4765
        event.type = handleObj.origType;
4766
        ret = handleObj.handler.apply( this, arguments );
4767
        event.type = fix;
4768
      }
4769
      return ret;
4770
    }
4771
  };
4772
});
4773
4774
// Support: Firefox, Chrome, Safari
4775
// Create "bubbling" focus and blur events
4776
if ( !support.focusinBubbles ) {
4777
  jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
4778
4779
    // Attach a single capturing handler on the document while someone wants focusin/focusout
4780
    var handler = function( event ) {
4781
        jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
4782
      };
4783
4784
    jQuery.event.special[ fix ] = {
4785
      setup: function() {
4786
        var doc = this.ownerDocument || this,
4787
          attaches = data_priv.access( doc, fix );
4788
4789
        if ( !attaches ) {
4790
          doc.addEventListener( orig, handler, true );
4791
        }
4792
        data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
4793
      },
4794
      teardown: function() {
4795
        var doc = this.ownerDocument || this,
4796
          attaches = data_priv.access( doc, fix ) - 1;
4797
4798
        if ( !attaches ) {
4799
          doc.removeEventListener( orig, handler, true );
4800
          data_priv.remove( doc, fix );
4801
4802
        } else {
4803
          data_priv.access( doc, fix, attaches );
4804
        }
4805
      }
4806
    };
4807
  });
4808
}
4809
4810
jQuery.fn.extend({
4811
4812
  on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
4813
    var origFn, type;
4814
4815
    // Types can be a map of types/handlers
4816
    if ( typeof types === "object" ) {
4817
      // ( types-Object, selector, data )
4818
      if ( typeof selector !== "string" ) {
4819
        // ( types-Object, data )
4820
        data = data || selector;
4821
        selector = undefined;
4822
      }
4823
      for ( type in types ) {
4824
        this.on( type, selector, data, types[ type ], one );
4825
      }
4826
      return this;
4827
    }
4828
4829
    if ( data == null && fn == null ) {
4830
      // ( types, fn )
4831
      fn = selector;
4832
      data = selector = undefined;
4833
    } else if ( fn == null ) {
4834
      if ( typeof selector === "string" ) {
4835
        // ( types, selector, fn )
4836
        fn = data;
4837
        data = undefined;
4838
      } else {
4839
        // ( types, data, fn )
4840
        fn = data;
4841
        data = selector;
4842
        selector = undefined;
4843
      }
4844
    }
4845
    if ( fn === false ) {
4846
      fn = returnFalse;
4847
    } else if ( !fn ) {
4848
      return this;
4849
    }
4850
4851
    if ( one === 1 ) {
4852
      origFn = fn;
4853
      fn = function( event ) {
4854
        // Can use an empty set, since event contains the info
4855
        jQuery().off( event );
4856
        return origFn.apply( this, arguments );
4857
      };
4858
      // Use same guid so caller can remove using origFn
4859
      fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4860
    }
4861
    return this.each( function() {
4862
      jQuery.event.add( this, types, fn, data, selector );
4863
    });
4864
  },
4865
  one: function( types, selector, data, fn ) {
4866
    return this.on( types, selector, data, fn, 1 );
4867
  },
4868
  off: function( types, selector, fn ) {
4869
    var handleObj, type;
4870
    if ( types && types.preventDefault && types.handleObj ) {
4871
      // ( event )  dispatched jQuery.Event
4872
      handleObj = types.handleObj;
4873
      jQuery( types.delegateTarget ).off(
4874
        handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
4875
        handleObj.selector,
4876
        handleObj.handler
4877
      );
4878
      return this;
4879
    }
4880
    if ( typeof types === "object" ) {
4881
      // ( types-object [, selector] )
4882
      for ( type in types ) {
4883
        this.off( type, selector, types[ type ] );
4884
      }
4885
      return this;
4886
    }
4887
    if ( selector === false || typeof selector === "function" ) {
4888
      // ( types [, fn] )
4889
      fn = selector;
4890
      selector = undefined;
4891
    }
4892
    if ( fn === false ) {
4893
      fn = returnFalse;
4894
    }
4895
    return this.each(function() {
4896
      jQuery.event.remove( this, types, fn, selector );
4897
    });
4898
  },
4899
4900
  trigger: function( type, data ) {
4901
    return this.each(function() {
4902
      jQuery.event.trigger( type, data, this );
4903
    });
4904
  },
4905
  triggerHandler: function( type, data ) {
4906
    var elem = this[0];
4907
    if ( elem ) {
4908
      return jQuery.event.trigger( type, data, elem, true );
4909
    }
4910
  }
4911
});
4912
4913
4914
var
4915
  rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
4916
  rtagName = /<([\w:]+)/,
4917
  rhtml = /<|&#?\w+;/,
4918
  rnoInnerhtml = /<(?:script|style|link)/i,
4919
  // checked="checked" or checked
4920
  rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
4921
  rscriptType = /^$|\/(?:java|ecma)script/i,
4922
  rscriptTypeMasked = /^true\/(.*)/,
4923
  rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
4924
4925
  // We have to close these tags to support XHTML (#13200)
4926
  wrapMap = {
4927
4928
    // Support: IE9
4929
    option: [ 1, "<select multiple='multiple'>", "</select>" ],
4930
4931
    thead: [ 1, "<table>", "</table>" ],
4932
    col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4933
    tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4934
    td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4935
4936
    _default: [ 0, "", "" ]
4937
  };
4938
4939
// Support: IE9
4940
wrapMap.optgroup = wrapMap.option;
4941
4942
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4943
wrapMap.th = wrapMap.td;
4944
4945
// Support: 1.x compatibility
4946
// Manipulating tables requires a tbody
4947
function manipulationTarget( elem, content ) {
4948
  return jQuery.nodeName( elem, "table" ) &&
4949
    jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
4950
4951
    elem.getElementsByTagName("tbody")[0] ||
4952
      elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
4953
    elem;
4954
}
4955
4956
// Replace/restore the type attribute of script elements for safe DOM manipulation
4957
function disableScript( elem ) {
4958
  elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
4959
  return elem;
4960
}
4961
function restoreScript( elem ) {
4962
  var match = rscriptTypeMasked.exec( elem.type );
4963
4964
  if ( match ) {
4965
    elem.type = match[ 1 ];
4966
  } else {
4967
    elem.removeAttribute("type");
4968
  }
4969
4970
  return elem;
4971
}
4972
4973
// Mark scripts as having already been evaluated
4974
function setGlobalEval( elems, refElements ) {
4975
  var i = 0,
4976
    l = elems.length;
4977
4978
  for ( ; i < l; i++ ) {
4979
    data_priv.set(
4980
      elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
4981
    );
4982
  }
4983
}
4984
4985
function cloneCopyEvent( src, dest ) {
4986
  var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
4987
4988
  if ( dest.nodeType !== 1 ) {
4989
    return;
4990
  }
4991
4992
  // 1. Copy private data: events, handlers, etc.
4993
  if ( data_priv.hasData( src ) ) {
4994
    pdataOld = data_priv.access( src );
4995
    pdataCur = data_priv.set( dest, pdataOld );
4996
    events = pdataOld.events;
4997
4998
    if ( events ) {
4999
      delete pdataCur.handle;
5000
      pdataCur.events = {};
5001
5002
      for ( type in events ) {
5003
        for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5004
          jQuery.event.add( dest, type, events[ type ][ i ] );
5005
        }
5006
      }
5007
    }
5008
  }
5009
5010
  // 2. Copy user data
5011
  if ( data_user.hasData( src ) ) {
5012
    udataOld = data_user.access( src );
5013
    udataCur = jQuery.extend( {}, udataOld );
5014
5015
    data_user.set( dest, udataCur );
5016
  }
5017
}
5018
5019
function getAll( context, tag ) {
5020
  var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
5021
      context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
5022
      [];
5023
5024
  return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
5025
    jQuery.merge( [ context ], ret ) :
5026
    ret;
5027
}
5028
5029
// Fix IE bugs, see support tests
5030
function fixInput( src, dest ) {
5031
  var nodeName = dest.nodeName.toLowerCase();
5032
5033
  // Fails to persist the checked state of a cloned checkbox or radio button.
5034
  if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5035
    dest.checked = src.checked;
5036
5037
  // Fails to return the selected option to the default selected state when cloning options
5038
  } else if ( nodeName === "input" || nodeName === "textarea" ) {
5039
    dest.defaultValue = src.defaultValue;
5040
  }
5041
}
5042
5043
jQuery.extend({
5044
  clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5045
    var i, l, srcElements, destElements,
5046
      clone = elem.cloneNode( true ),
5047
      inPage = jQuery.contains( elem.ownerDocument, elem );
5048
5049
    // Fix IE cloning issues
5050
    if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5051
        !jQuery.isXMLDoc( elem ) ) {
5052
5053
      // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5054
      destElements = getAll( clone );
5055
      srcElements = getAll( elem );
5056
5057
      for ( i = 0, l = srcElements.length; i < l; i++ ) {
5058
        fixInput( srcElements[ i ], destElements[ i ] );
5059
      }
5060
    }
5061
5062
    // Copy the events from the original to the clone
5063
    if ( dataAndEvents ) {
5064
      if ( deepDataAndEvents ) {
5065
        srcElements = srcElements || getAll( elem );
5066
        destElements = destElements || getAll( clone );
5067
5068
        for ( i = 0, l = srcElements.length; i < l; i++ ) {
5069
          cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5070
        }
5071
      } else {
5072
        cloneCopyEvent( elem, clone );
5073
      }
5074
    }
5075
5076
    // Preserve script evaluation history
5077
    destElements = getAll( clone, "script" );
5078
    if ( destElements.length > 0 ) {
5079
      setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5080
    }
5081
5082
    // Return the cloned set
5083
    return clone;
5084
  },
5085
5086
  buildFragment: function( elems, context, scripts, selection ) {
5087
    var elem, tmp, tag, wrap, contains, j,
5088
      fragment = context.createDocumentFragment(),
5089
      nodes = [],
5090
      i = 0,
5091
      l = elems.length;
5092
5093
    for ( ; i < l; i++ ) {
5094
      elem = elems[ i ];
5095
5096
      if ( elem || elem === 0 ) {
5097
5098
        // Add nodes directly
5099
        if ( jQuery.type( elem ) === "object" ) {
5100
          // Support: QtWebKit, PhantomJS
5101
          // push.apply(_, arraylike) throws on ancient WebKit
5102
          jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5103
5104
        // Convert non-html into a text node
5105
        } else if ( !rhtml.test( elem ) ) {
5106
          nodes.push( context.createTextNode( elem ) );
5107
5108
        // Convert html into DOM nodes
5109
        } else {
5110
          tmp = tmp || fragment.appendChild( context.createElement("div") );
5111
5112
          // Deserialize a standard representation
5113
          tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5114
          wrap = wrapMap[ tag ] || wrapMap._default;
5115
          tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
5116
5117
          // Descend through wrappers to the right content
5118
          j = wrap[ 0 ];
5119
          while ( j-- ) {
5120
            tmp = tmp.lastChild;
5121
          }
5122
5123
          // Support: QtWebKit, PhantomJS
5124
          // push.apply(_, arraylike) throws on ancient WebKit
5125
          jQuery.merge( nodes, tmp.childNodes );
5126
5127
          // Remember the top-level container
5128
          tmp = fragment.firstChild;
5129
5130
          // Ensure the created nodes are orphaned (#12392)
5131
          tmp.textContent = "";
5132
        }
5133
      }
5134
    }
5135
5136
    // Remove wrapper from fragment
5137
    fragment.textContent = "";
5138
5139
    i = 0;
5140
    while ( (elem = nodes[ i++ ]) ) {
5141
5142
      // #4087 - If origin and destination elements are the same, and this is
5143
      // that element, do not do anything
5144
      if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5145
        continue;
5146
      }
5147
5148
      contains = jQuery.contains( elem.ownerDocument, elem );
5149
5150
      // Append to fragment
5151
      tmp = getAll( fragment.appendChild( elem ), "script" );
5152
5153
      // Preserve script evaluation history
5154
      if ( contains ) {
5155
        setGlobalEval( tmp );
5156
      }
5157
5158
      // Capture executables
5159
      if ( scripts ) {
5160
        j = 0;
5161
        while ( (elem = tmp[ j++ ]) ) {
5162
          if ( rscriptType.test( elem.type || "" ) ) {
5163
            scripts.push( elem );
5164
          }
5165
        }
5166
      }
5167
    }
5168
5169
    return fragment;
5170
  },
5171
5172
  cleanData: function( elems ) {
5173
    var data, elem, type, key,
5174
      special = jQuery.event.special,
5175
      i = 0;
5176
5177
    for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
5178
      if ( jQuery.acceptData( elem ) ) {
5179
        key = elem[ data_priv.expando ];
5180
5181
        if ( key && (data = data_priv.cache[ key ]) ) {
5182
          if ( data.events ) {
5183
            for ( type in data.events ) {
5184
              if ( special[ type ] ) {
5185
                jQuery.event.remove( elem, type );
5186
5187
              // This is a shortcut to avoid jQuery.event.remove's overhead
5188
              } else {
5189
                jQuery.removeEvent( elem, type, data.handle );
5190
              }
5191
            }
5192
          }
5193
          if ( data_priv.cache[ key ] ) {
5194
            // Discard any remaining `private` data
5195
            delete data_priv.cache[ key ];
5196
          }
5197
        }
5198
      }
5199
      // Discard any remaining `user` data
5200
      delete data_user.cache[ elem[ data_user.expando ] ];
5201
    }
5202
  }
5203
});
5204
5205
jQuery.fn.extend({
5206
  text: function( value ) {
5207
    return access( this, function( value ) {
5208
      return value === undefined ?
5209
        jQuery.text( this ) :
5210
        this.empty().each(function() {
5211
          if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5212
            this.textContent = value;
5213
          }
5214
        });
5215
    }, null, value, arguments.length );
5216
  },
5217
5218
  append: function() {
5219
    return this.domManip( arguments, function( elem ) {
5220
      if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5221
        var target = manipulationTarget( this, elem );
5222
        target.appendChild( elem );
5223
      }
5224
    });
5225
  },
5226
5227
  prepend: function() {
5228
    return this.domManip( arguments, function( elem ) {
5229
      if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5230
        var target = manipulationTarget( this, elem );
5231
        target.insertBefore( elem, target.firstChild );
5232
      }
5233
    });
5234
  },
5235
5236
  before: function() {
5237
    return this.domManip( arguments, function( elem ) {
5238
      if ( this.parentNode ) {
5239
        this.parentNode.insertBefore( elem, this );
5240
      }
5241
    });
5242
  },
5243
5244
  after: function() {
5245
    return this.domManip( arguments, function( elem ) {
5246
      if ( this.parentNode ) {
5247
        this.parentNode.insertBefore( elem, this.nextSibling );
5248
      }
5249
    });
5250
  },
5251
5252
  remove: function( selector, keepData /* Internal Use Only */ ) {
5253
    var elem,
5254
      elems = selector ? jQuery.filter( selector, this ) : this,
5255
      i = 0;
5256
5257
    for ( ; (elem = elems[i]) != null; i++ ) {
5258
      if ( !keepData && elem.nodeType === 1 ) {
5259
        jQuery.cleanData( getAll( elem ) );
5260
      }
5261
5262
      if ( elem.parentNode ) {
5263
        if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5264
          setGlobalEval( getAll( elem, "script" ) );
5265
        }
5266
        elem.parentNode.removeChild( elem );
5267
      }
5268
    }
5269
5270
    return this;
5271
  },
5272
5273
  empty: function() {
5274
    var elem,
5275
      i = 0;
5276
5277
    for ( ; (elem = this[i]) != null; i++ ) {
5278
      if ( elem.nodeType === 1 ) {
5279
5280
        // Prevent memory leaks
5281
        jQuery.cleanData( getAll( elem, false ) );
5282
5283
        // Remove any remaining nodes
5284
        elem.textContent = "";
5285
      }
5286
    }
5287
5288
    return this;
5289
  },
5290
5291
  clone: function( dataAndEvents, deepDataAndEvents ) {
5292
    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5293
    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5294
5295
    return this.map(function() {
5296
      return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5297
    });
5298
  },
5299
5300
  html: function( value ) {
5301
    return access( this, function( value ) {
5302
      var elem = this[ 0 ] || {},
5303
        i = 0,
5304
        l = this.length;
5305
5306
      if ( value === undefined && elem.nodeType === 1 ) {
5307
        return elem.innerHTML;
5308
      }
5309
5310
      // See if we can take a shortcut and just use innerHTML
5311
      if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5312
        !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5313
5314
        value = value.replace( rxhtmlTag, "<$1></$2>" );
5315
5316
        try {
5317
          for ( ; i < l; i++ ) {
5318
            elem = this[ i ] || {};
5319
5320
            // Remove element nodes and prevent memory leaks
5321
            if ( elem.nodeType === 1 ) {
5322
              jQuery.cleanData( getAll( elem, false ) );
5323
              elem.innerHTML = value;
5324
            }
5325
          }
5326
5327
          elem = 0;
5328
5329
        // If using innerHTML throws an exception, use the fallback method
5330
        } catch( e ) {}
5331
      }
5332
5333
      if ( elem ) {
5334
        this.empty().append( value );
5335
      }
5336
    }, null, value, arguments.length );
5337
  },
5338
5339
  replaceWith: function() {
5340
    var arg = arguments[ 0 ];
5341
5342
    // Make the changes, replacing each context element with the new content
5343
    this.domManip( arguments, function( elem ) {
5344
      arg = this.parentNode;
5345
5346
      jQuery.cleanData( getAll( this ) );
5347
5348
      if ( arg ) {
5349
        arg.replaceChild( elem, this );
5350
      }
5351
    });
5352
5353
    // Force removal if there was no new content (e.g., from empty arguments)
5354
    return arg && (arg.length || arg.nodeType) ? this : this.remove();
5355
  },
5356
5357
  detach: function( selector ) {
5358
    return this.remove( selector, true );
5359
  },
5360
5361
  domManip: function( args, callback ) {
5362
5363
    // Flatten any nested arrays
5364
    args = concat.apply( [], args );
5365
5366
    var fragment, first, scripts, hasScripts, node, doc,
5367
      i = 0,
5368
      l = this.length,
5369
      set = this,
5370
      iNoClone = l - 1,
5371
      value = args[ 0 ],
5372
      isFunction = jQuery.isFunction( value );
5373
5374
    // We can't cloneNode fragments that contain checked, in WebKit
5375
    if ( isFunction ||
5376
        ( l > 1 && typeof value === "string" &&
5377
          !support.checkClone && rchecked.test( value ) ) ) {
5378
      return this.each(function( index ) {
5379
        var self = set.eq( index );
5380
        if ( isFunction ) {
5381
          args[ 0 ] = value.call( this, index, self.html() );
5382
        }
5383
        self.domManip( args, callback );
5384
      });
5385
    }
5386
5387
    if ( l ) {
5388
      fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
5389
      first = fragment.firstChild;
5390
5391
      if ( fragment.childNodes.length === 1 ) {
5392
        fragment = first;
5393
      }
5394
5395
      if ( first ) {
5396
        scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5397
        hasScripts = scripts.length;
5398
5399
        // Use the original fragment for the last item instead of the first because it can end up
5400
        // being emptied incorrectly in certain situations (#8070).
5401
        for ( ; i < l; i++ ) {
5402
          node = fragment;
5403
5404
          if ( i !== iNoClone ) {
5405
            node = jQuery.clone( node, true, true );
5406
5407
            // Keep references to cloned scripts for later restoration
5408
            if ( hasScripts ) {
5409
              // Support: QtWebKit
5410
              // jQuery.merge because push.apply(_, arraylike) throws
5411
              jQuery.merge( scripts, getAll( node, "script" ) );
5412
            }
5413
          }
5414
5415
          callback.call( this[ i ], node, i );
5416
        }
5417
5418
        if ( hasScripts ) {
5419
          doc = scripts[ scripts.length - 1 ].ownerDocument;
5420
5421
          // Reenable scripts
5422
          jQuery.map( scripts, restoreScript );
5423
5424
          // Evaluate executable scripts on first document insertion
5425
          for ( i = 0; i < hasScripts; i++ ) {
5426
            node = scripts[ i ];
5427
            if ( rscriptType.test( node.type || "" ) &&
5428
              !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5429
5430
              if ( node.src ) {
5431
                // Optional AJAX dependency, but won't run scripts if not present
5432
                if ( jQuery._evalUrl ) {
5433
                  jQuery._evalUrl( node.src );
5434
                }
5435
              } else {
5436
                jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5437
              }
5438
            }
5439
          }
5440
        }
5441
      }
5442
    }
5443
5444
    return this;
5445
  }
5446
});
5447
5448
jQuery.each({
5449
  appendTo: "append",
5450
  prependTo: "prepend",
5451
  insertBefore: "before",
5452
  insertAfter: "after",
5453
  replaceAll: "replaceWith"
5454
}, function( name, original ) {
5455
  jQuery.fn[ name ] = function( selector ) {
5456
    var elems,
5457
      ret = [],
5458
      insert = jQuery( selector ),
5459
      last = insert.length - 1,
5460
      i = 0;
5461
5462
    for ( ; i <= last; i++ ) {
5463
      elems = i === last ? this : this.clone( true );
5464
      jQuery( insert[ i ] )[ original ]( elems );
5465
5466
      // Support: QtWebKit
5467
      // .get() because push.apply(_, arraylike) throws
5468
      push.apply( ret, elems.get() );
5469
    }
5470
5471
    return this.pushStack( ret );
5472
  };
5473
});
5474
5475
5476
var iframe,
5477
  elemdisplay = {};
5478
5479
/**
5480
 * Retrieve the actual display of a element
5481
 * @param {String} name nodeName of the element
5482
 * @param {Object} doc Document object
5483
 */
5484
// Called only from within defaultDisplay
5485
function actualDisplay( name, doc ) {
5486
  var style,
5487
    elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5488
5489
    // getDefaultComputedStyle might be reliably used only on attached element
5490
    display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
5491
5492
      // Use of this method is a temporary fix (more like optimization) until something better comes along,
5493
      // since it was removed from specification and supported only in FF
5494
      style.display : jQuery.css( elem[ 0 ], "display" );
5495
5496
  // We don't have any data stored on the element,
5497
  // so use "detach" method as fast way to get rid of the element
5498
  elem.detach();
5499
5500
  return display;
5501
}
5502
5503
/**
5504
 * Try to determine the default display value of an element
5505
 * @param {String} nodeName
5506
 */
5507
function defaultDisplay( nodeName ) {
5508
  var doc = document,
5509
    display = elemdisplay[ nodeName ];
5510
5511
  if ( !display ) {
5512
    display = actualDisplay( nodeName, doc );
5513
5514
    // If the simple way fails, read from inside an iframe
5515
    if ( display === "none" || !display ) {
5516
5517
      // Use the already-created iframe if possible
5518
      iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
5519
5520
      // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5521
      doc = iframe[ 0 ].contentDocument;
5522
5523
      // Support: IE
5524
      doc.write();
5525
      doc.close();
5526
5527
      display = actualDisplay( nodeName, doc );
5528
      iframe.detach();
5529
    }
5530
5531
    // Store the correct default display
5532
    elemdisplay[ nodeName ] = display;
5533
  }
5534
5535
  return display;
5536
}
5537
var rmargin = (/^margin/);
5538
5539
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5540
5541
var getStyles = function( elem ) {
5542
    // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5543
    // IE throws on elements created in popups
5544
    // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5545
    if ( elem.ownerDocument.defaultView.opener ) {
5546
      return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
5547
    }
5548
5549
    return window.getComputedStyle( elem, null );
5550
  };
5551
5552
5553
5554
function curCSS( elem, name, computed ) {
5555
  var width, minWidth, maxWidth, ret,
5556
    style = elem.style;
5557
5558
  computed = computed || getStyles( elem );
5559
5560
  // Support: IE9
5561
  // getPropertyValue is only needed for .css('filter') (#12537)
5562
  if ( computed ) {
5563
    ret = computed.getPropertyValue( name ) || computed[ name ];
5564
  }
5565
5566
  if ( computed ) {
5567
5568
    if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
5569
      ret = jQuery.style( elem, name );
5570
    }
5571
5572
    // Support: iOS < 6
5573
    // A tribute to the "awesome hack by Dean Edwards"
5574
    // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
5575
    // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
5576
    if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5577
5578
      // Remember the original values
5579
      width = style.width;
5580
      minWidth = style.minWidth;
5581
      maxWidth = style.maxWidth;
5582
5583
      // Put in the new values to get a computed value out
5584
      style.minWidth = style.maxWidth = style.width = ret;
5585
      ret = computed.width;
5586
5587
      // Revert the changed values
5588
      style.width = width;
5589
      style.minWidth = minWidth;
5590
      style.maxWidth = maxWidth;
5591
    }
5592
  }
5593
5594
  return ret !== undefined ?
5595
    // Support: IE
5596
    // IE returns zIndex value as an integer.
5597
    ret + "" :
5598
    ret;
5599
}
5600
5601
5602
function addGetHookIf( conditionFn, hookFn ) {
5603
  // Define the hook, we'll check on the first run if it's really needed.
5604
  return {
5605
    get: function() {
5606
      if ( conditionFn() ) {
5607
        // Hook not needed (or it's not possible to use it due
5608
        // to missing dependency), remove it.
5609
        delete this.get;
5610
        return;
5611
      }
5612
5613
      // Hook needed; redefine it so that the support test is not executed again.
5614
      return (this.get = hookFn).apply( this, arguments );
5615
    }
5616
  };
5617
}
5618
5619
5620
(function() {
5621
  var pixelPositionVal, boxSizingReliableVal,
5622
    docElem = document.documentElement,
5623
    container = document.createElement( "div" ),
5624
    div = document.createElement( "div" );
5625
5626
  if ( !div.style ) {
5627
    return;
5628
  }
5629
5630
  // Support: IE9-11+
5631
  // Style of cloned element affects source element cloned (#8908)
5632
  div.style.backgroundClip = "content-box";
5633
  div.cloneNode( true ).style.backgroundClip = "";
5634
  support.clearCloneStyle = div.style.backgroundClip === "content-box";
5635
5636
  container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
5637
    "position:absolute";
5638
  container.appendChild( div );
5639
5640
  // Executing both pixelPosition & boxSizingReliable tests require only one layout
5641
  // so they're executed at the same time to save the second computation.
5642
  function computePixelPositionAndBoxSizingReliable() {
5643
    div.style.cssText =
5644
      // Support: Firefox<29, Android 2.3
5645
      // Vendor-prefix box-sizing
5646
      "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
5647
      "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
5648
      "border:1px;padding:1px;width:4px;position:absolute";
5649
    div.innerHTML = "";
5650
    docElem.appendChild( container );
5651
5652
    var divStyle = window.getComputedStyle( div, null );
5653
    pixelPositionVal = divStyle.top !== "1%";
5654
    boxSizingReliableVal = divStyle.width === "4px";
5655
5656
    docElem.removeChild( container );
5657
  }
5658
5659
  // Support: node.js jsdom
5660
  // Don't assume that getComputedStyle is a property of the global object
5661
  if ( window.getComputedStyle ) {
5662
    jQuery.extend( support, {
5663
      pixelPosition: function() {
5664
5665
        // This test is executed only once but we still do memoizing
5666
        // since we can use the boxSizingReliable pre-computing.
5667
        // No need to check if the test was already performed, though.
5668
        computePixelPositionAndBoxSizingReliable();
5669
        return pixelPositionVal;
5670
      },
5671
      boxSizingReliable: function() {
5672
        if ( boxSizingReliableVal == null ) {
5673
          computePixelPositionAndBoxSizingReliable();
5674
        }
5675
        return boxSizingReliableVal;
5676
      },
5677
      reliableMarginRight: function() {
5678
5679
        // Support: Android 2.3
5680
        // Check if div with explicit width and no margin-right incorrectly
5681
        // gets computed margin-right based on width of container. (#3333)
5682
        // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5683
        // This support function is only executed once so no memoizing is needed.
5684
        var ret,
5685
          marginDiv = div.appendChild( document.createElement( "div" ) );
5686
5687
        // Reset CSS: box-sizing; display; margin; border; padding
5688
        marginDiv.style.cssText = div.style.cssText =
5689
          // Support: Firefox<29, Android 2.3
5690
          // Vendor-prefix box-sizing
5691
          "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
5692
          "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
5693
        marginDiv.style.marginRight = marginDiv.style.width = "0";
5694
        div.style.width = "1px";
5695
        docElem.appendChild( container );
5696
5697
        ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
5698
5699
        docElem.removeChild( container );
5700
        div.removeChild( marginDiv );
5701
5702
        return ret;
5703
      }
5704
    });
5705
  }
5706
})();
5707
5708
5709
// A method for quickly swapping in/out CSS properties to get correct calculations.
5710
jQuery.swap = function( elem, options, callback, args ) {
5711
  var ret, name,
5712
    old = {};
5713
5714
  // Remember the old values, and insert the new ones
5715
  for ( name in options ) {
5716
    old[ name ] = elem.style[ name ];
5717
    elem.style[ name ] = options[ name ];
5718
  }
5719
5720
  ret = callback.apply( elem, args || [] );
5721
5722
  // Revert the old values
5723
  for ( name in options ) {
5724
    elem.style[ name ] = old[ name ];
5725
  }
5726
5727
  return ret;
5728
};
5729
5730
5731
var
5732
  // Swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
5733
  // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5734
  rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5735
  rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
5736
  rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
5737
5738
  cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5739
  cssNormalTransform = {
5740
    letterSpacing: "0",
5741
    fontWeight: "400"
5742
  },
5743
5744
  cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
5745
5746
// Return a css property mapped to a potentially vendor prefixed property
5747
function vendorPropName( style, name ) {
5748
5749
  // Shortcut for names that are not vendor prefixed
5750
  if ( name in style ) {
5751
    return name;
5752
  }
5753
5754
  // Check for vendor prefixed names
5755
  var capName = name[0].toUpperCase() + name.slice(1),
5756
    origName = name,
5757
    i = cssPrefixes.length;
5758
5759
  while ( i-- ) {
5760
    name = cssPrefixes[ i ] + capName;
5761
    if ( name in style ) {
5762
      return name;
5763
    }
5764
  }
5765
5766
  return origName;
5767
}
5768
5769
function setPositiveNumber( elem, value, subtract ) {
5770
  var matches = rnumsplit.exec( value );
5771
  return matches ?
5772
    // Guard against undefined "subtract", e.g., when used as in cssHooks
5773
    Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
5774
    value;
5775
}
5776
5777
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5778
  var i = extra === ( isBorderBox ? "border" : "content" ) ?
5779
    // If we already have the right measurement, avoid augmentation
5780
    4 :
5781
    // Otherwise initialize for horizontal or vertical properties
5782
    name === "width" ? 1 : 0,
5783
5784
    val = 0;
5785
5786
  for ( ; i < 4; i += 2 ) {
5787
    // Both box models exclude margin, so add it if we want it
5788
    if ( extra === "margin" ) {
5789
      val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5790
    }
5791
5792
    if ( isBorderBox ) {
5793
      // border-box includes padding, so remove it if we want content
5794
      if ( extra === "content" ) {
5795
        val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5796
      }
5797
5798
      // At this point, extra isn't border nor margin, so remove border
5799
      if ( extra !== "margin" ) {
5800
        val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5801
      }
5802
    } else {
5803
      // At this point, extra isn't content, so add padding
5804
      val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5805
5806
      // At this point, extra isn't content nor padding, so add border
5807
      if ( extra !== "padding" ) {
5808
        val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5809
      }
5810
    }
5811
  }
5812
5813
  return val;
5814
}
5815
5816
function getWidthOrHeight( elem, name, extra ) {
5817
5818
  // Start with offset property, which is equivalent to the border-box value
5819
  var valueIsBorderBox = true,
5820
    val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5821
    styles = getStyles( elem ),
5822
    isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5823
5824
  // Some non-html elements return undefined for offsetWidth, so check for null/undefined
5825
  // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5826
  // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5827
  if ( val <= 0 || val == null ) {
5828
    // Fall back to computed then uncomputed css if necessary
5829
    val = curCSS( elem, name, styles );
5830
    if ( val < 0 || val == null ) {
5831
      val = elem.style[ name ];
5832
    }
5833
5834
    // Computed unit is not pixels. Stop here and return.
5835
    if ( rnumnonpx.test(val) ) {
5836
      return val;
5837
    }
5838
5839
    // Check for style in case a browser which returns unreliable values
5840
    // for getComputedStyle silently falls back to the reliable elem.style
5841
    valueIsBorderBox = isBorderBox &&
5842
      ( support.boxSizingReliable() || val === elem.style[ name ] );
5843
5844
    // Normalize "", auto, and prepare for extra
5845
    val = parseFloat( val ) || 0;
5846
  }
5847
5848
  // Use the active box-sizing model to add/subtract irrelevant styles
5849
  return ( val +
5850
    augmentWidthOrHeight(
5851
      elem,
5852
      name,
5853
      extra || ( isBorderBox ? "border" : "content" ),
5854
      valueIsBorderBox,
5855
      styles
5856
    )
5857
  ) + "px";
5858
}
5859
5860
function showHide( elements, show ) {
5861
  var display, elem, hidden,
5862
    values = [],
5863
    index = 0,
5864
    length = elements.length;
5865
5866
  for ( ; index < length; index++ ) {
5867
    elem = elements[ index ];
5868
    if ( !elem.style ) {
5869
      continue;
5870
    }
5871
5872
    values[ index ] = data_priv.get( elem, "olddisplay" );
5873
    display = elem.style.display;
5874
    if ( show ) {
5875
      // Reset the inline display of this element to learn if it is
5876
      // being hidden by cascaded rules or not
5877
      if ( !values[ index ] && display === "none" ) {
5878
        elem.style.display = "";
5879
      }
5880
5881
      // Set elements which have been overridden with display: none
5882
      // in a stylesheet to whatever the default browser style is
5883
      // for such an element
5884
      if ( elem.style.display === "" && isHidden( elem ) ) {
5885
        values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
5886
      }
5887
    } else {
5888
      hidden = isHidden( elem );
5889
5890
      if ( display !== "none" || !hidden ) {
5891
        data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
5892
      }
5893
    }
5894
  }
5895
5896
  // Set the display of most of the elements in a second loop
5897
  // to avoid the constant reflow
5898
  for ( index = 0; index < length; index++ ) {
5899
    elem = elements[ index ];
5900
    if ( !elem.style ) {
5901
      continue;
5902
    }
5903
    if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
5904
      elem.style.display = show ? values[ index ] || "" : "none";
5905
    }
5906
  }
5907
5908
  return elements;
5909
}
5910
5911
jQuery.extend({
5912
5913
  // Add in style property hooks for overriding the default
5914
  // behavior of getting and setting a style property
5915
  cssHooks: {
5916
    opacity: {
5917
      get: function( elem, computed ) {
5918
        if ( computed ) {
5919
5920
          // We should always get a number back from opacity
5921
          var ret = curCSS( elem, "opacity" );
5922
          return ret === "" ? "1" : ret;
5923
        }
5924
      }
5925
    }
5926
  },
5927
5928
  // Don't automatically add "px" to these possibly-unitless properties
5929
  cssNumber: {
5930
    "columnCount": true,
5931
    "fillOpacity": true,
5932
    "flexGrow": true,
5933
    "flexShrink": true,
5934
    "fontWeight": true,
5935
    "lineHeight": true,
5936
    "opacity": true,
5937
    "order": true,
5938
    "orphans": true,
5939
    "widows": true,
5940
    "zIndex": true,
5941
    "zoom": true
5942
  },
5943
5944
  // Add in properties whose names you wish to fix before
5945
  // setting or getting the value
5946
  cssProps: {
5947
    "float": "cssFloat"
5948
  },
5949
5950
  // Get and set the style property on a DOM Node
5951
  style: function( elem, name, value, extra ) {
5952
5953
    // Don't set styles on text and comment nodes
5954
    if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
5955
      return;
5956
    }
5957
5958
    // Make sure that we're working with the right name
5959
    var ret, type, hooks,
5960
      origName = jQuery.camelCase( name ),
5961
      style = elem.style;
5962
5963
    name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
5964
5965
    // Gets hook for the prefixed version, then unprefixed version
5966
    hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
5967
5968
    // Check if we're setting a value
5969
    if ( value !== undefined ) {
5970
      type = typeof value;
5971
5972
      // Convert "+=" or "-=" to relative numbers (#7345)
5973
      if ( type === "string" && (ret = rrelNum.exec( value )) ) {
5974
        value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
5975
        // Fixes bug #9237
5976
        type = "number";
5977
      }
5978
5979
      // Make sure that null and NaN values aren't set (#7116)
5980
      if ( value == null || value !== value ) {
5981
        return;
5982
      }
5983
5984
      // If a number, add 'px' to the (except for certain CSS properties)
5985
      if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
5986
        value += "px";
5987
      }
5988
5989
      // Support: IE9-11+
5990
      // background-* props affect original clone's values
5991
      if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
5992
        style[ name ] = "inherit";
5993
      }
5994
5995
      // If a hook was provided, use that value, otherwise just set the specified value
5996
      if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
5997
        style[ name ] = value;
5998
      }
5999
6000
    } else {
6001
      // If a hook was provided get the non-computed value from there
6002
      if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6003
        return ret;
6004
      }
6005
6006
      // Otherwise just get the value from the style object
6007
      return style[ name ];
6008
    }
6009
  },
6010
6011
  css: function( elem, name, extra, styles ) {
6012
    var val, num, hooks,
6013
      origName = jQuery.camelCase( name );
6014
6015
    // Make sure that we're working with the right name
6016
    name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6017
6018
    // Try prefixed name followed by the unprefixed name
6019
    hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6020
6021
    // If a hook was provided get the computed value from there
6022
    if ( hooks && "get" in hooks ) {
6023
      val = hooks.get( elem, true, extra );
6024
    }
6025
6026
    // Otherwise, if a way to get the computed value exists, use that
6027
    if ( val === undefined ) {
6028
      val = curCSS( elem, name, styles );
6029
    }
6030
6031
    // Convert "normal" to computed value
6032
    if ( val === "normal" && name in cssNormalTransform ) {
6033
      val = cssNormalTransform[ name ];
6034
    }
6035
6036
    // Make numeric if forced or a qualifier was provided and val looks numeric
6037
    if ( extra === "" || extra ) {
6038
      num = parseFloat( val );
6039
      return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6040
    }
6041
    return val;
6042
  }
6043
});
6044
6045
jQuery.each([ "height", "width" ], function( i, name ) {
6046
  jQuery.cssHooks[ name ] = {
6047
    get: function( elem, computed, extra ) {
6048
      if ( computed ) {
6049
6050
        // Certain elements can have dimension info if we invisibly show them
6051
        // but it must have a current display style that would benefit
6052
        return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
6053
          jQuery.swap( elem, cssShow, function() {
6054
            return getWidthOrHeight( elem, name, extra );
6055
          }) :
6056
          getWidthOrHeight( elem, name, extra );
6057
      }
6058
    },
6059
6060
    set: function( elem, value, extra ) {
6061
      var styles = extra && getStyles( elem );
6062
      return setPositiveNumber( elem, value, extra ?
6063
        augmentWidthOrHeight(
6064
          elem,
6065
          name,
6066
          extra,
6067
          jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6068
          styles
6069
        ) : 0
6070
      );
6071
    }
6072
  };
6073
});
6074
6075
// Support: Android 2.3
6076
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6077
  function( elem, computed ) {
6078
    if ( computed ) {
6079
      return jQuery.swap( elem, { "display": "inline-block" },
6080
        curCSS, [ elem, "marginRight" ] );
6081
    }
6082
  }
6083
);
6084
6085
// These hooks are used by animate to expand properties
6086
jQuery.each({
6087
  margin: "",
6088
  padding: "",
6089
  border: "Width"
6090
}, function( prefix, suffix ) {
6091
  jQuery.cssHooks[ prefix + suffix ] = {
6092
    expand: function( value ) {
6093
      var i = 0,
6094
        expanded = {},
6095
6096
        // Assumes a single number if not a string
6097
        parts = typeof value === "string" ? value.split(" ") : [ value ];
6098
6099
      for ( ; i < 4; i++ ) {
6100
        expanded[ prefix + cssExpand[ i ] + suffix ] =
6101
          parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6102
      }
6103
6104
      return expanded;
6105
    }
6106
  };
6107
6108
  if ( !rmargin.test( prefix ) ) {
6109
    jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6110
  }
6111
});
6112
6113
jQuery.fn.extend({
6114
  css: function( name, value ) {
6115
    return access( this, function( elem, name, value ) {
6116
      var styles, len,
6117
        map = {},
6118
        i = 0;
6119
6120
      if ( jQuery.isArray( name ) ) {
6121
        styles = getStyles( elem );
6122
        len = name.length;
6123
6124
        for ( ; i < len; i++ ) {
6125
          map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6126
        }
6127
6128
        return map;
6129
      }
6130
6131
      return value !== undefined ?
6132
        jQuery.style( elem, name, value ) :
6133
        jQuery.css( elem, name );
6134
    }, name, value, arguments.length > 1 );
6135
  },
6136
  show: function() {
6137
    return showHide( this, true );
6138
  },
6139
  hide: function() {
6140
    return showHide( this );
6141
  },
6142
  toggle: function( state ) {
6143
    if ( typeof state === "boolean" ) {
6144
      return state ? this.show() : this.hide();
6145
    }
6146
6147
    return this.each(function() {
6148
      if ( isHidden( this ) ) {
6149
        jQuery( this ).show();
6150
      } else {
6151
        jQuery( this ).hide();
6152
      }
6153
    });
6154
  }
6155
});
6156
6157
6158
function Tween( elem, options, prop, end, easing ) {
6159
  return new Tween.prototype.init( elem, options, prop, end, easing );
6160
}
6161
jQuery.Tween = Tween;
6162
6163
Tween.prototype = {
6164
  constructor: Tween,
6165
  init: function( elem, options, prop, end, easing, unit ) {
6166
    this.elem = elem;
6167
    this.prop = prop;
6168
    this.easing = easing || "swing";
6169
    this.options = options;
6170
    this.start = this.now = this.cur();
6171
    this.end = end;
6172
    this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6173
  },
6174
  cur: function() {
6175
    var hooks = Tween.propHooks[ this.prop ];
6176
6177
    return hooks && hooks.get ?
6178
      hooks.get( this ) :
6179
      Tween.propHooks._default.get( this );
6180
  },
6181
  run: function( percent ) {
6182
    var eased,
6183
      hooks = Tween.propHooks[ this.prop ];
6184
6185
    if ( this.options.duration ) {
6186
      this.pos = eased = jQuery.easing[ this.easing ](
6187
        percent, this.options.duration * percent, 0, 1, this.options.duration
6188
      );
6189
    } else {
6190
      this.pos = eased = percent;
6191
    }
6192
    this.now = ( this.end - this.start ) * eased + this.start;
6193
6194
    if ( this.options.step ) {
6195
      this.options.step.call( this.elem, this.now, this );
6196
    }
6197
6198
    if ( hooks && hooks.set ) {
6199
      hooks.set( this );
6200
    } else {
6201
      Tween.propHooks._default.set( this );
6202
    }
6203
    return this;
6204
  }
6205
};
6206
6207
Tween.prototype.init.prototype = Tween.prototype;
6208
6209
Tween.propHooks = {
6210
  _default: {
6211
    get: function( tween ) {
6212
      var result;
6213
6214
      if ( tween.elem[ tween.prop ] != null &&
6215
        (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
6216
        return tween.elem[ tween.prop ];
6217
      }
6218
6219
      // Passing an empty string as a 3rd parameter to .css will automatically
6220
      // attempt a parseFloat and fallback to a string if the parse fails.
6221
      // Simple values such as "10px" are parsed to Float;
6222
      // complex values such as "rotate(1rad)" are returned as-is.
6223
      result = jQuery.css( tween.elem, tween.prop, "" );
6224
      // Empty strings, null, undefined and "auto" are converted to 0.
6225
      return !result || result === "auto" ? 0 : result;
6226
    },
6227
    set: function( tween ) {
6228
      // Use step hook for back compat.
6229
      // Use cssHook if its there.
6230
      // Use .style if available and use plain properties where available.
6231
      if ( jQuery.fx.step[ tween.prop ] ) {
6232
        jQuery.fx.step[ tween.prop ]( tween );
6233
      } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
6234
        jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6235
      } else {
6236
        tween.elem[ tween.prop ] = tween.now;
6237
      }
6238
    }
6239
  }
6240
};
6241
6242
// Support: IE9
6243
// Panic based approach to setting things on disconnected nodes
6244
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6245
  set: function( tween ) {
6246
    if ( tween.elem.nodeType && tween.elem.parentNode ) {
6247
      tween.elem[ tween.prop ] = tween.now;
6248
    }
6249
  }
6250
};
6251
6252
jQuery.easing = {
6253
  linear: function( p ) {
6254
    return p;
6255
  },
6256
  swing: function( p ) {
6257
    return 0.5 - Math.cos( p * Math.PI ) / 2;
6258
  }
6259
};
6260
6261
jQuery.fx = Tween.prototype.init;
6262
6263
// Back Compat <1.8 extension point
6264
jQuery.fx.step = {};
6265
6266
6267
6268
6269
var
6270
  fxNow, timerId,
6271
  rfxtypes = /^(?:toggle|show|hide)$/,
6272
  rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
6273
  rrun = /queueHooks$/,
6274
  animationPrefilters = [ defaultPrefilter ],
6275
  tweeners = {
6276
    "*": [ function( prop, value ) {
6277
      var tween = this.createTween( prop, value ),
6278
        target = tween.cur(),
6279
        parts = rfxnum.exec( value ),
6280
        unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
6281
6282
        // Starting value computation is required for potential unit mismatches
6283
        start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
6284
          rfxnum.exec( jQuery.css( tween.elem, prop ) ),
6285
        scale = 1,
6286
        maxIterations = 20;
6287
6288
      if ( start && start[ 3 ] !== unit ) {
6289
        // Trust units reported by jQuery.css
6290
        unit = unit || start[ 3 ];
6291
6292
        // Make sure we update the tween properties later on
6293
        parts = parts || [];
6294
6295
        // Iteratively approximate from a nonzero starting point
6296
        start = +target || 1;
6297
6298
        do {
6299
          // If previous iteration zeroed out, double until we get *something*.
6300
          // Use string for doubling so we don't accidentally see scale as unchanged below
6301
          scale = scale || ".5";
6302
6303
          // Adjust and apply
6304
          start = start / scale;
6305
          jQuery.style( tween.elem, prop, start + unit );
6306
6307
        // Update scale, tolerating zero or NaN from tween.cur(),
6308
        // break the loop if scale is unchanged or perfect, or if we've just had enough
6309
        } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
6310
      }
6311
6312
      // Update tween properties
6313
      if ( parts ) {
6314
        start = tween.start = +start || +target || 0;
6315
        tween.unit = unit;
6316
        // If a +=/-= token was provided, we're doing a relative animation
6317
        tween.end = parts[ 1 ] ?
6318
          start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
6319
          +parts[ 2 ];
6320
      }
6321
6322
      return tween;
6323
    } ]
6324
  };
6325
6326
// Animations created synchronously will run synchronously
6327
function createFxNow() {
6328
  setTimeout(function() {
6329
    fxNow = undefined;
6330
  });
6331
  return ( fxNow = jQuery.now() );
6332
}
6333
6334
// Generate parameters to create a standard animation
6335
function genFx( type, includeWidth ) {
6336
  var which,
6337
    i = 0,
6338
    attrs = { height: type };
6339
6340
  // If we include width, step value is 1 to do all cssExpand values,
6341
  // otherwise step value is 2 to skip over Left and Right
6342
  includeWidth = includeWidth ? 1 : 0;
6343
  for ( ; i < 4 ; i += 2 - includeWidth ) {
6344
    which = cssExpand[ i ];
6345
    attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6346
  }
6347
6348
  if ( includeWidth ) {
6349
    attrs.opacity = attrs.width = type;
6350
  }
6351
6352
  return attrs;
6353
}
6354
6355
function createTween( value, prop, animation ) {
6356
  var tween,
6357
    collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
6358
    index = 0,
6359
    length = collection.length;
6360
  for ( ; index < length; index++ ) {
6361
    if ( (tween = collection[ index ].call( animation, prop, value )) ) {
6362
6363
      // We're done with this property
6364
      return tween;
6365
    }
6366
  }
6367
}
6368
6369
function defaultPrefilter( elem, props, opts ) {
6370
  /* jshint validthis: true */
6371
  var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6372
    anim = this,
6373
    orig = {},
6374
    style = elem.style,
6375
    hidden = elem.nodeType && isHidden( elem ),
6376
    dataShow = data_priv.get( elem, "fxshow" );
6377
6378
  // Handle queue: false promises
6379
  if ( !opts.queue ) {
6380
    hooks = jQuery._queueHooks( elem, "fx" );
6381
    if ( hooks.unqueued == null ) {
6382
      hooks.unqueued = 0;
6383
      oldfire = hooks.empty.fire;
6384
      hooks.empty.fire = function() {
6385
        if ( !hooks.unqueued ) {
6386
          oldfire();
6387
        }
6388
      };
6389
    }
6390
    hooks.unqueued++;
6391
6392
    anim.always(function() {
6393
      // Ensure the complete handler is called before this completes
6394
      anim.always(function() {
6395
        hooks.unqueued--;
6396
        if ( !jQuery.queue( elem, "fx" ).length ) {
6397
          hooks.empty.fire();
6398
        }
6399
      });
6400
    });
6401
  }
6402
6403
  // Height/width overflow pass
6404
  if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6405
    // Make sure that nothing sneaks out
6406
    // Record all 3 overflow attributes because IE9-10 do not
6407
    // change the overflow attribute when overflowX and
6408
    // overflowY are set to the same value
6409
    opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6410
6411
    // Set display property to inline-block for height/width
6412
    // animations on inline elements that are having width/height animated
6413
    display = jQuery.css( elem, "display" );
6414
6415
    // Test default display if display is currently "none"
6416
    checkDisplay = display === "none" ?
6417
      data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6418
6419
    if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6420
      style.display = "inline-block";
6421
    }
6422
  }
6423
6424
  if ( opts.overflow ) {
6425
    style.overflow = "hidden";
6426
    anim.always(function() {
6427
      style.overflow = opts.overflow[ 0 ];
6428
      style.overflowX = opts.overflow[ 1 ];
6429
      style.overflowY = opts.overflow[ 2 ];
6430
    });
6431
  }
6432
6433
  // show/hide pass
6434
  for ( prop in props ) {
6435
    value = props[ prop ];
6436
    if ( rfxtypes.exec( value ) ) {
6437
      delete props[ prop ];
6438
      toggle = toggle || value === "toggle";
6439
      if ( value === ( hidden ? "hide" : "show" ) ) {
6440
6441
        // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
6442
        if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6443
          hidden = true;
6444
        } else {
6445
          continue;
6446
        }
6447
      }
6448
      orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6449
6450
    // Any non-fx value stops us from restoring the original display value
6451
    } else {
6452
      display = undefined;
6453
    }
6454
  }
6455
6456
  if ( !jQuery.isEmptyObject( orig ) ) {
6457
    if ( dataShow ) {
6458
      if ( "hidden" in dataShow ) {
6459
        hidden = dataShow.hidden;
6460
      }
6461
    } else {
6462
      dataShow = data_priv.access( elem, "fxshow", {} );
6463
    }
6464
6465
    // Store state if its toggle - enables .stop().toggle() to "reverse"
6466
    if ( toggle ) {
6467
      dataShow.hidden = !hidden;
6468
    }
6469
    if ( hidden ) {
6470
      jQuery( elem ).show();
6471
    } else {
6472
      anim.done(function() {
6473
        jQuery( elem ).hide();
6474
      });
6475
    }
6476
    anim.done(function() {
6477
      var prop;
6478
6479
      data_priv.remove( elem, "fxshow" );
6480
      for ( prop in orig ) {
6481
        jQuery.style( elem, prop, orig[ prop ] );
6482
      }
6483
    });
6484
    for ( prop in orig ) {
6485
      tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6486
6487
      if ( !( prop in dataShow ) ) {
6488
        dataShow[ prop ] = tween.start;
6489
        if ( hidden ) {
6490
          tween.end = tween.start;
6491
          tween.start = prop === "width" || prop === "height" ? 1 : 0;
6492
        }
6493
      }
6494
    }
6495
6496
  // If this is a noop like .hide().hide(), restore an overwritten display value
6497
  } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
6498
    style.display = display;
6499
  }
6500
}
6501
6502
function propFilter( props, specialEasing ) {
6503
  var index, name, easing, value, hooks;
6504
6505
  // camelCase, specialEasing and expand cssHook pass
6506
  for ( index in props ) {
6507
    name = jQuery.camelCase( index );
6508
    easing = specialEasing[ name ];
6509
    value = props[ index ];
6510
    if ( jQuery.isArray( value ) ) {
6511
      easing = value[ 1 ];
6512
      value = props[ index ] = value[ 0 ];
6513
    }
6514
6515
    if ( index !== name ) {
6516
      props[ name ] = value;
6517
      delete props[ index ];
6518
    }
6519
6520
    hooks = jQuery.cssHooks[ name ];
6521
    if ( hooks && "expand" in hooks ) {
6522
      value = hooks.expand( value );
6523
      delete props[ name ];
6524
6525
      // Not quite $.extend, this won't overwrite existing keys.
6526
      // Reusing 'index' because we have the correct "name"
6527
      for ( index in value ) {
6528
        if ( !( index in props ) ) {
6529
          props[ index ] = value[ index ];
6530
          specialEasing[ index ] = easing;
6531
        }
6532
      }
6533
    } else {
6534
      specialEasing[ name ] = easing;
6535
    }
6536
  }
6537
}
6538
6539
function Animation( elem, properties, options ) {
6540
  var result,
6541
    stopped,
6542
    index = 0,
6543
    length = animationPrefilters.length,
6544
    deferred = jQuery.Deferred().always( function() {
6545
      // Don't match elem in the :animated selector
6546
      delete tick.elem;
6547
    }),
6548
    tick = function() {
6549
      if ( stopped ) {
6550
        return false;
6551
      }
6552
      var currentTime = fxNow || createFxNow(),
6553
        remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6554
        // Support: Android 2.3
6555
        // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6556
        temp = remaining / animation.duration || 0,
6557
        percent = 1 - temp,
6558
        index = 0,
6559
        length = animation.tweens.length;
6560
6561
      for ( ; index < length ; index++ ) {
6562
        animation.tweens[ index ].run( percent );
6563
      }
6564
6565
      deferred.notifyWith( elem, [ animation, percent, remaining ]);
6566
6567
      if ( percent < 1 && length ) {
6568
        return remaining;
6569
      } else {
6570
        deferred.resolveWith( elem, [ animation ] );
6571
        return false;
6572
      }
6573
    },
6574
    animation = deferred.promise({
6575
      elem: elem,
6576
      props: jQuery.extend( {}, properties ),
6577
      opts: jQuery.extend( true, { specialEasing: {} }, options ),
6578
      originalProperties: properties,
6579
      originalOptions: options,
6580
      startTime: fxNow || createFxNow(),
6581
      duration: options.duration,
6582
      tweens: [],
6583
      createTween: function( prop, end ) {
6584
        var tween = jQuery.Tween( elem, animation.opts, prop, end,
6585
            animation.opts.specialEasing[ prop ] || animation.opts.easing );
6586
        animation.tweens.push( tween );
6587
        return tween;
6588
      },
6589
      stop: function( gotoEnd ) {
6590
        var index = 0,
6591
          // If we are going to the end, we want to run all the tweens
6592
          // otherwise we skip this part
6593
          length = gotoEnd ? animation.tweens.length : 0;
6594
        if ( stopped ) {
6595
          return this;
6596
        }
6597
        stopped = true;
6598
        for ( ; index < length ; index++ ) {
6599
          animation.tweens[ index ].run( 1 );
6600
        }
6601
6602
        // Resolve when we played the last frame; otherwise, reject
6603
        if ( gotoEnd ) {
6604
          deferred.resolveWith( elem, [ animation, gotoEnd ] );
6605
        } else {
6606
          deferred.rejectWith( elem, [ animation, gotoEnd ] );
6607
        }
6608
        return this;
6609
      }
6610
    }),
6611
    props = animation.props;
6612
6613
  propFilter( props, animation.opts.specialEasing );
6614
6615
  for ( ; index < length ; index++ ) {
6616
    result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
6617
    if ( result ) {
6618
      return result;
6619
    }
6620
  }
6621
6622
  jQuery.map( props, createTween, animation );
6623
6624
  if ( jQuery.isFunction( animation.opts.start ) ) {
6625
    animation.opts.start.call( elem, animation );
6626
  }
6627
6628
  jQuery.fx.timer(
6629
    jQuery.extend( tick, {
6630
      elem: elem,
6631
      anim: animation,
6632
      queue: animation.opts.queue
6633
    })
6634
  );
6635
6636
  // attach callbacks from options
6637
  return animation.progress( animation.opts.progress )
6638
    .done( animation.opts.done, animation.opts.complete )
6639
    .fail( animation.opts.fail )
6640
    .always( animation.opts.always );
6641
}
6642
6643
jQuery.Animation = jQuery.extend( Animation, {
6644
6645
  tweener: function( props, callback ) {
6646
    if ( jQuery.isFunction( props ) ) {
6647
      callback = props;
6648
      props = [ "*" ];
6649
    } else {
6650
      props = props.split(" ");
6651
    }
6652
6653
    var prop,
6654
      index = 0,
6655
      length = props.length;
6656
6657
    for ( ; index < length ; index++ ) {
6658
      prop = props[ index ];
6659
      tweeners[ prop ] = tweeners[ prop ] || [];
6660
      tweeners[ prop ].unshift( callback );
6661
    }
6662
  },
6663
6664
  prefilter: function( callback, prepend ) {
6665
    if ( prepend ) {
6666
      animationPrefilters.unshift( callback );
6667
    } else {
6668
      animationPrefilters.push( callback );
6669
    }
6670
  }
6671
});
6672
6673
jQuery.speed = function( speed, easing, fn ) {
6674
  var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6675
    complete: fn || !fn && easing ||
6676
      jQuery.isFunction( speed ) && speed,
6677
    duration: speed,
6678
    easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6679
  };
6680
6681
  opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
6682
    opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6683
6684
  // Normalize opt.queue - true/undefined/null -> "fx"
6685
  if ( opt.queue == null || opt.queue === true ) {
6686
    opt.queue = "fx";
6687
  }
6688
6689
  // Queueing
6690
  opt.old = opt.complete;
6691
6692
  opt.complete = function() {
6693
    if ( jQuery.isFunction( opt.old ) ) {
6694
      opt.old.call( this );
6695
    }
6696
6697
    if ( opt.queue ) {
6698
      jQuery.dequeue( this, opt.queue );
6699
    }
6700
  };
6701
6702
  return opt;
6703
};
6704
6705
jQuery.fn.extend({
6706
  fadeTo: function( speed, to, easing, callback ) {
6707
6708
    // Show any hidden elements after setting opacity to 0
6709
    return this.filter( isHidden ).css( "opacity", 0 ).show()
6710
6711
      // Animate to the value specified
6712
      .end().animate({ opacity: to }, speed, easing, callback );
6713
  },
6714
  animate: function( prop, speed, easing, callback ) {
6715
    var empty = jQuery.isEmptyObject( prop ),
6716
      optall = jQuery.speed( speed, easing, callback ),
6717
      doAnimation = function() {
6718
        // Operate on a copy of prop so per-property easing won't be lost
6719
        var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6720
6721
        // Empty animations, or finishing resolves immediately
6722
        if ( empty || data_priv.get( this, "finish" ) ) {
6723
          anim.stop( true );
6724
        }
6725
      };
6726
      doAnimation.finish = doAnimation;
6727
6728
    return empty || optall.queue === false ?
6729
      this.each( doAnimation ) :
6730
      this.queue( optall.queue, doAnimation );
6731
  },
6732
  stop: function( type, clearQueue, gotoEnd ) {
6733
    var stopQueue = function( hooks ) {
6734
      var stop = hooks.stop;
6735
      delete hooks.stop;
6736
      stop( gotoEnd );
6737
    };
6738
6739
    if ( typeof type !== "string" ) {
6740
      gotoEnd = clearQueue;
6741
      clearQueue = type;
6742
      type = undefined;
6743
    }
6744
    if ( clearQueue && type !== false ) {
6745
      this.queue( type || "fx", [] );
6746
    }
6747
6748
    return this.each(function() {
6749
      var dequeue = true,
6750
        index = type != null && type + "queueHooks",
6751
        timers = jQuery.timers,
6752
        data = data_priv.get( this );
6753
6754
      if ( index ) {
6755
        if ( data[ index ] && data[ index ].stop ) {
6756
          stopQueue( data[ index ] );
6757
        }
6758
      } else {
6759
        for ( index in data ) {
6760
          if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6761
            stopQueue( data[ index ] );
6762
          }
6763
        }
6764
      }
6765
6766
      for ( index = timers.length; index--; ) {
6767
        if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
6768
          timers[ index ].anim.stop( gotoEnd );
6769
          dequeue = false;
6770
          timers.splice( index, 1 );
6771
        }
6772
      }
6773
6774
      // Start the next in the queue if the last step wasn't forced.
6775
      // Timers currently will call their complete callbacks, which
6776
      // will dequeue but only if they were gotoEnd.
6777
      if ( dequeue || !gotoEnd ) {
6778
        jQuery.dequeue( this, type );
6779
      }
6780
    });
6781
  },
6782
  finish: function( type ) {
6783
    if ( type !== false ) {
6784
      type = type || "fx";
6785
    }
6786
    return this.each(function() {
6787
      var index,
6788
        data = data_priv.get( this ),
6789
        queue = data[ type + "queue" ],
6790
        hooks = data[ type + "queueHooks" ],
6791
        timers = jQuery.timers,
6792
        length = queue ? queue.length : 0;
6793
6794
      // Enable finishing flag on private data
6795
      data.finish = true;
6796
6797
      // Empty the queue first
6798
      jQuery.queue( this, type, [] );
6799
6800
      if ( hooks && hooks.stop ) {
6801
        hooks.stop.call( this, true );
6802
      }
6803
6804
      // Look for any active animations, and finish them
6805
      for ( index = timers.length; index--; ) {
6806
        if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6807
          timers[ index ].anim.stop( true );
6808
          timers.splice( index, 1 );
6809
        }
6810
      }
6811
6812
      // Look for any animations in the old queue and finish them
6813
      for ( index = 0; index < length; index++ ) {
6814
        if ( queue[ index ] && queue[ index ].finish ) {
6815
          queue[ index ].finish.call( this );
6816
        }
6817
      }
6818
6819
      // Turn off finishing flag
6820
      delete data.finish;
6821
    });
6822
  }
6823
});
6824
6825
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
6826
  var cssFn = jQuery.fn[ name ];
6827
  jQuery.fn[ name ] = function( speed, easing, callback ) {
6828
    return speed == null || typeof speed === "boolean" ?
6829
      cssFn.apply( this, arguments ) :
6830
      this.animate( genFx( name, true ), speed, easing, callback );
6831
  };
6832
});
6833
6834
// Generate shortcuts for custom animations
6835
jQuery.each({
6836
  slideDown: genFx("show"),
6837
  slideUp: genFx("hide"),
6838
  slideToggle: genFx("toggle"),
6839
  fadeIn: { opacity: "show" },
6840
  fadeOut: { opacity: "hide" },
6841
  fadeToggle: { opacity: "toggle" }
6842
}, function( name, props ) {
6843
  jQuery.fn[ name ] = function( speed, easing, callback ) {
6844
    return this.animate( props, speed, easing, callback );
6845
  };
6846
});
6847
6848
jQuery.timers = [];
6849
jQuery.fx.tick = function() {
6850
  var timer,
6851
    i = 0,
6852
    timers = jQuery.timers;
6853
6854
  fxNow = jQuery.now();
6855
6856
  for ( ; i < timers.length; i++ ) {
6857
    timer = timers[ i ];
6858
    // Checks the timer has not already been removed
6859
    if ( !timer() && timers[ i ] === timer ) {
6860
      timers.splice( i--, 1 );
6861
    }
6862
  }
6863
6864
  if ( !timers.length ) {
6865
    jQuery.fx.stop();
6866
  }
6867
  fxNow = undefined;
6868
};
6869
6870
jQuery.fx.timer = function( timer ) {
6871
  jQuery.timers.push( timer );
6872
  if ( timer() ) {
6873
    jQuery.fx.start();
6874
  } else {
6875
    jQuery.timers.pop();
6876
  }
6877
};
6878
6879
jQuery.fx.interval = 13;
6880
6881
jQuery.fx.start = function() {
6882
  if ( !timerId ) {
6883
    timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
6884
  }
6885
};
6886
6887
jQuery.fx.stop = function() {
6888
  clearInterval( timerId );
6889
  timerId = null;
6890
};
6891
6892
jQuery.fx.speeds = {
6893
  slow: 600,
6894
  fast: 200,
6895
  // Default speed
6896
  _default: 400
6897
};
6898
6899
6900
// Based off of the plugin by Clint Helfers, with permission.
6901
// http://blindsignals.com/index.php/2009/07/jquery-delay/
6902
jQuery.fn.delay = function( time, type ) {
6903
  time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
6904
  type = type || "fx";
6905
6906
  return this.queue( type, function( next, hooks ) {
6907
    var timeout = setTimeout( next, time );
6908
    hooks.stop = function() {
6909
      clearTimeout( timeout );
6910
    };
6911
  });
6912
};
6913
6914
6915
(function() {
6916
  var input = document.createElement( "input" ),
6917
    select = document.createElement( "select" ),
6918
    opt = select.appendChild( document.createElement( "option" ) );
6919
6920
  input.type = "checkbox";
6921
6922
  // Support: iOS<=5.1, Android<=4.2+
6923
  // Default value for a checkbox should be "on"
6924
  support.checkOn = input.value !== "";
6925
6926
  // Support: IE<=11+
6927
  // Must access selectedIndex to make default options select
6928
  support.optSelected = opt.selected;
6929
6930
  // Support: Android<=2.3
6931
  // Options inside disabled selects are incorrectly marked as disabled
6932
  select.disabled = true;
6933
  support.optDisabled = !opt.disabled;
6934
6935
  // Support: IE<=11+
6936
  // An input loses its value after becoming a radio
6937
  input = document.createElement( "input" );
6938
  input.value = "t";
6939
  input.type = "radio";
6940
  support.radioValue = input.value === "t";
6941
})();
6942
6943
6944
var nodeHook, boolHook,
6945
  attrHandle = jQuery.expr.attrHandle;
6946
6947
jQuery.fn.extend({
6948
  attr: function( name, value ) {
6949
    return access( this, jQuery.attr, name, value, arguments.length > 1 );
6950
  },
6951
6952
  removeAttr: function( name ) {
6953
    return this.each(function() {
6954
      jQuery.removeAttr( this, name );
6955
    });
6956
  }
6957
});
6958
6959
jQuery.extend({
6960
  attr: function( elem, name, value ) {
6961
    var hooks, ret,
6962
      nType = elem.nodeType;
6963
6964
    // don't get/set attributes on text, comment and attribute nodes
6965
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
6966
      return;
6967
    }
6968
6969
    // Fallback to prop when attributes are not supported
6970
    if ( typeof elem.getAttribute === strundefined ) {
6971
      return jQuery.prop( elem, name, value );
6972
    }
6973
6974
    // All attributes are lowercase
6975
    // Grab necessary hook if one is defined
6976
    if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
6977
      name = name.toLowerCase();
6978
      hooks = jQuery.attrHooks[ name ] ||
6979
        ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
6980
    }
6981
6982
    if ( value !== undefined ) {
6983
6984
      if ( value === null ) {
6985
        jQuery.removeAttr( elem, name );
6986
6987
      } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
6988
        return ret;
6989
6990
      } else {
6991
        elem.setAttribute( name, value + "" );
6992
        return value;
6993
      }
6994
6995
    } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
6996
      return ret;
6997
6998
    } else {
6999
      ret = jQuery.find.attr( elem, name );
7000
7001
      // Non-existent attributes return null, we normalize to undefined
7002
      return ret == null ?
7003
        undefined :
7004
        ret;
7005
    }
7006
  },
7007
7008
  removeAttr: function( elem, value ) {
7009
    var name, propName,
7010
      i = 0,
7011
      attrNames = value && value.match( rnotwhite );
7012
7013
    if ( attrNames && elem.nodeType === 1 ) {
7014
      while ( (name = attrNames[i++]) ) {
7015
        propName = jQuery.propFix[ name ] || name;
7016
7017
        // Boolean attributes get special treatment (#10870)
7018
        if ( jQuery.expr.match.bool.test( name ) ) {
7019
          // Set corresponding property to false
7020
          elem[ propName ] = false;
7021
        }
7022
7023
        elem.removeAttribute( name );
7024
      }
7025
    }
7026
  },
7027
7028
  attrHooks: {
7029
    type: {
7030
      set: function( elem, value ) {
7031
        if ( !support.radioValue && value === "radio" &&
7032
          jQuery.nodeName( elem, "input" ) ) {
7033
          var val = elem.value;
7034
          elem.setAttribute( "type", value );
7035
          if ( val ) {
7036
            elem.value = val;
7037
          }
7038
          return value;
7039
        }
7040
      }
7041
    }
7042
  }
7043
});
7044
7045
// Hooks for boolean attributes
7046
boolHook = {
7047
  set: function( elem, value, name ) {
7048
    if ( value === false ) {
7049
      // Remove boolean attributes when set to false
7050
      jQuery.removeAttr( elem, name );
7051
    } else {
7052
      elem.setAttribute( name, name );
7053
    }
7054
    return name;
7055
  }
7056
};
7057
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7058
  var getter = attrHandle[ name ] || jQuery.find.attr;
7059
7060
  attrHandle[ name ] = function( elem, name, isXML ) {
7061
    var ret, handle;
7062
    if ( !isXML ) {
7063
      // Avoid an infinite loop by temporarily removing this function from the getter
7064
      handle = attrHandle[ name ];
7065
      attrHandle[ name ] = ret;
7066
      ret = getter( elem, name, isXML ) != null ?
7067
        name.toLowerCase() :
7068
        null;
7069
      attrHandle[ name ] = handle;
7070
    }
7071
    return ret;
7072
  };
7073
});
7074
7075
7076
7077
7078
var rfocusable = /^(?:input|select|textarea|button)$/i;
7079
7080
jQuery.fn.extend({
7081
  prop: function( name, value ) {
7082
    return access( this, jQuery.prop, name, value, arguments.length > 1 );
7083
  },
7084
7085
  removeProp: function( name ) {
7086
    return this.each(function() {
7087
      delete this[ jQuery.propFix[ name ] || name ];
7088
    });
7089
  }
7090
});
7091
7092
jQuery.extend({
7093
  propFix: {
7094
    "for": "htmlFor",
7095
    "class": "className"
7096
  },
7097
7098
  prop: function( elem, name, value ) {
7099
    var ret, hooks, notxml,
7100
      nType = elem.nodeType;
7101
7102
    // Don't get/set properties on text, comment and attribute nodes
7103
    if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
7104
      return;
7105
    }
7106
7107
    notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
7108
7109
    if ( notxml ) {
7110
      // Fix name and attach hooks
7111
      name = jQuery.propFix[ name ] || name;
7112
      hooks = jQuery.propHooks[ name ];
7113
    }
7114
7115
    if ( value !== undefined ) {
7116
      return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
7117
        ret :
7118
        ( elem[ name ] = value );
7119
7120
    } else {
7121
      return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
7122
        ret :
7123
        elem[ name ];
7124
    }
7125
  },
7126
7127
  propHooks: {
7128
    tabIndex: {
7129
      get: function( elem ) {
7130
        return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
7131
          elem.tabIndex :
7132
          -1;
7133
      }
7134
    }
7135
  }
7136
});
7137
7138
if ( !support.optSelected ) {
7139
  jQuery.propHooks.selected = {
7140
    get: function( elem ) {
7141
      var parent = elem.parentNode;
7142
      if ( parent && parent.parentNode ) {
7143
        parent.parentNode.selectedIndex;
7144
      }
7145
      return null;
7146
    }
7147
  };
7148
}
7149
7150
jQuery.each([
7151
  "tabIndex",
7152
  "readOnly",
7153
  "maxLength",
7154
  "cellSpacing",
7155
  "cellPadding",
7156
  "rowSpan",
7157
  "colSpan",
7158
  "useMap",
7159
  "frameBorder",
7160
  "contentEditable"
7161
], function() {
7162
  jQuery.propFix[ this.toLowerCase() ] = this;
7163
});
7164
7165
7166
7167
7168
var rclass = /[\t\r\n\f]/g;
7169
7170
jQuery.fn.extend({
7171
  addClass: function( value ) {
7172
    var classes, elem, cur, clazz, j, finalValue,
7173
      proceed = typeof value === "string" && value,
7174
      i = 0,
7175
      len = this.length;
7176
7177
    if ( jQuery.isFunction( value ) ) {
7178
      return this.each(function( j ) {
7179
        jQuery( this ).addClass( value.call( this, j, this.className ) );
7180
      });
7181
    }
7182
7183
    if ( proceed ) {
7184
      // The disjunction here is for better compressibility (see removeClass)
7185
      classes = ( value || "" ).match( rnotwhite ) || [];
7186
7187
      for ( ; i < len; i++ ) {
7188
        elem = this[ i ];
7189
        cur = elem.nodeType === 1 && ( elem.className ?
7190
          ( " " + elem.className + " " ).replace( rclass, " " ) :
7191
          " "
7192
        );
7193
7194
        if ( cur ) {
7195
          j = 0;
7196
          while ( (clazz = classes[j++]) ) {
7197
            if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7198
              cur += clazz + " ";
7199
            }
7200
          }
7201
7202
          // only assign if different to avoid unneeded rendering.
7203
          finalValue = jQuery.trim( cur );
7204
          if ( elem.className !== finalValue ) {
7205
            elem.className = finalValue;
7206
          }
7207
        }
7208
      }
7209
    }
7210
7211
    return this;
7212
  },
7213
7214
  removeClass: function( value ) {
7215
    var classes, elem, cur, clazz, j, finalValue,
7216
      proceed = arguments.length === 0 || typeof value === "string" && value,
7217
      i = 0,
7218
      len = this.length;
7219
7220
    if ( jQuery.isFunction( value ) ) {
7221
      return this.each(function( j ) {
7222
        jQuery( this ).removeClass( value.call( this, j, this.className ) );
7223
      });
7224
    }
7225
    if ( proceed ) {
7226
      classes = ( value || "" ).match( rnotwhite ) || [];
7227
7228
      for ( ; i < len; i++ ) {
7229
        elem = this[ i ];
7230
        // This expression is here for better compressibility (see addClass)
7231
        cur = elem.nodeType === 1 && ( elem.className ?
7232
          ( " " + elem.className + " " ).replace( rclass, " " ) :
7233
          ""
7234
        );
7235
7236
        if ( cur ) {
7237
          j = 0;
7238
          while ( (clazz = classes[j++]) ) {
7239
            // Remove *all* instances
7240
            while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
7241
              cur = cur.replace( " " + clazz + " ", " " );
7242
            }
7243
          }
7244
7245
          // Only assign if different to avoid unneeded rendering.
7246
          finalValue = value ? jQuery.trim( cur ) : "";
7247
          if ( elem.className !== finalValue ) {
7248
            elem.className = finalValue;
7249
          }
7250
        }
7251
      }
7252
    }
7253
7254
    return this;
7255
  },
7256
7257
  toggleClass: function( value, stateVal ) {
7258
    var type = typeof value;
7259
7260
    if ( typeof stateVal === "boolean" && type === "string" ) {
7261
      return stateVal ? this.addClass( value ) : this.removeClass( value );
7262
    }
7263
7264
    if ( jQuery.isFunction( value ) ) {
7265
      return this.each(function( i ) {
7266
        jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
7267
      });
7268
    }
7269
7270
    return this.each(function() {
7271
      if ( type === "string" ) {
7272
        // Toggle individual class names
7273
        var className,
7274
          i = 0,
7275
          self = jQuery( this ),
7276
          classNames = value.match( rnotwhite ) || [];
7277
7278
        while ( (className = classNames[ i++ ]) ) {
7279
          // Check each className given, space separated list
7280
          if ( self.hasClass( className ) ) {
7281
            self.removeClass( className );
7282
          } else {
7283
            self.addClass( className );
7284
          }
7285
        }
7286
7287
      // Toggle whole class name
7288
      } else if ( type === strundefined || type === "boolean" ) {
7289
        if ( this.className ) {
7290
          // store className if set
7291
          data_priv.set( this, "__className__", this.className );
7292
        }
7293
7294
        // If the element has a class name or if we're passed `false`,
7295
        // then remove the whole classname (if there was one, the above saved it).
7296
        // Otherwise bring back whatever was previously saved (if anything),
7297
        // falling back to the empty string if nothing was stored.
7298
        this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
7299
      }
7300
    });
7301
  },
7302
7303
  hasClass: function( selector ) {
7304
    var className = " " + selector + " ",
7305
      i = 0,
7306
      l = this.length;
7307
    for ( ; i < l; i++ ) {
7308
      if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
7309
        return true;
7310
      }
7311
    }
7312
7313
    return false;
7314
  }
7315
});
7316
7317
7318
7319
7320
var rreturn = /\r/g;
7321
7322
jQuery.fn.extend({
7323
  val: function( value ) {
7324
    var hooks, ret, isFunction,
7325
      elem = this[0];
7326
7327
    if ( !arguments.length ) {
7328
      if ( elem ) {
7329
        hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7330
7331
        if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
7332
          return ret;
7333
        }
7334
7335
        ret = elem.value;
7336
7337
        return typeof ret === "string" ?
7338
          // Handle most common string cases
7339
          ret.replace(rreturn, "") :
7340
          // Handle cases where value is null/undef or number
7341
          ret == null ? "" : ret;
7342
      }
7343
7344
      return;
7345
    }
7346
7347
    isFunction = jQuery.isFunction( value );
7348
7349
    return this.each(function( i ) {
7350
      var val;
7351
7352
      if ( this.nodeType !== 1 ) {
7353
        return;
7354
      }
7355
7356
      if ( isFunction ) {
7357
        val = value.call( this, i, jQuery( this ).val() );
7358
      } else {
7359
        val = value;
7360
      }
7361
7362
      // Treat null/undefined as ""; convert numbers to string
7363
      if ( val == null ) {
7364
        val = "";
7365
7366
      } else if ( typeof val === "number" ) {
7367
        val += "";
7368
7369
      } else if ( jQuery.isArray( val ) ) {
7370
        val = jQuery.map( val, function( value ) {
7371
          return value == null ? "" : value + "";
7372
        });
7373
      }
7374
7375
      hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7376
7377
      // If set returns undefined, fall back to normal setting
7378
      if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
7379
        this.value = val;
7380
      }
7381
    });
7382
  }
7383
});
7384
7385
jQuery.extend({
7386
  valHooks: {
7387
    option: {
7388
      get: function( elem ) {
7389
        var val = jQuery.find.attr( elem, "value" );
7390
        return val != null ?
7391
          val :
7392
          // Support: IE10-11+
7393
          // option.text throws exceptions (#14686, #14858)
7394
          jQuery.trim( jQuery.text( elem ) );
7395
      }
7396
    },
7397
    select: {
7398
      get: function( elem ) {
7399
        var value, option,
7400
          options = elem.options,
7401
          index = elem.selectedIndex,
7402
          one = elem.type === "select-one" || index < 0,
7403
          values = one ? null : [],
7404
          max = one ? index + 1 : options.length,
7405
          i = index < 0 ?
7406
            max :
7407
            one ? index : 0;
7408
7409
        // Loop through all the selected options
7410
        for ( ; i < max; i++ ) {
7411
          option = options[ i ];
7412
7413
          // IE6-9 doesn't update selected after form reset (#2551)
7414
          if ( ( option.selected || i === index ) &&
7415
              // Don't return options that are disabled or in a disabled optgroup
7416
              ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
7417
              ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7418
7419
            // Get the specific value for the option
7420
            value = jQuery( option ).val();
7421
7422
            // We don't need an array for one selects
7423
            if ( one ) {
7424
              return value;
7425
            }
7426
7427
            // Multi-Selects return an array
7428
            values.push( value );
7429
          }
7430
        }
7431
7432
        return values;
7433
      },
7434
7435
      set: function( elem, value ) {
7436
        var optionSet, option,
7437
          options = elem.options,
7438
          values = jQuery.makeArray( value ),
7439
          i = options.length;
7440
7441
        while ( i-- ) {
7442
          option = options[ i ];
7443
          if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
7444
            optionSet = true;
7445
          }
7446
        }
7447
7448
        // Force browsers to behave consistently when non-matching value is set
7449
        if ( !optionSet ) {
7450
          elem.selectedIndex = -1;
7451
        }
7452
        return values;
7453
      }
7454
    }
7455
  }
7456
});
7457
7458
// Radios and checkboxes getter/setter
7459
jQuery.each([ "radio", "checkbox" ], function() {
7460
  jQuery.valHooks[ this ] = {
7461
    set: function( elem, value ) {
7462
      if ( jQuery.isArray( value ) ) {
7463
        return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
7464
      }
7465
    }
7466
  };
7467
  if ( !support.checkOn ) {
7468
    jQuery.valHooks[ this ].get = function( elem ) {
7469
      return elem.getAttribute("value") === null ? "on" : elem.value;
7470
    };
7471
  }
7472
});
7473
7474
7475
7476
7477
// Return jQuery for attributes-only inclusion
7478
7479
7480
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
7481
  "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7482
  "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
7483
7484
  // Handle event binding
7485
  jQuery.fn[ name ] = function( data, fn ) {
7486
    return arguments.length > 0 ?
7487
      this.on( name, null, data, fn ) :
7488
      this.trigger( name );
7489
  };
7490
});
7491
7492
jQuery.fn.extend({
7493
  hover: function( fnOver, fnOut ) {
7494
    return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7495
  },
7496
7497
  bind: function( types, data, fn ) {
7498
    return this.on( types, null, data, fn );
7499
  },
7500
  unbind: function( types, fn ) {
7501
    return this.off( types, null, fn );
7502
  },
7503
7504
  delegate: function( selector, types, data, fn ) {
7505
    return this.on( types, selector, data, fn );
7506
  },
7507
  undelegate: function( selector, types, fn ) {
7508
    // ( namespace ) or ( selector, types [, fn] )
7509
    return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
7510
  }
7511
});
7512
7513
7514
var nonce = jQuery.now();
7515
7516
var rquery = (/\?/);
7517
7518
7519
7520
// Support: Android 2.3
7521
// Workaround failure to string-cast null input
7522
jQuery.parseJSON = function( data ) {
7523
  return JSON.parse( data + "" );
7524
};
7525
7526
7527
// Cross-browser xml parsing
7528
jQuery.parseXML = function( data ) {
7529
  var xml, tmp;
7530
  if ( !data || typeof data !== "string" ) {
7531
    return null;
7532
  }
7533
7534
  // Support: IE9
7535
  try {
7536
    tmp = new DOMParser();
7537
    xml = tmp.parseFromString( data, "text/xml" );
7538
  } catch ( e ) {
7539
    xml = undefined;
7540
  }
7541
7542
  if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7543
    jQuery.error( "Invalid XML: " + data );
7544
  }
7545
  return xml;
7546
};
7547
7548
7549
var
7550
  rhash = /#.*$/,
7551
  rts = /([?&])_=[^&]*/,
7552
  rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7553
  // #7653, #8125, #8152: local protocol detection
7554
  rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7555
  rnoContent = /^(?:GET|HEAD)$/,
7556
  rprotocol = /^\/\//,
7557
  rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
7558
7559
  /* Prefilters
7560
   * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
7561
   * 2) These are called:
7562
   *    - BEFORE asking for a transport
7563
   *    - AFTER param serialization (s.data is a string if s.processData is true)
7564
   * 3) key is the dataType
7565
   * 4) the catchall symbol "*" can be used
7566
   * 5) execution will start with transport dataType and THEN continue down to "*" if needed
7567
   */
7568
  prefilters = {},
7569
7570
  /* Transports bindings
7571
   * 1) key is the dataType
7572
   * 2) the catchall symbol "*" can be used
7573
   * 3) selection will start with transport dataType and THEN go to "*" if needed
7574
   */
7575
  transports = {},
7576
7577
  // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
7578
  allTypes = "*/".concat( "*" ),
7579
7580
  // Document location
7581
  ajaxLocation = window.location.href,
7582
7583
  // Segment location into parts
7584
  ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
7585
7586
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
7587
function addToPrefiltersOrTransports( structure ) {
7588
7589
  // dataTypeExpression is optional and defaults to "*"
7590
  return function( dataTypeExpression, func ) {
7591
7592
    if ( typeof dataTypeExpression !== "string" ) {
7593
      func = dataTypeExpression;
7594
      dataTypeExpression = "*";
7595
    }
7596
7597
    var dataType,
7598
      i = 0,
7599
      dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
7600
7601
    if ( jQuery.isFunction( func ) ) {
7602
      // For each dataType in the dataTypeExpression
7603
      while ( (dataType = dataTypes[i++]) ) {
7604
        // Prepend if requested
7605
        if ( dataType[0] === "+" ) {
7606
          dataType = dataType.slice( 1 ) || "*";
7607
          (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
7608
7609
        // Otherwise append
7610
        } else {
7611
          (structure[ dataType ] = structure[ dataType ] || []).push( func );
7612
        }
7613
      }
7614
    }
7615
  };
7616
}
7617
7618
// Base inspection function for prefilters and transports
7619
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
7620
7621
  var inspected = {},
7622
    seekingTransport = ( structure === transports );
7623
7624
  function inspect( dataType ) {
7625
    var selected;
7626
    inspected[ dataType ] = true;
7627
    jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
7628
      var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
7629
      if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
7630
        options.dataTypes.unshift( dataTypeOrTransport );
7631
        inspect( dataTypeOrTransport );
7632
        return false;
7633
      } else if ( seekingTransport ) {
7634
        return !( selected = dataTypeOrTransport );
7635
      }
7636
    });
7637
    return selected;
7638
  }
7639
7640
  return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
7641
}
7642
7643
// A special extend for ajax options
7644
// that takes "flat" options (not to be deep extended)
7645
// Fixes #9887
7646
function ajaxExtend( target, src ) {
7647
  var key, deep,
7648
    flatOptions = jQuery.ajaxSettings.flatOptions || {};
7649
7650
  for ( key in src ) {
7651
    if ( src[ key ] !== undefined ) {
7652
      ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
7653
    }
7654
  }
7655
  if ( deep ) {
7656
    jQuery.extend( true, target, deep );
7657
  }
7658
7659
  return target;
7660
}
7661
7662
/* Handles responses to an ajax request:
7663
 * - finds the right dataType (mediates between content-type and expected dataType)
7664
 * - returns the corresponding response
7665
 */
7666
function ajaxHandleResponses( s, jqXHR, responses ) {
7667
7668
  var ct, type, finalDataType, firstDataType,
7669
    contents = s.contents,
7670
    dataTypes = s.dataTypes;
7671
7672
  // Remove auto dataType and get content-type in the process
7673
  while ( dataTypes[ 0 ] === "*" ) {
7674
    dataTypes.shift();
7675
    if ( ct === undefined ) {
7676
      ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
7677
    }
7678
  }
7679
7680
  // Check if we're dealing with a known content-type
7681
  if ( ct ) {
7682
    for ( type in contents ) {
7683
      if ( contents[ type ] && contents[ type ].test( ct ) ) {
7684
        dataTypes.unshift( type );
7685
        break;
7686
      }
7687
    }
7688
  }
7689
7690
  // Check to see if we have a response for the expected dataType
7691
  if ( dataTypes[ 0 ] in responses ) {
7692
    finalDataType = dataTypes[ 0 ];
7693
  } else {
7694
    // Try convertible dataTypes
7695
    for ( type in responses ) {
7696
      if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7697
        finalDataType = type;
7698
        break;
7699
      }
7700
      if ( !firstDataType ) {
7701
        firstDataType = type;
7702
      }
7703
    }
7704
    // Or just use first one
7705
    finalDataType = finalDataType || firstDataType;
7706
  }
7707
7708
  // If we found a dataType
7709
  // We add the dataType to the list if needed
7710
  // and return the corresponding response
7711
  if ( finalDataType ) {
7712
    if ( finalDataType !== dataTypes[ 0 ] ) {
7713
      dataTypes.unshift( finalDataType );
7714
    }
7715
    return responses[ finalDataType ];
7716
  }
7717
}
7718
7719
/* Chain conversions given the request and the original response
7720
 * Also sets the responseXXX fields on the jqXHR instance
7721
 */
7722
function ajaxConvert( s, response, jqXHR, isSuccess ) {
7723
  var conv2, current, conv, tmp, prev,
7724
    converters = {},
7725
    // Work with a copy of dataTypes in case we need to modify it for conversion
7726
    dataTypes = s.dataTypes.slice();
7727
7728
  // Create converters map with lowercased keys
7729
  if ( dataTypes[ 1 ] ) {
7730
    for ( conv in s.converters ) {
7731
      converters[ conv.toLowerCase() ] = s.converters[ conv ];
7732
    }
7733
  }
7734
7735
  current = dataTypes.shift();
7736
7737
  // Convert to each sequential dataType
7738
  while ( current ) {
7739
7740
    if ( s.responseFields[ current ] ) {
7741
      jqXHR[ s.responseFields[ current ] ] = response;
7742
    }
7743
7744
    // Apply the dataFilter if provided
7745
    if ( !prev && isSuccess && s.dataFilter ) {
7746
      response = s.dataFilter( response, s.dataType );
7747
    }
7748
7749
    prev = current;
7750
    current = dataTypes.shift();
7751
7752
    if ( current ) {
7753
7754
    // There's only work to do if current dataType is non-auto
7755
      if ( current === "*" ) {
7756
7757
        current = prev;
7758
7759
      // Convert response if prev dataType is non-auto and differs from current
7760
      } else if ( prev !== "*" && prev !== current ) {
7761
7762
        // Seek a direct converter
7763
        conv = converters[ prev + " " + current ] || converters[ "* " + current ];
7764
7765
        // If none found, seek a pair
7766
        if ( !conv ) {
7767
          for ( conv2 in converters ) {
7768
7769
            // If conv2 outputs current
7770
            tmp = conv2.split( " " );
7771
            if ( tmp[ 1 ] === current ) {
7772
7773
              // If prev can be converted to accepted input
7774
              conv = converters[ prev + " " + tmp[ 0 ] ] ||
7775
                converters[ "* " + tmp[ 0 ] ];
7776
              if ( conv ) {
7777
                // Condense equivalence converters
7778
                if ( conv === true ) {
7779
                  conv = converters[ conv2 ];
7780
7781
                // Otherwise, insert the intermediate dataType
7782
                } else if ( converters[ conv2 ] !== true ) {
7783
                  current = tmp[ 0 ];
7784
                  dataTypes.unshift( tmp[ 1 ] );
7785
                }
7786
                break;
7787
              }
7788
            }
7789
          }
7790
        }
7791
7792
        // Apply converter (if not an equivalence)
7793
        if ( conv !== true ) {
7794
7795
          // Unless errors are allowed to bubble, catch and return them
7796
          if ( conv && s[ "throws" ] ) {
7797
            response = conv( response );
7798
          } else {
7799
            try {
7800
              response = conv( response );
7801
            } catch ( e ) {
7802
              return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
7803
            }
7804
          }
7805
        }
7806
      }
7807
    }
7808
  }
7809
7810
  return { state: "success", data: response };
7811
}
7812
7813
jQuery.extend({
7814
7815
  // Counter for holding the number of active queries
7816
  active: 0,
7817
7818
  // Last-Modified header cache for next request
7819
  lastModified: {},
7820
  etag: {},
7821
7822
  ajaxSettings: {
7823
    url: ajaxLocation,
7824
    type: "GET",
7825
    isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7826
    global: true,
7827
    processData: true,
7828
    async: true,
7829
    contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7830
    /*
7831
    timeout: 0,
7832
    data: null,
7833
    dataType: null,
7834
    username: null,
7835
    password: null,
7836
    cache: null,
7837
    throws: false,
7838
    traditional: false,
7839
    headers: {},
7840
    */
7841
7842
    accepts: {
7843
      "*": allTypes,
7844
      text: "text/plain",
7845
      html: "text/html",
7846
      xml: "application/xml, text/xml",
7847
      json: "application/json, text/javascript"
7848
    },
7849
7850
    contents: {
7851
      xml: /xml/,
7852
      html: /html/,
7853
      json: /json/
7854
    },
7855
7856
    responseFields: {
7857
      xml: "responseXML",
7858
      text: "responseText",
7859
      json: "responseJSON"
7860
    },
7861
7862
    // Data converters
7863
    // Keys separate source (or catchall "*") and destination types with a single space
7864
    converters: {
7865
7866
      // Convert anything to text
7867
      "* text": String,
7868
7869
      // Text to html (true = no transformation)
7870
      "text html": true,
7871
7872
      // Evaluate text as a json expression
7873
      "text json": jQuery.parseJSON,
7874
7875
      // Parse text as xml
7876
      "text xml": jQuery.parseXML
7877
    },
7878
7879
    // For options that shouldn't be deep extended:
7880
    // you can add your own custom options here if
7881
    // and when you create one that shouldn't be
7882
    // deep extended (see ajaxExtend)
7883
    flatOptions: {
7884
      url: true,
7885
      context: true
7886
    }
7887
  },
7888
7889
  // Creates a full fledged settings object into target
7890
  // with both ajaxSettings and settings fields.
7891
  // If target is omitted, writes into ajaxSettings.
7892
  ajaxSetup: function( target, settings ) {
7893
    return settings ?
7894
7895
      // Building a settings object
7896
      ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
7897
7898
      // Extending ajaxSettings
7899
      ajaxExtend( jQuery.ajaxSettings, target );
7900
  },
7901
7902
  ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7903
  ajaxTransport: addToPrefiltersOrTransports( transports ),
7904
7905
  // Main method
7906
  ajax: function( url, options ) {
7907
7908
    // If url is an object, simulate pre-1.5 signature
7909
    if ( typeof url === "object" ) {
7910
      options = url;
7911
      url = undefined;
7912
    }
7913
7914
    // Force options to be an object
7915
    options = options || {};
7916
7917
    var transport,
7918
      // URL without anti-cache param
7919
      cacheURL,
7920
      // Response headers
7921
      responseHeadersString,
7922
      responseHeaders,
7923
      // timeout handle
7924
      timeoutTimer,
7925
      // Cross-domain detection vars
7926
      parts,
7927
      // To know if global events are to be dispatched
7928
      fireGlobals,
7929
      // Loop variable
7930
      i,
7931
      // Create the final options object
7932
      s = jQuery.ajaxSetup( {}, options ),
7933
      // Callbacks context
7934
      callbackContext = s.context || s,
7935
      // Context for global events is callbackContext if it is a DOM node or jQuery collection
7936
      globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
7937
        jQuery( callbackContext ) :
7938
        jQuery.event,
7939
      // Deferreds
7940
      deferred = jQuery.Deferred(),
7941
      completeDeferred = jQuery.Callbacks("once memory"),
7942
      // Status-dependent callbacks
7943
      statusCode = s.statusCode || {},
7944
      // Headers (they are sent all at once)
7945
      requestHeaders = {},
7946
      requestHeadersNames = {},
7947
      // The jqXHR state
7948
      state = 0,
7949
      // Default abort message
7950
      strAbort = "canceled",
7951
      // Fake xhr
7952
      jqXHR = {
7953
        readyState: 0,
7954
7955
        // Builds headers hashtable if needed
7956
        getResponseHeader: function( key ) {
7957
          var match;
7958
          if ( state === 2 ) {
7959
            if ( !responseHeaders ) {
7960
              responseHeaders = {};
7961
              while ( (match = rheaders.exec( responseHeadersString )) ) {
7962
                responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7963
              }
7964
            }
7965
            match = responseHeaders[ key.toLowerCase() ];
7966
          }
7967
          return match == null ? null : match;
7968
        },
7969
7970
        // Raw string
7971
        getAllResponseHeaders: function() {
7972
          return state === 2 ? responseHeadersString : null;
7973
        },
7974
7975
        // Caches the header
7976
        setRequestHeader: function( name, value ) {
7977
          var lname = name.toLowerCase();
7978
          if ( !state ) {
7979
            name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7980
            requestHeaders[ name ] = value;
7981
          }
7982
          return this;
7983
        },
7984
7985
        // Overrides response content-type header
7986
        overrideMimeType: function( type ) {
7987
          if ( !state ) {
7988
            s.mimeType = type;
7989
          }
7990
          return this;
7991
        },
7992
7993
        // Status-dependent callbacks
7994
        statusCode: function( map ) {
7995
          var code;
7996
          if ( map ) {
7997
            if ( state < 2 ) {
7998
              for ( code in map ) {
7999
                // Lazy-add the new callback in a way that preserves old ones
8000
                statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8001
              }
8002
            } else {
8003
              // Execute the appropriate callbacks
8004
              jqXHR.always( map[ jqXHR.status ] );
8005
            }
8006
          }
8007
          return this;
8008
        },
8009
8010
        // Cancel the request
8011
        abort: function( statusText ) {
8012
          var finalText = statusText || strAbort;
8013
          if ( transport ) {
8014
            transport.abort( finalText );
8015
          }
8016
          done( 0, finalText );
8017
          return this;
8018
        }
8019
      };
8020
8021
    // Attach deferreds
8022
    deferred.promise( jqXHR ).complete = completeDeferred.add;
8023
    jqXHR.success = jqXHR.done;
8024
    jqXHR.error = jqXHR.fail;
8025
8026
    // Remove hash character (#7531: and string promotion)
8027
    // Add protocol if not provided (prefilters might expect it)
8028
    // Handle falsy url in the settings object (#10093: consistency with old signature)
8029
    // We also use the url parameter if available
8030
    s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
8031
      .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
8032
8033
    // Alias method option to type as per ticket #12004
8034
    s.type = options.method || options.type || s.method || s.type;
8035
8036
    // Extract dataTypes list
8037
    s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8038
8039
    // A cross-domain request is in order when we have a protocol:host:port mismatch
8040
    if ( s.crossDomain == null ) {
8041
      parts = rurl.exec( s.url.toLowerCase() );
8042
      s.crossDomain = !!( parts &&
8043
        ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
8044
          ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
8045
            ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
8046
      );
8047
    }
8048
8049
    // Convert data if not already a string
8050
    if ( s.data && s.processData && typeof s.data !== "string" ) {
8051
      s.data = jQuery.param( s.data, s.traditional );
8052
    }
8053
8054
    // Apply prefilters
8055
    inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8056
8057
    // If request was aborted inside a prefilter, stop there
8058
    if ( state === 2 ) {
8059
      return jqXHR;
8060
    }
8061
8062
    // We can fire global events as of now if asked to
8063
    // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8064
    fireGlobals = jQuery.event && s.global;
8065
8066
    // Watch for a new set of requests
8067
    if ( fireGlobals && jQuery.active++ === 0 ) {
8068
      jQuery.event.trigger("ajaxStart");
8069
    }
8070
8071
    // Uppercase the type
8072
    s.type = s.type.toUpperCase();
8073
8074
    // Determine if request has content
8075
    s.hasContent = !rnoContent.test( s.type );
8076
8077
    // Save the URL in case we're toying with the If-Modified-Since
8078
    // and/or If-None-Match header later on
8079
    cacheURL = s.url;
8080
8081
    // More options handling for requests with no content
8082
    if ( !s.hasContent ) {
8083
8084
      // If data is available, append data to url
8085
      if ( s.data ) {
8086
        cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8087
        // #9682: remove data so that it's not used in an eventual retry
8088
        delete s.data;
8089
      }
8090
8091
      // Add anti-cache in url if needed
8092
      if ( s.cache === false ) {
8093
        s.url = rts.test( cacheURL ) ?
8094
8095
          // If there is already a '_' parameter, set its value
8096
          cacheURL.replace( rts, "$1_=" + nonce++ ) :
8097
8098
          // Otherwise add one to the end
8099
          cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8100
      }
8101
    }
8102
8103
    // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8104
    if ( s.ifModified ) {
8105
      if ( jQuery.lastModified[ cacheURL ] ) {
8106
        jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8107
      }
8108
      if ( jQuery.etag[ cacheURL ] ) {
8109
        jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8110
      }
8111
    }
8112
8113
    // Set the correct header, if data is being sent
8114
    if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8115
      jqXHR.setRequestHeader( "Content-Type", s.contentType );
8116
    }
8117
8118
    // Set the Accepts header for the server, depending on the dataType
8119
    jqXHR.setRequestHeader(
8120
      "Accept",
8121
      s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
8122
        s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8123
        s.accepts[ "*" ]
8124
    );
8125
8126
    // Check for headers option
8127
    for ( i in s.headers ) {
8128
      jqXHR.setRequestHeader( i, s.headers[ i ] );
8129
    }
8130
8131
    // Allow custom headers/mimetypes and early abort
8132
    if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8133
      // Abort if not done already and return
8134
      return jqXHR.abort();
8135
    }
8136
8137
    // Aborting is no longer a cancellation
8138
    strAbort = "abort";
8139
8140
    // Install callbacks on deferreds
8141
    for ( i in { success: 1, error: 1, complete: 1 } ) {
8142
      jqXHR[ i ]( s[ i ] );
8143
    }
8144
8145
    // Get transport
8146
    transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8147
8148
    // If no transport, we auto-abort
8149
    if ( !transport ) {
8150
      done( -1, "No Transport" );
8151
    } else {
8152
      jqXHR.readyState = 1;
8153
8154
      // Send global event
8155
      if ( fireGlobals ) {
8156
        globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8157
      }
8158
      // Timeout
8159
      if ( s.async && s.timeout > 0 ) {
8160
        timeoutTimer = setTimeout(function() {
8161
          jqXHR.abort("timeout");
8162
        }, s.timeout );
8163
      }
8164
8165
      try {
8166
        state = 1;
8167
        transport.send( requestHeaders, done );
8168
      } catch ( e ) {
8169
        // Propagate exception as error if not done
8170
        if ( state < 2 ) {
8171
          done( -1, e );
8172
        // Simply rethrow otherwise
8173
        } else {
8174
          throw e;
8175
        }
8176
      }
8177
    }
8178
8179
    // Callback for when everything is done
8180
    function done( status, nativeStatusText, responses, headers ) {
8181
      var isSuccess, success, error, response, modified,
8182
        statusText = nativeStatusText;
8183
8184
      // Called once
8185
      if ( state === 2 ) {
8186
        return;
8187
      }
8188
8189
      // State is "done" now
8190
      state = 2;
8191
8192
      // Clear timeout if it exists
8193
      if ( timeoutTimer ) {
8194
        clearTimeout( timeoutTimer );
8195
      }
8196
8197
      // Dereference transport for early garbage collection
8198
      // (no matter how long the jqXHR object will be used)
8199
      transport = undefined;
8200
8201
      // Cache response headers
8202
      responseHeadersString = headers || "";
8203
8204
      // Set readyState
8205
      jqXHR.readyState = status > 0 ? 4 : 0;
8206
8207
      // Determine if successful
8208
      isSuccess = status >= 200 && status < 300 || status === 304;
8209
8210
      // Get response data
8211
      if ( responses ) {
8212
        response = ajaxHandleResponses( s, jqXHR, responses );
8213
      }
8214
8215
      // Convert no matter what (that way responseXXX fields are always set)
8216
      response = ajaxConvert( s, response, jqXHR, isSuccess );
8217
8218
      // If successful, handle type chaining
8219
      if ( isSuccess ) {
8220
8221
        // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8222
        if ( s.ifModified ) {
8223
          modified = jqXHR.getResponseHeader("Last-Modified");
8224
          if ( modified ) {
8225
            jQuery.lastModified[ cacheURL ] = modified;
8226
          }
8227
          modified = jqXHR.getResponseHeader("etag");
8228
          if ( modified ) {
8229
            jQuery.etag[ cacheURL ] = modified;
8230
          }
8231
        }
8232
8233
        // if no content
8234
        if ( status === 204 || s.type === "HEAD" ) {
8235
          statusText = "nocontent";
8236
8237
        // if not modified
8238
        } else if ( status === 304 ) {
8239
          statusText = "notmodified";
8240
8241
        // If we have data, let's convert it
8242
        } else {
8243
          statusText = response.state;
8244
          success = response.data;
8245
          error = response.error;
8246
          isSuccess = !error;
8247
        }
8248
      } else {
8249
        // Extract error from statusText and normalize for non-aborts
8250
        error = statusText;
8251
        if ( status || !statusText ) {
8252
          statusText = "error";
8253
          if ( status < 0 ) {
8254
            status = 0;
8255
          }
8256
        }
8257
      }
8258
8259
      // Set data for the fake xhr object
8260
      jqXHR.status = status;
8261
      jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8262
8263
      // Success/Error
8264
      if ( isSuccess ) {
8265
        deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8266
      } else {
8267
        deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8268
      }
8269
8270
      // Status-dependent callbacks
8271
      jqXHR.statusCode( statusCode );
8272
      statusCode = undefined;
8273
8274
      if ( fireGlobals ) {
8275
        globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8276
          [ jqXHR, s, isSuccess ? success : error ] );
8277
      }
8278
8279
      // Complete
8280
      completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8281
8282
      if ( fireGlobals ) {
8283
        globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8284
        // Handle the global AJAX counter
8285
        if ( !( --jQuery.active ) ) {
8286
          jQuery.event.trigger("ajaxStop");
8287
        }
8288
      }
8289
    }
8290
8291
    return jqXHR;
8292
  },
8293
8294
  getJSON: function( url, data, callback ) {
8295
    return jQuery.get( url, data, callback, "json" );
8296
  },
8297
8298
  getScript: function( url, callback ) {
8299
    return jQuery.get( url, undefined, callback, "script" );
8300
  }
8301
});
8302
8303
jQuery.each( [ "get", "post" ], function( i, method ) {
8304
  jQuery[ method ] = function( url, data, callback, type ) {
8305
    // Shift arguments if data argument was omitted
8306
    if ( jQuery.isFunction( data ) ) {
8307
      type = type || callback;
8308
      callback = data;
8309
      data = undefined;
8310
    }
8311
8312
    return jQuery.ajax({
8313
      url: url,
8314
      type: method,
8315
      dataType: type,
8316
      data: data,
8317
      success: callback
8318
    });
8319
  };
8320
});
8321
8322
8323
jQuery._evalUrl = function( url ) {
8324
  return jQuery.ajax({
8325
    url: url,
8326
    type: "GET",
8327
    dataType: "script",
8328
    async: false,
8329
    global: false,
8330
    "throws": true
8331
  });
8332
};
8333
8334
8335
jQuery.fn.extend({
8336
  wrapAll: function( html ) {
8337
    var wrap;
8338
8339
    if ( jQuery.isFunction( html ) ) {
8340
      return this.each(function( i ) {
8341
        jQuery( this ).wrapAll( html.call(this, i) );
8342
      });
8343
    }
8344
8345
    if ( this[ 0 ] ) {
8346
8347
      // The elements to wrap the target around
8348
      wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8349
8350
      if ( this[ 0 ].parentNode ) {
8351
        wrap.insertBefore( this[ 0 ] );
8352
      }
8353
8354
      wrap.map(function() {
8355
        var elem = this;
8356
8357
        while ( elem.firstElementChild ) {
8358
          elem = elem.firstElementChild;
8359
        }
8360
8361
        return elem;
8362
      }).append( this );
8363
    }
8364
8365
    return this;
8366
  },
8367
8368
  wrapInner: function( html ) {
8369
    if ( jQuery.isFunction( html ) ) {
8370
      return this.each(function( i ) {
8371
        jQuery( this ).wrapInner( html.call(this, i) );
8372
      });
8373
    }
8374
8375
    return this.each(function() {
8376
      var self = jQuery( this ),
8377
        contents = self.contents();
8378
8379
      if ( contents.length ) {
8380
        contents.wrapAll( html );
8381
8382
      } else {
8383
        self.append( html );
8384
      }
8385
    });
8386
  },
8387
8388
  wrap: function( html ) {
8389
    var isFunction = jQuery.isFunction( html );
8390
8391
    return this.each(function( i ) {
8392
      jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
8393
    });
8394
  },
8395
8396
  unwrap: function() {
8397
    return this.parent().each(function() {
8398
      if ( !jQuery.nodeName( this, "body" ) ) {
8399
        jQuery( this ).replaceWith( this.childNodes );
8400
      }
8401
    }).end();
8402
  }
8403
});
8404
8405
8406
jQuery.expr.filters.hidden = function( elem ) {
8407
  // Support: Opera <= 12.12
8408
  // Opera reports offsetWidths and offsetHeights less than zero on some elements
8409
  return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
8410
};
8411
jQuery.expr.filters.visible = function( elem ) {
8412
  return !jQuery.expr.filters.hidden( elem );
8413
};
8414
8415
8416
8417
8418
var r20 = /%20/g,
8419
  rbracket = /\[\]$/,
8420
  rCRLF = /\r?\n/g,
8421
  rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8422
  rsubmittable = /^(?:input|select|textarea|keygen)/i;
8423
8424
function buildParams( prefix, obj, traditional, add ) {
8425
  var name;
8426
8427
  if ( jQuery.isArray( obj ) ) {
8428
    // Serialize array item.
8429
    jQuery.each( obj, function( i, v ) {
8430
      if ( traditional || rbracket.test( prefix ) ) {
8431
        // Treat each array item as a scalar.
8432
        add( prefix, v );
8433
8434
      } else {
8435
        // Item is non-scalar (array or object), encode its numeric index.
8436
        buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
8437
      }
8438
    });
8439
8440
  } else if ( !traditional && jQuery.type( obj ) === "object" ) {
8441
    // Serialize object item.
8442
    for ( name in obj ) {
8443
      buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8444
    }
8445
8446
  } else {
8447
    // Serialize scalar item.
8448
    add( prefix, obj );
8449
  }
8450
}
8451
8452
// Serialize an array of form elements or a set of
8453
// key/values into a query string
8454
jQuery.param = function( a, traditional ) {
8455
  var prefix,
8456
    s = [],
8457
    add = function( key, value ) {
8458
      // If value is a function, invoke it and return its value
8459
      value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8460
      s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8461
    };
8462
8463
  // Set traditional to true for jQuery <= 1.3.2 behavior.
8464
  if ( traditional === undefined ) {
8465
    traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8466
  }
8467
8468
  // If an array was passed in, assume that it is an array of form elements.
8469
  if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8470
    // Serialize the form elements
8471
    jQuery.each( a, function() {
8472
      add( this.name, this.value );
8473
    });
8474
8475
  } else {
8476
    // If traditional, encode the "old" way (the way 1.3.2 or older
8477
    // did it), otherwise encode params recursively.
8478
    for ( prefix in a ) {
8479
      buildParams( prefix, a[ prefix ], traditional, add );
8480
    }
8481
  }
8482
8483
  // Return the resulting serialization
8484
  return s.join( "&" ).replace( r20, "+" );
8485
};
8486
8487
jQuery.fn.extend({
8488
  serialize: function() {
8489
    return jQuery.param( this.serializeArray() );
8490
  },
8491
  serializeArray: function() {
8492
    return this.map(function() {
8493
      // Can add propHook for "elements" to filter or add form elements
8494
      var elements = jQuery.prop( this, "elements" );
8495
      return elements ? jQuery.makeArray( elements ) : this;
8496
    })
8497
    .filter(function() {
8498
      var type = this.type;
8499
8500
      // Use .is( ":disabled" ) so that fieldset[disabled] works
8501
      return this.name && !jQuery( this ).is( ":disabled" ) &&
8502
        rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8503
        ( this.checked || !rcheckableType.test( type ) );
8504
    })
8505
    .map(function( i, elem ) {
8506
      var val = jQuery( this ).val();
8507
8508
      return val == null ?
8509
        null :
8510
        jQuery.isArray( val ) ?
8511
          jQuery.map( val, function( val ) {
8512
            return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8513
          }) :
8514
          { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8515
    }).get();
8516
  }
8517
});
8518
8519
8520
jQuery.ajaxSettings.xhr = function() {
8521
  try {
8522
    return new XMLHttpRequest();
8523
  } catch( e ) {}
8524
};
8525
8526
var xhrId = 0,
8527
  xhrCallbacks = {},
8528
  xhrSuccessStatus = {
8529
    // file protocol always yields status code 0, assume 200
8530
    0: 200,
8531
    // Support: IE9
8532
    // #1450: sometimes IE returns 1223 when it should be 204
8533
    1223: 204
8534
  },
8535
  xhrSupported = jQuery.ajaxSettings.xhr();
8536
8537
// Support: IE9
8538
// Open requests must be manually aborted on unload (#5280)
8539
// See https://support.microsoft.com/kb/2856746 for more info
8540
if ( window.attachEvent ) {
8541
  window.attachEvent( "onunload", function() {
8542
    for ( var key in xhrCallbacks ) {
8543
      xhrCallbacks[ key ]();
8544
    }
8545
  });
8546
}
8547
8548
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
8549
support.ajax = xhrSupported = !!xhrSupported;
8550
8551
jQuery.ajaxTransport(function( options ) {
8552
  var callback;
8553
8554
  // Cross domain only allowed if supported through XMLHttpRequest
8555
  if ( support.cors || xhrSupported && !options.crossDomain ) {
8556
    return {
8557
      send: function( headers, complete ) {
8558
        var i,
8559
          xhr = options.xhr(),
8560
          id = ++xhrId;
8561
8562
        xhr.open( options.type, options.url, options.async, options.username, options.password );
8563
8564
        // Apply custom fields if provided
8565
        if ( options.xhrFields ) {
8566
          for ( i in options.xhrFields ) {
8567
            xhr[ i ] = options.xhrFields[ i ];
8568
          }
8569
        }
8570
8571
        // Override mime type if needed
8572
        if ( options.mimeType && xhr.overrideMimeType ) {
8573
          xhr.overrideMimeType( options.mimeType );
8574
        }
8575
8576
        // X-Requested-With header
8577
        // For cross-domain requests, seeing as conditions for a preflight are
8578
        // akin to a jigsaw puzzle, we simply never set it to be sure.
8579
        // (it can always be set on a per-request basis or even using ajaxSetup)
8580
        // For same-domain requests, won't change header if already provided.
8581
        if ( !options.crossDomain && !headers["X-Requested-With"] ) {
8582
          headers["X-Requested-With"] = "XMLHttpRequest";
8583
        }
8584
8585
        // Set headers
8586
        for ( i in headers ) {
8587
          xhr.setRequestHeader( i, headers[ i ] );
8588
        }
8589
8590
        // Callback
8591
        callback = function( type ) {
8592
          return function() {
8593
            if ( callback ) {
8594
              delete xhrCallbacks[ id ];
8595
              callback = xhr.onload = xhr.onerror = null;
8596
8597
              if ( type === "abort" ) {
8598
                xhr.abort();
8599
              } else if ( type === "error" ) {
8600
                complete(
8601
                  // file: protocol always yields status 0; see #8605, #14207
8602
                  xhr.status,
8603
                  xhr.statusText
8604
                );
8605
              } else {
8606
                complete(
8607
                  xhrSuccessStatus[ xhr.status ] || xhr.status,
8608
                  xhr.statusText,
8609
                  // Support: IE9
8610
                  // Accessing binary-data responseText throws an exception
8611
                  // (#11426)
8612
                  typeof xhr.responseText === "string" ? {
8613
                    text: xhr.responseText
8614
                  } : undefined,
8615
                  xhr.getAllResponseHeaders()
8616
                );
8617
              }
8618
            }
8619
          };
8620
        };
8621
8622
        // Listen to events
8623
        xhr.onload = callback();
8624
        xhr.onerror = callback("error");
8625
8626
        // Create the abort callback
8627
        callback = xhrCallbacks[ id ] = callback("abort");
8628
8629
        try {
8630
          // Do send the request (this may raise an exception)
8631
          xhr.send( options.hasContent && options.data || null );
8632
        } catch ( e ) {
8633
          // #14683: Only rethrow if this hasn't been notified as an error yet
8634
          if ( callback ) {
8635
            throw e;
8636
          }
8637
        }
8638
      },
8639
8640
      abort: function() {
8641
        if ( callback ) {
8642
          callback();
8643
        }
8644
      }
8645
    };
8646
  }
8647
});
8648
8649
8650
8651
8652
// Install script dataType
8653
jQuery.ajaxSetup({
8654
  accepts: {
8655
    script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
8656
  },
8657
  contents: {
8658
    script: /(?:java|ecma)script/
8659
  },
8660
  converters: {
8661
    "text script": function( text ) {
8662
      jQuery.globalEval( text );
8663
      return text;
8664
    }
8665
  }
8666
});
8667
8668
// Handle cache's special case and crossDomain
8669
jQuery.ajaxPrefilter( "script", function( s ) {
8670
  if ( s.cache === undefined ) {
8671
    s.cache = false;
8672
  }
8673
  if ( s.crossDomain ) {
8674
    s.type = "GET";
8675
  }
8676
});
8677
8678
// Bind script tag hack transport
8679
jQuery.ajaxTransport( "script", function( s ) {
8680
  // This transport only deals with cross domain requests
8681
  if ( s.crossDomain ) {
8682
    var script, callback;
8683
    return {
8684
      send: function( _, complete ) {
8685
        script = jQuery("<script>").prop({
8686
          async: true,
8687
          charset: s.scriptCharset,
8688
          src: s.url
8689
        }).on(
8690
          "load error",
8691
          callback = function( evt ) {
8692
            script.remove();
8693
            callback = null;
8694
            if ( evt ) {
8695
              complete( evt.type === "error" ? 404 : 200, evt.type );
8696
            }
8697
          }
8698
        );
8699
        document.head.appendChild( script[ 0 ] );
8700
      },
8701
      abort: function() {
8702
        if ( callback ) {
8703
          callback();
8704
        }
8705
      }
8706
    };
8707
  }
8708
});
8709
8710
8711
8712
8713
var oldCallbacks = [],
8714
  rjsonp = /(=)\?(?=&|$)|\?\?/;
8715
8716
// Default jsonp settings
8717
jQuery.ajaxSetup({
8718
  jsonp: "callback",
8719
  jsonpCallback: function() {
8720
    var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
8721
    this[ callback ] = true;
8722
    return callback;
8723
  }
8724
});
8725
8726
// Detect, normalize options and install callbacks for jsonp requests
8727
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
8728
8729
  var callbackName, overwritten, responseContainer,
8730
    jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
8731
      "url" :
8732
      typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
8733
    );
8734
8735
  // Handle iff the expected data type is "jsonp" or we have a parameter to set
8736
  if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
8737
8738
    // Get callback name, remembering preexisting value associated with it
8739
    callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
8740
      s.jsonpCallback() :
8741
      s.jsonpCallback;
8742
8743
    // Insert callback into url or form data
8744
    if ( jsonProp ) {
8745
      s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
8746
    } else if ( s.jsonp !== false ) {
8747
      s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
8748
    }
8749
8750
    // Use data converter to retrieve json after script execution
8751
    s.converters["script json"] = function() {
8752
      if ( !responseContainer ) {
8753
        jQuery.error( callbackName + " was not called" );
8754
      }
8755
      return responseContainer[ 0 ];
8756
    };
8757
8758
    // force json dataType
8759
    s.dataTypes[ 0 ] = "json";
8760
8761
    // Install callback
8762
    overwritten = window[ callbackName ];
8763
    window[ callbackName ] = function() {
8764
      responseContainer = arguments;
8765
    };
8766
8767
    // Clean-up function (fires after converters)
8768
    jqXHR.always(function() {
8769
      // Restore preexisting value
8770
      window[ callbackName ] = overwritten;
8771
8772
      // Save back as free
8773
      if ( s[ callbackName ] ) {
8774
        // make sure that re-using the options doesn't screw things around
8775
        s.jsonpCallback = originalSettings.jsonpCallback;
8776
8777
        // save the callback name for future use
8778
        oldCallbacks.push( callbackName );
8779
      }
8780
8781
      // Call if it was a function and we have a response
8782
      if ( responseContainer && jQuery.isFunction( overwritten ) ) {
8783
        overwritten( responseContainer[ 0 ] );
8784
      }
8785
8786
      responseContainer = overwritten = undefined;
8787
    });
8788
8789
    // Delegate to script
8790
    return "script";
8791
  }
8792
});
8793
8794
8795
8796
8797
// data: string of html
8798
// context (optional): If specified, the fragment will be created in this context, defaults to document
8799
// keepScripts (optional): If true, will include scripts passed in the html string
8800
jQuery.parseHTML = function( data, context, keepScripts ) {
8801
  if ( !data || typeof data !== "string" ) {
8802
    return null;
8803
  }
8804
  if ( typeof context === "boolean" ) {
8805
    keepScripts = context;
8806
    context = false;
8807
  }
8808
  context = context || document;
8809
8810
  var parsed = rsingleTag.exec( data ),
8811
    scripts = !keepScripts && [];
8812
8813
  // Single tag
8814
  if ( parsed ) {
8815
    return [ context.createElement( parsed[1] ) ];
8816
  }
8817
8818
  parsed = jQuery.buildFragment( [ data ], context, scripts );
8819
8820
  if ( scripts && scripts.length ) {
8821
    jQuery( scripts ).remove();
8822
  }
8823
8824
  return jQuery.merge( [], parsed.childNodes );
8825
};
8826
8827
8828
// Keep a copy of the old load method
8829
var _load = jQuery.fn.load;
8830
8831
/**
8832
 * Load a url into a page
8833
 */
8834
jQuery.fn.load = function( url, params, callback ) {
8835
  if ( typeof url !== "string" && _load ) {
8836
    return _load.apply( this, arguments );
8837
  }
8838
8839
  var selector, type, response,
8840
    self = this,
8841
    off = url.indexOf(" ");
8842
8843
  if ( off >= 0 ) {
8844
    selector = jQuery.trim( url.slice( off ) );
8845
    url = url.slice( 0, off );
8846
  }
8847
8848
  // If it's a function
8849
  if ( jQuery.isFunction( params ) ) {
8850
8851
    // We assume that it's the callback
8852
    callback = params;
8853
    params = undefined;
8854
8855
  // Otherwise, build a param string
8856
  } else if ( params && typeof params === "object" ) {
8857
    type = "POST";
8858
  }
8859
8860
  // If we have elements to modify, make the request
8861
  if ( self.length > 0 ) {
8862
    jQuery.ajax({
8863
      url: url,
8864
8865
      // if "type" variable is undefined, then "GET" method will be used
8866
      type: type,
8867
      dataType: "html",
8868
      data: params
8869
    }).done(function( responseText ) {
8870
8871
      // Save response for use in complete callback
8872
      response = arguments;
8873
8874
      self.html( selector ?
8875
8876
        // If a selector was specified, locate the right elements in a dummy div
8877
        // Exclude scripts to avoid IE 'Permission Denied' errors
8878
        jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
8879
8880
        // Otherwise use the full result
8881
        responseText );
8882
8883
    }).complete( callback && function( jqXHR, status ) {
8884
      self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
8885
    });
8886
  }
8887
8888
  return this;
8889
};
8890
8891
8892
8893
8894
// Attach a bunch of functions for handling common AJAX events
8895
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
8896
  jQuery.fn[ type ] = function( fn ) {
8897
    return this.on( type, fn );
8898
  };
8899
});
8900
8901
8902
8903
8904
jQuery.expr.filters.animated = function( elem ) {
8905
  return jQuery.grep(jQuery.timers, function( fn ) {
8906
    return elem === fn.elem;
8907
  }).length;
8908
};
8909
8910
8911
8912
8913
var docElem = window.document.documentElement;
8914
8915
/**
8916
 * Gets a window from an element
8917
 */
8918
function getWindow( elem ) {
8919
  return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
8920
}
8921
8922
jQuery.offset = {
8923
  setOffset: function( elem, options, i ) {
8924
    var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
8925
      position = jQuery.css( elem, "position" ),
8926
      curElem = jQuery( elem ),
8927
      props = {};
8928
8929
    // Set position first, in-case top/left are set even on static elem
8930
    if ( position === "static" ) {
8931
      elem.style.position = "relative";
8932
    }
8933
8934
    curOffset = curElem.offset();
8935
    curCSSTop = jQuery.css( elem, "top" );
8936
    curCSSLeft = jQuery.css( elem, "left" );
8937
    calculatePosition = ( position === "absolute" || position === "fixed" ) &&
8938
      ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
8939
8940
    // Need to be able to calculate position if either
8941
    // top or left is auto and position is either absolute or fixed
8942
    if ( calculatePosition ) {
8943
      curPosition = curElem.position();
8944
      curTop = curPosition.top;
8945
      curLeft = curPosition.left;
8946
8947
    } else {
8948
      curTop = parseFloat( curCSSTop ) || 0;
8949
      curLeft = parseFloat( curCSSLeft ) || 0;
8950
    }
8951
8952
    if ( jQuery.isFunction( options ) ) {
8953
      options = options.call( elem, i, curOffset );
8954
    }
8955
8956
    if ( options.top != null ) {
8957
      props.top = ( options.top - curOffset.top ) + curTop;
8958
    }
8959
    if ( options.left != null ) {
8960
      props.left = ( options.left - curOffset.left ) + curLeft;
8961
    }
8962
8963
    if ( "using" in options ) {
8964
      options.using.call( elem, props );
8965
8966
    } else {
8967
      curElem.css( props );
8968
    }
8969
  }
8970
};
8971
8972
jQuery.fn.extend({
8973
  offset: function( options ) {
8974
    if ( arguments.length ) {
8975
      return options === undefined ?
8976
        this :
8977
        this.each(function( i ) {
8978
          jQuery.offset.setOffset( this, options, i );
8979
        });
8980
    }
8981
8982
    var docElem, win,
8983
      elem = this[ 0 ],
8984
      box = { top: 0, left: 0 },
8985
      doc = elem && elem.ownerDocument;
8986
8987
    if ( !doc ) {
8988
      return;
8989
    }
8990
8991
    docElem = doc.documentElement;
8992
8993
    // Make sure it's not a disconnected DOM node
8994
    if ( !jQuery.contains( docElem, elem ) ) {
8995
      return box;
8996
    }
8997
8998
    // Support: BlackBerry 5, iOS 3 (original iPhone)
8999
    // If we don't have gBCR, just use 0,0 rather than error
9000
    if ( typeof elem.getBoundingClientRect !== strundefined ) {
9001
      box = elem.getBoundingClientRect();
9002
    }
9003
    win = getWindow( doc );
9004
    return {
9005
      top: box.top + win.pageYOffset - docElem.clientTop,
9006
      left: box.left + win.pageXOffset - docElem.clientLeft
9007
    };
9008
  },
9009
9010
  position: function() {
9011
    if ( !this[ 0 ] ) {
9012
      return;
9013
    }
9014
9015
    var offsetParent, offset,
9016
      elem = this[ 0 ],
9017
      parentOffset = { top: 0, left: 0 };
9018
9019
    // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
9020
    if ( jQuery.css( elem, "position" ) === "fixed" ) {
9021
      // Assume getBoundingClientRect is there when computed position is fixed
9022
      offset = elem.getBoundingClientRect();
9023
9024
    } else {
9025
      // Get *real* offsetParent
9026
      offsetParent = this.offsetParent();
9027
9028
      // Get correct offsets
9029
      offset = this.offset();
9030
      if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9031
        parentOffset = offsetParent.offset();
9032
      }
9033
9034
      // Add offsetParent borders
9035
      parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9036
      parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9037
    }
9038
9039
    // Subtract parent offsets and element margins
9040
    return {
9041
      top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9042
      left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9043
    };
9044
  },
9045
9046
  offsetParent: function() {
9047
    return this.map(function() {
9048
      var offsetParent = this.offsetParent || docElem;
9049
9050
      while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
9051
        offsetParent = offsetParent.offsetParent;
9052
      }
9053
9054
      return offsetParent || docElem;
9055
    });
9056
  }
9057
});
9058
9059
// Create scrollLeft and scrollTop methods
9060
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9061
  var top = "pageYOffset" === prop;
9062
9063
  jQuery.fn[ method ] = function( val ) {
9064
    return access( this, function( elem, method, val ) {
9065
      var win = getWindow( elem );
9066
9067
      if ( val === undefined ) {
9068
        return win ? win[ prop ] : elem[ method ];
9069
      }
9070
9071
      if ( win ) {
9072
        win.scrollTo(
9073
          !top ? val : window.pageXOffset,
9074
          top ? val : window.pageYOffset
9075
        );
9076
9077
      } else {
9078
        elem[ method ] = val;
9079
      }
9080
    }, method, val, arguments.length, null );
9081
  };
9082
});
9083
9084
// Support: Safari<7+, Chrome<37+
9085
// Add the top/left cssHooks using jQuery.fn.position
9086
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9087
// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9088
// getComputedStyle returns percent when specified for top/left/bottom/right;
9089
// rather than make the css module depend on the offset module, just check for it here
9090
jQuery.each( [ "top", "left" ], function( i, prop ) {
9091
  jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9092
    function( elem, computed ) {
9093
      if ( computed ) {
9094
        computed = curCSS( elem, prop );
9095
        // If curCSS returns percentage, fallback to offset
9096
        return rnumnonpx.test( computed ) ?
9097
          jQuery( elem ).position()[ prop ] + "px" :
9098
          computed;
9099
      }
9100
    }
9101
  );
9102
});
9103
9104
9105
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9106
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9107
  jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
9108
    // Margin is only for outerHeight, outerWidth
9109
    jQuery.fn[ funcName ] = function( margin, value ) {
9110
      var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9111
        extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9112
9113
      return access( this, function( elem, type, value ) {
9114
        var doc;
9115
9116
        if ( jQuery.isWindow( elem ) ) {
9117
          // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9118
          // isn't a whole lot we can do. See pull request at this URL for discussion:
9119
          // https://github.com/jquery/jquery/pull/764
9120
          return elem.document.documentElement[ "client" + name ];
9121
        }
9122
9123
        // Get document width or height
9124
        if ( elem.nodeType === 9 ) {
9125
          doc = elem.documentElement;
9126
9127
          // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9128
          // whichever is greatest
9129
          return Math.max(
9130
            elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9131
            elem.body[ "offset" + name ], doc[ "offset" + name ],
9132
            doc[ "client" + name ]
9133
          );
9134
        }
9135
9136
        return value === undefined ?
9137
          // Get width or height on the element, requesting but not forcing parseFloat
9138
          jQuery.css( elem, type, extra ) :
9139
9140
          // Set width or height on the element
9141
          jQuery.style( elem, type, value, extra );
9142
      }, type, chainable ? margin : undefined, chainable, null );
9143
    };
9144
  });
9145
});
9146
9147
9148
// The number of elements contained in the matched element set
9149
jQuery.fn.size = function() {
9150
  return this.length;
9151
};
9152
9153
jQuery.fn.andSelf = jQuery.fn.addBack;
9154
9155
9156
9157
9158
// Register as a named AMD module, since jQuery can be concatenated with other
9159
// files that may use define, but not via a proper concatenation script that
9160
// understands anonymous AMD modules. A named AMD is safest and most robust
9161
// way to register. Lowercase jquery is used because AMD module names are
9162
// derived from file names, and jQuery is normally delivered in a lowercase
9163
// file name. Do this after creating the global so that if an AMD module wants
9164
// to call noConflict to hide this version of jQuery, it will work.
9165
9166
// Note that for maximum portability, libraries that are not jQuery should
9167
// declare themselves as anonymous modules, and avoid setting a global if an
9168
// AMD loader is present. jQuery is a special case. For more information, see
9169
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9170
9171
if ( typeof define === "function" && define.amd ) {
9172
  define( "jquery", [], function() {
9173
    return jQuery;
9174
  });
9175
}
9176
9177
9178
9179
9180
var
9181
  // Map over jQuery in case of overwrite
9182
  _jQuery = window.jQuery,
9183
9184
  // Map over the $ in case of overwrite
9185
  _$ = window.$;
9186
9187
jQuery.noConflict = function( deep ) {
9188
  if ( window.$ === jQuery ) {
9189
    window.$ = _$;
9190
  }
9191
9192
  if ( deep && window.jQuery === jQuery ) {
9193
    window.jQuery = _jQuery;
9194
  }
9195
9196
  return jQuery;
9197
};
9198
9199
// Expose jQuery and $ identifiers, even in AMD
9200
// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9201
// and CommonJS for browser emulators (#13566)
9202
if ( typeof noGlobal === strundefined ) {
9203
  window.jQuery = window.$ = jQuery;
9204
}
9205
9206
9207
9208
9209
return jQuery;
9210
9211
}));
9212
9213
},{}],2:[function(require,module,exports){
9214
/**
9215
 * vivus - JavaScript library to make drawing animation on SVG
9216
 * @version v0.2.1
9217
 * @link https://github.com/maxwellito/vivus
9218
 * @license MIT
9219
 */
9220
9221
'use strict';
9222
9223
(function (window, document) {
9224
9225
  'use strict';
9226
9227
/**
9228
 * Pathformer
9229
 * Beta version
9230
 *
9231
 * Take any SVG version 1.1 and transform
9232
 * child elements to 'path' elements
9233
 *
9234
 * This code is purely forked from
9235
 * https://github.com/Waest/SVGPathConverter
9236
 */
9237
9238
/**
9239
 * Class constructor
9240
 *
9241
 * @param {DOM|String} element Dom element of the SVG or id of it
9242
 */
9243
function Pathformer(element) {
9244
  // Test params
9245
  if (typeof element === 'undefined') {
9246
    throw new Error('Pathformer [constructor]: "element" parameter is required');
9247
  }
9248
9249
  // Set the element
9250
  if (element.constructor === String) {
9251
    element = document.getElementById(element);
9252
    if (!element) {
9253
      throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');
9254
    }
9255
  }
9256
  if (element.constructor instanceof window.SVGElement || /^svg$/i.test(element.nodeName)) {
9257
    this.el = element;
9258
  } else {
9259
    throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');
9260
  }
9261
9262
  // Start
9263
  this.scan(element);
9264
}
9265
9266
/**
9267
 * List of tags which can be transformed
9268
 * to path elements
9269
 *
9270
 * @type {Array}
9271
 */
9272
Pathformer.prototype.TYPES = ['line', 'elipse', 'circle', 'polygon', 'polyline', 'rect'];
9273
9274
/**
9275
 * List of attribute names which contain
9276
 * data. This array list them to check if
9277
 * they contain bad values, like percentage. 
9278
 *
9279
 * @type {Array}
9280
 */
9281
Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', 'y1', 'y2'];
9282
9283
/**
9284
 * Finds the elements compatible for transform
9285
 * and apply the liked method
9286
 *
9287
 * @param  {object} options Object from the constructor
9288
 */
9289
Pathformer.prototype.scan = function (svg) {
9290
  var fn, element, pathData, pathDom,
9291
    elements = svg.querySelectorAll(this.TYPES.join(','));
9292
  for (var i = 0; i < elements.length; i++) {
9293
    element = elements[i];
9294
    fn = this[element.tagName.toLowerCase() + 'ToPath'];
9295
    pathData = fn(this.parseAttr(element.attributes));
9296
    pathDom = this.pathMaker(element, pathData);
9297
    element.parentNode.replaceChild(pathDom, element);
9298
  }
9299
};
9300
9301
9302
/**
9303
 * Read `line` element to extract and transform
9304
 * data, to make it ready for a `path` object.
9305
 *
9306
 * @param  {DOMelement} element Line element to transform
9307
 * @return {object}             Data for a `path` element
9308
 */
9309
Pathformer.prototype.lineToPath = function (element) {
9310
  var newElement = {};
9311
  newElement.d = 'M' + element.x1 + ',' + element.y1 + 'L' + element.x2 + ',' + element.y2;
9312
  return newElement;
9313
};
9314
9315
/**
9316
 * Read `rect` element to extract and transform
9317
 * data, to make it ready for a `path` object.
9318
 * The radius-border is not taken in charge yet.
9319
 * (your help is more than welcomed)
9320
 *
9321
 * @param  {DOMelement} element Rect element to transform
9322
 * @return {object}             Data for a `path` element
9323
 */
9324
Pathformer.prototype.rectToPath = function (element) {
9325
  var newElement = {},
9326
    x = parseFloat(element.x) || 0,
9327
    y = parseFloat(element.y) || 0,
9328
    width = parseFloat(element.width) || 0,
9329
    height = parseFloat(element.height) || 0;
9330
  newElement.d  = 'M' + x + ' ' + y + ' ';
9331
  newElement.d += 'L' + (x + width) + ' ' + y + ' ';
9332
  newElement.d += 'L' + (x + width) + ' ' + (y + height) + ' ';
9333
  newElement.d += 'L' + x + ' ' + (y + height) + ' Z';
9334
  return newElement;
9335
};
9336
9337
/**
9338
 * Read `polyline` element to extract and transform
9339
 * data, to make it ready for a `path` object.
9340
 *
9341
 * @param  {DOMelement} element Polyline element to transform
9342
 * @return {object}             Data for a `path` element
9343
 */
9344
Pathformer.prototype.polylineToPath = function (element) {
9345
  var i, path;
9346
  var newElement = {};
9347
  var points = element.points.split(' ');
9348
  
9349
  // Reformatting if points are defined without commas
9350
  if (element.points.indexOf(',') === -1) {
9351
    var formattedPoints = [];
9352
    for (i = 0; i < points.length; i+=2) {
9353
      formattedPoints.push(points[i] + ',' + points[i+1]);
9354
    }
9355
    points = formattedPoints;
9356
  }
9357
9358
  // Generate the path.d value
9359
  path = 'M' + points[0];
9360
  for(i = 1; i < points.length; i++) {
9361
    if (points[i].indexOf(',') !== -1) {
9362
      path += 'L' + points[i];
9363
    }
9364
  }
9365
  newElement.d = path;
9366
  return newElement;
9367
};
9368
9369
/**
9370
 * Read `polygon` element to extract and transform
9371
 * data, to make it ready for a `path` object.
9372
 * This method rely on polylineToPath, because the
9373
 * logic is similar. The path created is just closed,
9374
 * so it needs an 'Z' at the end.
9375
 *
9376
 * @param  {DOMelement} element Polygon element to transform
9377
 * @return {object}             Data for a `path` element
9378
 */
9379
Pathformer.prototype.polygonToPath = function (element) {
9380
  var newElement = Pathformer.prototype.polylineToPath(element);
9381
  newElement.d += 'Z';
9382
  return newElement;
9383
};
9384
9385
/**
9386
 * Read `elipse` element to extract and transform
9387
 * data, to make it ready for a `path` object.
9388
 *
9389
 * @param  {DOMelement} element Elipse element to transform
9390
 * @return {object}             Data for a `path` element
9391
 */
9392
Pathformer.prototype.elipseToPath = function (element) {
9393
  var startX = element.cx - element.rx,
9394
      startY = element.cy;
9395
  var endX = parseFloat(element.cx) + parseFloat(element.rx),
9396
      endY = element.cy;
9397
9398
  var newElement = {};
9399
  newElement.d = 'M' + startX + ',' + startY +
9400
                 'A' + element.rx + ',' + element.ry + ' 0,1,1 ' + endX + ',' + endY +
9401
                 'A' + element.rx + ',' + element.ry + ' 0,1,1 ' + startX + ',' + endY;
9402
  return newElement;
9403
};
9404
9405
/**
9406
 * Read `circle` element to extract and transform
9407
 * data, to make it ready for a `path` object.
9408
 *
9409
 * @param  {DOMelement} element Circle element to transform
9410
 * @return {object}             Data for a `path` element
9411
 */
9412
Pathformer.prototype.circleToPath = function (element) {
9413
  var newElement = {};
9414
  var startX = element.cx - element.r,
9415
      startY = element.cy;
9416
  var endX = parseFloat(element.cx) + parseFloat(element.r),
9417
      endY = element.cy;
9418
  newElement.d =  'M' + startX + ',' + startY +
9419
                  'A' + element.r + ',' + element.r + ' 0,1,1 ' + endX + ',' + endY +
9420
                  'A' + element.r + ',' + element.r + ' 0,1,1 ' + startX + ',' + endY;
9421
  return newElement;
9422
};
9423
9424
/**
9425
 * Create `path` elements form original element
9426
 * and prepared objects
9427
 *
9428
 * @param  {DOMelement} element  Original element to transform
9429
 * @param  {object} pathData     Path data (from `toPath` methods)
9430
 * @return {DOMelement}          Path element
9431
 */
9432
Pathformer.prototype.pathMaker = function (element, pathData) {
9433
  var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path');
9434
  for(i = 0; i < element.attributes.length; i++) {
9435
    attr = element.attributes[i];
9436
    if (this.ATTR_WATCH.indexOf(attr.name) === -1) {
9437
      pathTag.setAttribute(attr.name, attr.value);
9438
    }
9439
  }
9440
  for(i in pathData) {
9441
    pathTag.setAttribute(i, pathData[i]);
9442
  }
9443
  return pathTag;
9444
};
9445
9446
/**
9447
 * Parse attributes of a DOM element to
9448
 * get an object of attribute => value
9449
 *
9450
 * @param  {NamedNodeMap} attributes Attributes object from DOM element to parse
9451
 * @return {object}                  Object of attributes
9452
 */
9453
Pathformer.prototype.parseAttr = function (element) {
9454
  var attr, output = {};
9455
  for (var i = 0; i < element.length; i++) {
9456
    attr = element[i];
9457
    // Check if no data attribute contains '%', or the transformation is impossible
9458
    if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) {
9459
      throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.');
9460
    }
9461
    output[attr.name] = attr.value;
9462
  }
9463
  return output;
9464
};
9465
9466
  'use strict';
9467
9468
var requestAnimFrame, cancelAnimFrame, parsePositiveInt;
9469
9470
/**
9471
 * Vivus
9472
 * Beta version
9473
 *
9474
 * Take any SVG and make the animation
9475
 * to give give the impression of live drawing
9476
 *
9477
 * This in more than just inspired from codrops
9478
 * At that point, it's a pure fork.
9479
 */
9480
9481
/**
9482
 * Class constructor
9483
 * option structure
9484
 *   type: 'delayed'|'async'|'oneByOne'|'script' (to know if the item must be drawn asynchronously or not, default: delayed)
9485
 *   duration: <int> (in frames)
9486
 *   start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport)
9487
 *   delay: <int> (delay between the drawing of first and last path)
9488
 *   dashGap <integer> whitespace extra margin between dashes
9489
 *   pathTimingFunction <function> timing animation function for each path element of the SVG
9490
 *   animTimingFunction <function> timing animation function for the complete SVG
9491
 *   forceRender <boolean> force the browser to re-render all updated path items
9492
 *   selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original
9493
 *
9494
 * The attribute 'type' is by default on 'delayed'.
9495
 *  - 'delayed'
9496
 *    all paths are draw at the same time but with a
9497
 *    little delay between them before start
9498
 *  - 'async'
9499
 *    all path are start and finish at the same time
9500
 *  - 'oneByOne'
9501
 *    only one path is draw at the time
9502
 *    the end of the first one will trigger the draw
9503
 *    of the next one
9504
 *
9505
 * All these values can be overwritten individually
9506
 * for each path item in the SVG
9507
 * The value of frames will always take the advantage of
9508
 * the duration value.
9509
 * If you fail somewhere, an error will be thrown.
9510
 * Good luck.
9511
 *
9512
 * @constructor
9513
 * @this {Vivus}
9514
 * @param {DOM|String}   element  Dom element of the SVG or id of it
9515
 * @param {Object}       options  Options about the animation
9516
 * @param {Function}     callback Callback for the end of the animation
9517
 */
9518
function Vivus (element, options, callback) {
9519
9520
  // Setup
9521
  this.isReady = false;
9522
  this.setElement(element, options);
9523
  this.setOptions(options);
9524
  this.setCallback(callback);
9525
9526
  if (this.isReady) {
9527
    this.init();
9528
  }
9529
}
9530
9531
/**
9532
 * Timing functions
9533
 ************************************** 
9534
 * 
9535
 * Default functions to help developers.
9536
 * It always take a number as parameter (between 0 to 1) then
9537
 * return a number (between 0 and 1)
9538
 */
9539
Vivus.LINEAR          = function (x) {return x;};
9540
Vivus.EASE            = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
9541
Vivus.EASE_OUT        = function (x) {return 1 - Math.pow(1-x, 3);};
9542
Vivus.EASE_IN         = function (x) {return Math.pow(x, 3);};
9543
Vivus.EASE_OUT_BOUNCE = function (x) {
9544
  var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
9545
    rate = Math.pow(base,1.5),
9546
    rateR = Math.pow(1 - x, 2),
9547
    progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
9548
  return (1- rateR) + (progress * rateR);
9549
};
9550
9551
9552
/**
9553
 * Setters
9554
 **************************************
9555
 */
9556
9557
/**
9558
 * Check and set the element in the instance
9559
 * The method will not return anything, but will throw an
9560
 * error if the parameter is invalid
9561
 *
9562
 * @param {DOM|String}   element  SVG Dom element or id of it
9563
 */
9564
Vivus.prototype.setElement = function (element, options) {
9565
  // Basic check
9566
  if (typeof element === 'undefined') {
9567
    throw new Error('Vivus [constructor]: "element" parameter is required');
9568
  }
9569
9570
  // Set the element
9571
  if (element.constructor === String) {
9572
    element = document.getElementById(element);
9573
    if (!element) {
9574
      throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');
9575
    }
9576
  }
9577
9578
  // Create the object element if the property `file` exists in the options object
9579
  if (options && options.file) {
9580
    var objElm = document.createElement('object');
9581
    objElm.setAttribute('type', 'image/svg+xml');
9582
    objElm.setAttribute('data', options.file);
9583
    element.appendChild(objElm);
9584
    element = objElm;
9585
  }
9586
9587
  switch (element.constructor) {
9588
  case window.SVGSVGElement:
9589
  case window.SVGElement:
9590
    this.el = element;
9591
    this.isReady = true;
9592
    break;
9593
9594
  case window.HTMLObjectElement:
9595
    // If the Object is already loaded
9596
    this.el = element.contentDocument && element.contentDocument.querySelector('svg');
9597
    if (this.el) {
9598
      this.isReady = true;
9599
      return;
9600
    }
9601
9602
    // If we have to wait for it
9603
    var self = this;
9604
    element.addEventListener('load', function () {
9605
      self.el = element.contentDocument && element.contentDocument.querySelector('svg');
9606
      if (!self.el) {
9607
        throw new Error('Vivus [constructor]: object loaded does not contain any SVG');
9608
      }
9609
      else {
9610
        self.isReady = true;
9611
        self.init();
9612
      }
9613
    });
9614
    break;
9615
9616
  default:
9617
    throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)');
9618
  }
9619
};
9620
9621
/**
9622
 * Set up user option to the instance
9623
 * The method will not return anything, but will throw an
9624
 * error if the parameter is invalid
9625
 *
9626
 * @param  {object} options Object from the constructor
9627
 */
9628
Vivus.prototype.setOptions = function (options) {
9629
  var allowedTypes = ['delayed', 'async', 'oneByOne', 'scenario', 'scenario-sync'];
9630
  var allowedStarts =  ['inViewport', 'manual', 'autostart'];
9631
9632
  // Basic check
9633
  if (options !== undefined && options.constructor !== Object) {
9634
    throw new Error('Vivus [constructor]: "options" parameter must be an object');
9635
  }
9636
  else {
9637
    options = options || {};
9638
  }
9639
9640
  // Set the animation type
9641
  if (options.type && allowedTypes.indexOf(options.type) === -1) {
9642
    throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`');
9643
  }
9644
  else {
9645
    this.type = options.type || allowedTypes[0];
9646
  }
9647
9648
  // Set the start type
9649
  if (options.start && allowedStarts.indexOf(options.start) === -1) {
9650
    throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option');
9651
  }
9652
  else {
9653
    this.start = options.start || allowedStarts[0];
9654
  }
9655
9656
  this.isIE        = (window.navigator.userAgent.indexOf('MSIE') !== -1);
9657
  this.duration    = parsePositiveInt(options.duration, 120);
9658
  this.delay       = parsePositiveInt(options.delay, null);
9659
  this.dashGap     = parsePositiveInt(options.dashGap, 2);
9660
  this.forceRender = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE;
9661
  this.selfDestroy = !!options.selfDestroy;
9662
  this.onReady     = options.onReady;
9663
9664
  this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
9665
  this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR;
9666
9667
  if (this.delay >= this.duration) {
9668
    throw new Error('Vivus [constructor]: delay must be shorter than duration');
9669
  }
9670
};
9671
9672
/**
9673
 * Set up callback to the instance
9674
 * The method will not return enything, but will throw an
9675
 * error if the parameter is invalid
9676
 *
9677
 * @param  {Function} callback Callback for the animation end
9678
 */
9679
Vivus.prototype.setCallback = function (callback) {
9680
  // Basic check
9681
  if (!!callback && callback.constructor !== Function) {
9682
    throw new Error('Vivus [constructor]: "callback" parameter must be a function');
9683
  }
9684
  this.callback = callback || function () {};
9685
};
9686
9687
9688
/**
9689
 * Core
9690
 **************************************
9691
 */
9692
9693
/**
9694
 * Map the svg, path by path.
9695
 * The method return nothing, it just fill the
9696
 * `map` array. Each item in this array represent
9697
 * a path element from the SVG, with informations for
9698
 * the animation.
9699
 *
9700
 * ```
9701
 * [
9702
 *   {
9703
 *     el: <DOMobj> the path element
9704
 *     length: <number> length of the path line
9705
 *     startAt: <number> time start of the path animation (in frames)
9706
 *     duration: <number> path animation duration (in frames)
9707
 *   },
9708
 *   ...
9709
 * ]
9710
 * ```
9711
 *
9712
 */
9713
Vivus.prototype.mapping = function () {
9714
  var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint;
9715
  timePoint = totalLength = lengthMeter = 0;
9716
  paths = this.el.querySelectorAll('path');
9717
9718
  for (i = 0; i < paths.length; i++) {
9719
    path = paths[i];
9720
    pathObj = {
9721
      el: path,
9722
      length: Math.ceil(path.getTotalLength())
9723
    };
9724
    // Test if the path length is correct
9725
    if (isNaN(pathObj.length)) {
9726
      if (window.console && console.warn) {
9727
        console.warn('Vivus [mapping]: cannot retrieve a path element length', path);
9728
      }
9729
      continue;
9730
    }
9731
    totalLength += pathObj.length;
9732
    this.map.push(pathObj);
9733
    path.style.strokeDasharray  = pathObj.length + ' ' + (pathObj.length + this.dashGap);
9734
    path.style.strokeDashoffset = pathObj.length;
9735
9736
    // Fix IE glitch
9737
    if (this.isIE) {
9738
      pathObj.length += this.dashGap;
9739
    }
9740
    this.renderPath(i);
9741
  }
9742
9743
  totalLength = totalLength === 0 ? 1 : totalLength;
9744
  this.delay = this.delay === null ? this.duration / 3 : this.delay;
9745
  this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1);
9746
9747
  for (i = 0; i < this.map.length; i++) {
9748
    pathObj = this.map[i];
9749
9750
    switch (this.type) {
9751
    case 'delayed':
9752
      pathObj.startAt = this.delayUnit * i;
9753
      pathObj.duration = this.duration - this.delay;
9754
      break;
9755
9756
    case 'oneByOne':
9757
      pathObj.startAt = lengthMeter / totalLength * this.duration;
9758
      pathObj.duration = pathObj.length / totalLength * this.duration;
9759
      break;
9760
9761
    case 'async':
9762
      pathObj.startAt = 0;
9763
      pathObj.duration = this.duration;
9764
      break;
9765
9766
    case 'scenario-sync':
9767
      path = paths[i];
9768
      pAttrs = this.parseAttr(path);
9769
      pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0);
9770
      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
9771
      timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration;
9772
      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
9773
      break;
9774
9775
    case 'scenario':
9776
      path = paths[i];
9777
      pAttrs = this.parseAttr(path);
9778
      pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0;
9779
      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
9780
      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
9781
      break;
9782
    }
9783
    lengthMeter += pathObj.length;
9784
    this.frameLength = this.frameLength || this.duration;
9785
  }
9786
};
9787
9788
/**
9789
 * Interval method to draw the SVG from current
9790
 * position of the animation. It update the value of
9791
 * `currentFrame` and re-trace the SVG.
9792
 *
9793
 * It use this.handle to store the requestAnimationFrame
9794
 * and clear it one the animation is stopped. So this
9795
 * attribute can be used to know if the animation is
9796
 * playing.
9797
 *
9798
 * Once the animation at the end, this method will
9799
 * trigger the Vivus callback.
9800
 *
9801
 */
9802
Vivus.prototype.drawer = function () {
9803
  var self = this;
9804
  this.currentFrame += this.speed;
9805
9806
  if (this.currentFrame <= 0) {
9807
    this.stop();
9808
    this.reset();
9809
    this.callback(this);
9810
  } else if (this.currentFrame >= this.frameLength) {
9811
    this.stop();
9812
    this.currentFrame = this.frameLength;
9813
    this.trace();
9814
    if (this.selfDestroy) {
9815
      this.destroy();
9816
    }
9817
    this.callback(this);
9818
  } else {
9819
    this.trace();
9820
    this.handle = requestAnimFrame(function () {
9821
      self.drawer();
9822
    });
9823
  }
9824
};
9825
9826
/**
9827
 * Draw the SVG at the current instant from the
9828
 * `currentFrame` value. Here is where most of the magic is.
9829
 * The trick is to use the `strokeDashoffset` style property.
9830
 *
9831
 * For optimisation reasons, a new property called `progress`
9832
 * is added in each item of `map`. This one contain the current
9833
 * progress of the path element. Only if the new value is different
9834
 * the new value will be applied to the DOM element. This
9835
 * method save a lot of resources to re-render the SVG. And could
9836
 * be improved if the animation couldn't be played forward.
9837
 *
9838
 */
9839
Vivus.prototype.trace = function () {
9840
  var i, progress, path, currentFrame;
9841
  currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
9842
  for (i = 0; i < this.map.length; i++) {
9843
    path = this.map[i];
9844
    progress = (currentFrame - path.startAt) / path.duration;
9845
    progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress)));
9846
    if (path.progress !== progress) {
9847
      path.progress = progress;
9848
      path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress));
9849
      this.renderPath(i);
9850
    }
9851
  }
9852
};
9853
9854
/**
9855
 * Method forcing the browser to re-render a path element
9856
 * from it's index in the map. Depending on the `forceRender`
9857
 * value.
9858
 * The trick is to replace the path element by it's clone.
9859
 * This practice is not recommended because it's asking more
9860
 * ressources, too much DOM manupulation..
9861
 * but it's the only way to let the magic happen on IE.
9862
 * By default, this fallback is only applied on IE.
9863
 * 
9864
 * @param  {Number} index Path index
9865
 */
9866
Vivus.prototype.renderPath = function (index) {
9867
  if (this.forceRender && this.map && this.map[index]) {
9868
    var pathObj = this.map[index],
9869
        newPath = pathObj.el.cloneNode(true);
9870
    pathObj.el.parentNode.replaceChild(newPath, pathObj.el);
9871
    pathObj.el = newPath;
9872
  }
9873
};
9874
9875
/**
9876
 * When the SVG object is loaded and ready,
9877
 * this method will continue the initialisation.
9878
 *
9879
 * This this mainly due to the case of passing an
9880
 * object tag in the constructor. It will wait
9881
 * the end of the loading to initialise.
9882
 * 
9883
 */
9884
Vivus.prototype.init = function () {
9885
  // Set object variables
9886
  this.frameLength = 0;
9887
  this.currentFrame = 0;
9888
  this.map = [];
9889
9890
  // Start
9891
  new Pathformer(this.el);
9892
  this.mapping();
9893
  this.starter();
9894
9895
  if (this.onReady) {
9896
    this.onReady(this);
9897
  }
9898
};
9899
9900
/**
9901
 * Trigger to start of the animation.
9902
 * Depending on the `start` value, a different script
9903
 * will be applied.
9904
 *
9905
 * If the `start` value is not valid, an error will be thrown.
9906
 * Even if technically, this is impossible.
9907
 *
9908
 */
9909
Vivus.prototype.starter = function () {
9910
  switch (this.start) {
9911
  case 'manual':
9912
    return;
9913
9914
  case 'autostart':
9915
    this.play();
9916
    break;
9917
9918
  case 'inViewport':
9919
    var self = this,
9920
    listener = function () {
9921
      if (self.isInViewport(self.el, 1)) {
9922
        self.play();
9923
        window.removeEventListener('scroll', listener);
9924
      }
9925
    };
9926
    window.addEventListener('scroll', listener);
9927
    listener();
9928
    break;
9929
  }
9930
};
9931
9932
9933
/**
9934
 * Controls
9935
 **************************************
9936
 */
9937
9938
/**
9939
 * Get the current status of the animation between
9940
 * three different states: 'start', 'progress', 'end'.
9941
 * @return {string} Instance status
9942
 */
9943
Vivus.prototype.getStatus = function () {
9944
  return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress';
9945
};
9946
9947
9948
/**
9949
 * Controls
9950
 **************************************
9951
 */
9952
9953
/**
9954
 * Reset the instance to the initial state : undraw
9955
 * Be careful, it just reset the animation, if you're
9956
 * playing the animation, this won't stop it. But just
9957
 * make it start from start.
9958
 *
9959
 */
9960
Vivus.prototype.reset = function () {
9961
  return this.setFrameProgress(0);
9962
};
9963
9964
/**
9965
 * Set the instance to the final state : drawn
9966
 * Be careful, it just set the animation, if you're
9967
 * playing the animation on rewind, this won't stop it.
9968
 * But just make it start from the end.
9969
 *
9970
 */
9971
Vivus.prototype.finish = function () {
9972
  return this.setFrameProgress(1);
9973
};
9974
9975
/**
9976
 * Set the level of progress of the drawing.
9977
 * 
9978
 * @param {number} progress Level of progress to set
9979
 */
9980
Vivus.prototype.setFrameProgress = function (progress) {
9981
  progress = Math.min(1, Math.max(0, progress));
9982
  this.currentFrame = Math.round(this.frameLength * progress);
9983
  this.trace();
9984
  return this;
9985
};
9986
9987
/**
9988
 * Play the animation at the desired speed.
9989
 * Speed must be a valid number (no zero).
9990
 * By default, the speed value is 1.
9991
 * But a negative value is accepted to go forward.
9992
 *
9993
 * And works with float too.
9994
 * But don't forget we are in JavaScript, se be nice
9995
 * with him and give him a 1/2^x value.
9996
 *
9997
 * @param  {number} speed Animation speed [optional]
9998
 */
9999
Vivus.prototype.play = function (speed) {
10000
  if (speed && typeof speed !== 'number') {
10001
    throw new Error('Vivus [play]: invalid speed');
10002
  }
10003
  this.speed = speed || 1;
10004
  if (!this.handle) {
10005
    this.drawer();
10006
  }
10007
  return this;
10008
};
10009
10010
/**
10011
 * Stop the current animation, if on progress.
10012
 * Should not trigger any error.
10013
 *
10014
 */
10015
Vivus.prototype.stop = function () {
10016
  if (this.handle) {
10017
    cancelAnimFrame(this.handle);
10018
    delete this.handle;
10019
  }
10020
  return this;
10021
};
10022
10023
/**
10024
 * Destroy the instance.
10025
 * Remove all bad styling attributes on all
10026
 * path tags
10027
 *
10028
 */
10029
Vivus.prototype.destroy = function () {
10030
  var i, path;
10031
  for (i = 0; i < this.map.length; i++) {
10032
    path = this.map[i];
10033
    path.el.style.strokeDashoffset = null;
10034
    path.el.style.strokeDasharray = null;
10035
    this.renderPath(i);
10036
  }
10037
};
10038
10039
10040
/**
10041
 * Utils methods
10042
 * from Codrops
10043
 **************************************
10044
 */
10045
10046
/**
10047
 * Parse attributes of a DOM element to
10048
 * get an object of {attributeName => attributeValue}
10049
 *
10050
 * @param  {object} element DOM element to parse
10051
 * @return {object}         Object of attributes
10052
 */
10053
Vivus.prototype.parseAttr = function (element) {
10054
  var attr, output = {};
10055
  if (element && element.attributes) {
10056
    for (var i = 0; i < element.attributes.length; i++) {
10057
      attr = element.attributes[i];
10058
      output[attr.name] = attr.value;
10059
    }
10060
  }
10061
  return output;
10062
};
10063
10064
/**
10065
 * Reply if an element is in the page viewport
10066
 *
10067
 * @param  {object} el Element to observe
10068
 * @param  {number} h  Percentage of height
10069
 * @return {boolean}
10070
 */
10071
Vivus.prototype.isInViewport = function (el, h) {
10072
  var scrolled   = this.scrollY(),
10073
    viewed       = scrolled + this.getViewportH(),
10074
    elBCR        = el.getBoundingClientRect(),
10075
    elHeight     = elBCR.height,
10076
    elTop        = scrolled + elBCR.top,
10077
    elBottom     = elTop + elHeight;
10078
10079
  // if 0, the element is considered in the viewport as soon as it enters.
10080
  // if 1, the element is considered in the viewport only when it's fully inside
10081
  // value in percentage (1 >= h >= 0)
10082
  h = h || 0;
10083
10084
  return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled;
10085
};
10086
10087
/**
10088
 * Alias for document element
10089
 *
10090
 * @type {DOMelement}
10091
 */
10092
Vivus.prototype.docElem = window.document.documentElement;
10093
10094
/**
10095
 * Get the viewport height in pixels
10096
 *
10097
 * @return {integer} Viewport height
10098
 */
10099
Vivus.prototype.getViewportH = function () {
10100
  var client = this.docElem.clientHeight,
10101
    inner = window.innerHeight;
10102
10103
  if (client < inner) {
10104
    return inner;
10105
  }
10106
  else {
10107
    return client;
10108
  }
10109
};
10110
10111
/**
10112
 * Get the page Y offset
10113
 *
10114
 * @return {integer} Page Y offset
10115
 */
10116
Vivus.prototype.scrollY = function () {
10117
  return window.pageYOffset || this.docElem.scrollTop;
10118
};
10119
10120
/**
10121
 * Alias for `requestAnimationFrame` or
10122
 * `setTimeout` function for deprecated browsers.
10123
 *
10124
 */
10125
requestAnimFrame = (function () {
10126
  return (
10127
    window.requestAnimationFrame       ||
10128
    window.webkitRequestAnimationFrame ||
10129
    window.mozRequestAnimationFrame    ||
10130
    window.oRequestAnimationFrame      ||
10131
    window.msRequestAnimationFrame     ||
10132
    function(/* function */ callback){
10133
      return window.setTimeout(callback, 1000 / 60);
10134
    }
10135
  );
10136
})();
10137
10138
/**
10139
 * Alias for `cancelAnimationFrame` or
10140
 * `cancelTimeout` function for deprecated browsers.
10141
 *
10142
 */
10143
cancelAnimFrame = (function () {
10144
  return (
10145
    window.cancelAnimationFrame       ||
10146
    window.webkitCancelAnimationFrame ||
10147
    window.mozCancelAnimationFrame    ||
10148
    window.oCancelAnimationFrame      ||
10149
    window.msCancelAnimationFrame     ||
10150
    function(id){
10151
      return window.clearTimeout(id);
10152
    }
10153
  );
10154
})();
10155
10156
/**
10157
 * Parse string to integer.
10158
 * If the number is not positive or null
10159
 * the method will return the default value
10160
 * or 0 if undefined
10161
 *
10162
 * @param {string} value String to parse
10163
 * @param {*} defaultValue Value to return if the result parsed is invalid
10164
 * @return {number}
10165
 *
10166
 */
10167
parsePositiveInt = function (value, defaultValue) {
10168
  var output = parseInt(value, 10);
10169
  return (output >= 0) ? output : defaultValue;
10170
};
10171
10172
10173
  if (typeof define === 'function' && define.amd) {
10174
    // AMD. Register as an anonymous module.
10175
    define([], function() {
10176
      return Vivus;
10177
    });
10178
  } else if (typeof exports === 'object') {
10179
    // Node. Does not work with strict CommonJS, but
10180
    // only CommonJS-like environments that support module.exports,
10181
    // like Node.
10182
    module.exports = Vivus;
10183
  } else {
10184
    // Browser globals
10185
    window.Vivus = Vivus;
10186
  }
10187
10188
}(window, document));
10189
10190
},{}],3:[function(require,module,exports){
10191
var Vivus=require("vivus")
10192
var $=require("jquery")
10193
var ani = new Vivus("intro",{type: 'delayed', duration: 100 /*,file:'svg/logo.svg'*/},function(){$(".svg")[0].setAttribute("class","svg active")})
10194
//ani.play(2)
10195
//$(".svg .circle-container")[0].setAttribute("class","circle-container active")
10196
//$(".svg .circle")[0].setAttribute("class","circle active")
10197
10198
10199
},{"jquery":1,"vivus":2}],4:[function(require,module,exports){
10200
require("./animation.js")
10201
},{"./animation.js":3}]},{},[4])
!
必须是有效的URL
+ 添加另一个资源
Close

文件管理 点击文件查看URL

图片

  1. 暂无文件

CSS

  1. 暂无文件

JavaScript

  1. 暂无文件

其他

  1. 暂无文件
拖动文件到上面的区域或者:
加载中 ..................