@subiz/widget-v4 4.1.209 → 4.1.211

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +21 -2
  2. package/assets/less/chatbox.less +9 -0
  3. package/assets/less/form.less +10 -0
  4. package/assets/less/message.less +114 -13
  5. package/assets/less/widget.less +21 -16
  6. package/compiled_src/call/css.js +1 -1
  7. package/compiled_src/chatbox/Buttons.js +7 -4
  8. package/compiled_src/chatbox/ChatButton.js +115 -29
  9. package/compiled_src/chatbox/Event.js +37 -5
  10. package/compiled_src/chatbox/Events.js +348 -129
  11. package/compiled_src/chatbox/FormAttachment.js +1 -1
  12. package/compiled_src/chatbox/Header.js +6 -2
  13. package/compiled_src/chatbox/InfoMessage.js +1 -1
  14. package/compiled_src/chatbox/MessageInput.js +24 -9
  15. package/compiled_src/chatbox/OrderAttachments.js +13 -13
  16. package/compiled_src/chatbox/QuoteMessage.js +3 -2
  17. package/compiled_src/chatbox/TextMessage.js +22 -18
  18. package/compiled_src/chatbox/Widget.js +200 -129
  19. package/compiled_src/chatbox/block.js +39 -29
  20. package/compiled_src/chatbox/conversation-history.js +44 -0
  21. package/compiled_src/chatbox/event-layout.js +59 -0
  22. package/compiled_src/chatbox/greeting.js +32 -0
  23. package/compiled_src/common.js +13 -9
  24. package/compiled_src/form/css.js +1 -1
  25. package/compiled_src/lib.js +22 -32
  26. package/compiled_src/notif/css.js +1 -1
  27. package/compiled_src/plugin.js +11 -18
  28. package/compiled_src/popup/css.js +1 -1
  29. package/compiled_src/popup/popup.js +1 -1
  30. package/compiled_src/store/api.js +0 -2
  31. package/compiled_src/store/api_fake.js +1 -1
  32. package/compiled_src/store/attachments.js +28 -0
  33. package/compiled_src/store/chain.js +24 -10
  34. package/compiled_src/store/kv.js +9 -13
  35. package/compiled_src/store/lsdb.js +1 -1
  36. package/compiled_src/store/store.js +356 -117
  37. package/compiled_src/util/common.js +48 -41
  38. package/compiled_src/util/event.js +15 -0
  39. package/compiled_src/util/pubsub.js +28 -13
  40. package/compiled_src/util/url.js +18 -0
  41. package/dist/.HASH +1 -0
  42. package/dist/127.js +13 -13
  43. package/dist/132.js +1 -1
  44. package/dist/1a0ddc53cbb.127.js +1 -0
  45. package/dist/{1a08405c848.132.js → 1a0ddc53cbb.132.js} +1 -1
  46. package/dist/{1a08405c848.27.js → 1a0ddc53cbb.27.js} +1 -1
  47. package/dist/1a0ddc53cbb.278.js +1 -0
  48. package/dist/{1a08405c848.339.js → 1a0ddc53cbb.339.js} +1 -1
  49. package/dist/1a0ddc53cbb.459.js +1 -0
  50. package/dist/1a0ddc53cbb.app.js +1 -0
  51. package/dist/1a0ddc53cbb.chat.html +1 -0
  52. package/dist/1a0ddc53cbb.chat.js +1 -0
  53. package/dist/1a0ddc53cbb.form.html +1 -0
  54. package/dist/1a0ddc53cbb.form.js +1 -0
  55. package/dist/1a0ddc53cbb.index.html +72 -0
  56. package/dist/1a0ddc53cbb.library.html +72 -0
  57. package/dist/1a0ddc53cbb.library.js +1 -0
  58. package/dist/1a0ddc53cbb.preview.html +759 -0
  59. package/dist/1a0ddc53cbb.preview.js +1 -0
  60. package/dist/1a0ddc53cbb.webview.js +1 -0
  61. package/dist/27.js +4 -4
  62. package/dist/459.js +4 -4
  63. package/dist/screenshoot.js +1523 -654
  64. package/package.json +10 -3
  65. package/src/call/css.js +1 -1
  66. package/src/chatbox/Buttons.js +5 -4
  67. package/src/chatbox/ChatButton.js +120 -39
  68. package/src/chatbox/Event.js +38 -5
  69. package/src/chatbox/Events.js +306 -134
  70. package/src/chatbox/FormAttachment.js +1 -1
  71. package/src/chatbox/Header.js +4 -4
  72. package/src/chatbox/InfoMessage.js +1 -1
  73. package/src/chatbox/MessageInput.js +15 -10
  74. package/src/chatbox/OrderAttachments.js +13 -13
  75. package/src/chatbox/QuoteMessage.js +3 -2
  76. package/src/chatbox/TextMessage.js +21 -20
  77. package/src/chatbox/Widget.js +150 -150
  78. package/src/chatbox/block.js +29 -27
  79. package/src/chatbox/conversation-history.js +37 -0
  80. package/src/chatbox/event-layout.js +72 -0
  81. package/src/chatbox/greeting.js +13 -0
  82. package/src/common.js +15 -9
  83. package/src/form/css.js +1 -1
  84. package/src/lib.js +22 -35
  85. package/src/notif/css.js +1 -1
  86. package/src/plugin.js +11 -13
  87. package/src/popup/css.js +1 -1
  88. package/src/popup/popup.js +1 -1
  89. package/src/store/api.js +0 -2
  90. package/src/store/api_fake.js +1 -1
  91. package/src/store/attachments.js +21 -0
  92. package/src/store/chain.js +25 -12
  93. package/src/store/kv.js +10 -19
  94. package/src/store/lsdb.js +1 -1
  95. package/src/store/store.js +313 -130
  96. package/src/util/common.js +48 -43
  97. package/src/util/event.js +7 -0
  98. package/src/util/pubsub.js +27 -8
  99. package/src/util/url.js +14 -0
  100. package/test.cjs +59 -0
  101. package/webpack.prod.js +3 -0
  102. package/assets/less/contact.less +0 -126
  103. package/compiled_src/util/common.test.js +0 -414
  104. package/compiled_src/util/event.test.js +0 -38
  105. package/compiled_src/util/extractor.test.js +0 -299
  106. package/compiled_src/util/extractor.test2.js +0 -61
  107. package/compiled_src/util/gate.test.js +0 -18
  108. package/compiled_src/util/pubsub.test.js +0 -35
  109. package/dist/1a08405c848.127.js +0 -1
  110. package/dist/1a08405c848.278.js +0 -1
  111. package/dist/1a08405c848.459.js +0 -1
  112. package/dist/1a08405c848.74.js +0 -1
  113. package/dist/1a08405c848.997.js +0 -1
  114. package/dist/1a08405c848.app.js +0 -1
  115. package/dist/1a08405c848.chat.html +0 -1
  116. package/dist/1a08405c848.chat.js +0 -1
  117. package/dist/1a08405c848.form.html +0 -1
  118. package/dist/1a08405c848.form.js +0 -1
  119. package/dist/1a08405c848.index.html +0 -1
  120. package/dist/1a08405c848.library.html +0 -1
  121. package/dist/1a08405c848.library.js +0 -1
  122. package/dist/1a08405c848.preview.html +0 -1
  123. package/dist/1a08405c848.preview.js +0 -1
  124. package/dist/1a08405c848.webview.js +0 -1
  125. package/dist/74.js +0 -376
  126. package/dist/997.js +0 -37
  127. package/dist/HASH +0 -1
  128. package/src/contact/contact.js +0 -400
  129. package/src/contact/css.js +0 -1
  130. package/src/util/common.test.js +0 -301
  131. package/src/util/event.test.js +0 -31
  132. package/src/util/extractor.test.js +0 -240
  133. package/src/util/extractor.test2.js +0 -56
  134. package/src/util/gate.test.js +0 -20
  135. package/src/util/pubsub.test.js +0 -37
  136. /package/dist/{1a08405c848.185.js → 1a0ddc53cbb.185.js} +0 -0
  137. /package/dist/{1a08405c848.490.js → 1a0ddc53cbb.490.js} +0 -0
@@ -197,7 +197,13 @@ export function pipeExtracts(text, extractors) {
197
197
  }
198
198
 
199
199
  export function extractText(text) {
200
- var link = extractLinks
200
+ var link = (value) => {
201
+ const emails = extractEmails(value)
202
+ return extractLinks(value).map((span) => {
203
+ const matched = value.substr(span.index, span.length)
204
+ return {...span, length: matched.replace(/[.,;!?]+$/, '').length}
205
+ }).filter((span) => !emails.some((email) => span.index >= email.index && span.index + span.length <= email.index + email.length))
206
+ }
201
207
  link.type = 'link'
202
208
 
203
209
  var email = extractEmails
@@ -209,7 +215,8 @@ export function extractText(text) {
209
215
  var emoji = extractEmojis
210
216
  emoji.type = 'emoji'
211
217
 
212
- // extractLinks prefered over extractEmails becase some link is https://example.com/@something.vn would detect this is email over link
218
+ // Keep full URLs containing @ ahead of email extraction, while allowing
219
+ // standalone email addresses to become mailto links.
213
220
  return pipeExtracts(text, [link, email, phone, emoji])
214
221
  }
215
222
 
@@ -526,8 +533,15 @@ export function orderByF(a, f, d) {
526
533
  }
527
534
 
528
535
  export function isPhone(phone) {
529
- var re = /^[\+]?[(]?[0-9]{2,3}[)]?[-\s\.]?[0-9]{3,4}[-\s\.]?[0-9]{4,6}$/im
530
- return re.test(String(phone))
536
+ if (typeof phone !== 'string' && typeof phone !== 'number') return false
537
+ const value = String(phone).trim()
538
+ // Allow common display separators, but validate the entire value (no multiline matches).
539
+ const ungrouped = value.replace(/\((\d+)\)/g, '$1')
540
+ if (!/^\+?\d+(?:[ .-]\d+)*$/.test(ungrouped)) return false
541
+ const digits = value.replace(/\D/g, '')
542
+ if (digits.length < 7 || digits.length > 15 || /^(\d)\1+$/.test(digits)) return false
543
+ if (value.startsWith('+') && digits.startsWith('0')) return false
544
+ return true
531
545
  }
532
546
 
533
547
  export function isURL(url) {
@@ -541,9 +555,18 @@ export function isNumber(num) {
541
555
  }
542
556
 
543
557
  export function isEmail(email) {
558
+ if (typeof email !== 'string') return false
559
+ const value = email.trim()
560
+ if (value.length > 254) return false
561
+ const at = value.lastIndexOf('@')
562
+ const local = value.slice(0, at)
563
+ const domain = value.slice(at + 1)
564
+ if (!local || local.length > 64) return false
565
+ if (!local.startsWith('"') && (local.startsWith('.') || local.endsWith('.') || local.includes('..'))) return false
566
+ if (!domain.startsWith('[') && domain.split('.').some(label => label.length > 63 || !/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i.test(label))) return false
544
567
  const re =
545
568
  /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
546
- return re.test(String(email).toLowerCase())
569
+ return re.test(value.toLowerCase())
547
570
  }
548
571
 
549
572
  export function last(array) {
@@ -888,7 +911,7 @@ export function js2css(js, onlyprops, variables) {
888
911
 
889
912
  function browserName() {
890
913
  // Opera 8.0+
891
- var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0
914
+ var isOpera = (!!window.opr && !!window.opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0
892
915
 
893
916
  // Firefox 1.0+
894
917
  var isFirefox = typeof InstallTrigger !== 'undefined'
@@ -1040,11 +1063,11 @@ export function checkRunConditions(freq, conds, lastrun, store) {
1040
1063
  let attributes = op.get(store.matchUser(), 'attributes', [])
1041
1064
  let emailAttr = find(
1042
1065
  attributes,
1043
- (att) => att.key === 'emails' && attr.text && att.key === 'related_email' && attr.text,
1066
+ (att) => (att.key === 'emails' || att.key === 'related_email') && att.text,
1044
1067
  )
1045
1068
  let phoneAttr = find(
1046
1069
  attributes,
1047
- (att) => att.key === 'phones' && attr.text && att.key === 'related_phone' && attr.text,
1070
+ (att) => (att.key === 'phones' || att.key === 'related_phone') && att.text,
1048
1071
  )
1049
1072
  let hasContact = emailAttr || phoneAttr
1050
1073
  if (cond.user_is_a_contact) {
@@ -1397,8 +1420,7 @@ export function unicodeToAscii(str) {
1397
1420
  return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
1398
1421
  }
1399
1422
 
1400
- export function scrollIntoViewIfNeeded($ele) {
1401
- centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded
1423
+ export function scrollIntoViewIfNeeded($ele, centerIfNeeded = true) {
1402
1424
 
1403
1425
  var parent = $ele.parentNode
1404
1426
  var parentComputedStyle = window.getComputedStyle(parent, null)
@@ -1445,31 +1467,16 @@ export function blockToText(block) {
1445
1467
  }
1446
1468
 
1447
1469
  export function isBlockEmpty(block) {
1448
- return _isBlockEmpty(block)
1449
- }
1450
-
1451
- function _isBlockEmpty(block = {}) {
1452
- if (!size(block.content)) {
1453
- if ((block.text || '').trim()) return false
1454
- return true
1455
- }
1456
- let result = true
1457
- map(block.content, (content) => {
1458
- result = result && _isBlockEmpty(content)
1459
- })
1460
- return result
1470
+ return isEmptyBlock(block)
1461
1471
  }
1462
1472
 
1463
1473
  function _blockToText(block) {
1464
- if (!block || !block.type) return ''
1474
+ if (!block) return ''
1465
1475
  let out = ''
1466
1476
  if (block.type == 'bullet_list' || block.type == 'ordered_list') {
1467
- map(block.content, (item) => {
1468
- preifx = '\n* '
1469
- if (block.type == 'ordered_list') {
1470
- prefix = i + '\n. '
1471
- }
1472
- out += prefix + blockToText(item).trim()
1477
+ map(block.content, (item, i) => {
1478
+ let prefix = block.type == 'ordered_list' ? '\n' + (Number(i) + 1) + '. ' : '\n* '
1479
+ out += prefix + _blockToText(item).trim()
1473
1480
  })
1474
1481
  return out
1475
1482
  }
@@ -1483,26 +1490,20 @@ function _blockToText(block) {
1483
1490
  block.type == 'text' ||
1484
1491
  block.type == 'link' ||
1485
1492
  block.type == 'mention-agent' ||
1493
+ block.type == 'mention' ||
1486
1494
  block.type == 'dynamic-field'
1487
1495
  ) {
1488
- return out + block.text
1496
+ if (!size(block.content)) return out + (block.text || '')
1489
1497
  }
1490
1498
 
1491
1499
  if (block.type == 'horizontal_rule') return out + '\n---\n'
1492
1500
  if (block.type == 'emoji') {
1493
- let code
1494
- if (size(block.attrs) > 0) code = block.attrs['code']
1495
- if (code == '') code = block.text
1496
-
1497
- if (code != '') {
1498
- let emoji = find(LEXICAL_EMOJI_LIST, (emoji) => emoji.code === code)
1499
- out + op.get(emoji, 'text', code)
1500
- }
1501
- return out
1501
+ return out + (op.get(block, 'attrs.code') || block.text || block.Text || '')
1502
1502
  }
1503
1503
 
1504
- map(block.content, (block) => {
1505
- out += blockToText(block)
1504
+ if (!size(block.content)) return out + (block.text || '')
1505
+ map(block.content, (child) => {
1506
+ out += _blockToText(child)
1506
1507
  })
1507
1508
  return out
1508
1509
  }
@@ -1573,7 +1574,10 @@ function absLink(url) {
1573
1574
  }
1574
1575
 
1575
1576
  export function isEmptyBlock(block) {
1576
- if (!block || !block.type) return true
1577
+ if (!block) return true
1578
+ if (block.type === 'image' && op.get(block, 'image.url')) return false
1579
+ if (block.type === 'emoji' && (op.get(block, 'attrs.code') || block.Text)) return false
1580
+ if (block.type === 'horizontal_rule') return false
1577
1581
  let hasContent =
1578
1582
  size(
1579
1583
  filter(
@@ -1586,6 +1590,7 @@ export function isEmptyBlock(block) {
1586
1590
 
1587
1591
  export function isEmptyMessage(msg) {
1588
1592
  if (!msg) return true
1593
+ if (msg.deleted) return false
1589
1594
  if (!msg.text && isEmptyBlock(msg.block) && isEmptyAttachment(msg)) return true
1590
1595
  return false
1591
1596
  }
@@ -0,0 +1,7 @@
1
+ export function normalizeCdpEvent(type, payload, options) {
2
+ if (type && typeof type === 'object') return type
3
+ let data = {type}
4
+ if (payload !== undefined) data.payload = payload
5
+ if (options && typeof options === 'object') data = Object.assign({}, options, data)
6
+ return data
7
+ }
@@ -1,17 +1,36 @@
1
- var { filter, map } = require('./common.js')
2
-
3
1
  export default class Pubsub {
4
- constructor () {
2
+ constructor() {
5
3
  this.listeners = {}
6
4
  }
7
5
 
8
- publish (topic, payload, payload2, payload3) {
9
- this.listeners[topic] = filter(this.listeners[topic], sub => sub.obj._isMounted)
10
- map(this.listeners[topic], ({ cb }) => cb(payload, payload2, payload3))
6
+ publish(topic, ...payload) {
7
+ const subscriptions = (this.listeners[topic] || []).slice()
8
+ for (const subscription of subscriptions) {
9
+ if (!subscription.obj._isMounted) subscription.unsubscribe()
10
+ if (subscription.active) subscription.cb(...payload)
11
+ }
11
12
  }
12
13
 
13
- on2 (obj, topic, cb) {
14
+ on2(obj, topic, cb) {
15
+ const subscription = {obj, cb, active: true}
16
+ let release = () => {}
17
+ const unsubscribe = () => {
18
+ if (!subscription.active) return
19
+ subscription.active = false
20
+ this.listeners[topic] = (this.listeners[topic] || []).filter((sub) => sub !== subscription)
21
+ if (!this.listeners[topic].length) delete this.listeners[topic]
22
+ release()
23
+ }
24
+ subscription.unsubscribe = unsubscribe
14
25
  if (!this.listeners[topic]) this.listeners[topic] = []
15
- this.listeners[topic].push({ obj, cb })
26
+ this.listeners[topic].push(subscription)
27
+ if (typeof obj.onDispose === 'function') release = obj.onDispose(unsubscribe)
28
+ return unsubscribe
29
+ }
30
+
31
+ clear() {
32
+ for (const subscriptions of Object.values(this.listeners)) {
33
+ for (const subscription of subscriptions.slice()) subscription.unsubscribe()
34
+ }
16
35
  }
17
36
  }
@@ -0,0 +1,14 @@
1
+ // Check protocols before a URL reaches an anchor. Keep relative URLs usable
2
+ // on embedded sites, but reject executable and unknown schemes.
3
+ export function safeUrl(value, image = false) {
4
+ if (typeof value !== 'string') return ''
5
+ const url = value.trim()
6
+ const normalized = url.replace(/[\u0000-\u0020\u007f]/g, '')
7
+ const scheme = normalized.match(/^([a-z][a-z0-9+.-]*):/i)
8
+ if (!scheme) return url
9
+ if (/^https?$/i.test(scheme[1])) return url
10
+ if (!image && /^(mailto|tel)$/i.test(scheme[1])) return url
11
+ if (image && /^blob$/i.test(scheme[1])) return url
12
+ if (image && /^data:image\/(png|jpe?g|gif|webp|avif);base64,/i.test(normalized)) return url
13
+ return ''
14
+ }
package/test.cjs ADDED
@@ -0,0 +1,59 @@
1
+ const fs = require('node:fs')
2
+ const path = require('node:path')
3
+ const Module = require('node:module')
4
+ const babel = require('@babel/core')
5
+ const {JSDOM} = require('jsdom')
6
+
7
+ // Utilities deliberately get native browser APIs from an iframe. Exercise
8
+ // that same setup in tests rather than maintaining a fake copy of the APIs.
9
+ const dom = new JSDOM('<!doctype html><html><head></head><body></body></html>', {
10
+ url: 'https://widget.test/',
11
+ pretendToBeVisual: true,
12
+ })
13
+ global.window = dom.window
14
+ global.document = dom.window.document
15
+ for (const key of ['navigator', 'localStorage', 'XMLHttpRequest', 'Image', 'FileReader', 'CustomEvent']) {
16
+ Object.defineProperty(global, key, {configurable: true, value: dom.window[key]})
17
+ }
18
+
19
+ const source = path.resolve(__dirname, 'src')
20
+ const originalCompile = Module._extensions['.js']
21
+ Module._extensions['.js'] = (module, filename) => {
22
+ if (!filename.startsWith(source + path.sep)) return originalCompile(module, filename)
23
+ const {code} = babel.transformFileSync(filename, {
24
+ configFile: false,
25
+ babelrc: false,
26
+ presets: [['@babel/preset-env', {targets: {node: 'current'}, modules: 'commonjs'}]],
27
+ plugins: [['@babel/plugin-transform-react-jsx', {pragma: 'h'}], '@babel/plugin-proposal-class-properties'],
28
+ })
29
+ module._compile(code, filename)
30
+ }
31
+
32
+ // Webpack resolves these assets in production. Tests only need stable URLs
33
+ // and an empty stylesheet; they do not compile a second application bundle.
34
+ const originalLoad = Module._load
35
+ Module._load = function(request, parent, isMain) {
36
+ if (request.startsWith('css-loader!')) return {default: {toString: () => ''}}
37
+ return originalLoad.call(this, request, parent, isMain)
38
+ }
39
+ for (const extension of ['.svg', '.png', '.jpg', '.gif', '.mp3', '.ogg']) {
40
+ Module._extensions[extension] = (module, filename) => {module.exports = filename}
41
+ }
42
+
43
+ const test = require('tape')
44
+ test.onFinish(() => dom.window.close())
45
+ function loadTests(directory) {
46
+ for (const entry of fs.readdirSync(directory, {withFileTypes: true})) {
47
+ const filename = path.join(directory, entry.name)
48
+ if (entry.isDirectory()) loadTests(filename)
49
+ else if (/\.test(?:2)?\.js$/.test(entry.name)) require(filename)
50
+ }
51
+ }
52
+
53
+ try {
54
+ loadTests(source)
55
+ } catch (error) {
56
+ dom.window.close()
57
+ console.error(error)
58
+ process.exitCode = 1
59
+ }
package/webpack.prod.js CHANGED
@@ -27,6 +27,9 @@ webpackconfig.output.chunkFilename = HASH + '.[name].js'
27
27
  webpackconfig.output.filename = HASH + '.[name].js'
28
28
 
29
29
  webpackconfig.optimization.minimize = true
30
+ // HtmlWebpackPlugin already minifies its output. Webpack's HTML minimizer
31
+ // forwards inline-script metadata to Terser, which rejects the `as` option.
32
+ webpackconfig.optimization.minimizeOptions = {html: false}
30
33
  webpackconfig.mode = 'production'
31
34
  webpackconfig.plugins = [
32
35
  new HtmlWebpackPlugin({
@@ -1,126 +0,0 @@
1
- @spacer: '@spacer';
2
- @spacer0: '@spacer0';
3
- @spacer2: '@spacer2';
4
- @spacer3: '@spacer3';
5
-
6
- @primary_color: '@primary_color';
7
- @text_color: '@text_color';
8
- @font_family: '@font_family';
9
- @font_size: '@font_size';
10
- @background: '@background';
11
-
12
- @z-index: 2000000000;
13
-
14
- // stop client css rule on all elements inside #subiz
15
- /*
16
- #sbz92 * {
17
- all: unset !important;
18
- }
19
-
20
- #sbz92 {
21
- z-index: @z-index + 100 !important;
22
- #makeImportant() !important;
23
- }
24
-
25
- // prevent #subiz inheriting client site styles
26
- div#sbz92 {
27
- all: initial;
28
- }
29
-
30
- // prevent #subiz inheriting client site !important styles
31
- body div#sbz92 {
32
- all: initial !important;
33
- }
34
-
35
- body div#sbz92 .overlay {
36
- position: fixed !important;
37
- user-select: none !important;
38
- }
39
- */
40
-
41
- #sbz92 {
42
- z-index: @z-index + 100 !important;
43
- #makeImportant();
44
- }
45
- #makeImportant() {
46
- @import './base.less';
47
-
48
- .overlay {
49
- // must change to absolute so we can display in a box inside dashboard editor
50
- // widget will override this to be 'fixed'
51
- position: fixed;
52
- top: 0;
53
- left: 0;
54
- bottom: 0;
55
- right: 0;
56
- background: #000c; //@overlay;
57
- z-index: 20000000000100;
58
- overflow: auto;
59
- display: flex; // so .container's margin auto can work
60
- justify-content: center;
61
- align-items: center;
62
- }
63
-
64
- .overlay.overlay__hidden {
65
- display: none;
66
- }
67
-
68
- .map_modal {
69
- max-with: 80%;
70
- max-height: 80%;
71
- width: 400px;
72
- height: 400px;
73
- background: white;
74
- }
75
-
76
- .map_body {
77
- width: 100%;
78
- height: 100%;
79
- display: flex;
80
-
81
- }
82
-
83
- .map_location {
84
- border-bottom: 1px solid lightgray;
85
- padding: 20px;
86
- font-size: 16px;
87
- font-family: 'roboto';
88
- }
89
-
90
- .map_title {
91
- font-size: 18px;
92
- font-weight: 500;
93
- padding: 10px;
94
- text-align: center;
95
- border-bottom: 1px solid lightgray;
96
- font-family: 'roboto';
97
- }
98
-
99
- .map_locations {
100
- border-right: 1px solid lightgray;
101
- width: 200px;
102
- height: 100%;
103
- }
104
-
105
- .sm.contact_button {
106
- width: 40px;
107
- height: 40px;
108
- }
109
-
110
- .lg.contact_button {
111
- width: 60px;
112
- height: 60px;
113
- }
114
-
115
- .contact_button {
116
- width: 50px;
117
- height: 50px;
118
-
119
- display: flex;
120
- align-items: center;
121
- justify-content: center;
122
- border-radius: 50%;
123
- background: pink;
124
- }
125
-
126
- }