Blame view

src/components/tabs/tabs.vue 17.4 KB
871ed4d8   梁灏   init Tabs component
1
  <template>
17f52abf   梁灏   update Tabs
2
3
      <div :class="classes">
          <div :class="[prefixCls + '-bar']">
be3fbd24   marxy   Tabs add scroll
4
              <div :class="[prefixCls + '-nav-right']" v-if="showSlot"><slot name="extra"></slot></div>
7be1069a   Sergio Crisostomo   Add tab navigatio...
5
6
7
8
9
              <div
                  :class="[prefixCls + '-nav-container']"
                  tabindex="0"
                  ref="navContainer"
                  @keydown="handleTabKeyNavigation"
bb6efbaa   Aresn   Update tabs.vue
10
                  @keydown.space.prevent="handleTabKeyboardSelect(false)"
7be1069a   Sergio Crisostomo   Add tab navigatio...
11
              >
67a9c1cc   梁灏   update Tabs
12
                  <div ref="navWrap" :class="[prefixCls + '-nav-wrap', scrollable ? prefixCls + '-nav-scrollable' : '']">
be3fbd24   marxy   Tabs add scroll
13
14
15
16
                      <span :class="[prefixCls + '-nav-prev', scrollable ? '' : prefixCls + '-nav-scroll-disabled']" @click="scrollPrev"><Icon type="chevron-left"></Icon></span>
                      <span :class="[prefixCls + '-nav-next', scrollable ? '' : prefixCls + '-nav-scroll-disabled']" @click="scrollNext"><Icon type="chevron-right"></Icon></span>
                      <div ref="navScroll" :class="[prefixCls + '-nav-scroll']">
                          <div ref="nav" :class="[prefixCls + '-nav']" class="nav-text"  :style="navStyle">
17f52abf   梁灏   update Tabs
17
                              <div :class="barClasses" :style="barStyle"></div>
30510c3d   梁灏   support Tabs
18
                              <div :class="tabCls(item)" v-for="(item, index) in navList" @click="handleChange(index)">
17f52abf   梁灏   update Tabs
19
                                  <Icon v-if="item.icon !== ''" :type="item.icon"></Icon>
1f974700   Aresn   Tabs support rend...
20
21
                                  <Render v-if="item.labelType === 'function'" :render="item.label"></Render>
                                  <template v-else>{{ item.label }}</template>
30510c3d   梁灏   support Tabs
22
                                  <Icon v-if="showClose(item)" type="ios-close-empty" @click.native.stop="handleRemove(index)"></Icon>
17f52abf   梁灏   update Tabs
23
24
                              </div>
                          </div>
17f52abf   梁灏   update Tabs
25
26
27
28
                      </div>
                  </div>
              </div>
          </div>
7be1069a   Sergio Crisostomo   Add tab navigatio...
29
          <div :class="contentClasses" :style="contentStyle" ref="panes"><slot></slot></div>
17f52abf   梁灏   update Tabs
30
      </div>
871ed4d8   梁灏   init Tabs component
31
32
  </template>
  <script>
17f52abf   梁灏   update Tabs
33
      import Icon from '../icon/icon.vue';
55dbf62d   Aresn   update Tabs render
34
      import Render from '../base/render';
3be0aa12   Kang Cheng   Import custom Mut...
35
      import { oneOf, MutationObserver } from '../../utils/assist';
67c9b1c8   梁灏   fixed #591
36
      import Emitter from '../../mixins/emitter';
be3fbd24   marxy   Tabs add scroll
37
      import elementResizeDetectorMaker from 'element-resize-detector';
17f52abf   梁灏   update Tabs
38
39
  
      const prefixCls = 'ivu-tabs';
7be1069a   Sergio Crisostomo   Add tab navigatio...
40
41
42
43
44
45
      const transitionTime = 300; // from CSS
  
      const getNextTab = (list, activeKey, direction, countDisabledAlso) => {
          const currentIndex = list.findIndex(tab => tab.name === activeKey);
          const nextIndex = (currentIndex + direction + list.length) % list.length;
          const nextTab = list[nextIndex];
45dbc6fd   Sergio Crisostomo   Correct disabled ...
46
          if (nextTab.disabled) return getNextTab(list, nextTab.name, direction, countDisabledAlso);
7be1069a   Sergio Crisostomo   Add tab navigatio...
47
48
49
50
51
          else return nextTab;
      };
  
      const focusFirst = (element, root) => {
          try {element.focus();}
2f40e7ea   Sergio Crisostomo   add eslint-disabl...
52
          catch(err) {} // eslint-disable-line no-empty
7be1069a   Sergio Crisostomo   Add tab navigatio...
53
54
55
56
57
58
59
60
61
  
          if (document.activeElement == element && element !== root) return true;
  
          const candidates = element.children;
          for (let candidate of candidates) {
              if (focusFirst(candidate, root)) return true;
          }
          return false;
      };
17f52abf   梁灏   update Tabs
62
  
871ed4d8   梁灏   init Tabs component
63
      export default {
30510c3d   梁灏   support Tabs
64
          name: 'Tabs',
67c9b1c8   梁灏   fixed #591
65
          mixins: [ Emitter ],
1f974700   Aresn   Tabs support rend...
66
          components: { Icon, Render },
17f52abf   梁灏   update Tabs
67
          props: {
30510c3d   梁灏   support Tabs
68
              value: {
17f52abf   梁灏   update Tabs
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
                  type: [String, Number]
              },
              type: {
                  validator (value) {
                      return oneOf(value, ['line', 'card']);
                  },
                  default: 'line'
              },
              size: {
                  validator (value) {
                      return oneOf(value, ['small', 'default']);
                  },
                  default: 'default'
              },
              animated: {
                  type: Boolean,
                  default: true
              },
28026b3f   Sergio Crisostomo   Fix 3732 - add pr...
87
88
89
90
              captureFocus: {
                  type: Boolean,
                  default: false
              },
17f52abf   梁灏   update Tabs
91
92
93
94
95
              closable: {
                  type: Boolean,
                  default: false
              }
          },
871ed4d8   梁灏   init Tabs component
96
          data () {
17f52abf   梁灏   update Tabs
97
98
99
100
              return {
                  prefixCls: prefixCls,
                  navList: [],
                  barWidth: 0,
30510c3d   梁灏   support Tabs
101
                  barOffset: 0,
c4eb5dcf   H   tabs组件导航区添加右侧slot...
102
                  activeKey: this.value,
7be1069a   Sergio Crisostomo   Add tab navigatio...
103
                  focusedKey: this.value,
be3fbd24   marxy   Tabs add scroll
104
                  showSlot: false,
a730a849   梁灏   update Tabs
105
                  navStyle: {
be3fbd24   marxy   Tabs add scroll
106
107
                      transform: ''
                  },
7be1069a   Sergio Crisostomo   Add tab navigatio...
108
109
                  scrollable: false,
                  transitioning: false,
b0893113   jingsam   :art: add eslint
110
              };
17f52abf   梁灏   update Tabs
111
112
113
114
115
116
117
118
119
120
          },
          computed: {
              classes () {
                  return [
                      `${prefixCls}`,
                      {
                          [`${prefixCls}-card`]: this.type === 'card',
                          [`${prefixCls}-mini`]: this.size === 'small' && this.type === 'line',
                          [`${prefixCls}-no-animation`]: !this.animated
                      }
b0893113   jingsam   :art: add eslint
121
                  ];
17f52abf   梁灏   update Tabs
122
123
124
125
              },
              contentClasses () {
                  return [
                      `${prefixCls}-content`,
77bafb31   梁灏   update Tabs
126
127
128
                      {
                          [`${prefixCls}-content-animated`]: this.animated
                      }
b0893113   jingsam   :art: add eslint
129
                  ];
17f52abf   梁灏   update Tabs
130
131
132
133
              },
              barClasses () {
                  return [
                      `${prefixCls}-ink-bar`,
77bafb31   梁灏   update Tabs
134
135
136
                      {
                          [`${prefixCls}-ink-bar-animated`]: this.animated
                      }
b0893113   jingsam   :art: add eslint
137
                  ];
17f52abf   梁灏   update Tabs
138
139
              },
              contentStyle () {
e45d1bce   Sergio Crisostomo   fix too early vis...
140
                  const x = this.getTabIndex(this.activeKey);
17f52abf   梁灏   update Tabs
141
142
143
144
145
146
                  const p = x === 0 ? '0%' : `-${x}00%`;
  
                  let style = {};
                  if (x > -1) {
                      style = {
                          transform: `translateX(${p}) translateZ(0px)`
b0893113   jingsam   :art: add eslint
147
                      };
17f52abf   梁灏   update Tabs
148
149
150
151
152
                  }
                  return style;
              },
              barStyle () {
                  let style = {
3ce6b446   Sergio Crisostomo   Use visibility in...
153
                      visibility: 'hidden',
77bafb31   梁灏   update Tabs
154
                      width: `${this.barWidth}px`
17f52abf   梁灏   update Tabs
155
                  };
e906d570   Aresn   Update tabs.vue
156
                  if (this.type === 'line') style.visibility = 'visible';
77bafb31   梁灏   update Tabs
157
158
159
160
161
                  if (this.animated) {
                      style.transform = `translate3d(${this.barOffset}px, 0px, 0px)`;
                  } else {
                      style.left = `${this.barOffset}px`;
                  }
17f52abf   梁灏   update Tabs
162
163
164
165
166
167
168
169
170
171
172
173
  
                  return style;
              }
          },
          methods: {
              getTabs () {
                  return this.$children.filter(item => item.$options.name === 'TabPane');
              },
              updateNav () {
                  this.navList = [];
                  this.getTabs().forEach((pane, index) => {
                      this.navList.push({
1f974700   Aresn   Tabs support rend...
174
                          labelType: typeof pane.label,
17f52abf   梁灏   update Tabs
175
176
                          label: pane.label,
                          icon: pane.icon || '',
30510c3d   梁灏   support Tabs
177
                          name: pane.currentName || index,
7a737482   梁灏   fixed #206
178
179
                          disabled: pane.disabled,
                          closable: pane.closable
17f52abf   梁灏   update Tabs
180
                      });
30510c3d   梁灏   support Tabs
181
                      if (!pane.currentName) pane.currentName = index;
17f52abf   梁灏   update Tabs
182
                      if (index === 0) {
30510c3d   梁灏   support Tabs
183
                          if (!this.activeKey) this.activeKey = pane.currentName || index;
17f52abf   梁灏   update Tabs
184
185
                      }
                  });
77bafb31   梁灏   update Tabs
186
                  this.updateStatus();
17f52abf   梁灏   update Tabs
187
188
189
190
                  this.updateBar();
              },
              updateBar () {
                  this.$nextTick(() => {
e45d1bce   Sergio Crisostomo   fix too early vis...
191
                      const index = this.getTabIndex(this.activeKey);
2993f4ee   梁灏   update Tab
192
                      if (!this.$refs.nav) return;  // 页面销毁时,这里会报错,为了解决 #2100
30510c3d   梁灏   support Tabs
193
                      const prevTabs = this.$refs.nav.querySelectorAll(`.${prefixCls}-tab`);
17f52abf   梁灏   update Tabs
194
                      const tab = prevTabs[index];
bdfab3b9   梁灏   fixed #1842
195
                      this.barWidth = tab ? parseFloat(tab.offsetWidth) : 0;
17f52abf   梁灏   update Tabs
196
197
198
199
200
  
                      if (index > 0) {
                          let offset = 0;
                          const gutter = this.size === 'small' ? 0 : 16;
                          for (let i = 0; i < index; i++) {
75798f5b   erhuluanzi   getComputedStyle在...
201
                              offset += parseFloat(prevTabs[i].offsetWidth) + gutter;
17f52abf   梁灏   update Tabs
202
203
204
205
206
207
                          }
  
                          this.barOffset = offset;
                      } else {
                          this.barOffset = 0;
                      }
be3fbd24   marxy   Tabs add scroll
208
                      this.updateNavScroll();
17f52abf   梁灏   update Tabs
209
210
                  });
              },
77bafb31   梁灏   update Tabs
211
212
              updateStatus () {
                  const tabs = this.getTabs();
30510c3d   梁灏   support Tabs
213
                  tabs.forEach(tab => tab.show = (tab.currentName === this.activeKey) || this.animated);
77bafb31   梁灏   update Tabs
214
              },
17f52abf   梁灏   update Tabs
215
216
217
218
219
              tabCls (item) {
                  return [
                      `${prefixCls}-tab`,
                      {
                          [`${prefixCls}-tab-disabled`]: item.disabled,
7be1069a   Sergio Crisostomo   Add tab navigatio...
220
221
                          [`${prefixCls}-tab-active`]: item.name === this.activeKey,
                          [`${prefixCls}-tab-focused`]: item.name === this.focusedKey,
17f52abf   梁灏   update Tabs
222
                      }
b0893113   jingsam   :art: add eslint
223
                  ];
17f52abf   梁灏   update Tabs
224
225
              },
              handleChange (index) {
7be1069a   Sergio Crisostomo   Add tab navigatio...
226
227
228
229
230
                  if (this.transitioning) return;
  
                  this.transitioning = true;
                  setTimeout(() => this.transitioning = false, transitionTime);
  
17f52abf   梁灏   update Tabs
231
232
                  const nav = this.navList[index];
                  if (nav.disabled) return;
30510c3d   梁灏   support Tabs
233
234
235
                  this.activeKey = nav.name;
                  this.$emit('input', nav.name);
                  this.$emit('on-click', nav.name);
17f52abf   梁灏   update Tabs
236
              },
7be1069a   Sergio Crisostomo   Add tab navigatio...
237
238
239
240
241
242
              handleTabKeyNavigation(e){
                  if (e.keyCode !== 37 && e.keyCode !== 39) return;
                  const direction = e.keyCode === 39 ? 1 : -1;
                  const nextTab = getNextTab(this.navList, this.focusedKey, direction);
                  this.focusedKey = nextTab.name;
              },
8b410220   Aresn   handleTabKeyboard...
243
244
              handleTabKeyboardSelect(init = false){
                  if (init) return;
38ab7442   Sergio Crisostomo   Correct logic for...
245
                  const focused = this.focusedKey || 0;
e45d1bce   Sergio Crisostomo   fix too early vis...
246
                  const index = this.getTabIndex(focused);
38ab7442   Sergio Crisostomo   Correct logic for...
247
                  this.handleChange(index);
7be1069a   Sergio Crisostomo   Add tab navigatio...
248
              },
17f52abf   梁灏   update Tabs
249
250
251
              handleRemove (index) {
                  const tabs = this.getTabs();
                  const tab = tabs[index];
087ad37d   梁灏   update Tabs
252
                  tab.$destroy();
17f52abf   梁灏   update Tabs
253
  
30510c3d   梁灏   support Tabs
254
                  if (tab.currentName === this.activeKey) {
17f52abf   梁灏   update Tabs
255
256
257
258
259
260
261
262
                      const newTabs = this.getTabs();
                      let activeKey = -1;
  
                      if (newTabs.length) {
                          const leftNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex < index);
                          const rightNoDisabledTabs = tabs.filter((item, itemIndex) => !item.disabled && itemIndex > index);
  
                          if (rightNoDisabledTabs.length) {
30510c3d   梁灏   support Tabs
263
                              activeKey = rightNoDisabledTabs[0].currentName;
17f52abf   梁灏   update Tabs
264
                          } else if (leftNoDisabledTabs.length) {
30510c3d   梁灏   support Tabs
265
                              activeKey = leftNoDisabledTabs[leftNoDisabledTabs.length - 1].currentName;
17f52abf   梁灏   update Tabs
266
                          } else {
30510c3d   梁灏   support Tabs
267
                              activeKey = newTabs[0].currentName;
17f52abf   梁灏   update Tabs
268
269
270
                          }
                      }
                      this.activeKey = activeKey;
087ad37d   梁灏   update Tabs
271
                      this.$emit('input', activeKey);
17f52abf   梁灏   update Tabs
272
                  }
30510c3d   梁灏   support Tabs
273
                  this.$emit('on-tab-remove', tab.currentName);
17f52abf   梁灏   update Tabs
274
                  this.updateNav();
7a737482   梁灏   fixed #206
275
276
277
278
279
280
281
282
283
284
285
              },
              showClose (item) {
                  if (this.type === 'card') {
                      if (item.closable !== null) {
                          return item.closable;
                      } else {
                          return this.closable;
                      }
                  } else {
                      return false;
                  }
be3fbd24   marxy   Tabs add scroll
286
287
288
289
290
291
292
293
              },
              scrollPrev() {
                  const containerWidth = this.$refs.navScroll.offsetWidth;
                  const currentOffset = this.getCurrentScrollOffset();
  
                  if (!currentOffset) return;
  
                  let newOffset = currentOffset > containerWidth
a74be22e   Sergio Crisostomo   don't check DOM t...
294
295
                      ? currentOffset - containerWidth
                      : 0;
be3fbd24   marxy   Tabs add scroll
296
297
298
299
300
301
302
303
304
305
  
                  this.setOffset(newOffset);
              },
              scrollNext() {
                  const navWidth = this.$refs.nav.offsetWidth;
                  const containerWidth = this.$refs.navScroll.offsetWidth;
                  const currentOffset = this.getCurrentScrollOffset();
                  if (navWidth - currentOffset <= containerWidth) return;
  
                  let newOffset = navWidth - currentOffset > containerWidth * 2
a74be22e   Sergio Crisostomo   don't check DOM t...
306
307
                      ? currentOffset + containerWidth
                      : (navWidth - containerWidth);
be3fbd24   marxy   Tabs add scroll
308
309
310
311
312
313
  
                  this.setOffset(newOffset);
              },
              getCurrentScrollOffset() {
                  const { navStyle } = this;
                  return navStyle.transform
a74be22e   Sergio Crisostomo   don't check DOM t...
314
315
                      ? Number(navStyle.transform.match(/translateX\(-(\d+(\.\d+)*)px\)/)[1])
                      : 0;
be3fbd24   marxy   Tabs add scroll
316
              },
e45d1bce   Sergio Crisostomo   fix too early vis...
317
318
319
              getTabIndex(name){
                  return this.navList.findIndex(nav => nav.name === name);
              },
be3fbd24   marxy   Tabs add scroll
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
              setOffset(value) {
                  this.navStyle.transform = `translateX(-${value}px)`;
              },
              scrollToActiveTab() {
                  if (!this.scrollable) return;
                  const nav = this.$refs.nav;
                  const activeTab = this.$el.querySelector(`.${prefixCls}-tab-active`);
                  if(!activeTab) return;
  
                  const navScroll = this.$refs.navScroll;
                  const activeTabBounding = activeTab.getBoundingClientRect();
                  const navScrollBounding = navScroll.getBoundingClientRect();
                  const navBounding = nav.getBoundingClientRect();
                  const currentOffset = this.getCurrentScrollOffset();
                  let newOffset = currentOffset;
  
                  if (navBounding.right < navScrollBounding.right) {
                      newOffset = nav.offsetWidth - navScrollBounding.width;
                  }
  
                  if (activeTabBounding.left < navScrollBounding.left) {
                      newOffset = currentOffset - (navScrollBounding.left - activeTabBounding.left);
                  }else if (activeTabBounding.right > navScrollBounding.right) {
                      newOffset = currentOffset + activeTabBounding.right - navScrollBounding.right;
                  }
  
                  if(currentOffset !== newOffset){
                      this.setOffset(Math.max(newOffset, 0));
                  }
              },
              updateNavScroll(){
                  const navWidth = this.$refs.nav.offsetWidth;
                  const containerWidth = this.$refs.navScroll.offsetWidth;
                  const currentOffset = this.getCurrentScrollOffset();
                  if (containerWidth < navWidth) {
                      this.scrollable = true;
                      if (navWidth - currentOffset < containerWidth) {
                          this.setOffset(navWidth - containerWidth);
                      }
                  } else {
                      this.scrollable = false;
                      if (currentOffset > 0) {
                          this.setOffset(0);
                      }
                  }
              },
              handleResize(){
                  this.updateNavScroll();
79885751   Kang Cheng   fix issue #1846
368
369
370
              },
              isInsideHiddenElement () {
                  let parentNode = this.$el.parentNode;
a74be22e   Sergio Crisostomo   don't check DOM t...
371
                  while(parentNode && parentNode !== document.body) {
a90d1a20   yangdan8   解决isInsideHiddenE...
372
                      if (parentNode.style && parentNode.style.display === 'none') {
79885751   Kang Cheng   fix issue #1846
373
374
375
376
377
                          return parentNode;
                      }
                      parentNode = parentNode.parentNode;
                  }
                  return false;
e45d1bce   Sergio Crisostomo   fix too early vis...
378
379
380
381
382
              },
              updateVisibility(index){
                  [...this.$refs.panes.children].forEach((el, i) => {
                      if (index === i) {
                          [...el.children].forEach(child => child.style.visibility = 'visible');
28026b3f   Sergio Crisostomo   Fix 3732 - add pr...
383
                          if (this.captureFocus) setTimeout(() => focusFirst(el, el), transitionTime);
e45d1bce   Sergio Crisostomo   fix too early vis...
384
385
386
387
388
389
                      } else {
                          setTimeout(() => {
                              [...el.children].forEach(child => child.style.visibility = 'hidden');
                          }, transitionTime);
                      }
                  });
17f52abf   梁灏   update Tabs
390
391
              }
          },
17f52abf   梁灏   update Tabs
392
          watch: {
30510c3d   梁灏   support Tabs
393
394
              value (val) {
                  this.activeKey = val;
7be1069a   Sergio Crisostomo   Add tab navigatio...
395
                  this.focusedKey = val;
30510c3d   梁灏   support Tabs
396
              },
7be1069a   Sergio Crisostomo   Add tab navigatio...
397
398
              activeKey (val) {
                  this.focusedKey = val;
17f52abf   梁灏   update Tabs
399
                  this.updateBar();
0c5e01f1   梁灏   fixed #185
400
                  this.updateStatus();
67c9b1c8   梁灏   fixed #591
401
                  this.broadcast('Table', 'on-visible-change', true);
a730a849   梁灏   update Tabs
402
                  this.$nextTick(() => {
be3fbd24   marxy   Tabs add scroll
403
404
                      this.scrollToActiveTab();
                  });
38ab7442   Sergio Crisostomo   Correct logic for...
405
406
  
                  // update visibility
e45d1bce   Sergio Crisostomo   fix too early vis...
407
408
                  const nextIndex = Math.max(this.getTabIndex(this.focusedKey), 0);
                  this.updateVisibility(nextIndex);
17f52abf   梁灏   update Tabs
409
              }
c4eb5dcf   H   tabs组件导航区添加右侧slot...
410
          },
8e4f708f   梁灏   update Tabs
411
412
          mounted () {
              this.showSlot = this.$slots.extra !== undefined;
be3fbd24   marxy   Tabs add scroll
413
414
              this.observer = elementResizeDetectorMaker();
              this.observer.listenTo(this.$refs.navWrap, this.handleResize);
79885751   Kang Cheng   fix issue #1846
415
416
417
  
              const hiddenParentNode = this.isInsideHiddenElement();
              if (hiddenParentNode) {
3be0aa12   Kang Cheng   Import custom Mut...
418
                  this.mutationObserver = new MutationObserver(() => {
79885751   Kang Cheng   fix issue #1846
419
420
                      if (hiddenParentNode.style.display !== 'none') {
                          this.updateBar();
3be0aa12   Kang Cheng   Import custom Mut...
421
                          this.mutationObserver.disconnect();
79885751   Kang Cheng   fix issue #1846
422
423
424
                      }
                  });
  
3be0aa12   Kang Cheng   Import custom Mut...
425
                  this.mutationObserver.observe(hiddenParentNode, { attributes: true, childList: true, characterData: true, attributeFilter: ['style'] });
79885751   Kang Cheng   fix issue #1846
426
              }
45dbc6fd   Sergio Crisostomo   Correct disabled ...
427
  
8b410220   Aresn   handleTabKeyboard...
428
              this.handleTabKeyboardSelect(true);
e45d1bce   Sergio Crisostomo   fix too early vis...
429
              this.updateVisibility(this.getTabIndex(this.activeKey));
be3fbd24   marxy   Tabs add scroll
430
431
432
          },
          beforeDestroy() {
              this.observer.removeListener(this.$refs.navWrap, this.handleResize);
9b6f316e   梁灏   fixed Tabs bug
433
              if (this.mutationObserver) this.mutationObserver.disconnect();
17f52abf   梁灏   update Tabs
434
          }
b0893113   jingsam   :art: add eslint
435
436
      };
  </script>