Compare commits
	
		
			4678 Commits
		
	
	
		
			bidi-17
			...
			fix-menu-p
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 53184715bc | ||
|  | 7d7682b34e | ||
|  | 83655a749c | ||
|  | b9444e8197 | ||
|  | 5ff70b2a36 | ||
|  | 4ed559af95 | ||
|  | ce529a9b9f | ||
|  | 31e472145c | ||
|  | 1664428429 | ||
|  | 1780cb9b91 | ||
|  | ad32677263 | ||
|  | 0eba4bdd61 | ||
|  | 28238eb5a7 | ||
|  | cce4f6f7f7 | ||
|  | 6bea3dabbb | ||
|  | ea46947054 | ||
|  | 22879f8c23 | ||
|  | 77c4423059 | ||
|  | 62a2a4a9f5 | ||
|  | 59690328e2 | ||
|  | e50ecd613f | ||
|  | d873a6138a | ||
|  | 8093ae8570 | ||
|  | 98ebb02763 | ||
|  | ba22b07dce | ||
|  | d1312703c5 | ||
|  | 8d99a42307 | ||
|  | 3ab93ecdd4 | ||
|  | 8762d0e164 | ||
|  | 2b91edeb74 | ||
|  | 6c49d1aa3f | ||
|  | f07f086d62 | ||
|  | c28862f8c7 | ||
|  | 9cfaf567be | ||
|  | 53f453bf34 | ||
|  | a16032a8ed | ||
|  | 8cec0d8fcd | ||
|  | 6f6f67829b | ||
|  | 94471b6d07 | ||
|  | 7eed9c0584 | ||
|  | 3e717862a4 | ||
|  | 30d88bbe7e | ||
|  | 551e73adef | ||
|  | 99d32c4758 | ||
|  | 9e52c15829 | ||
|  | 71a272f0a6 | ||
|  | 64061c3440 | ||
|  | 3e34d0badb | ||
|  | b2e8474df3 | ||
|  | 73ff7e2de4 | ||
|  | b5d8d34718 | ||
|  | ac44d22cee | ||
|  | 6e8fa12172 | ||
|  | deb9c4ecc0 | ||
|  | 3046798ec5 | ||
|  | c4332658ba | ||
|  | 50e3da0849 | ||
|  | 62cd3b2061 | ||
|  | 7e6dfa7b92 | ||
|  | 7fbebbf361 | ||
|  | 121372802f | ||
|  | 7924907384 | ||
|  | 51d429f9ae | ||
|  | 267aebb9cb | ||
|  | 3f9ebb588e | ||
|  | f424f07e54 | ||
|  | e5a21a3261 | ||
|  | 6f0de7c80e | ||
|  | 3ace7eeafd | ||
|  | eb9f15e4e4 | ||
|  | bc80569fe9 | ||
|  | a147458120 | ||
|  | 6182e22d18 | ||
|  | dda84c5cd5 | ||
|  | 6c15fb6978 | ||
|  | b17b68c44b | ||
|  | afdb15dc58 | ||
|  | 98b4b0dce0 | ||
|  | 70f26e0bea | ||
|  | b6ad396a6c | ||
|  | e44bb57b0e | ||
|  | 5c10b16b65 | ||
|  | 7ec1d42808 | ||
|  | 03e9e89558 | ||
|  | 3057035dec | ||
|  | 4af72cc7ba | ||
|  | f6aee81651 | ||
|  | a22f569ca0 | ||
|  | 8043f5d865 | ||
|  | 2ef50ab71f | ||
|  | 192a4f5e7f | ||
|  | 1af56a7f00 | ||
|  | d2fab7fddd | ||
|  | 1818b0281d | ||
|  | 09973ba8cf | ||
|  | dd3174c40f | ||
|  | f0293b8f52 | ||
|  | d549a9ad92 | ||
|  | 0385c72a8f | ||
|  | e223b20cbd | ||
|  | a0f7e92e40 | ||
|  | c87ff3ca26 | ||
|  | 82672a825d | ||
|  | 98d524e82d | ||
|  | 3d3090a8f2 | ||
|  | 5561e89201 | ||
|  | 9ed96de237 | ||
|  | 0f2420576a | ||
|  | d1b74675d9 | ||
|  | abb81a0bac | ||
|  | 05eb055b8c | ||
|  | e8ddd6d16d | ||
|  | 8706998c8c | ||
|  | 06e0869767 | ||
|  | 7841fc6d3e | ||
|  | 1f7311deeb | ||
|  | 07a9e69e7b | ||
|  | 9bc8adc715 | ||
|  | 7845ebffc5 | ||
|  | b985de6df2 | ||
|  | 11f6491889 | ||
|  | b2ec040a8d | ||
|  | 424a53da4e | ||
|  | 963c289af7 | ||
|  | c5af71e0a2 | ||
|  | 329008bf6d | ||
|  | 531dbc5f83 | ||
|  | 851a925956 | ||
|  | 5d4e01eea6 | ||
|  | 7484dc5b4c | ||
|  | e04f5cb277 | ||
|  | c513cff843 | ||
|  | a4603a4396 | ||
|  | bc5eafce66 | ||
|  | 5fb811eb4c | ||
|  | 84a3884ffc | ||
|  | 50ae29a08c | ||
|  | bf8bfa582a | ||
|  | 492d1ef30e | ||
|  | bd19c203e1 | ||
|  | 1141f9de86 | ||
|  | 7955a17a17 | ||
|  | 58085e39d1 | ||
|  | bbc32c4cd0 | ||
|  | 3841039728 | ||
|  | f04d954882 | ||
|  | 39602ff5f2 | ||
|  | 55ecc7a92c | ||
|  | 1148960d43 | ||
|  | 415107fbf0 | ||
|  | 437cc20198 | ||
|  | 32f78a99fd | ||
|  | 65c7855afd | ||
|  | 7f68e341da | ||
|  | a2f750ed1a | ||
|  | b74a42cdf5 | ||
|  | 95b35be541 | ||
|  | ea747a3d58 | ||
|  | 9b644e3c47 | ||
|  | 3f776397d1 | ||
|  | 1ec75035ba | ||
|  | 97b7b7b968 | ||
|  | 135427dcc8 | ||
|  | a2de514c05 | ||
|  | f1bada7fd8 | ||
|  | ea5d25c794 | ||
|  | 193e420eb3 | ||
|  | 8a972ee543 | ||
|  | b51eb7326f | ||
|  | be3b5b7fe2 | ||
|  | 3a7a606f6a | ||
|  | 294fc6b62f | ||
|  | 662a44fccf | ||
|  | b0a5d4fb6f | ||
|  | 4fb8292618 | ||
|  | 539e5899e3 | ||
|  | bee9e20827 | ||
|  | 12f527a120 | ||
|  | bd626899df | ||
|  | 54d036715f | ||
|  | 54c87f81a6 | ||
|  | 5de078dc61 | ||
|  | ff57de0753 | ||
|  | 9565aee3c5 | ||
|  | f63da0c58b | ||
|  | 205dbc1a25 | ||
|  | 12c309fd50 | ||
|  | f04e3d5338 | ||
|  | dc03d0b300 | ||
|  | 3e16cc4912 | ||
|  | fcdf252f03 | ||
|  | b23fea9cb5 | ||
|  | e714ff35c4 | ||
|  | 4054d0eca7 | ||
|  | 367f9b6232 | ||
|  | 194eb4e266 | ||
|  | f717eb7388 | ||
|  | e8f20285af | ||
|  | 0fec9c7c55 | ||
|  | f8d0ed7ca6 | ||
|  | 020eaef5ba | ||
|  | 973b31521e | ||
|  | 59e513f130 | ||
|  | 62e730b621 | ||
|  | f4bb62adbc | ||
|  | 48a528a4b8 | ||
|  | 5aba66ea78 | ||
|  | c5efdf5ae3 | ||
|  | 15958cd4a3 | ||
|  | edcdc6c97c | ||
|  | 143b807e9b | ||
|  | 861379c227 | ||
|  | 2fb9f62d0b | ||
|  | 84e02fc144 | ||
|  | 57ac90f837 | ||
|  | 10a45ece76 | ||
|  | c88a177cb2 | ||
|  | a63dfc4650 | ||
|  | 8924ac2783 | ||
|  | 4fffa2d0ba | ||
|  | 856d2ab266 | ||
|  | 750d2c76f5 | ||
|  | 47157049c0 | ||
|  | 22000f10df | ||
|  | d802ce1484 | ||
|  | 4b10b9ffc3 | ||
|  | 552408f488 | ||
|  | 4884938036 | ||
|  | cdcc8cc59a | ||
|  | f7bd600715 | ||
|  | 0014fec63f | ||
|  | 812efde342 | ||
|  | 889f0e1569 | ||
|  | 3a26c5cd65 | ||
|  | 12a25c37aa | ||
|  | 4706e20a1d | ||
|  | 14c23051ee | ||
|  | 330ddfa3ad | ||
|  | a1e9a14ef3 | ||
|  | 958f57085f | ||
|  | 646a786b75 | ||
|  | c8516bc5f4 | ||
|  | 58e87b3ddf | ||
|  | ea0abb70a2 | ||
|  | 908f9562f6 | ||
|  | 8131d9a640 | ||
|  | e092f41074 | ||
|  | 79a90dc476 | ||
|  | 25962dbf39 | ||
|  | 8df53e441d | ||
|  | 6f89efa40b | ||
|  | d6a1b4e71f | ||
|  | a2c0e53f87 | ||
|  | 013af7619e | ||
|  | aa302ecc32 | ||
|  | 99b049fe2d | ||
|  | dbdd1b8671 | ||
|  | 8ba6a7436e | ||
|  | 6e35a9f682 | ||
|  | 78f456911a | ||
|  | 8f5d3dc49c | ||
|  | 97678577fb | ||
|  | ce67737cc9 | ||
|  | b9919b0a9c | ||
|  | 226f45d8d5 | ||
|  | accbf6ecfc | ||
|  | 0aa80d82d9 | ||
|  | ace5f81a17 | ||
|  | 21a0b33645 | ||
|  | 8b991e11a2 | ||
|  | 8f013776df | ||
|  | c30aedd309 | ||
|  | 39f303fcd6 | ||
|  | 76c0e140cf | ||
|  | ccb3c991a6 | ||
|  | a7932da207 | ||
|  | 5fda20c330 | ||
|  | 1be6e4565f | ||
|  | e606d0b1de | ||
|  | b4bcb7ace2 | ||
|  | a63fee1223 | ||
|  | ae76ff0aaf | ||
|  | bba819ba84 | ||
|  | d0d0da6cb7 | ||
|  | 475113838a | ||
|  | b8435efc97 | ||
|  | 780e41d6a6 | ||
|  | 6d0b55f753 | ||
|  | c9fa5c7284 | ||
|  | e97f4c4054 | ||
|  | 96d15b7505 | ||
|  | 2f77596034 | ||
|  | 5619c105aa | ||
|  | 9a6ee023b3 | ||
|  | 77e2e44abc | ||
|  | 32bddfdd47 | ||
|  | c9aa654ef0 | ||
|  | 5e501857aa | ||
|  | 6b00aba039 | ||
|  | 14fa9cfa4b | ||
|  | 5633c5224e | ||
|  | 03763a1423 | ||
|  | cf6df1556c | ||
|  | cdc8a42393 | ||
|  | a2fd705153 | ||
|  | 3388f699a0 | ||
|  | 5e197713ff | ||
|  | 50718495da | ||
|  | b7b604aed4 | ||
|  | a1f5cabbba | ||
|  | c2aae6ddf6 | ||
|  | 8a40622815 | ||
|  | cb88409102 | ||
|  | b918b75414 | ||
|  | 37f0e36c98 | ||
|  | c8dc2327a3 | ||
|  | f660973168 | ||
|  | cf2e7744f3 | ||
|  | 855d799b21 | ||
|  | 97dd1d0f4f | ||
|  | 5b5553b9a3 | ||
|  | 702545e0b2 | ||
|  | fa2787eb5d | ||
|  | 0f37b326a0 | ||
|  | 7f9f551cfe | ||
|  | ecf1847dd2 | ||
|  | 40a9dce869 | ||
|  | a6696733fa | ||
|  | d9bd736159 | ||
|  | 4f5f5d31a3 | ||
|  | fad1325427 | ||
|  | 8b6678a453 | ||
|  | c7f48a83c0 | ||
|  | af0f02d63e | ||
|  | 497d63e67e | ||
|  | 4d048af384 | ||
|  | 3649f10600 | ||
|  | 49e69a54bd | ||
|  | a0acc89fcb | ||
|  | 64d1a82920 | ||
|  | 2396e28479 | ||
|  | db1ad0df63 | ||
|  | c5de18caae | ||
|  | e57774e121 | ||
|  | b7ee46d400 | ||
|  | 6007132640 | ||
|  | 31b3a4c342 | ||
|  | 73ff852648 | ||
|  | 6d50eb5737 | ||
|  | 3c0b74005b | ||
|  | 93ff667df1 | ||
|  | a8579fa68a | ||
|  | 10f77fdf1a | ||
|  | 99d824a999 | ||
|  | 97d2b5df15 | ||
|  | 84a9cf7adf | ||
|  | a49927f173 | ||
|  | 6a5c50ff77 | ||
|  | c948573c2d | ||
|  | 5233bc501c | ||
|  | ad96c6f838 | ||
|  | 0e92f68b4a | ||
|  | ac97e8c613 | ||
|  | 95fe717ca7 | ||
|  | 10b18de3e0 | ||
|  | 08295eb807 | ||
|  | fce4f0c116 | ||
|  | cf1424976f | ||
|  | 94e8fce40a | ||
|  | ea671bf395 | ||
|  | fdb868516f | ||
|  | c75bebfc90 | ||
|  | 3e102ef760 | ||
|  | c07eddbd97 | ||
|  | e85b925f40 | ||
|  | 27761ba6f2 | ||
|  | b665698e78 | ||
|  | 97ebe33d68 | ||
|  | 249f7e45fb | ||
|  | c0612e6193 | ||
|  | 79a789c557 | ||
|  | 450888f542 | ||
|  | 380a08242a | ||
|  | e653a933f1 | ||
|  | bda5dffa34 | ||
|  | 29df7e84a1 | ||
|  | 19cf43a10e | ||
|  | 0398ef3b90 | ||
|  | 8c19daf949 | ||
|  | e4f0688a02 | ||
|  | 25f4fbf2bb | ||
|  | 0533c08438 | ||
|  | 5f0ea85f47 | ||
|  | 6c7c1202ed | ||
|  | 669aa769c2 | ||
|  | fcf2994015 | ||
|  | bee21ddc9e | ||
|  | 263e68e677 | ||
|  | 2b958f5724 | ||
|  | 95f7177ef4 | ||
|  | 006324b78e | ||
|  | efd8c1229d | ||
|  | 0f1aea3e0d | ||
|  | 6a41cbebc9 | ||
|  | fba95e6a42 | ||
|  | bffb91f196 | ||
|  | 4573b65639 | ||
|  | 3d8505385a | ||
|  | 95d3a8cc22 | ||
|  | 99c053f86b | ||
|  | f2dde705ef | ||
|  | be11fda814 | ||
|  | 0261105c52 | ||
|  | 264047dc0c | ||
|  | 4d84926ed2 | ||
|  | da3211fee6 | ||
|  | 1388b03cf2 | ||
|  | 9f98b4b082 | ||
|  | b3f1401ab4 | ||
|  | e5e3832809 | ||
|  | 2eff7da171 | ||
|  | e9622bcfe8 | ||
|  | 63ebadc526 | ||
|  | fe47b07229 | ||
|  | dc73997be3 | ||
|  | 62315fd478 | ||
|  | fb81121bd3 | ||
|  | 5293563a6a | ||
|  | 2e1e61dabe | ||
|  | 280d63fde7 | ||
|  | c6104195f6 | ||
|  | e55cbb3e3d | ||
|  | 56b85e4194 | ||
|  | 6431c43d0e | ||
|  | a62107fbd1 | ||
|  | 7959d18248 | ||
|  | 2f66915a9f | ||
|  | a508177e21 | ||
|  | 5a9d858604 | ||
|  | 514da83961 | ||
|  | b7bae18849 | ||
|  | fbde247c72 | ||
|  | 3a69af9034 | ||
|  | 5c87a6cb76 | ||
|  | 9c6bb434e8 | ||
|  | d1bd303dfa | ||
|  | 3813c32454 | ||
|  | 3b00a692ee | ||
|  | 3304ebe9d3 | ||
|  | 513120cbfe | ||
|  | b06049d5a3 | ||
|  | 0f50355deb | ||
|  | bd6e35fea2 | ||
|  | a4fd63cd44 | ||
|  | fdc4219b68 | ||
|  | 5b428bb8e6 | ||
|  | c948ff88a5 | ||
|  | 9b9a0d7060 | ||
|  | 16578e3677 | ||
|  | be7f84bc67 | ||
|  | 033d26f2cb | ||
|  | 4c0826b1c4 | ||
|  | c4cc204c94 | ||
|  | 3747db18b1 | ||
|  | 4173625fca | ||
|  | 0e7863a6fb | ||
|  | 207ba00ad2 | ||
|  | 87c89586a5 | ||
|  | 1cea1ced82 | ||
|  | 08732bac0f | ||
|  | 283e8d3c08 | ||
|  | 42a7165596 | ||
|  | aa3f5001d5 | ||
|  | 56580c4005 | ||
|  | ba304c9651 | ||
|  | 703c5adba7 | ||
|  | 8b85f6e0a6 | ||
|  | c136d22382 | ||
|  | 42358419ad | ||
|  | ab2ced5c37 | ||
|  | faf31be0dc | ||
|  | ff4c67d068 | ||
|  | 10b133db02 | ||
|  | f0bf607b43 | ||
|  | 8948ca5323 | ||
|  | 9c3be51fe9 | ||
|  | 2da9161f29 | ||
|  | 983dad5b53 | ||
|  | 8b23d341b4 | ||
|  | 0ad60013aa | ||
|  | 289815e128 | ||
|  | f7ee83f1b9 | ||
|  | f67aafa8d3 | ||
|  | 4e5ddd57bf | ||
|  | e0d4ecf835 | ||
|  | 81a461115b | ||
|  | d679b02658 | ||
|  | 5effcdb024 | ||
|  | 211a5eb2bb | ||
|  | c4465ba58d | ||
|  | 7903c53876 | ||
|  | dbefe6a560 | ||
|  | 8b1f412255 | ||
|  | a2e0074061 | ||
|  | 5fc920087b | ||
|  | 085233ab9b | ||
|  | 6657b2629f | ||
|  | 310a279aaf | ||
|  | 58f3a76da7 | ||
|  | a2c9458b1b | ||
|  | 75bcd9e8d5 | ||
|  | 977e7ef395 | ||
|  | eb1b8b577f | ||
|  | 28f91685ce | ||
|  | 81a4fe59d9 | ||
|  | e7189ab81f | ||
|  | 346db89e66 | ||
|  | f786c7f144 | ||
|  | 51f45293b8 | ||
|  | 943b103001 | ||
|  | f055d42277 | ||
|  | fb7a2a8d5d | ||
|  | 1e5ed2a2e3 | ||
|  | e1467dfe23 | ||
|  | c480f96d30 | ||
|  | cf613aafb2 | ||
|  | 20dbf7c5f4 | ||
|  | 47c912c25b | ||
|  | 48fb1a8127 | ||
|  | 6c1b55db16 | ||
|  | df70c8a800 | ||
|  | 82ae2e7118 | ||
|  | 0cf9b5f3df | ||
|  | 036a825892 | ||
|  | 8b43b31c64 | ||
|  | 3abef972a7 | ||
|  | 30b00741b5 | ||
|  | f86e743cce | ||
|  | cb96fb735e | ||
|  | 459a52d31d | ||
|  | 44ef9a13d6 | ||
|  | 0bb3652a63 | ||
|  | 6a82d683a9 | ||
|  | fad708e8de | ||
|  | c6a38b8355 | ||
|  | ee84eb666b | ||
|  | 6d2793cac6 | ||
|  | 86d518fc2e | ||
|  | 25dba1a6d5 | ||
|  | af949c62c2 | ||
|  | ea20342d76 | ||
|  | 7732d52583 | ||
|  | c801bc5e6b | ||
|  | ea43729063 | ||
|  | e26bae8027 | ||
|  | 555f155cad | ||
|  | f8c47f59bc | ||
|  | f3997128b9 | ||
|  | 154a4e23dd | ||
|  | 52e4e0e569 | ||
|  | 30f2b96c68 | ||
|  | 58c94b7773 | ||
|  | 83203d5f5d | ||
|  | f77d161643 | ||
|  | 6580b139c0 | ||
|  | 2743c7c6ac | ||
|  | 062f76214e | ||
|  | ce98ed98a2 | ||
|  | dce9d93f6c | ||
|  | f7e35a6cbe | ||
|  | 931335220f | ||
|  | 3ce35a8a4b | ||
|  | 9ac4e5cf6a | ||
|  | bd77d7eec3 | ||
|  | b5e48aa509 | ||
|  | b14c42b6a4 | ||
|  | ba794ba58c | ||
|  | b00282590d | ||
|  | 44616c6872 | ||
|  | aaa2b4c3db | ||
|  | 8974d8e4df | ||
|  | 699063cbb0 | ||
|  | e76000b713 | ||
|  | 332b372e31 | ||
|  | cb3fcb7bfa | ||
|  | bef641609e | ||
|  | 24b52f09df | ||
|  | 942b17b807 | ||
|  | cf19d7f3ad | ||
|  | ebd62a4112 | ||
|  | 9af7357ca4 | ||
|  | 0dbc35c252 | ||
|  | c9f03f1ac5 | ||
|  | 02bd292b8c | ||
|  | e5f1029d0c | ||
|  | cae247160f | ||
|  | 6692b1992c | ||
|  | 0937837b7f | ||
|  | 828888490a | ||
|  | 91cb6ba73b | ||
|  | 4ee4d32b2e | ||
|  | 8df630a2f5 | ||
|  | 2cad42870e | ||
|  | 43651135f3 | ||
|  | 6ae42eb787 | ||
|  | ecaf866613 | ||
|  | 5ea3329b36 | ||
|  | 7bb7149f4c | ||
|  | 5856d043ca | ||
|  | 7cd3e49f04 | ||
|  | 173e75175e | ||
|  | 800006dd76 | ||
|  | a824b6910a | ||
|  | dcea382b38 | ||
|  | d9f976baea | ||
|  | 1fa13efe19 | ||
|  | 33af5cd7c6 | ||
|  | 7cb8f97ef1 | ||
|  | bf965a9cde | ||
|  | 17ffff685a | ||
|  | ae76271cff | ||
|  | 8f3a96d615 | ||
|  | 30e750dfe5 | ||
|  | 682dff7c6f | ||
|  | 85415eb8a8 | ||
|  | 68a80b9244 | ||
|  | c331da7323 | ||
|  | 04ffa06221 | ||
|  | 1f0690c6ec | ||
|  | 711467abcd | ||
|  | 9439cd0e3d | ||
|  | 314c19650d | ||
|  | ed6afcd802 | ||
|  | 082d4fe8e1 | ||
|  | cd23b44506 | ||
|  | 46b6b024b9 | ||
|  | cb88cc35e5 | ||
|  | 75c0c44809 | ||
|  | a091b82ba9 | ||
|  | a3b8f022e6 | ||
|  | 279fcb7c51 | ||
|  | 49a9376073 | ||
|  | 96840ede56 | ||
|  | 7e7f481f99 | ||
|  | 3edbf52bc6 | ||
|  | fba6e801fc | ||
|  | 720a163273 | ||
|  | a9b12e5172 | ||
|  | 6ac0c0a367 | ||
|  | 300402d253 | ||
|  | 0d9bfae503 | ||
|  | bfe0d3b8a3 | ||
|  | 5fdd9c0546 | ||
|  | b6570a16b8 | ||
|  | 8e2d3ea16f | ||
|  | bc2c81f058 | ||
|  | 3e0f080ea7 | ||
|  | 679e07189d | ||
|  | a38ebef100 | ||
|  | b8ad6475e1 | ||
|  | 0f0cb3ac6d | ||
|  | d3efb9d7cc | ||
|  | 84a237d3f5 | ||
|  | e6de52eede | ||
|  | 98aee964d7 | ||
|  | 570e5442e0 | ||
|  | b77a2dc353 | ||
|  | 87af31de20 | ||
|  | cfe201dbe1 | ||
|  | 6ccdab35e0 | ||
|  | 55b9f36b45 | ||
|  | fbcb1130c9 | ||
|  | d4f7a6d2bc | ||
|  | 8a19f71abe | ||
|  | fb153757b5 | ||
|  | 4f175fc93e | ||
|  | 2d4ca7cec0 | ||
|  | bf0ea89969 | ||
|  | 073f0c2a20 | ||
|  | ba83be9062 | ||
|  | 2e7188ea4f | ||
|  | 5a012182d9 | ||
|  | b855438af6 | ||
|  | 2ffea143e7 | ||
|  | 61d85b49e6 | ||
|  | 35f617e96c | ||
|  | 6b6ad47c35 | ||
|  | e57183ed0e | ||
|  | ecfd61a822 | ||
|  | 153f87704b | ||
|  | 836f7d2163 | ||
|  | d4d6f71cf4 | ||
|  | 42a9da006e | ||
|  | 2bd5c4f527 | ||
|  | 6a49b5c106 | ||
|  | 23e14d1b72 | ||
|  | f4f11c8884 | ||
|  | 2b220abdb7 | ||
|  | c1d947ebe3 | ||
|  | d695cf392e | ||
|  | 21304a695c | ||
|  | fa51b06c46 | ||
|  | 7560bb8d7b | ||
|  | fc9d65abcc | ||
|  | a7413cccd0 | ||
|  | 7610353f07 | ||
|  | d3f978c90c | ||
|  | b55a8ef62a | ||
|  | 8d79deffb5 | ||
|  | 8158487c3e | ||
|  | 0cc061196d | ||
|  | d0ec055222 | ||
|  | ae12ddd32b | ||
|  | 31da3adaa9 | ||
|  | 9fd5213f13 | ||
|  | de882f5849 | ||
|  | fded1e0021 | ||
|  | 6cb06c146d | ||
|  | b8f1386ad0 | ||
|  | 2b38b5ea50 | ||
|  | 2f707a6b16 | ||
|  | d4c2fcd559 | ||
|  | 082970cdb7 | ||
|  | fe97c78977 | ||
|  | 79394aa69f | ||
|  | 21fd6e3c21 | ||
|  | de4944cd83 | ||
|  | 3fde5c27ed | ||
|  | e1d492813e | ||
|  | 48d0ee3b6d | ||
|  | eebb64901c | ||
|  | 60e0ed2af6 | ||
|  | f030694ef4 | ||
|  | e9ed13459a | ||
|  | af1e38fdf7 | ||
|  | b12900e680 | ||
|  | 44aa1f4a5e | ||
|  | 9425548a85 | ||
|  | bfd4fc81fe | ||
|  | 439af2a325 | ||
|  | 3204b04455 | ||
|  | bed1be14ba | ||
|  | 7cd92faf0d | ||
|  | be7e28af5d | ||
|  | 8eaa762ec5 | ||
|  | 953a9f7cd4 | ||
|  | 36f099d68b | ||
|  | c8fd5090bd | ||
|  | 155e1be494 | ||
|  | cf5e125cb3 | ||
|  | 764fc8477d | ||
|  | d35e62f8cf | ||
|  | 904babdd13 | ||
|  | 154d3842a8 | ||
|  | edb8a120bd | ||
|  | cdfeba0b82 | ||
|  | 8ce1465e9f | ||
|  | a296b1c9c8 | ||
|  | bb8d7058a4 | ||
|  | 816cfa1c7e | ||
|  | 53938200fc | ||
|  | 3885bb039d | ||
|  | 4adad6e424 | ||
|  | 5fb9531338 | ||
|  | 273d9c76a7 | ||
|  | 79a1d6c561 | ||
|  | 4b0eb8475d | ||
|  | 3dc874b517 | ||
|  | 8a3da1ce8d | ||
|  | 42d90542b5 | ||
|  | 690a93d82d | ||
|  | 8042fe4e2b | ||
|  | a27ce375db | ||
|  | db3688799d | ||
|  | a88be35292 | ||
|  | e2d7fcbfc2 | ||
|  | 421d155586 | ||
|  | 7f9e318214 | ||
|  | 57386edb7c | ||
|  | 94d5ba4550 | ||
|  | 2a0b4ea828 | ||
|  | 893ef227d4 | ||
|  | 1fe6e5a00d | ||
|  | 6c96cde73c | ||
|  | 2b12834d53 | ||
|  | 8a2e74b3b8 | ||
|  | aa1721ab3d | ||
|  | c0a256306b | ||
|  | f0b03b4ada | ||
|  | 5503f53af2 | ||
|  | a89d294b27 | ||
|  | 012e1cbcc5 | ||
|  | 3759e0f778 | ||
|  | 1c18641699 | ||
|  | e50e2201b1 | ||
|  | 1419729458 | ||
|  | c14177b0e8 | ||
|  | 126df969b3 | ||
|  | f8ee92ba06 | ||
|  | 81a278dd8c | ||
|  | a98013806c | ||
|  | 0171ffac6a | ||
|  | 7544241316 | ||
|  | 061afb3a94 | ||
|  | 8a5eda9c1f | ||
|  | f62040f0ec | ||
|  | f2e51779e4 | ||
|  | da114fa3a5 | ||
|  | 3775a1657b | ||
|  | 2bd7c4bc81 | ||
|  | 253c489a33 | ||
|  | ac84b6fe3f | ||
|  | 8761e61439 | ||
|  | 29e903e1c8 | ||
|  | ec27e19e3f | ||
|  | 5df0dae11a | ||
|  | 7fffc1a36d | ||
|  | f3d0179834 | ||
|  | 8bf69c598a | ||
|  | aa5fad6628 | ||
|  | b0f1fad4e2 | ||
|  | 3b6d0995b4 | ||
|  | 0cbf4ac37d | ||
|  | 9ccffee82c | ||
|  | 1b38e2eedf | ||
|  | ce87abe96e | ||
|  | becbda8483 | ||
|  | da210e2ae4 | ||
|  | d4fc6feeba | ||
|  | f1cbca8d76 | ||
|  | dfd9364061 | ||
|  | 1931395fdb | ||
|  | b01fd24e15 | ||
|  | c9d1329fc2 | ||
|  | ab2d3bfd80 | ||
|  | 36bb172f29 | ||
|  | 01e64be39d | ||
|  | 4ebe160f6c | ||
|  | b427eca21f | ||
|  | 3eb438c8d2 | ||
|  | 068f425833 | ||
|  | b3c84242dc | ||
|  | 24672d91d8 | ||
|  | 4422af26ec | ||
|  | 5329e803e2 | ||
|  | ad542b91fa | ||
|  | e9e03c945b | ||
|  | e20cfb3dae | ||
|  | 48baac916c | ||
|  | adadf38b08 | ||
|  | d4e1469450 | ||
|  | 2c456f044f | ||
|  | 228c15ace3 | ||
|  | a0d15e6e7b | ||
|  | 2fe78cf971 | ||
|  | 5ec3544340 | ||
|  | 5443a17775 | ||
|  | 40d60e4eb3 | ||
|  | f3312a6403 | ||
|  | e638b55b30 | ||
|  | 5caa76a8b3 | ||
|  | 901a5ce9d2 | ||
|  | 6ab74951f4 | ||
|  | c2625d696d | ||
|  | 77fb5ef2ab | ||
|  | c20ca3399e | ||
|  | 5825da9c76 | ||
|  | e3853ae402 | ||
|  | bd142a9710 | ||
|  | 4f23847546 | ||
|  | 85820c571d | ||
|  | d9bed03025 | ||
|  | d6e05962c9 | ||
|  | d32636ed6b | ||
|  | bbf066f030 | ||
|  | a3d2f6592e | ||
|  | 87b6327c5e | ||
|  | abaebb329d | ||
|  | 8970fe412d | ||
|  | 9dc5ae21c4 | ||
|  | 4132fb79a6 | ||
|  | 9a4dc30604 | ||
|  | 192b542fe4 | ||
|  | 490547cd3d | ||
|  | 17f9829498 | ||
|  | 234e77fd06 | ||
|  | 87ac831c8a | ||
|  | 4e92492165 | ||
|  | c3d0b1114f | ||
|  | 4463a7d4ba | ||
|  | 741fe3dd90 | ||
|  | e910f3915d | ||
|  | 39aafc5007 | ||
|  | 9b83afae42 | ||
|  | bdf54f6cff | ||
|  | f2a9887a12 | ||
|  | 4f4d78bfab | ||
|  | 3b460fb8fa | ||
|  | ee15e9acc5 | ||
|  | 48fce35fb3 | ||
|  | 78899378c2 | ||
|  | 67404a327d | ||
|  | 702dfa4b79 | ||
|  | 2144407e41 | ||
|  | b36dd62c50 | ||
|  | 7026df7d96 | ||
|  | ed8e7afdf6 | ||
|  | d78e5932f9 | ||
|  | 26d83bb9ea | ||
|  | 8e89b1bdf2 | ||
|  | c880cc0987 | ||
|  | 0874ba7a03 | ||
|  | 7962278475 | ||
|  | c8949f5eeb | ||
|  | 8108b93c5f | ||
|  | 9dbe531bf7 | ||
|  | 46e2ff1001 | ||
|  | d2cdc67ec7 | ||
|  | 56121203bf | ||
|  | e13133fd2b | ||
|  | f20565fd16 | ||
|  | cf2d5841f5 | ||
|  | 630d2ca926 | ||
|  | 34cb93794c | ||
|  | 122b5ba468 | ||
|  | 401466d6c0 | ||
|  | 7f2627dbc8 | ||
|  | 6aecc3915c | ||
|  | ef1b3aa7f5 | ||
|  | 1aaab2a814 | ||
|  | e93734b209 | ||
|  | 9e5218f6b4 | ||
|  | 711ec39327 | ||
|  | 08049252f2 | ||
|  | f1e7ec0c6b | ||
|  | 23765d9139 | ||
|  | 43febe269c | ||
|  | 40233c7702 | ||
|  | 27ed81614b | ||
|  | 889d23e9bd | ||
|  | f8571023f6 | ||
|  | 6364e00202 | ||
|  | a76c6f86c6 | ||
|  | 555e815402 | ||
|  | 8a1d81989b | ||
|  | ee9234b2c6 | ||
|  | 735b9c5844 | ||
|  | 064f3eb3bc | ||
|  | f1775d4fd1 | ||
|  | a9bc111c4f | ||
|  | c100612473 | ||
|  | 26087f8dc7 | ||
|  | 36e75cb728 | ||
|  | d7a2fc2be4 | ||
|  | 142176f194 | ||
|  | c5892fc17e | ||
|  | 6e69cfbca4 | ||
|  | 775181f761 | ||
|  | 36e83d628e | ||
|  | 5f6fcb2bc0 | ||
|  | 7b106e5650 | ||
|  | 79d9c83a2d | ||
|  | 269669ba28 | ||
|  | 4ef7240598 | ||
|  | efdf689c31 | ||
|  | f7606e92ca | ||
|  | 6750be3ec9 | ||
|  | 68fb5089f8 | ||
|  | a8d093bacd | ||
|  | 233a1995b3 | ||
|  | 8ef3baaffb | ||
|  | c9597b9447 | ||
|  | b2dc1d8b23 | ||
|  | 859c0c7f6c | ||
|  | aaf18e2416 | ||
|  | fd679ef117 | ||
|  | 6cc611b3f1 | ||
|  | 77ee726f66 | ||
|  | dc603b76a4 | ||
|  | bcb3371acc | ||
|  | d14ce7e476 | ||
|  | 4d26b806dd | ||
|  | a2b95dbb39 | ||
|  | 47f7b43bcc | ||
|  | 77fd8c120c | ||
|  | a1a6f40158 | ||
|  | ed09cd7489 | ||
|  | eb3330d145 | ||
|  | 5ba0588c7b | ||
|  | d4a199f0e1 | ||
|  | 32dd186f4d | ||
|  | d820f55358 | ||
|  | 81f0fb3c74 | ||
|  | 972c83cd52 | ||
|  | 66a704af55 | ||
|  | 31c5d6e1c1 | ||
|  | bf0ab95c09 | ||
|  | c1d85f760d | ||
|  | 88ad2f4c18 | ||
|  | be9f9e7b0c | ||
|  | 2cc1973f62 | ||
|  | eb4625a0b9 | ||
|  | 5bfb01254b | ||
|  | bb80fa4a2d | ||
|  | ddb715d88d | ||
|  | 395b499856 | ||
|  | cce6a47f11 | ||
|  | 7fd17b4ec0 | ||
|  | e16ab2a0fd | ||
|  | 15f5364c30 | ||
|  | 65081767bf | ||
|  | c7c595e5fa | ||
|  | 5b24e8b69c | ||
|  | e6a845e606 | ||
|  | ec8b8a7b87 | ||
|  | 51a9205105 | ||
|  | ed5567fc73 | ||
|  | 4b3f5d74a0 | ||
|  | b01c5a05e7 | ||
|  | 36eddabc1c | ||
|  | ea11aa7a0d | ||
|  | e7efa76e6d | ||
|  | 41c8ca8ab4 | ||
|  | 4624079be7 | ||
|  | c6f6042271 | ||
|  | e9e3b9b7c6 | ||
|  | becbb09a29 | ||
|  | 6f6ab50995 | ||
|  | d8ee766860 | ||
|  | 108c26d8af | ||
|  | ed8d3088ca | ||
|  | 46c4e2d212 | ||
|  | 94891d45f9 | ||
|  | 7448ad109e | ||
|  | 6211dfe024 | ||
|  | 9b85200954 | ||
|  | 94ee739d91 | ||
|  | e81a6db9a3 | ||
|  | b2f5a259ab | ||
|  | c8a0d3c10d | ||
|  | 97df964051 | ||
|  | 66dd05f8bc | ||
|  | 19589d9117 | ||
|  | 8147b2e0b1 | ||
|  | be22f8cd14 | ||
|  | 868be9b7ff | ||
|  | 5011281104 | ||
|  | 42992c64ec | ||
|  | 2baff243ed | ||
|  | 83440a6b0f | ||
|  | 87c9a1c06c | ||
|  | b848fe249f | ||
|  | 1e804d97ce | ||
|  | 218d3c144b | ||
|  | 05a4905490 | ||
|  | 75103da378 | ||
|  | 9db9b53c81 | ||
|  | 0e4787f3e8 | ||
|  | f8d8d4b186 | ||
|  | 45e0a1ffea | ||
|  | 75c58093f1 | ||
|  | cc708e9fb4 | ||
|  | 2ce0e38827 | ||
|  | 5b980e8c13 | ||
|  | 21b602650c | ||
|  | fa4b7a1a69 | ||
|  | 977dfe700b | ||
|  | 48ac50e1c9 | ||
|  | 1a817947eb | ||
|  | be64603097 | ||
|  | f6b90c8271 | ||
|  | 26e4be87c7 | ||
|  | cddbb8d80d | ||
|  | 58023b4bf0 | ||
|  | 4f18a5f1c3 | ||
|  | 56df8d8bd3 | ||
|  | 211ec104c2 | ||
|  | 3fb573247d | ||
|  | 6aac44db14 | ||
|  | 3255e11cfc | ||
|  | 844bf29de1 | ||
|  | 04d91d1422 | ||
|  | db90e1f801 | ||
|  | 7f30748a41 | ||
|  | a4e0abb48f | ||
|  | 3f27dc89d8 | ||
|  | d6f6efc189 | ||
|  | 2cda49fc38 | ||
|  | 04f4a76b41 | ||
|  | 0a8f7085f3 | ||
|  | 7ae48d7390 | ||
|  | c908502644 | ||
|  | 2f0631809d | ||
|  | 91ab3bd972 | ||
|  | 672636313c | ||
|  | 79875ef50d | ||
|  | aea5445495 | ||
|  | 754a36fbc9 | ||
|  | 85dafc0b3c | ||
|  | b516ab9b4f | ||
|  | 1a27e60e55 | ||
|  | 2c710736e8 | ||
|  | 69b9ff69be | ||
|  | a3a4fc0cc2 | ||
|  | ae686bb15d | ||
|  | 68a5325849 | ||
|  | 75e3bddfa9 | ||
|  | bd3a8db438 | ||
|  | 102868bf74 | ||
|  | 1a73a27102 | ||
|  | a9cf34ab56 | ||
|  | 46d17c3314 | ||
|  | 40f816c311 | ||
|  | 13f1c12912 | ||
|  | 93c25f5d1b | ||
|  | aa6ec60c34 | ||
|  | ac159bb52e | ||
|  | 919aee64f9 | ||
|  | 553bec1a1f | ||
|  | bcb6d1cf93 | ||
|  | 7d24e5b279 | ||
|  | 12253e23b5 | ||
|  | 4acb66fb7a | ||
|  | 68ef85b64b | ||
|  | b73efe6bb4 | ||
|  | 89c84522d2 | ||
|  | 98172764ac | ||
|  | 448e881104 | ||
|  | f16134ab1f | ||
|  | f5dc1564a4 | ||
|  | 133df75bd4 | ||
|  | 440be0653a | ||
|  | d721a40ca5 | ||
|  | a9b252b8fa | ||
|  | 8a5b3ddee7 | ||
|  | d83e543a98 | ||
|  | bcd6e8fd63 | ||
|  | d5c5738aab | ||
|  | 9e4dfe081f | ||
|  | 090852b72b | ||
|  | ff5e038c49 | ||
|  | 5cc2e5f6e1 | ||
|  | 4e8c0573c4 | ||
|  | ce905ba2c4 | ||
|  | 3104c17fb3 | ||
|  | 7651941722 | ||
|  | 7bf938901a | ||
|  | f8b61d2926 | ||
|  | 4edea59ab1 | ||
|  | c8bcd2818d | ||
|  | 9b46dbaff1 | ||
|  | 17a139f27f | ||
|  | bd00c728d1 | ||
|  | 9d510b514c | ||
|  | 00dcc5ecda | ||
|  | dbbdd3f799 | ||
|  | 3541b4b968 | ||
|  | 5b1bf35a23 | ||
|  | 591b61945f | ||
|  | bd1943626b | ||
|  | f152cdef51 | ||
|  | 33f8c9747d | ||
|  | 714a5e26b3 | ||
|  | 7f2c6e40d3 | ||
|  | db676ec223 | ||
|  | ffb3e511a7 | ||
|  | e9e64f6a44 | ||
|  | a7b8adb0e1 | ||
|  | 4140ff03d7 | ||
|  | e042ef05a4 | ||
|  | 7c02e4d66a | ||
|  | 711794cfe1 | ||
|  | c0e4cf2358 | ||
|  | a92f8f36c1 | ||
|  | 12698dc347 | ||
|  | 3e6a55f78e | ||
|  | 7585f14b89 | ||
|  | 01b5fc4d49 | ||
|  | 0fb7d3bfc8 | ||
|  | 2cd74d355c | ||
|  | 3d405f8c63 | ||
|  | a92f0c4c6e | ||
|  | de142ac9d6 | ||
|  | 468ef7ecff | ||
|  | 4d768fd236 | ||
|  | bfc1f95190 | ||
|  | bc17ebd90e | ||
|  | bb1b3727cb | ||
|  | 4dbebefb45 | ||
|  | e1c5764fbf | ||
|  | 70f975e4f0 | ||
|  | 845567d1ba | ||
|  | f570447000 | ||
|  | 9d7b8f1f2f | ||
|  | bae6bfc32d | ||
|  | 8a63390464 | ||
|  | 0b52cd8b31 | ||
|  | f97569dd34 | ||
|  | a9164e63ab | ||
|  | 8c95067ec4 | ||
|  | 4f77bbeb2b | ||
|  | 8bbed2c831 | ||
|  | 6b43a23c4b | ||
|  | be9521f659 | ||
|  | 90761fd840 | ||
|  | d49d9a783c | ||
|  | d7dc7c4eda | ||
|  | fe64c6a841 | ||
|  | 2bbdc85a29 | ||
|  | 74628b7034 | ||
|  | 15aa249f64 | ||
|  | fdf58e1225 | ||
|  | 866f305686 | ||
|  | 1550e5343c | ||
|  | add3dd1077 | ||
|  | 79a142fb19 | ||
|  | 1a30fe4a1a | ||
|  | 4ff991764e | ||
|  | 001f066769 | ||
|  | c47b553a8e | ||
|  | 319af51f84 | ||
|  | 5dbaaae68e | ||
|  | 8c1a749a5a | ||
|  | fc8643f238 | ||
|  | c8653f19bf | ||
|  | b01100d818 | ||
|  | d4096a9026 | ||
|  | b9e780cdcd | ||
|  | b77cd56a01 | ||
|  | 9cdec156dc | ||
|  | 6aa5968863 | ||
|  | 8f7686cd7b | ||
|  | d8d384a979 | ||
|  | ade318bb78 | ||
|  | ed3aa8189f | ||
|  | 3e43597617 | ||
|  | 4c8e895ac7 | ||
|  | f6a3671366 | ||
|  | e641b0a965 | ||
|  | eddddc6c9b | ||
|  | f249d6306f | ||
|  | 5c31bd54e4 | ||
|  | 71ba73b38f | ||
|  | db0ff74857 | ||
|  | 1acb073737 | ||
|  | 251dda3652 | ||
|  | 22db24509d | ||
|  | 54c9d27fd8 | ||
|  | 01888ff078 | ||
|  | ffbd140a97 | ||
|  | dedf5c52d9 | ||
|  | 10465c5d68 | ||
|  | 1f4f64a7c0 | ||
|  | a6f116b57b | ||
|  | 0a80186a92 | ||
|  | 635bdf15cb | ||
|  | a72bdfdacc | ||
|  | dc3e04456c | ||
|  | b0e4fb7602 | ||
|  | df7aa3339b | ||
|  | c475536388 | ||
|  | cc7def89af | ||
|  | 58da87898e | ||
|  | bded5490d2 | ||
|  | c3715a2a3d | ||
|  | abf084f6c2 | ||
|  | 37ba409dc3 | ||
|  | f29488b24f | ||
|  | 71bdade7b9 | ||
|  | 60d97c887d | ||
|  | 5bba50f01f | ||
|  | 1f7884dc70 | ||
|  | 69dafd6c68 | ||
|  | 64b79cd5ac | ||
|  | 1af21735a9 | ||
|  | 9886af3cec | ||
|  | 1eb8f9ad97 | ||
|  | 08e73d9d7d | ||
|  | b0e349b215 | ||
|  | caa98b08da | ||
|  | 00caa13a12 | ||
|  | cfc0135e86 | ||
|  | 9ee8c1c791 | ||
|  | cd3aba2b89 | ||
|  | a150d8e289 | ||
|  | 6da8e92f20 | ||
|  | 1d4dd4be96 | ||
|  | 7df1a03b4b | ||
|  | ad316ffd37 | ||
|  | 91f5542a57 | ||
|  | d47a8aa562 | ||
|  | 676f790933 | ||
|  | 70433f3d05 | ||
|  | 9f2a2b9869 | ||
|  | a0c09fc617 | ||
|  | 19d391fa05 | ||
|  | d1aa1fd4d8 | ||
|  | 0e02d03d9a | ||
|  | 4133f9c56f | ||
|  | 53055064e1 | ||
|  | 06090d8de1 | ||
|  | d6ccae38f8 | ||
|  | f7210effec | ||
|  | 8e7efd98b2 | ||
|  | ea50ba16f9 | ||
|  | b62e4f6662 | ||
|  | f5a1c8bc49 | ||
|  | 4cb8e99430 | ||
|  | bbac49ff38 | ||
|  | 1d12017f11 | ||
|  | 46af2e37a7 | ||
|  | a480919ec3 | ||
|  | f8abf9fce1 | ||
|  | 62f2a552ea | ||
|  | b053e02174 | ||
|  | 3798167908 | ||
|  | 56fe2014e1 | ||
|  | be2e64433f | ||
|  | 8732e89e55 | ||
|  | fdd0a93bad | ||
|  | dd12572b1d | ||
|  | e23f20227a | ||
|  | 5cc791690b | ||
|  | 9f1deb0c36 | ||
|  | 4cebbf8d22 | ||
|  | 93971537b4 | ||
|  | 87e816a7f5 | ||
|  | 0f45b1da48 | ||
|  | a20049c82a | ||
|  | e57ebdb583 | ||
|  | 372122037f | ||
|  | 23a5cb1917 | ||
|  | f8d5fef3c4 | ||
|  | 250005ad16 | ||
|  | 719aea2a58 | ||
|  | 0e06da6c63 | ||
|  | 68fef169f3 | ||
|  | c668201df4 | ||
|  | 1d68c8cc87 | ||
|  | b9ac8b42ea | ||
|  | b4a03a56b4 | ||
|  | 9eb668ab30 | ||
|  | 233a74c146 | ||
|  | e0c7269b8e | ||
|  | 73063df11b | ||
|  | ff00afb5d7 | ||
|  | 3f43dc1855 | ||
|  | 4a4e7fc7cb | ||
|  | 0253dc9623 | ||
|  | f8855b83fa | ||
|  | 0d0459d83d | ||
|  | 374ef3902c | ||
|  | 235690064f | ||
|  | 0167c25e08 | ||
|  | d2432716ea | ||
|  | 52ef85cba3 | ||
|  | 8140057bea | ||
|  | 22df59e229 | ||
|  | ed351eee54 | ||
|  | c021b4c368 | ||
|  | 04a3c4bb22 | ||
|  | b5fda5642f | ||
|  | b0955705be | ||
|  | a4a624d537 | ||
|  | 6a8cf1b768 | ||
|  | aac2a8f830 | ||
|  | 8269490dd1 | ||
|  | 39274b0c5d | ||
|  | 55c2430671 | ||
|  | 023486e175 | ||
|  | 8227643741 | ||
|  | e44131f97a | ||
|  | 5028377d45 | ||
|  | 51aaf1b150 | ||
|  | 13406e76de | ||
|  | 4672d98e8a | ||
|  | 858b3d640a | ||
|  | 6087002562 | ||
|  | 82ced56bed | ||
|  | 982b8ea51d | ||
|  | 877c463494 | ||
|  | 9882582903 | ||
|  | ba566657f1 | ||
|  | cb1a178fbf | ||
|  | ad788fbed1 | ||
|  | 749533b0b4 | ||
|  | 142a5f7ca1 | ||
|  | 28bfa8e418 | ||
|  | 7b8ed487e9 | ||
|  | 0059f9475e | ||
|  | 9429ea7c64 | ||
|  | a157580b22 | ||
|  | 41a0147938 | ||
|  | 16e021e94f | ||
|  | 449d76a6c7 | ||
|  | 70172db693 | ||
|  | ff93a38354 | ||
|  | e3b70b10d1 | ||
|  | 400141b093 | ||
|  | ca5e45a46d | ||
|  | 74b547b93c | ||
|  | a688305572 | ||
|  | f0f2eefb59 | ||
|  | bdb548ffdc | ||
|  | fe5d4abec1 | ||
|  | 70632706f9 | ||
|  | 8f424c063e | ||
|  | 9955c3dd5d | ||
|  | d555fcf7bd | ||
|  | 8da00c0872 | ||
|  | 393290df2c | ||
|  | f8a7835341 | ||
|  | 082bac8c3a | ||
|  | 4cafe42cf4 | ||
|  | 89485971fa | ||
|  | cb72d5100e | ||
|  | f103533852 | ||
|  | 55f1e7ece1 | ||
|  | c0a765c998 | ||
|  | ed44fb461c | ||
|  | 8543613563 | ||
|  | 734adc6445 | ||
|  | 827f8d4d51 | ||
|  | 5bbd3d6273 | ||
|  | df90e3414d | ||
|  | 16b9abbe92 | ||
|  | 2de43b719e | ||
|  | 3b84f27f36 | ||
|  | f7a6a333e1 | ||
|  | c37ea90206 | ||
|  | 0b39ef68d9 | ||
|  | 40ea759e2c | ||
|  | 3671a70e3b | ||
|  | 2fa50e458f | ||
|  | 9c7db1381c | ||
|  | 2d4f5b8603 | ||
|  | 5181890433 | ||
|  | 99a9e3a91b | ||
|  | 101378c625 | ||
|  | aa5e47b462 | ||
|  | 15715a2968 | ||
|  | b5751e5746 | ||
|  | 7e40cb5331 | ||
|  | 4b1a86ee02 | ||
|  | 6c66ca8acf | ||
|  | d58a091bb7 | ||
|  | 0566a2d9b1 | ||
|  | 3d23d1de4f | ||
|  | c9c5f7f088 | ||
|  | 8e65408b1c | ||
|  | c3adc956d7 | ||
|  | f69d6b4eb1 | ||
|  | 916d377aaa | ||
|  | 39532a9d65 | ||
|  | 3dc696b2a9 | ||
|  | 7be7dec19a | ||
|  | fc709ba266 | ||
|  | 080e2f2589 | ||
|  | 0dc4440a99 | ||
|  | f770786b89 | ||
|  | 46bc331428 | ||
|  | 3af77b6a31 | ||
|  | 8c4461c4f8 | ||
|  | bccfd21cf4 | ||
|  | e6f1394a74 | ||
|  | de24831fb9 | ||
|  | e5716162ad | ||
|  | 5809a3af0d | ||
|  | 11a385550a | ||
|  | 255b8f2005 | ||
|  | 3d398cfd53 | ||
|  | 5f8804c25c | ||
|  | 02d1369d5b | ||
|  | 0fef2ab509 | ||
|  | 16088b8a08 | ||
|  | 69befe8f0e | ||
|  | ae7a3981c0 | ||
|  | 8b4aa3f5af | ||
|  | 60c8a2c598 | ||
|  | fbb7dd4c3f | ||
|  | 833ecfb1af | ||
|  | c20bab2436 | ||
|  | afb17af571 | ||
|  | 5012568464 | ||
|  | 02dd141095 | ||
|  | 0be82d964e | ||
|  | b41c7962c2 | ||
|  | 6f9e06e78d | ||
|  | c2347076f4 | ||
|  | c744af161d | ||
|  | 74ea382cf2 | ||
|  | ab4a9e72d4 | ||
|  | 3f9a29730f | ||
|  | 8a076c01ab | ||
|  | ca75efcbaf | ||
|  | f96ce2fd83 | ||
|  | d5f4f987f2 | ||
|  | 11475b0c38 | ||
|  | 137fa98903 | ||
|  | ea62c1806e | ||
|  | 45afd06047 | ||
|  | e6ec59092c | ||
|  | 35f788693d | ||
|  | d5314d2a85 | ||
|  | efd8c3d6d2 | ||
|  | 7d04353843 | ||
|  | 644da0b77b | ||
|  | 785c349adc | ||
|  | 1608196cd2 | ||
|  | 9d34abf603 | ||
|  | 05beb6ca79 | ||
|  | 12c7238c72 | ||
|  | ed359ca10c | ||
|  | b66468c4ea | ||
|  | d2c9ccbfdd | ||
|  | 85e05b787f | ||
|  | e5471b44e0 | ||
|  | e0f0a76ae4 | ||
|  | 6336ab121e | ||
|  | e899d2d5b8 | ||
|  | a94c19a6cf | ||
|  | 9c09ee3b71 | ||
|  | d8e68a75b9 | ||
|  | 302c5cfe09 | ||
|  | 1be337fbc5 | ||
|  | 3ec37e2c66 | ||
|  | 3740c21bee | ||
|  | 5a6568e7c2 | ||
|  | 4cd9b7b050 | ||
|  | dd780945e1 | ||
|  | e86f6a841a | ||
|  | fad8dcd304 | ||
|  | 1633a2ff70 | ||
|  | a2878fa066 | ||
|  | 735de2908a | ||
|  | 818021e0b7 | ||
|  | 3cc6c4433f | ||
|  | 8306ddd40f | ||
|  | 024e71cdf5 | ||
|  | 4313cbaa5c | ||
|  | f5da2eb633 | ||
|  | 23f0cd3a26 | ||
|  | 74db3e17d0 | ||
|  | 7bde7f0cfd | ||
|  | ac68e9c6b5 | ||
|  | 32692dce07 | ||
|  | 64d3b8e104 | ||
|  | a03edf3d58 | ||
|  | e5b7ccb612 | ||
|  | 9c1ce5543d | ||
|  | ba387a8e4e | ||
|  | 7fa25c1ff4 | ||
|  | 3bd1bfc769 | ||
|  | dad47ade38 | ||
|  | fa6e0c8964 | ||
|  | bb4b252401 | ||
|  | a50404b141 | ||
|  | 61690ecf4a | ||
|  | f4c87af5c1 | ||
|  | 83d12f7d39 | ||
|  | 2e73b229d7 | ||
|  | 3a0074d96e | ||
|  | 7068c175f2 | ||
|  | 9b5ed8407f | ||
|  | 7d08de9c99 | ||
|  | 575d07e41a | ||
|  | 24da3608c4 | ||
|  | 37935bf388 | ||
|  | 9eb7fad621 | ||
|  | 438d51d26e | ||
|  | 34ef055d7b | ||
|  | 4a1d66f210 | ||
|  | 1f6328bf4e | ||
|  | 8e7a230dbc | ||
|  | 6e718ca772 | ||
|  | 70554e24b1 | ||
|  | a0f736bb88 | ||
|  | 79473c243d | ||
|  | 441eb3bb29 | ||
|  | ca44af0625 | ||
|  | 9e179170ee | ||
|  | 9f71dbb006 | ||
|  | 7531314e3f | ||
|  | a006b52052 | ||
|  | bebebaa3dd | ||
|  | 55ff035fc9 | ||
|  | d8c8d7bc57 | ||
|  | b0acb58442 | ||
|  | 2b28ae3402 | ||
|  | aa47bae2ad | ||
|  | ccfde84769 | ||
|  | b1df6d5149 | ||
|  | d51aefa156 | ||
|  | c40412d7c6 | ||
|  | b0bc7ecacb | ||
|  | 5489bd37c9 | ||
|  | ea2e3f25d8 | ||
|  | 09b37cf538 | ||
|  | e30a01310e | ||
|  | d5cc5b2574 | ||
|  | 160ca6add4 | ||
|  | da96c85d32 | ||
|  | de15a1c36f | ||
|  | 814fc8bc69 | ||
|  | 0c9fd25d3e | ||
|  | 9a660f3fe9 | ||
|  | 6e1466e411 | ||
|  | 7913b3cbc2 | ||
|  | 87c9ed6356 | ||
|  | 06ceb056f3 | ||
|  | 65b4ef6c3d | ||
|  | 0284ef401e | ||
|  | 8a87f93741 | ||
|  | af19536222 | ||
|  | abe77ab96f | ||
|  | ea720bb4a5 | ||
|  | 6ee2e2b570 | ||
|  | 3885107e6e | ||
|  | 30a68fefec | ||
|  | fa84c4e461 | ||
|  | 5743a5f91d | ||
|  | 9d2d060dec | ||
|  | b36e7e172e | ||
|  | aacb92a7ae | ||
|  | 4943bde3d4 | ||
|  | fc459be531 | ||
|  | 3151502a3f | ||
|  | 79b10ed18a | ||
|  | 34b27f2e68 | ||
|  | c433f736a5 | ||
|  | 55e6c6e01a | ||
|  | 496b5a092f | ||
|  | 02510efda1 | ||
|  | be828af3e2 | ||
|  | 9b1c114c3f | ||
|  | 4df27d4b0b | ||
|  | e3445dae46 | ||
|  | f5fcf23678 | ||
|  | 0a6c08e2c3 | ||
|  | b80a7459cf | ||
|  | f6480e6e0c | ||
|  | 41d12c433e | ||
|  | 169a2484f2 | ||
|  | be52ec1390 | ||
|  | 00db43198d | ||
|  | 6bac207611 | ||
|  | df1eb631e1 | ||
|  | 6150ae787d | ||
|  | fc7967d455 | ||
|  | fca21ac126 | ||
|  | 6fb96fa3c1 | ||
|  | a1f565f756 | ||
|  | 5992ed1fab | ||
|  | beccdac717 | ||
|  | 9f3e9786a8 | ||
|  | b72ea63100 | ||
|  | 27550f2d4b | ||
|  | 6917919f35 | ||
|  | 48d6fe5918 | ||
|  | c9bc530df0 | ||
|  | 0b569a4120 | ||
|  | 950fd7d2cf | ||
|  | 50dd0354d1 | ||
|  | 78f1cb8a66 | ||
|  | 4bfe9a9ae9 | ||
|  | c5d38d8962 | ||
|  | bbe3ee701f | ||
|  | 2f86bb1ca5 | ||
|  | 3999690062 | ||
|  | b1c0d6b452 | ||
|  | d57edaa4c1 | ||
|  | 3033d2086e | ||
|  | 0f7d185a61 | ||
|  | 81f200641b | ||
|  | c6129b44a1 | ||
|  | 088419b38e | ||
|  | 8ebcee32c2 | ||
|  | 2b801a756a | ||
|  | 98b639540b | ||
|  | e0b797fc7e | ||
|  | 795416a84d | ||
|  | 545dda166f | ||
|  | f19ec5d9b6 | ||
|  | 6ea978d83d | ||
|  | 42f3b70a22 | ||
|  | 1cd10f074b | ||
|  | bed1d31bc8 | ||
|  | 99478897c5 | ||
|  | d79cd463a0 | ||
|  | 2a8290a4b7 | ||
|  | ccf4e73701 | ||
|  | 01b67c692b | ||
|  | 4023ab3f28 | ||
|  | 70f3b7450f | ||
|  | ca4960e097 | ||
|  | ebe604e1af | ||
|  | 32b04cd32f | ||
|  | e149174696 | ||
|  | f878ffc01b | ||
|  | 15b49f4db8 | ||
|  | b1cc7b3296 | ||
|  | 65d90a6dff | ||
|  | a58f4c2ec2 | ||
|  | f038069fe2 | ||
|  | 407cb3e7d5 | ||
|  | b8bc62ee11 | ||
|  | ccbd179f23 | ||
|  | dac7830bd4 | ||
|  | 75d7ac2d8a | ||
|  | 468cfeffb6 | ||
|  | bc82ca2106 | ||
|  | 725c962236 | ||
|  | 6720c1aa46 | ||
|  | 280203e64e | ||
|  | 281d8b7cec | ||
|  | 2c6cda1f27 | ||
|  | d7dfeaf0c1 | ||
|  | fa532da8c7 | ||
|  | cbf84647de | ||
|  | dbfbd54e1f | ||
|  | c38a490a6f | ||
|  | 9d7a450821 | ||
|  | 8007bea7db | ||
|  | dc1ab7e331 | ||
|  | a0d197d0c0 | ||
|  | a776ba248e | ||
|  | 0ecd9673b8 | ||
|  | 97aa1230ef | ||
|  | ff0be73b1f | ||
|  | 8049e44dec | ||
|  | dc26022fb4 | ||
|  | e8e44f9a32 | ||
|  | 12d56b8b03 | ||
|  | e62fd7ed15 | ||
|  | 978eb95acd | ||
|  | e34f4acb22 | ||
|  | 195aeb5caf | ||
|  | 15a600c763 | ||
|  | 82ad5839fa | ||
|  | 9af883231d | ||
|  | 9bfe8ac007 | ||
|  | f46367d77b | ||
|  | 38649de85f | ||
|  | eb2e1c0c45 | ||
|  | 33bb86cbcf | ||
|  | baffc2d6ca | ||
|  | 96ab508c91 | ||
|  | 57e42659e3 | ||
|  | f059e97697 | ||
|  | 516e6430eb | ||
|  | f194a8ecf4 | ||
|  | 13f046f310 | ||
|  | 1edf5acb87 | ||
|  | af636870d4 | ||
|  | 379b8ada61 | ||
|  | 5e63471983 | ||
|  | 086f0f8450 | ||
|  | 97a4b3dc2a | ||
|  | 4eb8d681c1 | ||
|  | 2066584164 | ||
|  | a954c198fb | ||
|  | bb1f8cd5e8 | ||
|  | 101e96dcb3 | ||
|  | 59adf82895 | ||
|  | 3b68f56b15 | ||
|  | 2962c4372c | ||
|  | 517e376582 | ||
|  | 7a90fe5aec | ||
|  | ea45dde63a | ||
|  | 22a301b55e | ||
|  | 605177dcf0 | ||
|  | 460e1f5563 | ||
|  | 6f25337b99 | ||
|  | 08148a07b2 | ||
|  | 27c0e45940 | ||
|  | bdd736315a | ||
|  | d57ec0cd53 | ||
|  | 952c9d8bdb | ||
|  | cf84ec78fa | ||
|  | b595e84c30 | ||
|  | 6e5f115bd5 | ||
|  | a1ab00c93e | ||
|  | 6e5c4e832e | ||
|  | 48ea487974 | ||
|  | 54dc98a90b | ||
|  | c5bdd3d056 | ||
|  | 64d6e1f8e1 | ||
|  | 69d60ffb24 | ||
|  | e6ffa3d143 | ||
|  | bb4330e486 | ||
|  | 1a4d720978 | ||
|  | 91c2f479bb | ||
|  | b61701fa17 | ||
|  | cb9f910642 | ||
|  | 4b8d07f301 | ||
|  | 2db3a4f1ef | ||
|  | ead1f65887 | ||
|  | aae9866866 | ||
|  | 085ff84bc9 | ||
|  | e12975cf0b | ||
|  | a33cf6b532 | ||
|  | 5be25d9538 | ||
|  | 2b29eeb795 | ||
|  | 785561a0cc | ||
|  | b46dc88346 | ||
|  | 96d81ef72b | ||
|  | 81dc3de26a | ||
|  | 4d0c572c2e | ||
|  | fb2da0ee9e | ||
|  | b8b0247717 | ||
|  | 103e212aee | ||
|  | 2f33575907 | ||
|  | 576c528573 | ||
|  | 3c444d3fb3 | ||
|  | 7cb499cde9 | ||
|  | 5a174ba014 | ||
|  | 041feb4e86 | ||
|  | 19726cf428 | ||
|  | aaf134b1c5 | ||
|  | 9d5f5ee94b | ||
|  | a48f0827ae | ||
|  | 5686158245 | ||
|  | 3824cdde68 | ||
|  | e619b9bf7b | ||
|  | b7243c2226 | ||
|  | 70b6674f44 | ||
|  | ef67b8481e | ||
|  | baffe4861c | ||
|  | 5cf489a270 | ||
|  | 44b1819926 | ||
|  | d84c2b780b | ||
|  | dc8991a1da | ||
|  | 7bd0ca2212 | ||
|  | 4dd619b8c6 | ||
|  | 3a86ab186c | ||
|  | 2f2a6367c2 | ||
|  | be880c25f9 | ||
|  | 17812f0d77 | ||
|  | 0c5eae2349 | ||
|  | 3ad1803057 | ||
|  | 02c20e97b7 | ||
|  | 716dc781e4 | ||
|  | d9900d8e4c | ||
|  | 3b9065b057 | ||
|  | e73b748b95 | ||
|  | b309161f00 | ||
|  | b21667834e | ||
|  | 183fa59c83 | ||
|  | 0c5586ddfb | ||
|  | 33855bcb8b | ||
|  | dc81b7a699 | ||
|  | b0b2c32654 | ||
|  | 6f1ed76b4c | ||
|  | f81cee0be2 | ||
|  | bcd85b11a1 | ||
|  | ec368ae3fd | ||
|  | d28c264422 | ||
|  | fba505bc90 | ||
|  | c50ed2c328 | ||
|  | 7e11ff2b20 | ||
|  | 3fb83c46e2 | ||
|  | 763f2bd5c5 | ||
|  | 85edee288f | ||
|  | 1aa494a97a | ||
|  | a8e7627184 | ||
|  | d590bbdd2c | ||
|  | 80d65b5acb | ||
|  | 1d250f7491 | ||
|  | dd741ec6d8 | ||
|  | e741af6d55 | ||
|  | e691b1b7c3 | ||
|  | 29142128f2 | ||
|  | 758f44e25f | ||
|  | 16c26d8098 | ||
|  | a004c61afc | ||
|  | a9d1a64c32 | ||
|  | 889224715b | ||
|  | 442b9d23f1 | ||
|  | e4dd895709 | ||
|  | 82677c304e | ||
|  | 73d8dfe381 | ||
|  | 1177aa8aca | ||
|  | 0eda0a4935 | ||
|  | a19dab0dc9 | ||
|  | d8eb80b72e | ||
|  | 4f3a6821d1 | ||
|  | 77bd7541ca | ||
|  | ca46bc5366 | ||
|  | 2e19bc07df | ||
|  | 3f4de43b67 | ||
|  | 0d0bf62fc4 | ||
|  | 3c8654fa25 | ||
|  | 756a6ec5aa | ||
|  | 98c7364924 | ||
|  | 62c01b59b2 | ||
|  | 43db1824be | ||
|  | 7f671c9f3f | ||
|  | 410009dd61 | ||
|  | 580cc00967 | ||
|  | 612c565cfd | ||
|  | 979c5351a8 | ||
|  | 97b7479081 | ||
|  | 1df2f5e96a | ||
|  | 0601833387 | ||
|  | 8b36279e52 | ||
|  | 32163d5f21 | ||
|  | 1c337f6817 | ||
|  | 6df26f2400 | ||
|  | a9431a5aee | ||
|  | 5a3c832a98 | ||
|  | c4b5bb22db | ||
|  | 2b5a976f35 | ||
|  | 5d7a625883 | ||
|  | ae1ca85924 | ||
|  | c9acfdb1d7 | ||
|  | 11ac8fbf13 | ||
|  | dc541444ba | ||
|  | 8ea25bcd1c | ||
|  | f5e46a663a | ||
|  | 64ec415a54 | ||
|  | 57154b2853 | ||
|  | 0243a902b2 | ||
|  | 6c04402a98 | ||
|  | ef7c9b5c2a | ||
|  | 73448a6039 | ||
|  | 176a0ff99b | ||
|  | b96d562700 | ||
|  | 7a3ead8f3b | ||
|  | f72903ccc2 | ||
|  | 668678b2c4 | ||
|  | e2802175a5 | ||
|  | 71c5b1be86 | ||
|  | 44da085e0b | ||
|  | 362554ad3b | ||
|  | f01866d76f | ||
|  | 53490cd368 | ||
|  | c171088838 | ||
|  | 0cc944dc5a | ||
|  | 8bd8834237 | ||
|  | 84fc739c8d | ||
|  | a7fa2cf0c9 | ||
|  | 1137cd5ca5 | ||
|  | d47906b525 | ||
|  | 13a59a882e | ||
|  | 3b7348f862 | ||
|  | 07585f01e3 | ||
|  | 5042137006 | ||
|  | a2ea79130c | ||
|  | 979401f3ac | ||
|  | 4c98db2269 | ||
|  | 209c5f337c | ||
|  | 8080ed4787 | ||
|  | f3be5f0e67 | ||
|  | fb2d185c5f | ||
|  | f2d696b48e | ||
|  | 5596d2df8e | ||
|  | b72ca439e2 | ||
|  | 432ed264c2 | ||
|  | 0a411cbe4f | ||
|  | 581f71911a | ||
|  | e548bf8bc2 | ||
|  | 1d944bab51 | ||
|  | 6f407750f5 | ||
|  | 19ffe8f308 | ||
|  | c9069d472f | ||
|  | 68d3cc7507 | ||
|  | 0c90376752 | ||
|  | f5eb832cd2 | ||
|  | c3a058a479 | ||
|  | bc87210ce3 | ||
|  | d595eb2614 | ||
|  | cb4d118ccc | ||
|  | 62c723866a | ||
|  | c9e54f2ba9 | ||
|  | e2c86c4b96 | ||
|  | 4469a334fd | ||
|  | aca379db6e | ||
|  | 9ce5210c33 | ||
|  | 4dd68452b4 | ||
|  | 714b3d3fe0 | ||
|  | 2378e0d961 | ||
|  | f78bbdc29f | ||
|  | 708620f929 | ||
|  | 9f0490fc12 | ||
|  | d37eebd8ed | ||
|  | bfeda23ce5 | ||
|  | 52eb158231 | ||
|  | afb782410d | ||
|  | aebb7da3c7 | ||
|  | b90710945a | ||
|  | 56efd51c06 | ||
|  | 76728d1783 | ||
|  | 5b1fe9aa0a | ||
|  | e3c8466819 | ||
|  | 6a70cd1975 | ||
|  | 2c45771024 | ||
|  | ebca8c0217 | ||
|  | 752a080876 | ||
|  | 0541d9189d | ||
|  | 0e454b08c8 | ||
|  | 2d0ca20a03 | ||
|  | 61d9ccf263 | ||
|  | 1c30584153 | ||
|  | 5c5bebd689 | ||
|  | d9548a2891 | ||
|  | d25e027201 | ||
|  | 93211470d1 | ||
|  | b5800205c4 | ||
|  | eeebf04509 | ||
|  | f4f99f594d | ||
|  | 5e8e739f78 | ||
|  | a15adc43af | ||
|  | 07556592c1 | ||
|  | 7694349078 | ||
|  | 4f3cb3103e | ||
|  | 842cd1ecf0 | ||
|  | 81a4f42673 | ||
|  | 152e695f4c | ||
|  | 5a0c10b80e | ||
|  | 06adf3d346 | ||
|  | 7be824640c | ||
|  | c061487a16 | ||
|  | 97fd34150f | ||
|  | 6d294a0c74 | ||
|  | fe4ef354ac | ||
|  | d28b8b5e8d | ||
|  | f2b30d9a3f | ||
|  | 0a614f2741 | ||
|  | a9fb50787b | ||
|  | ce7d7a8e01 | ||
|  | 7006c00233 | ||
|  | 21866634b3 | ||
|  | 34dfd50702 | ||
|  | d9502a6c00 | ||
|  | 95f7b9205a | ||
|  | d14d4944a0 | ||
|  | b4b2729e96 | ||
|  | 299b81f51b | ||
|  | ad6b18e66f | ||
|  | 091a462a42 | ||
|  | cb218a57f1 | ||
|  | ba8649117d | ||
|  | 20daebd965 | ||
|  | 7c2786969a | ||
|  | 565aae5967 | ||
|  | 16a634063a | ||
|  | 4c28b5b227 | ||
|  | a7a949377b | ||
|  | c048b1a25b | ||
|  | f7e7f7ed01 | ||
|  | 5dfcb80de8 | ||
|  | c8f6100a6a | ||
|  | c0f4e07e10 | ||
|  | 3c259b2c22 | ||
|  | 3b3a2d4edc | ||
|  | e930098b51 | ||
|  | 43d5df4a12 | ||
|  | 914cfdbc55 | ||
|  | aa8f4af339 | ||
|  | b6fbe7d07d | ||
|  | bf9d6c7ac4 | ||
|  | 139ae547c6 | ||
|  | 8b252b458c | ||
|  | efecfa328b | ||
|  | 5651e7107f | ||
|  | b6b3ceef4d | ||
|  | e44d89c2af | ||
|  | 3e74d75f28 | ||
|  | 6d737b9e4c | ||
|  | dec82589d1 | ||
|  | f0193b0f67 | ||
|  | fdf8eb0657 | ||
|  | 2ce424b567 | ||
|  | 8995fa9ed1 | ||
|  | dc412b305c | ||
|  | d7505da997 | ||
|  | 4b54a81dfd | ||
|  | 132254b3a5 | ||
|  | 9128b12960 | ||
|  | e9104df047 | ||
|  | bae52613ab | ||
|  | 18af906fd3 | ||
|  | d45415ab22 | ||
|  | c6c42740c5 | ||
|  | b4c033ca50 | ||
|  | b67f2d874b | ||
|  | a8d8540346 | ||
|  | cbf1afc9fe | ||
|  | 8a798e620a | ||
|  | 774751a25c | ||
|  | 13718032f6 | ||
|  | 1b497b340b | ||
|  | bb41ab482c | ||
|  | 215aab0fe4 | ||
|  | 666822cf51 | ||
|  | 40101df6ec | ||
|  | 4adcb9c439 | ||
|  | a6cd0bf7e9 | ||
|  | 8158744829 | ||
|  | 70c0c7bc14 | ||
|  | fdda29f048 | ||
|  | 95cc8ea80d | ||
|  | 18f8dde712 | ||
|  | effff3405b | ||
|  | 9d8cbcb993 | ||
|  | 3345f2f3b8 | ||
|  | bcf1d986a4 | ||
|  | a51e74bfa1 | ||
|  | cf00acac04 | ||
|  | 876a7a4646 | ||
|  | 95d1b7bc36 | ||
|  | d4ae0b0a2e | ||
|  | 36739fb444 | ||
|  | 7906c28abb | ||
|  | f87b40941f | ||
|  | 05f816fc5d | ||
|  | f9a157fe18 | ||
|  | ca213589ac | ||
|  | c5ca9fafee | ||
|  | 82b3a97d99 | ||
|  | 1c94064c57 | ||
|  | 7969dd431f | ||
|  | 22e7ddcb1d | ||
|  | b1eafac67a | ||
|  | 5d81cec00c | ||
|  | 9512450d7c | ||
|  | ed1998162f | ||
|  | ac2a21f992 | ||
|  | ad78ce0eb6 | ||
|  | 8ce49c25d4 | ||
|  | 4c24bd4ab9 | ||
|  | 0de49e2a75 | ||
|  | 05c3f459ad | ||
|  | 50aaef5103 | ||
|  | 38872049fd | ||
|  | 5dc1cc54d5 | ||
|  | 57f0fbbb98 | ||
|  | 977fef03b0 | ||
|  | 7d67e6a276 | ||
|  | 0832be5970 | ||
|  | 2343fbd86a | ||
|  | 367ebc1dd4 | ||
|  | 15cc88de6c | ||
|  | 64b3c11682 | ||
|  | b8784185e8 | ||
|  | fdc721baa1 | ||
|  | 03b64bc493 | ||
|  | a6a781f67c | ||
|  | fe1f8ca0a8 | ||
|  | a600feb5de | ||
|  | 1f2c0a78c2 | ||
|  | e4b9c6a2ee | ||
|  | a69db4d572 | ||
|  | 12c92072d0 | ||
|  | e674d9246b | ||
|  | b71f81af57 | ||
|  | b3535281ef | ||
|  | 5f5e6ea845 | ||
|  | 64d2e80690 | ||
|  | b6e0568e76 | ||
|  | dca5b3b2a0 | ||
|  | 243915516e | ||
|  | bc3683d8f6 | ||
|  | 1d36ce0fdf | ||
|  | 88d4d306f3 | ||
|  | 184d928cf7 | ||
|  | fbd911ed27 | ||
|  | dec3762b7a | ||
|  | a849872c21 | ||
|  | 1d71fb3554 | ||
|  | 0d3bf0cd00 | ||
|  | 6c766eba86 | ||
|  | cc760acb62 | ||
|  | f4d4bf8779 | ||
|  | 90f62e5e4a | ||
|  | f1bd3e1711 | ||
|  | 01dde8bea5 | ||
|  | 341c66a199 | ||
|  | bc1fb2770b | ||
|  | 9f1373945b | ||
|  | 266ee2ca81 | ||
|  | 35738cc1a3 | ||
|  | ff310f89bd | ||
|  | 2dd004f6cd | ||
|  | 964b7e0e23 | ||
|  | bc039bde81 | ||
|  | 9505f82d9b | ||
|  | 9189db5531 | ||
|  | bfa5f39b6d | ||
|  | 15f97bbf26 | ||
|  | 90ba761325 | ||
|  | ddd428f76e | ||
|  | 0c83fa7060 | ||
|  | f2e2c7e4d0 | ||
|  | 717bfffa63 | ||
|  | a764a4a44b | ||
|  | 247fa0ce7c | ||
|  | 13932b2cfb | ||
|  | 0bd0540d2f | ||
|  | 9a17cc503c | ||
|  | 89a048e5fa | ||
|  | 88bc022e2a | ||
|  | 00e080459e | ||
|  | 5b197adf33 | ||
|  | 9019c31f91 | ||
|  | 2e14703b16 | ||
|  | f87698438d | ||
|  | 4af1cf1d1f | ||
|  | d6ad7dc6eb | ||
|  | f25e4ea520 | ||
|  | 17891d373b | ||
|  | 9f29149d87 | ||
|  | 010e20989a | ||
|  | c885f2edaa | ||
|  | ae5a7176ba | ||
|  | ee13cd10fe | ||
|  | b0f9bf2c62 | ||
|  | 9fbfc3d677 | ||
|  | 189389f96a | ||
|  | 2af7066512 | ||
|  | 9cbc40a229 | ||
|  | 18bf220ca4 | ||
|  | 8750c4b121 | ||
|  | 417d2cb40a | ||
|  | 36b0698432 | ||
|  | 0edc57f0e3 | ||
|  | 3d76137247 | ||
|  | df9d231389 | ||
|  | e2aebaf0e7 | ||
|  | 20e84a847a | ||
|  | ad4779e32f | ||
|  | 90537e42ba | ||
|  | 4615465599 | ||
|  | 95418724fa | ||
|  | 989cb05257 | ||
|  | d7df20413d | ||
|  | f7e0f55c13 | ||
|  | e16f48c9fd | ||
|  | 4694644043 | ||
|  | f468d6e947 | ||
|  | 9a19477796 | ||
|  | 00d41c6de2 | ||
|  | fc2a9a85ff | ||
|  | 78c86880e4 | ||
|  | aca61c0354 | ||
|  | 73dde4de51 | ||
|  | 597c4a2e4f | ||
|  | 62ec7f4d37 | ||
|  | 319c7e9e9f | ||
|  | 580492b0c8 | ||
|  | 655ce7b87a | ||
|  | 4e09b404a2 | ||
|  | 748f831495 | ||
|  | bb3b87814c | ||
|  | 0bfe20182f | ||
|  | 4245c0a0ad | ||
|  | 25aadc690a | ||
|  | 12dc4ab1fa | ||
|  | 55a5917282 | ||
|  | a5b33d11fc | ||
|  | d2d872f51c | ||
|  | 5c0b500f48 | ||
|  | 28418288e3 | ||
|  | 0150769c17 | ||
|  | 2eaea02489 | ||
|  | 1a9c4b7714 | ||
|  | d9f710aa52 | ||
|  | 2069cc4392 | ||
|  | f78be9050a | ||
|  | feb5d13e1c | ||
|  | a3b0448f53 | ||
|  | 3dfbefb9f5 | ||
|  | 9f6bac1b1b | ||
|  | 0f2ed14d16 | ||
|  | 3e898c487a | ||
|  | efb9dce92f | ||
|  | f024e0bbed | ||
|  | 3f1bb6771a | ||
|  | 0b3ced5203 | ||
|  | 373267c53b | ||
|  | ae3e250269 | ||
|  | 33200b2d08 | ||
|  | b032e00d01 | ||
|  | fda95dfc5d | ||
|  | bc96f2d0cb | ||
|  | c649e1b4a2 | ||
|  | f54ed8ebd1 | ||
|  | b82167fefa | ||
|  | 2efc2bc186 | ||
|  | f572c11912 | ||
|  | 4595a77c41 | ||
|  | 7c1853431a | ||
|  | e26eb85718 | ||
|  | 821b5686f2 | ||
|  | c989f466ed | ||
|  | 97c771f93a | ||
|  | 54dbdde9cb | ||
|  | 513957eea1 | ||
|  | 5eed4672ed | ||
|  | aafa4fe0b9 | ||
|  | 572c03631d | ||
|  | 2f869a55e2 | ||
|  | 161f6090c1 | ||
|  | efad7270b7 | ||
|  | 24eb78d137 | ||
|  | e969a1c97c | ||
|  | 4f31632863 | ||
|  | 1d417c07cd | ||
|  | 344c9fe57e | ||
|  | 9d4400349b | ||
|  | 24f7000918 | ||
|  | 6ff3286d78 | ||
|  | f058de8bcd | ||
|  | fbfc74e5ca | ||
|  | 1b5654001c | ||
|  | e0f3e94e2b | ||
|  | 5da89892b4 | ||
|  | a6ecb54cc4 | ||
|  | 04da13eaf9 | ||
|  | 7fa4df082e | ||
|  | ae001c5e82 | ||
|  | e7f942eda7 | ||
|  | fa8236ee2c | ||
|  | 08ec04c889 | ||
|  | e5150ea012 | ||
|  | 222ece2533 | ||
|  | 294696daf5 | ||
|  | d099356207 | ||
|  | 5c06761b1a | ||
|  | 05fc3c5eca | ||
|  | 9d4e2adde4 | ||
|  | a8db3d8dd3 | ||
|  | 6ae7c51dc5 | ||
|  | 84771f5864 | ||
|  | 4304d44851 | ||
|  | 1018c0e8a5 | ||
|  | b1d0013214 | ||
|  | 94ef25bbb9 | ||
|  | 13830ffc9c | ||
|  | e0bef941b4 | ||
|  | 03e9522d98 | ||
|  | 1bdbd31b96 | ||
|  | ef9db701f8 | ||
|  | afb564a4fc | ||
|  | 3e7f58dedd | ||
|  | e46d8345db | ||
|  | 2e364b6d9a | ||
|  | b4177836a8 | ||
|  | 5b2ee21204 | ||
|  | 9b6e798eb6 | ||
|  | 7c91c4ae5a | ||
|  | 7bc3b662e4 | ||
|  | 64af1f7e9b | ||
|  | f0038e9796 | ||
|  | 768aa4ac92 | ||
|  | f61c137ea3 | ||
|  | 20a8059758 | ||
|  | 58696c6ad4 | ||
|  | b5ed018bae | ||
|  | 91b7dd988e | ||
|  | b0c3c78899 | ||
|  | 282f00e091 | ||
|  | 5cd2791506 | ||
|  | 9b2e9ec41a | ||
|  | 08ef9ee682 | ||
|  | a8bc753720 | ||
|  | 266df86d98 | ||
|  | 85a1f59a93 | ||
|  | 43258ee816 | ||
|  | c4ca0b6e91 | ||
|  | 1bf3b3077e | ||
|  | c9194c3635 | ||
|  | 27c462fee9 | ||
|  | 7886e5d57c | ||
|  | 6912dec166 | ||
|  | b8e610e1b6 | ||
|  | 421b5846f2 | ||
|  | 6a30f2cbc8 | ||
|  | a8b1e91843 | ||
|  | 20f97d0d13 | ||
|  | 4c78f06c2b | ||
|  | c700d5c922 | ||
|  | a9508a2c04 | ||
|  | 09d55a0cbd | ||
|  | b165129388 | ||
|  | 0ef3471f8f | ||
|  | 9ba9998bd6 | ||
|  | 72126730ef | ||
|  | fd2213232c | ||
|  | 369c5754f2 | ||
|  | fc3d0ab053 | ||
|  | 1c63d7ff31 | ||
|  | de971fa53f | ||
|  | d005eb46cf | ||
|  | d1dd7d1d51 | ||
|  | b78ef006ec | ||
|  | 134c68c98e | ||
|  | 82539fc420 | ||
|  | 7a5604697f | ||
|  | 84d2b8ad6d | ||
|  | 9a0c843f29 | ||
|  | 4d96d95370 | ||
|  | 51ea5dc342 | ||
|  | 97d58e34f2 | ||
|  | 86ce5c591b | ||
|  | dea47a6e3d | ||
|  | 7621cf3377 | ||
|  | 5090b01b8e | ||
|  | 6675fdf3c2 | ||
|  | 491812fac5 | ||
|  | 8a82552bdc | ||
|  | bd4fc2e5cc | ||
|  | 32aa4c41ce | ||
|  | 2a6bedbd8d | ||
|  | 83942c2551 | ||
|  | 458d794f52 | ||
|  | 95982ad464 | ||
|  | 7723ff461b | ||
|  | 0ca36a89e3 | ||
|  | cc5fdd9844 | ||
|  | d09ee6611f | ||
|  | bba6855872 | ||
|  | 43970b404e | ||
|  | 1868289b71 | ||
|  | 37bcd5c603 | ||
|  | c9ad5bea93 | ||
|  | a09b3bb6c7 | ||
|  | 3d6170be5e | ||
|  | 00477fd67a | ||
|  | 21c57f968a | ||
|  | f7d2314d64 | ||
|  | 5ecf8c83db | ||
|  | 608834eafb | ||
|  | 1fd4b2b9fc | ||
|  | 01a143cd5a | ||
|  | 6321b21a1a | ||
|  | 8405826fab | ||
|  | 22de8855c1 | ||
|  | 1830478ec3 | ||
|  | 6d98b93135 | ||
|  | 54978e4d64 | ||
|  | 9d567d61fe | ||
|  | 79feb691bd | ||
|  | e16fe1e6a5 | ||
|  | 04d3981921 | ||
|  | 40c3099e4e | ||
|  | 3f86fd7176 | ||
|  | 9e6bc46540 | ||
|  | 5e892f222b | ||
|  | 2da1554caa | ||
|  | a53d0c091e | ||
|  | f88bfa059d | ||
|  | 2e38999506 | ||
|  | 42b841cb78 | ||
|  | c0d007ffa9 | ||
|  | 127b361979 | ||
|  | e3dab3cf20 | ||
|  | 569b9f3d06 | ||
|  | d6b5494625 | ||
|  | f76edf74f9 | ||
|  | 5c199d3bb4 | ||
|  | 634a51635c | ||
|  | 4f9395e881 | ||
|  | 8035531a27 | ||
|  | cc177533e8 | ||
|  | cd210d9fbf | ||
|  | 87b9b56b65 | ||
|  | bffcaa1c17 | ||
|  | 33cbb2ada8 | ||
|  | d08e77cf36 | ||
|  | 1f8ed9dcb9 | ||
|  | 53b127902c | ||
|  | 389cbf4900 | ||
|  | 80d100f3f9 | ||
|  | a05589c5a6 | ||
|  | 7d32636133 | ||
|  | 3db5f928ee | ||
|  | 797da3bc8e | ||
|  | 1e8d695311 | ||
|  | 00eb474e02 | ||
|  | ad6104baeb | ||
|  | cd552ab202 | ||
|  | bbd471ad93 | ||
|  | 0f1ca1c7cf | ||
|  | 62fc554d25 | ||
|  | 84dc34e68f | ||
|  | 0bb77bfa7f | ||
|  | b6702a0c3b | ||
|  | a781a1dd4d | ||
|  | d771527f77 | ||
|  | 3d9945b60c | ||
|  | 5897045f24 | ||
|  | b2f53a183e | ||
|  | be3dd63360 | ||
|  | f951fe6939 | ||
|  | 0622be843b | ||
|  | 272fbc0cb0 | ||
|  | 36bf2a3c38 | ||
|  | 663ed9833a | ||
|  | fcf757f715 | ||
|  | 88e729664a | ||
|  | c03abdb5e7 | ||
|  | 6d3eb7bb4b | ||
|  | 7ffd37d9cb | ||
|  | 87aacb4270 | ||
|  | 3f756aac21 | ||
|  | 504d13943d | ||
|  | 59b1466e5d | ||
|  | d5d9ac5c76 | ||
|  | bb12ec702a | ||
|  | 82490b0a58 | ||
|  | 2cbf625483 | ||
|  | 44f2a986a2 | ||
|  | c3df1c6cde | ||
|  | 6b52206186 | ||
|  | 9d4238e5cc | ||
|  | c16c119a7d | ||
|  | b49835c72f | ||
|  | ee6f6ae391 | ||
|  | 95a51aafdc | ||
|  | 5e7cd79ed9 | ||
|  | aba6173e23 | ||
|  | 468beee045 | ||
|  | 70ad66bcff | ||
|  | e2c3b35391 | ||
|  | 448de23f59 | ||
|  | 74a015c329 | ||
|  | 44a07c74fd | ||
|  | 0f8af4ba1c | ||
|  | 214d788029 | ||
|  | 530bf22bd5 | ||
|  | ccc98370eb | ||
|  | 7640bc029c | ||
|  | 3f72eb51a0 | ||
|  | 8801ace247 | ||
|  | faf46e4447 | ||
|  | 63978e226b | ||
|  | b96164d4f5 | ||
|  | 944070dfb1 | ||
|  | f0584df1d0 | ||
|  | ba209c2bdd | ||
|  | c6e2f28b97 | ||
|  | 2436bb0128 | ||
|  | 9c4640e010 | ||
|  | 1ee43113b1 | ||
|  | 902f477ee3 | ||
|  | 9c1d46ff92 | ||
|  | fe0d4f08f3 | ||
|  | 9cbd0fceea | ||
|  | b22a4f94ab | ||
|  | 14c2005bbc | ||
|  | a4c351fd4f | ||
|  | a364d4950d | ||
|  | d017dd75cd | ||
|  | 021df83c3f | ||
|  | 7805974736 | ||
|  | c1dae95f71 | ||
|  | e7c2ff3bd2 | ||
|  | 25459b52a1 | ||
|  | d45274494d | ||
|  | b81be8f358 | ||
|  | aa6c0b9d6e | ||
|  | 64580237d5 | ||
|  | b93165592e | ||
|  | 83c1e44925 | ||
|  | 3088115aba | ||
|  | fc93e502b8 | ||
|  | e90e6eaac3 | ||
|  | 2f4dcba54d | ||
|  | 683c6a748e | ||
|  | 175a871ee0 | ||
|  | b4e2061e85 | ||
|  | 2aef99c440 | ||
|  | 6c125e125f | ||
|  | 88cbc32abc | ||
|  | 8f45e8f84a | ||
|  | 21635aadfe | ||
|  | d5234888b3 | ||
|  | f478afb58a | ||
|  | a54ca699b5 | ||
|  | 1f5ff0c6d3 | ||
|  | 2a2541df59 | ||
|  | cd629c1699 | ||
|  | ff96773295 | ||
|  | 4d6828ec14 | ||
|  | dae1d6057e | ||
|  | 6726c42cc8 | ||
|  | 4f6023e44c | ||
|  | 9e16d7f433 | ||
|  | aa86cfc55f | ||
|  | 6931cb9895 | ||
|  | d32d04bd4e | ||
|  | 0b3e9bf5e2 | ||
|  | a4af7b8e21 | ||
|  | 72deee5d74 | ||
|  | 5e9e523d4c | ||
|  | c54509df3d | ||
|  | 63cc9adeaa | ||
|  | 74d760a46d | ||
|  | d46531def8 | ||
|  | eb09ec6834 | ||
|  | 9bd9c6a400 | ||
|  | 7321e206c5 | ||
|  | 2c7917f0ca | ||
|  | d94b20a908 | ||
|  | b1b1fe21dd | ||
|  | 1db3af7c8e | ||
|  | 397fe31f97 | ||
|  | bc283aa025 | ||
|  | 9dbdf0947b | ||
|  | 7c21bf4555 | ||
|  | 361dc194ee | ||
|  | 8c1aa83d12 | ||
|  | d2755a8049 | ||
|  | 1b78bd1684 | ||
|  | 5f67f1f078 | ||
|  | 07061928df | ||
|  | 18ff2df65c | ||
|  | 7b1411d171 | ||
|  | 3a1d0f3695 | ||
|  | 2cd5e1d3c5 | ||
|  | 000765fb77 | ||
|  | 0ff324b0db | ||
|  | a96d5096fe | ||
|  | e8ef476a6d | ||
|  | 22b9df62d1 | ||
|  | 6026da867b | ||
|  | 4d58902ba7 | ||
|  | 4dc1343445 | ||
|  | 080487cb33 | ||
|  | 0febcf4f9e | ||
|  | cd23f711ed | ||
|  | f9b147af42 | ||
|  | 775f1110d3 | ||
|  | 57649a9b81 | ||
|  | 72a268b70a | ||
|  | f86a171dff | ||
|  | e022b782a9 | ||
|  | bd67731bb7 | ||
|  | 25de4e4782 | ||
|  | c590247afa | ||
|  | 5d36539271 | ||
|  | 0d673486a3 | ||
|  | 29f1651a18 | ||
|  | dd20a3e685 | ||
|  | 75a5b1354c | ||
|  | dae9ac8173 | ||
|  | 78b735276b | ||
|  | e10dd54e2b | ||
|  | cb8deab1f9 | ||
|  | e5c27d0236 | ||
|  | faf6fa9450 | ||
|  | 873bdc6733 | ||
|  | 8a40b075b5 | ||
|  | 56c41374bf | ||
|  | a08c2c6437 | ||
|  | e94634544c | ||
|  | 07fe5b247b | ||
|  | c1c694035d | ||
|  | 147d2a02be | ||
|  | 6f91786f4d | ||
|  | f62a933d1c | ||
|  | 451835fbeb | ||
|  | 547e7a1b21 | ||
|  | 053e3ba923 | ||
|  | bf65dcd49b | ||
|  | a1d186112a | ||
|  | ca7a298509 | ||
|  | ff4d58f648 | ||
|  | a1e10e99fa | ||
|  | 16bda530f6 | ||
|  | bf9e04d9db | ||
|  | 8df86a75b1 | ||
|  | 5056203023 | ||
|  | a0026e66ce | ||
|  | f75dd2209d | ||
|  | e35f6d9e35 | ||
|  | 3cb00ce4e0 | ||
|  | 8e18cf5986 | ||
|  | 81f80600f5 | ||
|  | 895156675f | ||
|  | 1c424e2e0a | ||
|  | 0124bb17e8 | ||
|  | 2c89b2d262 | ||
|  | c7bbe2f1fe | ||
|  | 88609a8829 | ||
|  | 329beb166c | ||
|  | e36f3d937c | ||
|  | 1395092ca6 | ||
|  | c09004dbc8 | ||
|  | 7efe4a2776 | ||
|  | b763e0b0cb | ||
|  | ddd0d1bef3 | ||
|  | dbca2178c0 | ||
|  | af742ea536 | ||
|  | 14c1a86b9b | ||
|  | ee3dc8c4cd | ||
|  | 1ed148aaf5 | ||
|  | 3327adb1ae | ||
|  | 4d5f771f9f | ||
|  | aa69d663ed | ||
|  | 29d1894f9a | ||
|  | e5738d608c | ||
|  | 9775d3a33d | ||
|  | ad4cf8d631 | ||
|  | a27e8777aa | ||
|  | d23edcc0b5 | ||
|  | 52373e5bef | ||
|  | bb70e796a1 | ||
|  | 7957ec4369 | ||
|  | 3365d26b40 | ||
|  | d3c111b533 | ||
|  | ec876eb102 | ||
|  | dddfb1ec08 | ||
|  | 6fc9c03d70 | ||
|  | 199ff071e8 | ||
|  | 7e4a06044a | ||
|  | d047b75cb7 | ||
|  | 6fb6b13037 | ||
|  | 460c5a1ae3 | ||
|  | 9955bcc339 | ||
|  | 0a3ab996eb | ||
|  | 46f912a6f9 | ||
|  | 01e0f24752 | ||
|  | 7178c63e10 | ||
|  | 30c402eb83 | ||
|  | 2601cc898c | ||
|  | d2a8823808 | ||
|  | 6b61fa9f6f | ||
|  | 247052df5f | ||
|  | 8eb28555bc | ||
|  | 73132475dc | ||
|  | 42c6487ff3 | ||
|  | 8d2ca25fd6 | ||
|  | 5c5919a7eb | ||
|  | 34cdbfc852 | ||
|  | 1bc50194aa | ||
|  | 4a75236e74 | ||
|  | 64b2f881c4 | ||
|  | 4709ddea5d | ||
|  | 6ef49152f3 | ||
|  | 1c44b0bc98 | ||
|  | 11bce8c17c | ||
|  | b42fff1055 | ||
|  | 1b2e442513 | ||
|  | a4d48077ba | ||
|  | 901e2527d8 | ||
|  | f0839571d0 | ||
|  | 89d0d6ec93 | ||
|  | 922ab1d17b | ||
|  | 7c7be378bc | ||
|  | ec01f8f54b | ||
|  | 5a094b44c4 | ||
|  | 3c657a6645 | ||
|  | 3129d44ff1 | ||
|  | 00306f82c5 | ||
|  | 7def676a17 | ||
|  | 6c48735854 | ||
|  | a0b1831cdb | ||
|  | db9fb8480a | ||
|  | c138e2ffb4 | ||
|  | 473c45794e | ||
|  | a12aa81d73 | ||
|  | 0033e279f1 | ||
|  | a25e98d0cb | ||
|  | bc65480f27 | ||
|  | 8582cda124 | ||
|  | d963dfdbb6 | ||
|  | f7e9c109f6 | ||
|  | 30c3004f27 | ||
|  | 17653761b9 | ||
|  | 4f049fd94b | ||
|  | f98d1c95cc | ||
|  | a2b5c0247b | ||
|  | bca9b5d8c0 | ||
|  | bc789c7f9f | ||
|  | 28bda9fa41 | ||
|  | 18aeeab041 | ||
|  | c7427a5f7c | ||
|  | 03aa6c7d3a | ||
|  | 10077ae750 | ||
|  | 74eec25285 | ||
|  | b6055479a1 | ||
|  | 69b781419f | ||
|  | da6db24f9e | ||
|  | 2b66723d42 | ||
|  | 00a3e25714 | ||
|  | 8ccbd2d8f9 | ||
|  | 8307f26099 | ||
|  | c686f7eefc | ||
|  | 311c7b1158 | ||
|  | a17325f028 | ||
|  | b734097d16 | ||
|  | afaf077aca | ||
|  | bf14af6a1f | ||
|  | e72faef839 | ||
|  | b274bafe8e | ||
|  | 7bed967755 | ||
|  | 944b81b71c | ||
|  | cd529d53ae | ||
|  | 0d680a58f3 | ||
|  | b30d519523 | ||
|  | 83932e1725 | ||
|  | 4ce0e39760 | ||
|  | 84232f25f0 | ||
|  | 2daedf8fd5 | ||
|  | fe084a4478 | ||
|  | 5bf9646a76 | ||
|  | 2b1f28e6c2 | ||
|  | 5b8bd6e64f | ||
|  | 426fd499ce | ||
|  | 17d3a5840d | ||
|  | be49e1d383 | ||
|  | daa98e8925 | ||
|  | 58784b7568 | ||
|  | 419a183167 | ||
|  | 675b4bde14 | ||
|  | ee6ee99577 | ||
|  | 3bc1f69e75 | ||
|  | 5b9df6d5f2 | ||
|  | 9f062ec1b8 | ||
|  | b52a47bd03 | ||
|  | 5e20134f4f | ||
|  | 89d267d6a2 | ||
|  | 607bc42f59 | ||
|  | 880757fb5d | ||
|  | c8acc6a12e | ||
|  | 7d4c2442da | ||
|  | e5255b0c7c | ||
|  | ac3ef9b6fc | ||
|  | 7b5a41c3ff | ||
|  | d5b0d2a886 | ||
|  | 4d60447242 | ||
|  | 78bee3dc59 | ||
|  | e2db958510 | ||
|  | 16440072fb | ||
|  | be2dd6dc32 | ||
|  | 189bde7c9c | ||
|  | 6a4760e291 | ||
|  | c082bb97e0 | ||
|  | c8e14f91e7 | ||
|  | 6032d096ec | ||
|  | defa9a2270 | ||
|  | 77a913f858 | ||
|  | 6e3fa974ba | ||
|  | 7926055b97 | ||
|  | ffd10e656e | ||
|  | 59c1828078 | ||
|  | 6164271fe8 | ||
|  | 26ba35933d | ||
|  | 87359937c9 | ||
|  | 9b938f6515 | ||
|  | 6c3913785d | ||
|  | 542cf3147d | ||
|  | fb9828badc | ||
|  | 2505ac3f98 | ||
|  | fde8548166 | ||
|  | fe91295704 | ||
|  | 15b99c5749 | ||
|  | 9d66ca4a49 | ||
|  | b749a27f86 | ||
|  | 083212cffe | ||
|  | c4e8756210 | ||
|  | 3a6448f727 | ||
|  | fe18df25ba | ||
|  | db65460ec0 | ||
|  | 0ad3eceb82 | ||
|  | a376d6e361 | ||
|  | 45c7f3f3ca | ||
|  | 238de59a2a | ||
|  | 96255e51d2 | ||
|  | 18c3223105 | ||
|  | b9e97792f3 | ||
|  | cbce9b8637 | ||
|  | 5ab90b85da | ||
|  | f3e1e8a2c7 | ||
|  | e41b292e54 | ||
|  | 86928bbb2d | ||
|  | 2f5ec8b5bf | ||
|  | a42d7d867e | ||
|  | 14ac6446de | ||
|  | 260a9723a4 | ||
|  | 4e7b000dcd | ||
|  | 2254e4c57e | ||
|  | d517697564 | ||
|  | 25a27733b9 | ||
|  | 6ab520984c | ||
|  | 04d7106956 | ||
|  | db5589f2aa | ||
|  | d06dbbb4bd | ||
|  | b7a62bd9e7 | ||
|  | 93ad9a3aa6 | ||
|  | f1855174f0 | ||
|  | a2dedba0ef | ||
|  | 5a65f445f0 | ||
|  | f52289b2c3 | ||
|  | 3b5ea0f15f | ||
|  | 238bcb8698 | ||
|  | 3ee8bcad8c | ||
|  | f0a51bafbe | ||
|  | 944f3bd329 | ||
|  | 8bb7b2e88b | ||
|  | aab0b0b4bf | ||
|  | 083d6c5125 | ||
|  | c2167a2c5f | ||
|  | 1a695e0451 | ||
|  | 8847f325ed | ||
|  | 94c9da468e | ||
|  | 24b38407e4 | ||
|  | f49d1ae860 | ||
|  | 8b3b541a56 | ||
|  | a974e84ad1 | ||
|  | c4f4115bcb | ||
|  | 3c5adbee31 | ||
|  | 55645e3730 | ||
|  | d918bb568c | ||
|  | b1bff62bf7 | ||
|  | d11d389ae4 | ||
|  | a73c159160 | ||
|  | 7adf102d8d | ||
|  | e4d3ff623a | ||
|  | 2433d59f00 | ||
|  | 8c68e76c3e | ||
|  | 0b204de5a9 | ||
|  | 93c811ab70 | ||
|  | 3ff861099a | ||
|  | f22762539f | ||
|  | 677442a3c0 | ||
|  | b73f12cdba | ||
|  | 28fbb61e81 | ||
|  | c1104d1cd6 | ||
|  | e346702292 | ||
|  | 90887779ea | ||
|  | a941b1437c | ||
|  | 04bdcbd490 | ||
|  | 87a815fd6f | ||
|  | d623848c87 | ||
|  | 46abd0cc42 | ||
|  | e315325d91 | ||
|  | f3fc083330 | ||
|  | 92cb57eb7b | ||
|  | d645fbff2f | ||
|  | 8486f4d43a | ||
|  | 60b1a05894 | ||
|  | f955d63707 | ||
|  | f106019938 | ||
|  | 2473249c8b | ||
|  | d13dc4fba3 | ||
|  | 41a0af032c | ||
|  | 70cf7b0c5a | ||
|  | 14f6788ab9 | ||
|  | bb67049d90 | ||
|  | ae2162beaf | ||
|  | 19f2c5e07f | ||
|  | 8abc5b3889 | ||
|  | 4d37c28bc7 | ||
|  | cc0933eee4 | ||
|  | 2de9a804a0 | ||
|  | ffeb2e91f4 | ||
|  | 8cf5ec9e5a | ||
|  | ea0526f29a | ||
|  | cfcb3a69e5 | ||
|  | e3e0378857 | ||
|  | ccc3809daa | ||
|  | c97786e12c | ||
|  | 400071879f | ||
|  | 4cd6e20c91 | ||
|  | 460e3ad395 | ||
|  | 6f08bd6fc5 | ||
|  | eed3a749db | ||
|  | 6587d12fbd | ||
|  | f8dd68ecc4 | ||
|  | f0aef2b853 | ||
|  | 7d27df1b97 | ||
|  | 457ec86c25 | ||
|  | a24c66958f | ||
|  | 617628b886 | ||
|  | 6b7e623d33 | ||
|  | 5ca85b7e83 | ||
|  | 5965bf3332 | ||
|  | baf2dd293b | ||
|  | 2cc19e7e32 | ||
|  | 53ab6f8569 | ||
|  | cf8faac7ef | ||
|  | 86947a384d | ||
|  | 22855279bd | ||
|  | e56fdecdc6 | ||
|  | dc75a5812f | ||
|  | 33e20c9969 | ||
|  | 109204897f | ||
|  | 3b3a2d62f8 | ||
|  | b1b4b3fb63 | ||
|  | d583c68de5 | ||
|  | d360f30af6 | ||
|  | ed033565a4 | ||
|  | 2d6acfae1b | ||
|  | 10da894124 | ||
|  | 6dda8f21e4 | ||
|  | 1a9d759002 | ||
|  | df24e13eb5 | ||
|  | 2ab19937af | ||
|  | 390b86cd8e | ||
|  | 423aba5bab | ||
|  | dc0b9231cd | ||
|  | 3b177bedf8 | ||
|  | 12ce719213 | ||
|  | 320433b1bf | ||
|  | 7f35e2280e | ||
|  | c514d988df | ||
|  | 749a080397 | ||
|  | b105a12505 | ||
|  | abaf363ddd | ||
|  | 16db9d4290 | ||
|  | a694b0364d | ||
|  | b68835f171 | ||
|  | 32714c5dac | ||
|  | 245e06f026 | ||
|  | e0111d3fe6 | ||
|  | a71d4223ff | ||
|  | 20cba6411b | ||
|  | 502a8112b5 | ||
|  | 308c6ee4da | ||
|  | cae003d4fa | ||
|  | b9b900e908 | ||
|  | 8bdba9178a | ||
|  | 97f11e38cd | ||
|  | c4f5df0cd0 | ||
|  | 9ed3a6748a | ||
|  | 359c0354f6 | ||
|  | fc77c089fa | ||
|  | 137a7ac48c | ||
|  | 42b60aef4e | ||
|  | 5ab7380ad1 | ||
|  | afa25df1af | ||
|  | 5cb888328e | ||
|  | 78aeb94917 | ||
|  | 5f3e9a19ea | ||
|  | 420e8c001b | ||
|  | c63b8a4ebc | ||
|  | 5f5feaed5f | ||
|  | 87a1f616b0 | ||
|  | cc051544f9 | ||
|  | 85a438a40f | ||
|  | 877260a243 | ||
|  | 83d99043a8 | ||
|  | 6a57d25f4a | ||
|  | 91473e731e | ||
|  | 1d91ac1169 | ||
|  | 2850477a71 | ||
|  | 651b1c92c3 | ||
|  | 77e74eb37b | ||
|  | 5bb2bc7077 | ||
|  | 98a001a8ca | ||
|  | 0d75ff336d | ||
|  | 8567f1655e | ||
|  | 68b94737ed | ||
|  | 094c92ed85 | ||
|  | 42ab6deff1 | ||
|  | 3a257e1e00 | ||
|  | 2bf9a353a6 | ||
|  | bbe41febf1 | ||
|  | 031362a633 | ||
|  | 4418f8bfce | ||
|  | 364175fa9d | ||
|  | 13cf2b48e1 | ||
|  | e4f6694223 | ||
|  | 59093f1721 | ||
|  | db5e79a19b | ||
|  | f0b1585b52 | ||
|  | 50228c5970 | ||
|  | b98e85016a | ||
|  | bc540eefb6 | ||
|  | 3f1c4b4117 | ||
|  | 5e7689a151 | ||
|  | 42845cfcc0 | ||
|  | caad0eca67 | ||
|  | 67f8ec7f87 | ||
|  | d8d37a66e4 | ||
|  | 69db23f2f6 | ||
|  | c3f6bcad56 | ||
|  | ab1521bf26 | ||
|  | fafe8b88c2 | ||
|  | 9276988ff6 | ||
|  | 85179edf1b | ||
|  | 2f1ba6cf1f | ||
|  | 93674b4e29 | ||
|  | 20851664e8 | ||
|  | 38c87a056c | ||
|  | ad77565508 | ||
|  | 0e02e21967 | ||
|  | 1e35a6ce5e | ||
|  | 90b167eba1 | ||
|  | 5b1defad9f | ||
|  | 8dc1ad8168 | ||
|  | 126a42056d | ||
|  | 5866dad79a | ||
|  | 9dac679b72 | ||
|  | 12ff3abeda | ||
|  | 0f07fb4479 | ||
|  | d9d98439b2 | ||
|  | d251a30cb8 | ||
|  | a2632fdcc8 | ||
|  | 10c818474c | ||
|  | 5e8279cf51 | ||
|  | 4c8c081c31 | ||
|  | bad2baba7f | ||
|  | b5da6f9c74 | ||
|  | 7ec999475e | ||
|  | 742bf85a89 | ||
|  | c9c6f41aad | ||
|  | b0d93df387 | ||
|  | 3e20892fdf | ||
|  | 369f8b3fe0 | ||
|  | 337dfba2b8 | ||
|  | 493687b5bb | ||
|  | c7587960fb | ||
|  | 5c962aa899 | ||
|  | 3e9d2a8062 | ||
|  | c2aa8a206a | ||
|  | 6d8ea2b6a4 | ||
|  | b581e33611 | ||
|  | 5e43a02cd3 | ||
|  | 6f37d5ca5c | ||
|  | 3263008379 | ||
|  | 4588089bd6 | ||
|  | 44b75f0b92 | ||
|  | 162bd6a8c3 | ||
|  | 0c13603185 | ||
|  | ed2a45e975 | ||
|  | 0fa165c606 | ||
|  | fe63ab1242 | ||
|  | faf808da69 | ||
|  | 71709cd662 | ||
|  | d92040b804 | ||
|  | 3662fbb462 | ||
|  | d89ae3ebbf | ||
|  | 6175fecdd8 | ||
|  | fab632da62 | ||
|  | c1e3b0d971 | ||
|  | 7b15ba31ea | ||
|  | f11d4ccd45 | ||
|  | fbec803129 | ||
|  | 0f57d1a433 | ||
|  | 63829b6382 | ||
|  | 8ac3899ddc | ||
|  | 59fb4ea6f8 | ||
|  | 92bb9bb3c3 | ||
|  | 1795c491a8 | ||
|  | ea333c19f7 | ||
|  | 28ef879c07 | ||
|  | 10839abf24 | ||
|  | 9832394f8e | ||
|  | dd89ea3731 | ||
|  | 5d9fd6dc3b | ||
|  | f7c87e26db | ||
|  | f98f4085bf | ||
|  | 543519d055 | ||
|  | 5a9fcd9267 | ||
|  | fe2360883f | ||
|  | b45ddadb09 | ||
|  | a3cbe80a36 | ||
|  | ee6c6266cc | ||
|  | d6bd35287f | ||
|  | 962a29110c | ||
|  | a242475b38 | ||
|  | d59bf84470 | ||
|  | 161ee17f45 | ||
|  | 8aa00b0cfc | ||
|  | afe89c3621 | ||
|  | bdf68311b4 | ||
|  | afa69f4c0e | ||
|  | 6fe2b24592 | ||
|  | 7442b356e3 | ||
|  | 1d7be6457f | ||
|  | c9ff05ba80 | ||
|  | faae184f1c | ||
|  | 515a8a9bbb | ||
|  | 58914e5c5f | ||
|  | c944eaab5c | ||
|  | d3d9533493 | ||
|  | 9c474cc089 | ||
|  | 3f1b0b986f | ||
|  | 28e08ebaf5 | ||
|  | 3213c03754 | ||
|  | 4447288a4c | ||
|  | eee4e83a1e | ||
|  | a67b492620 | ||
|  | 6062ff2748 | ||
|  | 3b11195caa | ||
|  | 9946ea111c | ||
|  | 7074d66f8e | ||
|  | 008b26f329 | ||
|  | b246f0779f | ||
|  | dc89218702 | ||
|  | 3c013b3533 | ||
|  | fe0d0f08e4 | ||
|  | 38b5063038 | ||
|  | e55481a454 | ||
|  | 7063a88513 | ||
|  | a9bf3d0226 | ||
|  | 781b3aff1b | ||
|  | b011b9203b | ||
|  | 39344fcae5 | ||
|  | a046b357da | ||
|  | d8e4020cec | ||
|  | f80b172022 | ||
|  | 66fc4b536c | ||
|  | 1f97ccdddb | ||
|  | 308d6889a7 | ||
|  | c3b9982c44 | ||
|  | fab796e4e4 | ||
|  | 749db6ba82 | ||
|  | 12d6c4ddf5 | ||
|  | 430a03bb14 | ||
|  | 43f21fc7aa | ||
|  | b27da3d1a0 | ||
|  | 4463a8e3b2 | ||
|  | 9e74ddac48 | ||
|  | 5f62e41d62 | ||
|  | 19a103d3a0 | ||
|  | 8fb6bc059e | ||
|  | 8f61a0d258 | ||
|  | 7fa589e430 | ||
|  | 6d8d826764 | ||
|  | a40e84e1f6 | ||
|  | 4844c2123f | ||
|  | 236d437430 | ||
|  | ae726c199b | ||
|  | e7f54f005c | ||
|  | e7b1ec6904 | ||
|  | f4f664a4a2 | ||
|  | fec52a8151 | ||
|  | d8b4c1e209 | ||
|  | eac853c7dd | ||
|  | a04337a270 | ||
|  | 50d7e16365 | ||
|  | ef7bc931b7 | ||
|  | 41de771074 | ||
|  | 2ebdd6c5cb | ||
|  | b51cfcc753 | ||
|  | 91cc03dd80 | ||
|  | 9d673a213e | ||
|  | 97e789538e | ||
|  | e05ff01d57 | ||
|  | 0748dff355 | ||
|  | 28d4084aa0 | ||
|  | afd2ccfb4f | ||
|  | 057127f4de | ||
|  | 2937b25d6d | ||
|  | 419f26db87 | ||
|  | be1b9c0e43 | ||
|  | 894d28c60b | ||
|  | 06cc08d9f7 | ||
|  | 75393c0b28 | ||
|  | bdc1da70c1 | ||
|  | 7cef990ba6 | ||
|  | fb0f12bb20 | ||
|  | e94b8d3e84 | ||
|  | 8c00e1fdf4 | ||
|  | a31fa82284 | ||
|  | 5d0af45d8f | ||
|  | e9f248020e | ||
|  | a8e1058af6 | ||
|  | 1a087fd799 | ||
|  | 50c81533e0 | ||
|  | 5eab9aa4b1 | ||
|  | 1970cbfe37 | ||
|  | 6d736201f9 | ||
|  | 51ec52b573 | ||
|  | d099387186 | ||
|  | 3f91e4da66 | ||
|  | 4124159378 | ||
|  | 18f3789e29 | ||
|  | a713c92530 | ||
|  | 7828af591e | ||
|  | d432dba726 | ||
|  | 72ae87857f | ||
|  | 724acff591 | ||
|  | 482b432e2c | ||
|  | 351c0cb0a8 | ||
|  | 314a0fb5d6 | ||
|  | a301bf8bf5 | ||
|  | 37b3601c47 | ||
|  | 6e944485f0 | ||
|  | 431266069e | ||
|  | d48a09e68b | ||
|  | 1db1ec7b5e | ||
|  | 2a8f0a4eab | ||
|  | 79f3669fac | ||
|  | aab0f2dcd5 | ||
|  | a47831e278 | ||
|  | f1a5e8a42c | ||
|  | 723e9b3cba | ||
|  | ff759a8074 | ||
|  | 4de1056d82 | ||
|  | 884b8da8bf | ||
|  | 044ad77a4b | ||
|  | 1fe8b388a3 | ||
|  | 79fe7d684c | ||
|  | c409af0ea8 | ||
|  | 5110eaff96 | ||
|  | db3eee72b5 | ||
|  | 3bcff91328 | ||
|  | e843f192ec | ||
|  | f3d2053878 | ||
|  | efe8fbbd11 | ||
|  | ce507b3b52 | ||
|  | 85de227003 | ||
|  | 7c6eb7c794 | ||
|  | 2037741b54 | ||
|  | d534a8952d | ||
|  | 0b05b883cb | ||
|  | 6937aa5ddd | ||
|  | 8f6b24e0aa | ||
|  | ba3b64a6c6 | ||
|  | d23b32a830 | ||
|  | ceba08a801 | ||
|  | e0bb03a53f | ||
|  | 0881c6a20b | ||
|  | f88a4b1791 | ||
|  | 2b43e3ee23 | ||
|  | 2e063f91bc | ||
|  | 79062e2034 | ||
|  | a413f3cded | ||
|  | 4baaaa8d59 | ||
|  | c99b35428b | ||
|  | 3c8e4f8bbf | ||
|  | aa9a37da38 | ||
|  | 85efb48c1f | ||
|  | 888e7ee023 | ||
|  | d7bbf8a8da | ||
|  | e2ee88de84 | ||
|  | 1d1ab5b7b2 | ||
|  | 54c863d48f | ||
|  | acc633b4b6 | ||
|  | 766ccf85c2 | ||
|  | 7ab5a2be47 | ||
|  | 7a6e1fe566 | ||
|  | 4749c92252 | ||
|  | 0e035e47df | ||
|  | 1359545e13 | ||
|  | 5b2f24f842 | ||
|  | bb73e30909 | ||
|  | 490903ca25 | ||
|  | 901b32297e | ||
|  | dd72046922 | ||
|  | 6286b34d00 | ||
|  | 81f4e0de56 | ||
|  | 596fbfb517 | ||
|  | da756fa568 | ||
|  | 30aebc4ee3 | ||
|  | 45138ce5ca | ||
|  | f26b9feeaf | ||
|  | 9e47d933af | ||
|  | f309a9d537 | ||
|  | a786b37cb9 | ||
|  | 6a519a30a2 | ||
|  | 81ae552e69 | ||
|  | 0ec04a3624 | ||
|  | 81d5b47fce | ||
|  | ed31a0cf15 | ||
|  | 201d1926bc | ||
|  | 9ee6655bfa | ||
|  | c4beab6b0d | ||
|  | 34b6643913 | ||
|  | 98e391b867 | ||
|  | 19eb8e9a6d | ||
|  | 43b7aa40c3 | ||
|  | 747af44fc1 | ||
|  | a73381e24b | ||
|  | d5ef428edd | ||
|  | 5fa4d227b8 | ||
|  | cc7e3b0c26 | ||
|  | 473a2ae275 | ||
|  | 7f5d47f39d | ||
|  | 6031f146aa | ||
|  | 020a469f3b | ||
|  | 091de3aa66 | ||
|  | b837f7608c | ||
|  | afe9367bac | ||
|  | 9bd9023cb6 | ||
|  | 8502cf8498 | ||
|  | 33dade0584 | ||
|  | 84cc2ad0fa | ||
|  | dc2d3bc7c0 | ||
|  | 64df557423 | ||
|  | 715cc77e76 | ||
|  | b80d1af3d7 | ||
|  | f05f534fd2 | ||
|  | c0837ead0e | ||
|  | a1f135bd66 | ||
|  | 978f4ecc58 | ||
|  | 46a8d96997 | ||
|  | c283224000 | ||
|  | a6ef755139 | ||
|  | 29a257d17a | ||
|  | 368b76a183 | ||
|  | 8bb861124d | ||
|  | 2f884ec778 | ||
|  | 8c561e92c8 | ||
|  | 633b9180d7 | ||
|  | 0e2d0e1b6f | ||
|  | ea4d65ceee | ||
|  | d47ac84d2e | ||
|  | a97759aa35 | ||
|  | 3fcfd4abdd | ||
|  | 6d771da9a9 | ||
|  | 6201247875 | ||
|  | 8c367bcc53 | ||
|  | 8198132ca7 | ||
|  | cf3b4e9e63 | ||
|  | 987dbf8a92 | ||
|  | acf8c9bc4a | ||
|  | 7173895d36 | ||
|  | 43530d4a5f | ||
|  | fefabef9ee | ||
|  | 0dd40a941b | ||
|  | 24b6670bc4 | ||
|  | 76661abbf5 | ||
|  | e9dc9eff9b | ||
|  | 2f160743bc | ||
|  | 98616e772c | ||
|  | bc014fec9b | ||
|  | 732598d9d2 | ||
|  | 2979acd5b8 | ||
|  | fd20cd524e | ||
|  | 7b80ae42e1 | ||
|  | b7012674c6 | ||
|  | c76bd39280 | ||
|  | 09cd710f66 | ||
|  | d9aadf9d98 | ||
|  | 86716b5ffb | ||
|  | 96e3aab3b4 | ||
|  | 72c78fe3ad | ||
|  | abe746020b | ||
|  | 8e1c15419c | ||
|  | ee47646cf7 | ||
|  | 32d9acdaa5 | ||
|  | 4eb3bd496b | ||
|  | 3c4f4d27d6 | ||
|  | 2060af8a92 | ||
|  | 21bf74a467 | ||
|  | 677833a277 | ||
|  | 0b5e4f2dd7 | ||
|  | 06a1f30350 | ||
|  | c1ff241550 | ||
|  | 5717f75eac | ||
|  | 6b3b68a4e5 | ||
|  | 8bda2d0add | ||
|  | bc02c9573c | ||
|  | 86bb5503ab | ||
|  | 21ce23d27d | ||
|  | 6c75baecb2 | ||
|  | 8167608f04 | ||
|  | 514e31aef9 | ||
|  | 20a31a6d38 | ||
|  | 4f0aa1bc02 | ||
|  | be0ef6e594 | ||
|  | 93a8dbd31a | ||
|  | cf931e8ddf | ||
|  | 510bfbf268 | ||
|  | 2f93bb969b | ||
|  | 27365c9f7b | ||
|  | b1d2e188f5 | ||
|  | e4f67df2a1 | ||
|  | e094ea3d2a | ||
|  | 7515b745b5 | ||
|  | 0e902a7e71 | ||
|  | 2dfb443625 | ||
|  | e6e7747ae1 | ||
|  | d80ea6c0f5 | ||
|  | ac6e3988a8 | ||
|  | bfd98f3767 | ||
|  | cc8bc1339f | ||
|  | 542d1dc600 | ||
|  | 1c66c88f95 | ||
|  | dc880c672a | ||
|  | 073f38c68c | ||
|  | 6a6d13b075 | ||
|  | 9bb7e72c69 | ||
|  | 7436e01188 | ||
|  | 3d272d0f10 | ||
|  | ee66a12dad | ||
|  | 47de85b012 | ||
|  | f85b63a972 | ||
|  | e630919ef8 | ||
|  | 2e3fd49b40 | ||
|  | dd54af2c08 | ||
|  | 737bf411ff | ||
|  | 5070b1a6b5 | ||
|  | c849da92cf | ||
|  | 6a4e7201fe | ||
|  | ffa6dea452 | ||
|  | 30c1d31a99 | ||
|  | 6934a2d5c3 | ||
|  | b9906ced9a | ||
|  | 5500b4fe35 | ||
|  | 2353f12cd6 | ||
|  | 1b8cab0f58 | ||
|  | 869c1d4ea4 | ||
|  | 9b938195a8 | ||
|  | bb3c52821a | ||
|  | 81c8ae95e2 | ||
|  | 6098570ab7 | ||
|  | d033c24fe5 | ||
|  | 4995e52dd6 | ||
|  | c685a31056 | ||
|  | c32ce3bb7b | ||
|  | c0d8f904b3 | ||
|  | 8dba0dac9e | ||
|  | d0bf4a5329 | ||
|  | 7b28ba6078 | ||
|  | e6466c3c3a | ||
|  | d96d3064d6 | ||
|  | d4589ed7e3 | ||
|  | 5cfc52ea18 | ||
|  | 3fcacd8339 | ||
|  | 49fe13f22f | ||
|  | 4d27ba1bda | ||
|  | b715ac8bf4 | ||
|  | d96049416f | ||
|  | 1c4df785fd | ||
|  | 8f94c5efeb | ||
|  | 7cffa1ece7 | ||
|  | 1ac18d7b33 | ||
|  | 1111d2518b | ||
|  | ba7416450e | ||
|  | 3b02d36acb | ||
|  | c2aa9a5337 | ||
|  | 70fb181b7b | ||
|  | e64f4e3f39 | ||
|  | e4d518749f | ||
|  | 7dcca2c907 | ||
|  | 4a027b8a79 | ||
|  | c2c6e6080e | ||
|  | 4f87ebdf0a | ||
|  | 09abec15b1 | ||
|  | 33d0d12bc8 | ||
|  | f488869635 | ||
|  | 6382564727 | ||
|  | 7476b4c7db | ||
|  | daf3e6a47a | ||
|  | 19b6cba398 | ||
|  | 5bd3d12c7b | ||
|  | c9db74ebca | ||
|  | f8a88cc1a4 | ||
|  | 4a081bf125 | ||
|  | 8a68a3e861 | ||
|  | 7a9dd9ad9c | ||
|  | 6c01d0f9d8 | ||
|  | 45a53ac168 | ||
|  | dabb2790c9 | ||
|  | c66c5ea53c | ||
|  | 0a98ba6985 | ||
|  | bb8e491856 | ||
|  | 5590d31336 | ||
|  | dc7e48dc53 | ||
|  | 371d357218 | ||
|  | f22960ad59 | ||
|  | 34ead436b0 | ||
|  | 808d5a75ae | ||
|  | 55e897faac | ||
|  | 5a5dda21e4 | ||
|  | f085655daa | ||
|  | 5cf9c07b73 | ||
|  | 9751089807 | ||
|  | 211eeea05d | ||
|  | b2516117f5 | ||
|  | 2816b3edae | ||
|  | 242398c724 | ||
|  | 289583325d | ||
|  | 0f793ebd65 | ||
|  | ce014044ea | ||
|  | 1064e531f0 | ||
|  | dc3128fb3e | ||
|  | 51a3521834 | ||
|  | d40aa7260f | ||
|  | fc8c4063f2 | ||
|  | f204c77ba3 | ||
|  | 7a8545273c | ||
|  | 6a9575e9f4 | ||
|  | c13e79e9c3 | ||
|  | 62088259ae | ||
|  | 925ebcc06e | ||
|  | a20eaf852f | ||
|  | 84a6a5235e | ||
|  | 8235b7b96d | ||
|  | 0376e0d711 | ||
|  | 6bd0682e8c | ||
|  | e24c22f9be | ||
|  | 673a6bbe2c | ||
|  | cf32a33984 | ||
|  | f4ca8cd738 | ||
|  | 98c1bc276d | ||
|  | 629536b562 | ||
|  | 422109868d | ||
|  | bcc7834650 | ||
|  | 1161e4f6c1 | ||
|  | 14435c24ac | ||
|  | 22ede79799 | ||
|  | 6cb3699ee9 | ||
|  | 6c65d3830e | ||
|  | cdcf39fe82 | ||
|  | 1441042458 | ||
|  | 71403e5acd | ||
|  | 3d70bc722a | ||
|  | b2f50da322 | ||
|  | 2a50c66df8 | ||
|  | 8de47c0a6e | ||
|  | 023391e22a | ||
|  | a4ddfd404f | ||
|  | 7307e558cb | ||
|  | 47356f5221 | ||
|  | c6f8950b64 | ||
|  | 58c8311d56 | ||
|  | 071f4eacde | ||
|  | f96bdc578e | ||
|  | e03a0fffa9 | ||
|  | 8e2c12f8d9 | ||
|  | 114420e8fd | ||
|  | ba49b2c681 | ||
|  | 5391fc962a | ||
|  | 7cec7ae608 | ||
|  | d6211af5bd | ||
|  | ef114e31c2 | ||
|  | fd74a03479 | ||
|  | 428bf634e9 | ||
|  | c49f722e4f | ||
|  | d4d95a43b6 | ||
|  | 8789d983ed | ||
|  | 10faa96bcf | ||
|  | 42d31b9ee6 | ||
|  | c9dc9b4fe9 | ||
|  | a345089c8b | ||
|  | 67c268e13d | ||
|  | f13e02a1a9 | ||
|  | d887ab126b | ||
|  | 1a7868159a | ||
|  | c6a1c8e8c4 | ||
|  | fba339f666 | ||
|  | 09d41a9708 | ||
|  | ce85c8d986 | ||
|  | 4630a162af | ||
|  | fde157ff50 | ||
|  | 51f875c02d | ||
|  | f0957c838f | ||
|  | f5bebef37f | ||
|  | 80a15089b4 | ||
|  | cb35604ef5 | ||
|  | 61681bb1d6 | ||
|  | 8edf399631 | ||
|  | d5ffd1432f | ||
|  | e73bf03615 | ||
|  | 665fe0e01e | ||
|  | 1a226c4dc6 | ||
|  | a866aa9c18 | ||
|  | d9089b798c | ||
|  | d34ebd4d1b | ||
|  | 716aa74004 | ||
|  | 2aae76c9bc | ||
|  | 5fc3ca0e23 | ||
|  | 5bb27109bf | ||
|  | 7406ab6017 | ||
|  | 08fccc4e77 | ||
|  | c1d50e82e1 | ||
|  | 9777af7cb5 | ||
|  | fd86035865 | ||
|  | a8ec032553 | ||
|  | 66ee27c5fa | ||
|  | 17a737ca88 | ||
|  | f30ff7a2fd | ||
|  | c102828a99 | ||
|  | cb0e631b85 | ||
|  | 75e7c0e50d | ||
|  | 62b2adab78 | ||
|  | fc0cf1ff51 | ||
|  | 0f4d46671f | ||
|  | 048f9c0294 | ||
|  | 0529eed0c9 | ||
|  | ca77842b5b | ||
|  | 8c169dc82b | ||
|  | 195342f7db | ||
|  | cfaaef7860 | ||
|  | e939d5e96e | ||
|  | 6fa8b7f5f1 | ||
|  | a2d03c14ae | ||
|  | c667a0e74c | ||
|  | 8123828113 | ||
|  | 72b8dbb45b | ||
|  | 9f4628cf0a | ||
|  | ec4d24af91 | ||
|  | 7703875740 | ||
|  | 6442bb8a13 | ||
|  | 51373f59e2 | ||
|  | 6cc56879d3 | ||
|  | f29d7c9252 | ||
|  | 2f7f53ed96 | ||
|  | da89460830 | ||
|  | 9e006d42bb | ||
|  | 4c02bab4ee | ||
|  | 5800ed41f1 | ||
|  | 18b5b4901f | ||
|  | 368418cf56 | ||
|  | 94031a52a5 | ||
|  | d67f91e7ed | ||
|  | 3e6cadf3d8 | ||
|  | f37697c4fb | ||
|  | 0c5a76b391 | ||
|  | 69448c7329 | ||
|  | 8e9815fb91 | ||
|  | bf1afcfe8a | ||
|  | 2980818f0d | ||
|  | 9da58dbaf0 | ||
|  | 4cdd7978cf | ||
|  | 40d81358f4 | ||
|  | c7b62aed91 | ||
|  | 55d71659f8 | ||
|  | c0e7d6d826 | ||
|  | f809377de8 | ||
|  | 9767bd9697 | ||
|  | 3a55528552 | ||
|  | 56197ffe3a | ||
|  | 0f0d0c046c | ||
|  | 8d5b546763 | ||
|  | 19c9707d62 | ||
|  | ecc4973645 | ||
|  | 79e004a040 | ||
|  | 3169f93cc2 | ||
|  | c1a1a73599 | ||
|  | 48308db45b | ||
|  | 3f37e96f78 | ||
|  | db1b0ccb79 | ||
|  | df161ce672 | ||
|  | 4e21a5e557 | ||
|  | 72fe30892e | ||
|  | 19fa69811b | ||
|  | 0ddb4c625d | ||
|  | d373105b32 | ||
|  | 36dc1d2f97 | ||
|  | 11fa2cb35d | ||
|  | 546f07156f | ||
|  | 7e7117632d | ||
|  | 954226da0d | ||
|  | 38a1291c5b | ||
|  | 998bf92ad4 | ||
|  | 974ba40f28 | ||
|  | e57d8ba0ef | ||
|  | 6b79c6135f | ||
|  | 28b311b7ed | ||
|  | dcda513901 | ||
|  | 72c400794c | ||
|  | a747d8c2d5 | ||
|  | a3aec6b939 | ||
|  | 042409f870 | ||
|  | 5b8f4f4069 | ||
|  | d132d63c1d | ||
|  | 4374506981 | ||
|  | ef8b936069 | ||
|  | 36e3bfffb4 | ||
|  | 91a38bdb60 | ||
|  | f169a68319 | ||
|  | ee886f98dd | ||
|  | a3826cc6a7 | ||
|  | ba33b832ba | ||
|  | f6c017176b | ||
|  | 7a01b115bb | ||
|  | 1dc021e871 | ||
|  | c9f916ebab | ||
|  | ff627fd128 | ||
|  | bba57f8d2b | ||
|  | 695873d35a | ||
|  | 15da19dcea | ||
|  | 4312a01707 | ||
|  | ecd8f97d8b | ||
|  | d5bdc1600b | ||
|  | dfa077fd5f | ||
|  | 06abe63fb1 | ||
|  | 5155770213 | ||
|  | 9d507b09ca | ||
|  | 9c4a712dc7 | ||
|  | f1d5bbb036 | ||
|  | 69ed0aebc3 | ||
|  | 549e56e220 | ||
|  | 450f4d9a5a | ||
|  | 6533a9793c | ||
|  | 2000cadb17 | ||
|  | 083c321efa | ||
|  | f64c4a981f | ||
|  | 3ac8ce03bf | ||
|  | 66fca8710e | ||
|  | 1e245ece46 | ||
|  | 81efce03ba | ||
|  | 4e549dd426 | ||
|  | 52f74ff7e0 | ||
|  | 3c71b815f5 | ||
|  | 9efd48fe51 | ||
|  | 4609ee75b6 | ||
|  | 963ea4177e | ||
|  | 17e6940a42 | ||
|  | 315a9ceba3 | ||
|  | a2bdeedb09 | ||
|  | da5700d2d7 | ||
|  | 90e7f30247 | ||
|  | 3ccf6ba892 | ||
|  | e50cd5b745 | ||
|  | db77be5d72 | ||
|  | c36870c23e | ||
|  | e9be007040 | ||
|  | 9e400d9aa6 | ||
|  | 490c8dae75 | ||
|  | 3bcffe375d | ||
|  | 9f81a591e1 | ||
|  | 3db5306c70 | ||
|  | 45029dd084 | ||
|  | b01cd30339 | ||
|  | 09329e1104 | ||
|  | ab0fc2ecfa | ||
|  | bf5d36d6bd | ||
|  | a29527ec96 | ||
|  | 45e7ad8049 | ||
|  | 4d54663efd | ||
|  | 29d386cc51 | ||
|  | ba1a67969b | ||
|  | 390ea5419e | ||
|  | 0fdeec7cc4 | ||
|  | e34d883e50 | ||
|  | 507871687b | ||
|  | ed58f62cd1 | ||
|  | 94bc4e7125 | ||
|  | 5832f7930d | ||
|  | 0066a20c22 | ||
|  | 774e4bfced | ||
|  | 054c7a76a4 | ||
|  | c7f3b77aac | ||
|  | a6a4620374 | ||
|  | 5148c62d1c | ||
|  | 6fc863a91e | ||
|  | e066a154a1 | ||
|  | d432edaed2 | ||
|  | 8f34f4e80b | ||
|  | 39b751acf5 | ||
|  | bd5e8ba961 | ||
|  | ed20327c41 | ||
|  | 991c68c394 | ||
|  | 2acc31a4e7 | ||
|  | b9733e3dfa | ||
|  | bb106bfce7 | ||
|  | daf1388a6a | ||
|  | 8226f1fa75 | ||
|  | e675512fa3 | ||
|  | 65e67b6c3e | ||
|  | 7612481570 | ||
|  | f6c7cb5804 | ||
|  | 2201c9062f | ||
|  | ca3da262da | ||
|  | 5847f92bef | ||
|  | 31ee1be81e | ||
|  | 6bccdd015f | ||
|  | cecea318da | ||
|  | 8663ec6880 | ||
|  | 9b03f128aa | ||
|  | 8a51f97616 | ||
|  | ee74ed9ce9 | ||
|  | 0f947c756e | ||
|  | cae7949a48 | ||
|  | be58b614e1 | ||
|  | b0a01fa4b2 | ||
|  | 9734228001 | ||
|  | 9df1d44bc4 | ||
|  | 13d887028a | ||
|  | 83a8979309 | ||
|  | 75c29f1cb7 | ||
|  | d9d15e41c7 | ||
|  | d3598d5854 | ||
|  | 3a8aaee5d7 | ||
|  | 4fcf57d42c | ||
|  | adb0891335 | ||
|  | d21e719cc1 | ||
|  | 5807ab82c1 | ||
|  | 65cb04da63 | ||
|  | 312e3611b1 | ||
|  | 46acc62279 | ||
|  | 529b358c9b | ||
|  | 7fca04404e | ||
|  | 3a1cc6a2be | ||
|  | 5b76c91004 | ||
|  | cf87837f7d | ||
|  | 5a0a7b907b | ||
|  | 6a2b1669b3 | ||
|  | ca8264b3f4 | ||
|  | b44ecd8819 | ||
|  | 987942959e | ||
|  | 91992b48c1 | ||
|  | c9a335a6f9 | ||
|  | b7ed159b50 | ||
|  | c72961a52a | ||
|  | afe6afca36 | ||
|  | 050acd239c | ||
|  | 24505ee4f5 | ||
|  | 63a249aba3 | ||
|  | 7bd94df2a0 | ||
|  | 761161a8e5 | ||
|  | 513579a7ee | ||
|  | 7165483d83 | ||
|  | f8bcf219cb | ||
|  | 590506e306 | ||
|  | 9a5439c580 | ||
|  | 6b2f5fbb19 | ||
|  | 051c147b41 | ||
|  | 9111adf15f | ||
|  | ba18b27371 | ||
|  | 2a287b2ae6 | ||
|  | fc9040f715 | ||
|  | 0029022ef6 | ||
|  | 94f728d3fd | ||
|  | d53ced7830 | ||
|  | 053d8c44c2 | ||
|  | 9f5767ea16 | ||
|  | e8d76b0555 | ||
|  | c2675600f6 | ||
|  | 6f087b4ec1 | ||
|  | e94708606d | ||
|  | c248f1a762 | ||
|  | 28402b0894 | ||
|  | 7dd98e99f9 | ||
|  | dba195b396 | ||
|  | 88b153bc12 | ||
|  | d4a47dc974 | ||
|  | fe3ea6edfd | ||
|  | 6c8fc4846b | ||
|  | b14a0e0dde | ||
|  | e982f5076f | ||
|  | 54d9656f09 | ||
|  | 42188b9f49 | ||
|  | 49da324c5d | ||
|  | 9bf87697fd | ||
|  | f368f5a9c4 | ||
|  | eea85485e6 | ||
|  | 1a544b3b82 | ||
|  | 8b38fe9fe0 | ||
|  | 1bf4addf63 | ||
|  | 407e16e900 | ||
|  | 6e9fe3248a | ||
|  | d8cf86fd6f | ||
|  | f8aa4a9588 | ||
|  | c249907846 | ||
|  | 57c1524a9a | ||
|  | d8d82e2ba3 | ||
|  | 807b512ef7 | ||
|  | b2f06b6777 | ||
|  | d7adff9a65 | ||
|  | b0d7e11d48 | ||
|  | fc9cdb61f2 | ||
|  | 9c00492dc2 | ||
|  | 1a6babd199 | ||
|  | 1b693eed37 | ||
|  | afb566b6b4 | ||
|  | f870e9ed3e | ||
|  | 4bcf13cb58 | ||
|  | 50e2dcbcd5 | ||
|  | 6104bb98f1 | ||
|  | 946a6d6041 | ||
|  | 372c213c2c | ||
|  | a5a79d3ab7 | ||
|  | e6c5cfb703 | ||
|  | 7843eccae8 | ||
|  | 7ca153abd0 | ||
|  | 33b4774c49 | ||
|  | c243481432 | ||
|  | 80873e4ea9 | ||
|  | 4e4a1f11e6 | ||
|  | 9bbe405cd0 | ||
|  | c440a4c730 | ||
|  | a1251371d7 | ||
|  | 7d702e8332 | ||
|  | 43d7c8d48c | ||
|  | 7423583508 | ||
|  | 08b0838f9a | ||
|  | 038d821a7c | ||
|  | 6a218814d3 | ||
|  | 905f89b0f5 | ||
|  | 14882bda78 | ||
|  | 781fa4634b | ||
|  | cdb173fd6e | ||
|  | 466cb4be89 | ||
|  | c39e2ffd56 | ||
|  | 17bf09e276 | ||
|  | bc01f9f8fd | ||
|  | c0870c5694 | ||
|  | 3b5174a2ea | ||
|  | af6885f3e8 | ||
|  | e01996095f | ||
|  | 5d86f7b6ba | ||
|  | 8d6ac6406d | ||
|  | 40ff54f67e | ||
|  | cce7ac09d0 | ||
|  | 73a18891c5 | ||
|  | fe22cedc1d | ||
|  | fa09c7c8b2 | ||
|  | 15e28e3cc0 | ||
|  | 2cb4f6b1fc | ||
|  | b17a483b85 | ||
|  | 7c3e5443ab | ||
|  | f95a2851c8 | ||
|  | 2b2eee352f | ||
|  | 11569d8056 | ||
|  | bdf87452b6 | ||
|  | 0c6bf81c24 | ||
|  | f2fa26fb07 | ||
|  | f5e212ff1e | ||
|  | 461e6562ca | ||
|  | fd67d08402 | ||
|  | e6411d11b1 | ||
|  | dd81d947fc | ||
|  | 23b887c30e | ||
|  | c4eae3f130 | ||
|  | 41a04a2849 | ||
|  | ed1d34e678 | ||
|  | f44487338d | ||
|  | 7aced85a31 | ||
|  | fbe0e2d6eb | ||
|  | 6e34f0697c | ||
|  | a835f9f0cb | ||
|  | 16715673c3 | ||
|  | c48c74f173 | ||
|  | f262348497 | ||
|  | 7185bcd51f | ||
|  | 28d05e2449 | ||
|  | 7fafa21a1b | ||
|  | 84f598e143 | ||
|  | e30f8628db | ||
|  | 0be9c88106 | ||
|  | e046fc1ac5 | ||
|  | 3a476ac493 | ||
|  | e33ec0cf50 | ||
|  | b4b70a988e | ||
|  | e66b381070 | ||
|  | 771b598c09 | ||
|  | cd44f13171 | ||
|  | aa6b72ac87 | ||
|  | a467fe5ed7 | ||
|  | 467411c6c3 | ||
|  | 2648b7ca54 | ||
|  | de35c7024a | ||
|  | 9d219c163d | ||
|  | f7434b5ec8 | ||
|  | 5ed3360c0b | ||
|  | 6f5974f875 | ||
|  | 56db1da3cf | ||
|  | fef71f29c4 | ||
|  | d46b66878a | ||
|  | 6cad80c4ad | ||
|  | 68779caa2e | ||
|  | 2a122ed283 | ||
|  | 17c5fdf0d5 | ||
|  | 0835fdd0d1 | ||
|  | f6274445a2 | ||
|  | 3b0300b834 | ||
|  | 4fbf1fe780 | ||
|  | dcf44fed58 | ||
|  | 7136dc1c72 | ||
|  | 0e4cedbc5e | ||
|  | dc139bcc30 | ||
|  | b204b183de | ||
|  | ab788bc1e3 | ||
|  | 95b4c8d515 | ||
|  | b025644525 | ||
|  | 9e87a60597 | ||
|  | 5a70bea67a | ||
|  | 2a95af3928 | ||
|  | 0a0ca380d3 | ||
|  | 4cfbf7f71c | ||
|  | de43148341 | ||
|  | 0a2aab7d68 | ||
|  | 745821c420 | ||
|  | 57c4c754d0 | ||
|  | 4b5c437533 | ||
|  | 8d63b6a1ed | ||
|  | 245a8adbf9 | ||
|  | 4f7d98aace | ||
|  | b0c693cc3a | ||
|  | b2cca10e8b | ||
|  | a84b2ab5bb | ||
|  | 4565342b05 | ||
|  | 0ad54cc2d1 | ||
|  | 865853da19 | ||
|  | 392ed706fd | ||
|  | 0ff0f25aaf | ||
|  | c157960846 | ||
|  | a5c00b5c81 | ||
|  | 472bbdb59f | ||
|  | 7877093713 | ||
|  | 8cb2e51407 | ||
|  | d5cee81fb6 | ||
|  | bca020bc4d | ||
|  | 5069f2844c | ||
|  | 252df81f59 | ||
|  | 7f89a4a26f | ||
|  | 40f4167894 | ||
|  | 0ef16989cd | ||
|  | 3df3d6f516 | ||
|  | 10395ef254 | ||
|  | 83854c28db | ||
|  | fcbea2629c | ||
|  | 522360dcb7 | ||
|  | 26bc142cc2 | ||
|  | a4eb8e11c3 | ||
|  | 9fd5d1db56 | ||
|  | 1d05b4c981 | ||
|  | 61f6535be8 | ||
|  | 7dd329b5ee | ||
|  | b761904424 | ||
|  | 36105412b1 | ||
|  | 184b1b018c | ||
|  | f3e1b85d82 | ||
|  | 626d012775 | ||
|  | 9ad9c0ec6a | ||
|  | e13fed9fc6 | ||
|  | eb6d093e56 | ||
|  | 979713c4db | ||
|  | af1ea610ea | ||
|  | d4d9190919 | ||
|  | 4d3d1a02a8 | ||
|  | 30c2aa96d6 | ||
|  | 4edb1f80b0 | ||
|  | 0a82459233 | ||
|  | db87b0dfa5 | ||
|  | e41d5c249f | ||
|  | f82a779817 | ||
|  | cd42cf7583 | ||
|  | 2d5980ff2a | ||
|  | df8a8ea204 | ||
|  | 8957d33e49 | ||
|  | d49c7a3adb | ||
|  | 28fe1e4c8f | ||
|  | 0c7f4e2168 | ||
|  | 4fdd09a262 | ||
|  | d6878512c4 | ||
|  | 8b1b8250ff | ||
|  | 9dccbf747e | ||
|  | 08727e1938 | ||
|  | 7584820987 | ||
|  | d572356642 | ||
|  | 3b5a2815a9 | ||
|  | f3cf01df25 | ||
|  | 63e6e64ad3 | ||
|  | e8d7b48bff | ||
|  | 12944d1ebd | ||
|  | fa1ff6e393 | ||
|  | 98546b6e6a | ||
|  | 2fef6fd1fa | ||
|  | 20cf91f1dc | ||
|  | 2efa78d590 | ||
|  | 880af0671a | ||
|  | 62471e4531 | ||
|  | b15f8535f8 | ||
|  | 7a3a4493da | ||
|  | 11078235c4 | ||
|  | f3e05cd08a | ||
|  | 0ca3cabbe8 | ||
|  | 44a75c1291 | ||
|  | 4a4513a746 | ||
|  | 60ff8660de | ||
|  | 6fa0d671c0 | ||
|  | f478d7c9f0 | ||
|  | 53e3e08d70 | ||
|  | c4d1ccb6f5 | ||
|  | e3520309fc | ||
|  | 27bf72372e | ||
|  | ae4b1b17a9 | ||
|  | 94cb03f4b5 | ||
|  | e691351976 | ||
|  | 3190de873e | ||
|  | b22956bd99 | ||
|  | 42516206d9 | ||
|  | fc4edde6e6 | ||
|  | 54cc04fd96 | ||
|  | 80062b6a62 | ||
|  | 99af79fcf3 | ||
|  | 11d87205d7 | ||
|  | 5866d414ce | ||
|  | 9a972b0b8a | ||
|  | e6aeeea8c1 | ||
|  | 5d064aa1d7 | ||
|  | 34832d5942 | ||
|  | e3b1179a21 | ||
|  | f94a36613c | ||
|  | efc3cc24f4 | ||
|  | b47f8aaf70 | ||
|  | 94ca4607bc | ||
|  | 2dab1d3e6e | ||
|  | 825b0fb22f | ||
|  | 1cdb039ea2 | ||
|  | 7409cb3abb | ||
|  | e8e8f70c27 | ||
|  | e8a637498d | ||
|  | e1195ac00a | ||
|  | 6cd9ccc37c | ||
|  | 25345302e8 | ||
|  | eccd5e9801 | ||
|  | ff355af9f2 | ||
|  | 5967f4b0d4 | ||
|  | ff18618032 | ||
|  | 20f03c356c | ||
|  | 27fdc9e56e | ||
|  | 52d9578a19 | ||
|  | f4c2938b41 | ||
|  | 9f703de5ec | ||
|  | a327fd85e2 | ||
|  | 9d22a86ec8 | ||
|  | 29e0b194dd | ||
|  | ae9cf13fc2 | ||
|  | 64ae67586a | ||
|  | 838c7a5e89 | ||
|  | 89bfc90f40 | ||
|  | acad9f57f9 | ||
|  | 0d08dc410e | ||
|  | ebb3fb96cd | ||
|  | f31f23ff07 | ||
|  | d2aa3d1868 | ||
|  | c9e2fce94d | ||
|  | 8b0e76dd55 | ||
|  | 884618adfe | ||
|  | 6e2e36e7a0 | ||
|  | 9994df9601 | ||
|  | 98f7271ac8 | ||
|  | 087cd121b8 | ||
|  | 2d52527fb4 | ||
|  | fe289e62b5 | ||
|  | 2845475e3f | ||
|  | b307492487 | ||
|  | d48284f7ea | ||
|  | 7e416797e9 | ||
|  | 5d54ca7477 | ||
|  | b979b4e61a | ||
|  | 2527f7984a | ||
|  | d9350b2362 | ||
|  | bd0b903f1a | ||
|  | f243c0df19 | ||
|  | 7482978953 | ||
|  | 77966689d4 | ||
|  | cf43939d65 | ||
|  | 391ac4b351 | ||
|  | e1e48aadd9 | ||
|  | 0681f206c4 | ||
|  | d257c6f3d3 | ||
|  | fa45c82cdc | ||
|  | e805b58da6 | ||
|  | 943976d207 | ||
|  | 3a2e5a6ccd | ||
|  | 35ef036246 | ||
|  | e09c3bbdd3 | ||
|  | 3b12076d4b | ||
|  | cfcf78ae28 | ||
|  | 341ff9bf5c | ||
|  | 10d8ca30b0 | ||
|  | 4ebb5d099e | ||
|  | 1e82b66bf0 | ||
|  | 06a5e4273b | ||
|  | e123e7b0b0 | ||
|  | aeadc40c65 | ||
|  | 7ef418ec52 | ||
|  | 2ed52820b6 | ||
|  | e8fd7484b6 | ||
|  | ce5242cfe8 | ||
|  | af947879d8 | ||
|  | 3ed112cde6 | ||
|  | 99c6a9eccd | ||
|  | 2029f6ea0a | ||
|  | e984e1f30f | ||
|  | f21260370f | ||
|  | fdae75c99b | ||
|  | a0489f2a0d | ||
|  | 0123eacbdb | ||
|  | 53401b6aa7 | ||
|  | 9a5139f452 | ||
|  | 2ee0c8c228 | ||
|  | c53562cc9c | ||
|  | ec5d7c2e5c | ||
|  | d6fc258485 | ||
|  | f953612695 | ||
|  | 2ab93acca8 | ||
|  | 326c6c496e | ||
|  | 9f7f50664c | ||
|  | f6f1436123 | ||
|  | c3c519419d | ||
|  | e569a80b72 | ||
|  | 284f437c1a | ||
|  | 1fd44a9958 | ||
|  | cad34742f6 | ||
|  | 323359b3c8 | ||
|  | 35db8b45f0 | ||
|  | 50ae815ceb | ||
|  | 1a4389c90d | ||
|  | fdaa5ce1da | ||
|  | 09d9936aed | ||
|  | b3f6109b1c | ||
|  | 5fb3ffc240 | ||
|  | 360db252bb | ||
|  | 0b6e290271 | ||
|  | 7f0174e6db | ||
|  | a25dad6c2e | ||
|  | 6191a49ed3 | ||
|  | 6252b075bc | ||
|  | 7face138fd | ||
|  | 382b83b093 | ||
|  | 691687d1bc | ||
|  | 5814b80a72 | ||
|  | e147fbb1fa | ||
|  | b9e256adfa | ||
|  | 3b7bf04e22 | ||
|  | 43408a724c | ||
|  | 5fbd5bf9e2 | ||
|  | 5e87828b29 | ||
|  | 9066cedc29 | ||
|  | aa1cf0b228 | ||
|  | 06a6a4408f | ||
|  | d5619d2b9d | ||
|  | 2f6ac42efe | ||
|  | 0bba3dd83d | ||
|  | abe60b62e6 | ||
|  | 555b7df986 | ||
|  | b3786700e6 | ||
|  | ce9643d21b | ||
|  | 4a5cb7f2f5 | ||
|  | 42a7e902e6 | ||
|  | aebe080e85 | ||
|  | c316284924 | ||
|  | 8d98b228ab | ||
|  | 5b4c42ff05 | ||
|  | a596a4551a | ||
|  | 0968f96982 | ||
|  | 5931e13b9c | ||
|  | 415c768ae4 | ||
|  | b4c8bf21d5 | ||
|  | 5fe5db603d | ||
|  | 9f7dd7f5d4 | ||
|  | e6d32aab7b | ||
|  | 08bd6d963c | ||
|  | ff05fb14a6 | ||
|  | 22d942b705 | ||
|  | 0526372f28 | ||
|  | f99051906a | ||
|  | d1f7fd8bfd | ||
|  | fc1436a96d | ||
|  | d21568497b | ||
|  | df4beef060 | ||
|  | a52f195d41 | ||
|  | 419019a656 | ||
|  | 42b5635485 | ||
|  | a8fc5b01f3 | ||
|  | ead841d844 | ||
|  | 67d7930aef | ||
|  | 6f69995f4e | ||
|  | 05252fa239 | ||
|  | 1377439bb0 | ||
|  | 407123a280 | ||
|  | 750dd590c8 | ||
|  | 44112a9d18 | ||
|  | b220bf0d99 | ||
|  | d0d93d7070 | ||
|  | 4117961236 | ||
|  | 68a3d71ee6 | ||
|  | bf5d741f0d | ||
|  | 55a33bc408 | ||
|  | 3ec35ed119 | ||
|  | 3d8d6953ec | ||
|  | 528db67c34 | ||
|  | b847e962aa | ||
|  | bbb9a3c63b | ||
|  | 322cebc48c | ||
|  | 1cceb3d880 | ||
|  | effc64db9a | ||
|  | 7e5bd5f2c1 | ||
|  | e32cc4d1af | ||
|  | 09a3cd850e | ||
|  | b0c876019a | ||
|  | 6725f870d2 | ||
|  | 0e5adc1f0a | ||
|  | 57ebb93dc0 | ||
|  | 05dc0bfa1d | ||
|  | 2d0264116c | ||
|  | 3938550ea8 | ||
|  | 9f0c567794 | ||
|  | 8672fcd2bb | ||
|  | 3f2a92e801 | ||
|  | 771e43583a | ||
|  | 9353d5c1c4 | ||
|  | 5e462f0f02 | ||
|  | a25f6fec9f | ||
|  | 519edce0ed | ||
|  | 0bc7702d95 | ||
|  | 18be0d6d26 | ||
|  | 1d4a435f20 | ||
|  | 34e46fc6d3 | ||
|  | 50956c51f7 | ||
|  | dd7bb28b6a | ||
|  | 8516f41ba8 | ||
|  | 15c3cc60f6 | ||
|  | 716bca211b | ||
|  | 8179813fe1 | ||
|  | d355de509b | ||
|  | b04a2d4c08 | ||
|  | 6d3232a4f0 | ||
|  | 2753075180 | ||
|  | d0166b25e4 | ||
|  | 73ee657d74 | ||
|  | 45913e5ee8 | ||
|  | e6369820a9 | ||
|  | 22a5b339f7 | ||
|  | 2cea3b6435 | ||
|  | 5d2d06fb3e | ||
|  | 0dd7bc7fb9 | ||
|  | 0b0005337c | ||
|  | d26fb02bb9 | ||
|  | af683835d9 | ||
|  | c43647ca86 | ||
|  | 6d02e70025 | ||
|  | 5498c6f87d | ||
|  | 11f59bc3ac | ||
|  | 94cb7de79f | ||
|  | 838f45775b | ||
|  | 1c1422e4b5 | ||
|  | cd8ca6fc62 | ||
|  | b7a0a9d7c2 | ||
|  | 7822ab113a | ||
|  | e250a91f09 | ||
|  | 92a65dcda5 | ||
|  | 4b129d94e4 | ||
|  | e7960d1d44 | ||
|  | 95589307cd | ||
|  | 20a0e4f3e0 | ||
|  | 6a9213da64 | ||
|  | 7a89e3cf33 | ||
|  | 64607df929 | ||
|  | a62a1012fa | ||
|  | 14efd0b2f9 | ||
|  | 7ad2192df8 | ||
|  | 3cb5cbd8d5 | ||
|  | cc9011cd68 | ||
|  | dc3d89008d | ||
|  | 1893642187 | ||
|  | a9ece5772d | ||
|  | cf34716a57 | ||
|  | 1337831061 | ||
|  | 757e72100d | ||
|  | a75b819858 | ||
|  | da4a0f09ed | ||
|  | 87d847a074 | ||
|  | 84711beec0 | ||
|  | f3cf58c8ff | ||
|  | cf40497e6e | ||
|  | dfebc4b78d | ||
|  | 15f41a2e7c | ||
|  | ad6e55ca17 | ||
|  | 6b466d217a | ||
|  | 00dcb304c7 | ||
|  | c6fb3d6f41 | ||
|  | ac3143811f | ||
|  | 7e27dd7678 | ||
|  | c2508296a5 | ||
|  | a9b50ce6fc | ||
|  | eac98a6d4d | ||
|  | 7e2b2a9a02 | ||
|  | 353de471eb | ||
|  | 85fc20b52d | ||
|  | cc25a781f8 | ||
|  | fc3012ba72 | ||
|  | d93a92c1c8 | ||
|  | f7f795f58a | ||
|  | 2700f8cdd2 | ||
|  | 6310de0d20 | ||
|  | 218794be77 | ||
|  | af71ae649b | ||
|  | 9bc72c1a06 | ||
|  | 8d7c157751 | ||
|  | 558a66fbe5 | ||
|  | f95b414d22 | ||
|  | e793a1e1aa | ||
|  | b76010cb5a | ||
|  | 52475df783 | ||
|  | 1f3f32d377 | ||
|  | 3f5ba10354 | ||
|  | 25f4a018d9 | ||
|  | a11a279c00 | ||
|  | fd4fdb31b5 | ||
|  | 1921796d6d | ||
|  | 543a2b9dc7 | ||
|  | dd23e03342 | ||
|  | 5307c74f85 | ||
|  | d701c406e2 | ||
|  | 3ba56a0a65 | ||
|  | 4adafb6d1e | ||
|  | 4453a51211 | ||
|  | 14429d2943 | ||
|  | 1a62a7831b | ||
|  | 242e35c212 | ||
|  | ea763fdfd5 | ||
|  | e762b7ff48 | ||
|  | 298068b2b9 | ||
|  | cb4120ec4b | ||
|  | 5cfbb87bee | ||
|  | 9e472ed83c | ||
|  | ebca753fc4 | ||
|  | 548f45cd56 | ||
|  | 8ffabf1813 | ||
|  | 1f40d4f941 | ||
|  | 41582045d0 | ||
|  | fd9e3fc03a | ||
|  | 8c42b2bdb4 | ||
|  | 7b1787fdbb | ||
|  | 71fee0025d | ||
|  | 1204cf1ba0 | ||
|  | 7bd8d8c3ae | ||
|  | 2c4d5fa38d | ||
|  | bedb2d943e | ||
|  | a3640bd9bf | ||
|  | 7c0b9ffe06 | ||
|  | 161c7d30ca | ||
|  | 4ff6e792cd | ||
|  | af5df890a5 | ||
|  | 9ba011003a | ||
|  | bb168d35a8 | ||
|  | 3306d30094 | ||
|  | 6516e0dfd2 | ||
|  | 00a396014b | ||
|  | 13356047dc | ||
|  | 8a6488b067 | ||
|  | 1c2ea56f42 | ||
|  | 1d7ae300e2 | ||
|  | 6013e186ed | ||
|  | 207d3d3340 | ||
|  | 5a6cde1446 | ||
|  | 63f7d826bc | ||
|  | ff8773f6bd | ||
|  | a868cb97d9 | ||
|  | 915d73e6f2 | ||
|  | 5f4f6e37b5 | ||
|  | 9c350311e8 | ||
|  | 3c6ba72a2a | ||
|  | 816442f5f0 | ||
|  | 3b51d18ce7 | ||
|  | 6696b6661a | ||
|  | 8c87478636 | ||
|  | d870b072d7 | ||
|  | 2ea2af7d2a | ||
|  | f737ea96f3 | ||
|  | 05f90394db | ||
|  | c24b0c6bb4 | ||
|  | e07a4dc7ba | ||
|  | fc6748a46b | ||
|  | 7697c46652 | ||
|  | ed52e5afd1 | ||
|  | 33a5b84181 | ||
|  | c09a407f4c | ||
|  | d35784ec61 | ||
|  | 53e012f296 | ||
|  | 2a9d0a5e7d | ||
|  | 474f4572f2 | ||
|  | bf57cb209f | ||
|  | 9bc41c1709 | ||
|  | fe10b8650f | ||
|  | 3a311c9584 | ||
|  | d1106f53e0 | ||
|  | a3a1bba5ef | ||
|  | 028d66befc | ||
|  | bb59cd5742 | ||
|  | 604e3068b2 | ||
|  | 27f1d3b704 | ||
|  | d007623347 | ||
|  | 6a5cf7a1fa | ||
|  | 3adfe249b0 | ||
|  | 923893e160 | ||
|  | 256e5360d4 | ||
|  | 304c597a2f | ||
|  | f86d3a69d2 | ||
|  | d7c8adfd82 | ||
|  | 55cd069043 | ||
|  | 3ca0e9c420 | ||
|  | 1dd4323613 | ||
|  | d78916f85f | ||
|  | 1840d15397 | ||
|  | b98d1216b1 | ||
|  | 27db727321 | ||
|  | 3f6b1f6ccb | ||
|  | 6d633b372a | ||
|  | 91352e855a | ||
|  | 8bb9b594cf | ||
|  | 6d2fd2e641 | ||
|  | 422fbcb0b7 | ||
|  | afce106186 | ||
|  | f21c8154ed | ||
|  | 3988a648d6 | ||
|  | 1b632894d3 | ||
|  | 5e128f89f6 | ||
|  | fff0b15ae5 | ||
|  | a7e14f1093 | ||
|  | 94eeaeb8d3 | ||
|  | 64191e8303 | ||
|  | 21cfb71617 | ||
|  | 806457063f | ||
|  | b9213b73bd | ||
|  | d7f0102aa2 | ||
|  | f09e61a59a | ||
|  | d426aaa88a | ||
|  | 19e45389e1 | ||
|  | 6d2389945b | ||
|  | 14c48253f6 | ||
|  | e5ff25b92d | ||
|  | 5c88888e02 | ||
|  | 10057de9b3 | ||
|  | cc88ebd2b9 | ||
|  | 6baedf909d | ||
|  | f39d9d6f1b | ||
|  | ab61a95f83 | ||
|  | 10ceed30c6 | ||
|  | 2b9aa94f3a | ||
|  | 848fb975ed | ||
|  | d7f59dac84 | ||
|  | dd47e615ee | ||
|  | 8f2f7ea1a5 | ||
|  | 80a8efd8ce | ||
|  | d9dce77ef4 | ||
|  | ce7053a1fe | ||
|  | 0db1530171 | ||
|  | 3745504107 | ||
|  | 57533fd831 | ||
|  | f57a0d4d6b | ||
|  | 22772ca33e | ||
|  | dba6ff1d51 | ||
|  | 40146dedaf | ||
|  | 387b822f53 | ||
|  | b9a3563e5b | ||
|  | 3d6468326a | ||
|  | 298e37ec53 | ||
|  | 5b137c457b | ||
|  | 5218a3fbac | ||
|  | 4569cb432d | ||
|  | 611e598756 | ||
|  | 937d79d28f | ||
|  | 23c2a771d3 | ||
|  | 58a890e836 | ||
|  | 6a869e120c | ||
|  | ae7c298b1a | ||
|  | 53bfe12ac1 | ||
|  | 140ea683a6 | ||
|  | 0634a97598 | ||
|  | 3479c794de | ||
|  | 89cad116f7 | ||
|  | 19c84eb694 | ||
|  | eae390acf5 | ||
|  | 10567afbb9 | ||
|  | 51bad3bf3c | ||
|  | 9134d8841d | ||
|  | e9a026c131 | ||
|  | 9a2fd0e2b2 | ||
|  | 522f7e6844 | ||
|  | cb4f46decc | ||
|  | 81256279a8 | ||
|  | 039bd1ddc0 | ||
|  | 0791d4797f | ||
|  | 6a06142e1e | ||
|  | ef53dca062 | ||
|  | 6ce761edda | ||
|  | d8fd218409 | ||
|  | edc2310599 | ||
|  | b1cd13d629 | ||
|  | b81940351f | ||
|  | a42e99c4aa | ||
|  | ff40b521b7 | ||
|  | 85392496e7 | ||
|  | 29cae9975e | ||
|  | 170d6b28f8 | ||
|  | 9a8b404054 | ||
|  | 41af5187aa | ||
|  | 8dcc114873 | ||
|  | 8cc9aeba4a | ||
|  | ba0823c38c | 
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | ||||
| /packages/node_modules/** linguist-generated=false | ||||
							
								
								
									
										61
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,61 @@ | ||||
| name: 🐞 Report a bug | ||||
| description: File a bug/issue on the core of Node-RED | ||||
| labels: [needs-triage] | ||||
| body: | ||||
| - type: markdown | ||||
|   attributes: | ||||
|     value: | | ||||
|         This issue tracker is for problems with the Node-RED runtime, the editor or the core nodes. | ||||
|  | ||||
|         If your issue is: | ||||
|           - a general 'how-to' type question, | ||||
|           - a feature request or suggestion for a change, | ||||
|           - or problems with 3rd party (`node-red-contrib-`) nodes | ||||
|  | ||||
|         please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). | ||||
|  | ||||
|         You could also consider asking a question on [Stack Overflow](https://stackoverflow.com/questions/tagged/node-red) and tag it `node-red`. | ||||
|  | ||||
|         That way the whole Node-RED user community can help, rather than rely on the core development team. | ||||
|  | ||||
|         To help us understand the issue, please fill-in as much of the following information as you can: | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Current Behavior | ||||
|     description: A clear & concise description of what you're experiencing. | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Expected Behavior | ||||
|     description: A clear & concise description of what you expected to happen. | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Steps To Reproduce | ||||
|     description: Steps to reproduce the behavior. | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Example flow | ||||
|     description: If you have a minimal example flow that demonstrates the issue, share it here. | ||||
|     value: | | ||||
|       ``` | ||||
|       paste your flow here | ||||
|       ``` | ||||
|   validations: | ||||
|     required: false | ||||
| - type: textarea | ||||
|   attributes: | ||||
|     label: Environment | ||||
|     description: Please tell us about your environment. Include any relevant information on how you are running Node-RED. | ||||
|     value: | | ||||
|         - Node-RED version: | ||||
|         - Node.js version: | ||||
|         - npm version: | ||||
|         - Platform/OS: | ||||
|         - Browser: | ||||
|   validations: | ||||
|     required: false | ||||
							
								
								
									
										14
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,14 @@ | ||||
| blank_issues_enabled: true | ||||
| contact_links: | ||||
|   - name: ❓ Questions | ||||
|     url: https://discourse.nodered.org | ||||
|     about: Ask your question on the Node-RED forum | ||||
|   - name: ⭐️ Feature Request | ||||
|     url: https://discourse.nodered.org/c/development/feature-requests | ||||
|     about: Discuss your request with the community | ||||
|   - name: 🗂 Documentation | ||||
|     url: https://nodered.org/docs | ||||
|     about: Go straight to the documentation | ||||
|   - name: 💬 Slack | ||||
|     url: https://nodered.org/slack | ||||
|     about: Chat about the project on our slack team | ||||
							
								
								
									
										34
									
								
								.github/PULL_REQUEST_TEMPLATE.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,34 @@ | ||||
| <!-- | ||||
| ## Before you hit that Submit button.... | ||||
|  | ||||
| Please read our [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md) | ||||
| before submitting a pull-request. | ||||
|  | ||||
| ## Types of changes | ||||
|  | ||||
| What types of changes does your code introduce? | ||||
| Put an `x` in the boxes that apply | ||||
| --> | ||||
|  | ||||
| - [ ] Bugfix (non-breaking change which fixes an issue) | ||||
| - [ ] New feature (non-breaking change which adds functionality) | ||||
|  | ||||
| <!-- | ||||
| If you want to raise a pull-request with a new feature, or a refactoring | ||||
| of existing code, it **may well get rejected** if it hasn't been discussed on | ||||
| the [forum](https://discourse.nodered.org) or | ||||
| [slack team](https://nodered.org/slack) first. | ||||
|  | ||||
| --> | ||||
|  | ||||
| ## Proposed changes | ||||
|  | ||||
| <!-- Describe the nature of this change. What problem does it address? --> | ||||
|  | ||||
| ## Checklist | ||||
| <!-- Put an `x` in the boxes that apply --> | ||||
|  | ||||
| - [ ] I have read the [contribution guidelines](https://github.com/node-red/node-red/blob/master/CONTRIBUTING.md) | ||||
| - [ ] For non-bugfix PRs, I have discussed this change on the forum/slack team. | ||||
| - [ ] I have run `grunt` to verify the unit tests pass | ||||
| - [ ] I have added suitable unit tests to cover the new/changed functionality | ||||
							
								
								
									
										29
									
								
								.github/scripts/update-node-red-docker.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,29 @@ | ||||
| const fs = require("fs"); | ||||
|  | ||||
| const newVersion = require("../../package.json").version; | ||||
|  | ||||
| if (process.env.GITHUB_REF !== "refs/tags/"+newVersion) { | ||||
|     console.log(`GITHUB_REF doesn't match the package.json version: ${process.env.GITHUB_REF} !== ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| if (!/^\d+\.\d+\.\d+$/.test(newVersion)) { | ||||
|     console.log(`Not updating for a non-stable release - ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| const currentVersion = require("../../../node-red-docker/package.json").version; | ||||
|  | ||||
| console.log(`Update from ${currentVersion} to ${newVersion}`) | ||||
|  | ||||
| updateFile(__dirname+"/../../../node-red-docker/package.json", currentVersion, newVersion); | ||||
| updateFile(__dirname+"/../../../node-red-docker/docker-custom/package.json", currentVersion, newVersion); | ||||
| updateFile(__dirname+"/../../../node-red-docker/README.md", currentVersion, newVersion); | ||||
|  | ||||
| console.log(`::set-env name=newVersion::${newVersion}`); | ||||
|  | ||||
| function updateFile(path,from,to) { | ||||
|     let contents = fs.readFileSync(path,"utf8"); | ||||
|     contents = contents.replace(new RegExp(from.replace(/\./g,"\\."),"g"), to); | ||||
|     fs.writeFileSync(path, contents); | ||||
| } | ||||
							
								
								
									
										18
									
								
								.github/scripts/update-node-red-website.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,18 @@ | ||||
| const fs = require("fs"); | ||||
|  | ||||
| const newVersion = require("../../package.json").version; | ||||
|  | ||||
| if (process.env.GITHUB_REF !== "refs/tags/"+newVersion) { | ||||
|     console.log(`GITHUB_REF doesn't match the package.json version: ${process.env.GITHUB_REF} !== ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| if (!/^\d+\.\d+\.\d+$/.test(newVersion)) { | ||||
|     console.log(`Not updating for a non-stable release - ${newVersion}`); | ||||
|     process.exit(0); | ||||
| } | ||||
|  | ||||
| const path = __dirname+"/../../../node-red.github.io/index.html"; | ||||
| let contents = fs.readFileSync(path, "utf8"); | ||||
| contents = contents.replace(/<span class="node-red-latest-version">v\d+\.\d+\.\d+<\/span>/, `<span class="node-red-latest-version">v${newVersion}<\/span>` ); | ||||
| fs.writeFileSync(path, contents); | ||||
							
								
								
									
										59
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,59 @@ | ||||
| name: Publish Release | ||||
| env: | ||||
|   ACTIONS_ALLOW_UNSECURE_COMMANDS: true | ||||
| on: | ||||
|   release: | ||||
|     types: [published] | ||||
|  | ||||
| jobs: | ||||
|   generate: | ||||
|     name: 'Update node-red-docker image' | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Check out node-red repository | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|             path: 'node-red' | ||||
|       - name: Check out node-red-docker repository | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|             repository: 'node-red/node-red-docker' | ||||
|             path: 'node-red-docker' | ||||
|       - name: Check out node-red.github.io repository | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|             repository: 'node-red/node-red.github.io' | ||||
|             path: 'node-red.github.io' | ||||
|       - uses: actions/setup-node@v1 | ||||
|         with: | ||||
|             node-version: '16' | ||||
|       - run: node ./node-red/.github/scripts/update-node-red-docker.js | ||||
|       - name: Create Docker Pull Request | ||||
|         uses: peter-evans/create-pull-request@v2 | ||||
|         with: | ||||
|           token: ${{ secrets.NR_REPO_TOKEN }} | ||||
|           committer: GitHub <noreply@github.com> | ||||
|           author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> | ||||
|           path: 'node-red-docker' | ||||
|           commit-message: 'Bump to ${{ env.newVersion }}' | ||||
|           title: '🚀 Update to Node-RED ${{ env.newVersion }} release' | ||||
|           body: | | ||||
|             Updates the Node-RED Docker repo for the ${{ env.newVersion }} release. | ||||
|  | ||||
|             Once this is merged, you will need to create a new release with the tag `v${{ env.newVersion }}`. | ||||
|  | ||||
|             This PR was auto-generated by a GitHub Action. Any questions, speak to @knolleary | ||||
|       - run: node ./node-red/.github/scripts/update-node-red-website.js | ||||
|       - name: Create Website Pull Request | ||||
|         uses: peter-evans/create-pull-request@v2 | ||||
|         with: | ||||
|           token: ${{ secrets.NR_REPO_TOKEN }} | ||||
|           committer: GitHub <noreply@github.com> | ||||
|           author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com> | ||||
|           path: 'node-red.github.io' | ||||
|           commit-message: 'Bump to ${{ env.newVersion }}' | ||||
|           title: '🚀 Update to Node-RED ${{ env.newVersion }} release' | ||||
|           body: | | ||||
|             Updates the Node-RED Website repo for the ${{ env.newVersion }} release. | ||||
|  | ||||
|             This PR was auto-generated by a GitHub Action. Any questions, speak to @knolleary | ||||
							
								
								
									
										30
									
								
								.github/workflows/tests.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,30 @@ | ||||
| name: Run tests | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: [ master, dev ] | ||||
|   pull_request: | ||||
|     branches: [ master, dev ] | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       matrix: | ||||
|         node-version: [14, 16] | ||||
|     steps: | ||||
|     - uses: actions/checkout@v2 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v2 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|     - name: Install Dependencies | ||||
|       run: npm install | ||||
|     - name: Run tests | ||||
|       run: | | ||||
|         npm run test | ||||
|     - name: Publish to coveralls.io | ||||
|       if: ${{ matrix.node-version == 14 }} | ||||
|       uses: coverallsapp/github-action@v1.1.2 | ||||
|       with: | ||||
|         github-token: ${{ github.token }} | ||||
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -7,7 +7,9 @@ | ||||
| .sessions.json | ||||
| .settings | ||||
| .tern-project | ||||
| .i18n-editor-metadata | ||||
| *.backup | ||||
| *.bak | ||||
| *_cred* | ||||
| coverage | ||||
| credentials.json | ||||
| @@ -17,3 +19,11 @@ node_modules | ||||
| public | ||||
| locales/zz-ZZ | ||||
| nodes/core/locales/zz-ZZ | ||||
| !packages/node_modules | ||||
| packages/node_modules/@node-red/editor-client/public | ||||
| !test/**/node_modules | ||||
| docs | ||||
| !packages/node_modules/**/docs | ||||
| .vscode | ||||
| .nyc_output | ||||
| sync.ffs_db | ||||
|   | ||||
| @@ -1,5 +1,4 @@ | ||||
| /Gruntfile.js | ||||
| /.git/* | ||||
| /lib/* | ||||
| *.backup | ||||
| /public/* | ||||
|   | ||||
| @@ -1,7 +0,0 @@ | ||||
| .settings | ||||
| .jshintignore | ||||
| .jshintrc | ||||
| .project | ||||
| .tern-project | ||||
| .travis.yml | ||||
| .git | ||||
							
								
								
									
										21
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						| @@ -1,21 +0,0 @@ | ||||
| sudo: false | ||||
| language: node_js | ||||
| env: | ||||
|   - CXX="g++-4.8" | ||||
| addons: | ||||
|   apt: | ||||
|     sources: | ||||
|     - ubuntu-toolchain-r-test | ||||
|     packages: | ||||
|     - g++-4.8 | ||||
|     - gcc-4.8 | ||||
| node_js: | ||||
|   - "8" | ||||
|   - "7" | ||||
|   - "6" | ||||
|   - "4" | ||||
| script: | ||||
|   - istanbul cover ./node_modules/.bin/grunt --report lcovonly && istanbul report text && ( cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js || true ) && rm -rf coverage | ||||
| before_script: | ||||
|   - npm install -g istanbul | ||||
|   - npm install coveralls | ||||
							
								
								
									
										19
									
								
								API.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | ||||
| Node-RED consists of 6 node modules under the `@node-red` scope, which are pulled together | ||||
| by the top-level `node-red` module. The typical scenario is where you are embedding Node-RED into your | ||||
| own application, in which case you would use the `node-red` module rather than any of the | ||||
| internal modules directly. | ||||
|  | ||||
| ```javascript | ||||
| let RED = require("node-red"); | ||||
| ``` | ||||
|  | ||||
|  | ||||
| Module | Description | ||||
| -------|------- | ||||
| [node-red](node-red.html) | the main module that pulls together all of the internal modules and provides the executable version of Node-RED | ||||
| [@node-red/editor-api](@node-red_editor-api.html) | an Express application that serves the Node-RED editor and provides the Admin HTTP API | ||||
| [@node-red/runtime](@node-red_runtime.html) | the core runtime of Node-RED | ||||
| [@node-red/util](@node-red_util.html) | common utilities for the Node-RED runtime and editor modules | ||||
| [@node-red/registry](@node-red_registry.html) | the internal node registry | ||||
| @node-red/nodes | the default set of core nodes. This module only contains the Node-RED nodes - it does not expose any APIs. | ||||
| @node-red/editor-client | the client-side resources of the Node-RED editor application | ||||
							
								
								
									
										1483
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						| @@ -9,7 +9,7 @@ We welcome contributions, but request you follow these guidelines. | ||||
|  | ||||
| This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/). | ||||
| By participating, you are expected to uphold this code. Please report unacceptable | ||||
| behavior to any of the [project's core team](https://github.com/orgs/node-red/teams/core). | ||||
| behavior to the project's core team at team@nodered.org. | ||||
|  | ||||
| ## Raising issues | ||||
|  | ||||
| @@ -26,25 +26,30 @@ relevant nodes, press Ctrl-E and copy the flow data from the Export dialog. | ||||
| At a minimum, please include: | ||||
|  | ||||
|  - Version of Node-RED - either release number if you downloaded a zip, or the first few lines of `git log` if you are cloning the repository directly. | ||||
|  - Version of node.js - what does `node -v` say? | ||||
|  - Version of Node.js - what does `node -v` say? | ||||
|  | ||||
| ## Feature requests | ||||
|  | ||||
| For feature requests, please raise them on the [mailing list](https://groups.google.com/forum/#!forum/node-red). | ||||
| For feature requests, please raise them on the [forum](https://discourse.nodered.org). | ||||
|  | ||||
| ## Pull-Requests | ||||
|  | ||||
| If you want to raise a pull-request with a new feature, or a refactoring | ||||
| of existing code, it may well get rejected if you haven't discussed it on | ||||
| the [mailing list](https://groups.google.com/forum/#!forum/node-red) first. | ||||
| the [forum](https://discourse.nodered.org) first. | ||||
|  | ||||
| All contributors need to sign the JS Foundation's Contributor License Agreement. | ||||
| It is an online process and quick to do. You can read the details of the agreement | ||||
| here: https://cla.js.foundation/node-red/node-red. | ||||
| All contributors need to sign the OpenJS Foundation's Contributor License Agreement. | ||||
| It is an online process and quick to do. If you raise a pull-request without | ||||
| having signed the CLA, you will be prompted to do so automatically. | ||||
|  | ||||
| If you raise a pull-request without having signed the CLA, you will be prompted | ||||
| to do so automatically. | ||||
|  | ||||
| ### Code Branches | ||||
|  | ||||
| When raising a PR for a fix or a new feature, it is important to target the right branch. | ||||
|  | ||||
|  - `master` - this is the main branch for the latest stable release of Node-RED. All bug fixes for that release should target this branch. | ||||
|  - `v1.x` - this is the maintenance branch for the 1.x stream. If a fix *only* applies to 1.x, then it should target this branch. If it applies to the current stable release as well, target `master` first. We will then decide if it needs to be back ported to the 1.x stream. | ||||
|  - `dev` - this is the branch for new feature development targeting the next milestone release. | ||||
|  | ||||
| ### Coding standards | ||||
|  | ||||
|   | ||||
							
								
								
									
										570
									
								
								Gruntfile.js
									
									
									
									
									
								
							
							
						
						| @@ -15,17 +15,35 @@ | ||||
|  **/ | ||||
|  | ||||
| var path = require("path"); | ||||
| var fs = require("fs-extra"); | ||||
| var sass = require("sass"); | ||||
|  | ||||
| module.exports = function(grunt) { | ||||
|  | ||||
|     var nodemonArgs = ["-v"]; | ||||
|     var nodemonArgs = ["-V"]; | ||||
|     var flowFile = grunt.option('flowFile'); | ||||
|     if (flowFile) { | ||||
|         nodemonArgs.push(flowFile); | ||||
|         process.env.NODE_RED_ENABLE_PROJECTS=false; | ||||
|     } | ||||
|     var userDir = grunt.option('userDir'); | ||||
|     if (userDir) { | ||||
|         nodemonArgs.push("-u"); | ||||
|         nodemonArgs.push(userDir); | ||||
|     } | ||||
|  | ||||
|     var browserstack = grunt.option('browserstack'); | ||||
|     if (browserstack) { | ||||
|         process.env.BROWSERSTACK = true; | ||||
|     } | ||||
|     var nonHeadless = grunt.option('non-headless'); | ||||
|     if (nonHeadless) { | ||||
|         process.env.NODE_RED_NON_HEADLESS = true; | ||||
|     } | ||||
|     const pkg = grunt.file.readJSON('package.json'); | ||||
|     process.env.NODE_RED_PACKAGE_VERSION = pkg.version; | ||||
|     grunt.initConfig({ | ||||
|         pkg: grunt.file.readJSON('package.json'), | ||||
|         pkg: pkg, | ||||
|         paths: { | ||||
|             dist: ".dist" | ||||
|         }, | ||||
| @@ -37,20 +55,28 @@ module.exports = function(grunt) { | ||||
|                 ui: 'bdd', | ||||
|                 reporter: 'spec' | ||||
|             }, | ||||
|             all: { src: ['test/**/*_spec.js'] }, | ||||
|             core: { src: ["test/_spec.js","test/red/**/*_spec.js"]}, | ||||
|             all: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js","test/nodes/**/*_spec.js"] }, | ||||
|             core: { src: ["test/unit/_spec.js","test/unit/**/*_spec.js"]}, | ||||
|             nodes: { src: ["test/nodes/**/*_spec.js"]} | ||||
|         }, | ||||
|         mocha_istanbul: { | ||||
|         webdriver: { | ||||
|             all: { | ||||
|                 configFile: 'test/editor/wdio.conf.js' | ||||
|             } | ||||
|         }, | ||||
|         nyc: { | ||||
|             options: { | ||||
|                 globals: ['expect'], | ||||
|                 timeout: 3000, | ||||
|                 ignoreLeaks: false, | ||||
|                 ui: 'bdd', | ||||
|                 reportFormats: ['lcov'], | ||||
|                 print: 'both' | ||||
|                 cwd: '.', | ||||
|                 include: ['packages/node_modules/**'], | ||||
|                 excludeNodeModules: false, | ||||
|                 exclude: ['packages/node_modules/@node-red/editor-client/**'], | ||||
|                 reporter: ['lcov', 'html','text-summary'], | ||||
|                 reportDir: 'coverage', | ||||
|                 all: true | ||||
|             }, | ||||
|             coverage: { src: ['test/**/*_spec.js'] } | ||||
|             all:   { cmd: false, args: ['grunt', 'simplemocha:all'] }, | ||||
|             core:  { options: { exclude:['packages/node_modules/@node-red/editor-client/**', 'packages/node_modules/@node-red/nodes/**']},cmd: false, args: ['grunt', 'simplemocha:core'] }, | ||||
|             nodes: { cmd: false, args: ['grunt', 'simplemocha:nodes'] } | ||||
|         }, | ||||
|         jshint: { | ||||
|             options: { | ||||
| @@ -66,22 +92,20 @@ module.exports = function(grunt) { | ||||
|                 //"loopfunc": true, // allow functions to be defined in loops | ||||
|                 //"sub": true       // don't warn that foo['bar'] should be written as foo.bar | ||||
|             }, | ||||
|             all: [ | ||||
|                 'Gruntfile.js', | ||||
|                 'red.js', | ||||
|                 'red/**/*.js', | ||||
|                 'nodes/core/*/*.js', | ||||
|                 'editor/js/**/*.js' | ||||
|             ], | ||||
|             core: { | ||||
|                 files: { | ||||
|                     src: [ | ||||
|                         'Gruntfile.js', | ||||
|                         'red.js', | ||||
|                         'red/**/*.js' | ||||
|                     ] | ||||
|                 } | ||||
|             }, | ||||
|             // all: [ | ||||
|             //     'Gruntfile.js', | ||||
|             //     'red.js', | ||||
|             //     'packages/**/*.js' | ||||
|             // ], | ||||
|             // core: { | ||||
|             //     files: { | ||||
|             //         src: [ | ||||
|             //             'Gruntfile.js', | ||||
|             //             'red.js', | ||||
|             //             'packages/**/*.js', | ||||
|             //         ] | ||||
|             //     } | ||||
|             // }, | ||||
|             nodes: { | ||||
|                 files: { | ||||
|                     src: [ 'nodes/core/*/*.js' ] | ||||
| @@ -89,7 +113,7 @@ module.exports = function(grunt) { | ||||
|             }, | ||||
|             editor: { | ||||
|                 files: { | ||||
|                     src: [ 'editor/js/**/*.js' ] | ||||
|                     src: [ 'packages/node_modules/@node-red/editor-client/src/js/**/*.js' ] | ||||
|                 } | ||||
|             }, | ||||
|             tests: { | ||||
| @@ -109,74 +133,105 @@ module.exports = function(grunt) { | ||||
|                 src: [ | ||||
|                     // Ensure editor source files are concatenated in | ||||
|                     // the right order | ||||
|                     "editor/js/red.js", | ||||
|                     "editor/js/events.js", | ||||
|                     "editor/js/i18n.js", | ||||
|                     "editor/js/settings.js", | ||||
|                     "editor/js/user.js", | ||||
|                     "editor/js/comms.js", | ||||
|                     "editor/js/text/bidi.js", | ||||
|                     "editor/js/text/format.js", | ||||
|                     "editor/js/ui/state.js", | ||||
|                     "editor/js/nodes.js", | ||||
|                     "editor/js/history.js", | ||||
|                     "editor/js/validators.js", | ||||
|                     "editor/js/ui/utils.js", | ||||
|                     "editor/js/ui/common/editableList.js", | ||||
|                     "editor/js/ui/common/checkboxSet.js", | ||||
|                     "editor/js/ui/common/menu.js", | ||||
|                     "editor/js/ui/common/panels.js", | ||||
|                     "editor/js/ui/common/popover.js", | ||||
|                     "editor/js/ui/common/searchBox.js", | ||||
|                     "editor/js/ui/common/tabs.js", | ||||
|                     "editor/js/ui/common/stack.js", | ||||
|                     "editor/js/ui/common/typedInput.js", | ||||
|                     "editor/js/ui/actions.js", | ||||
|                     "editor/js/ui/deploy.js", | ||||
|                     "editor/js/ui/diff.js", | ||||
|                     "editor/js/ui/keyboard.js", | ||||
|                     "editor/js/ui/workspaces.js", | ||||
|                     "editor/js/ui/view.js", | ||||
|                     "editor/js/ui/sidebar.js", | ||||
|                     "editor/js/ui/palette.js", | ||||
|                     "editor/js/ui/tab-info.js", | ||||
|                     "editor/js/ui/tab-config.js", | ||||
|                     "editor/js/ui/palette-editor.js", | ||||
|                     "editor/js/ui/editor.js", | ||||
|                     "editor/js/ui/tray.js", | ||||
|                     "editor/js/ui/clipboard.js", | ||||
|                     "editor/js/ui/library.js", | ||||
|                     "editor/js/ui/notifications.js", | ||||
|                     "editor/js/ui/search.js", | ||||
|                     "editor/js/ui/typeSearch.js", | ||||
|                     "editor/js/ui/subflow.js", | ||||
|                     "editor/js/ui/userSettings.js", | ||||
|                     "editor/js/ui/touch/radialMenu.js" | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/polyfills.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/jquery-addons.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/red.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/events.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/hooks.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/i18n.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/settings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/user.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/comms.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/text/bidi.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/text/format.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/state.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/plugins.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/nodes.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/font-awesome.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/history.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/validators.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/utils.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/menu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/popover.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/searchBox.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/stack.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/toggleButton.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/common/autoComplete.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/actions.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/diagnostics.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/diff.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/keyboard.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/workspaces.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/statusBar.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/palette.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-info-outliner.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-help.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tab-context.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/palette-editor.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editor.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/*.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editors/*.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/*.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/event-log.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tray.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/library.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/search.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/group.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/userSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/projectUserSettings.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/projects/tab-versionControl.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/touch/radialMenu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/tour/*.js" | ||||
|                 ], | ||||
|                 dest: "public/red/red.js" | ||||
|                 dest: "packages/node_modules/@node-red/editor-client/public/red/red.js" | ||||
|             }, | ||||
|             vendor: { | ||||
|                 files: { | ||||
|                     "public/vendor/vendor.js": [ | ||||
|                         "editor/vendor/jquery/js/jquery-1.11.3.min.js", | ||||
|                         "editor/vendor/bootstrap/js/bootstrap.min.js", | ||||
|                         "editor/vendor/jquery/js/jquery-ui-1.10.3.custom.min.js", | ||||
|                         "editor/vendor/jquery/js/jquery.ui.touch-punch.min.js", | ||||
|                         "editor/vendor/marked/marked.min.js", | ||||
|                         "editor/vendor/d3/d3.v3.min.js", | ||||
|                         "editor/vendor/i18next/i18next.min.js" | ||||
|                     ], | ||||
|                     "public/vendor/vendor.css": [ | ||||
|                         // TODO: resolve relative resource paths in | ||||
|                         //       bootstrap/FA/jquery | ||||
|                     ], | ||||
|                     "public/vendor/jsonata/jsonata.min.js": [ | ||||
|                     "packages/node_modules/@node-red/editor-client/public/vendor/vendor.js": [ | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-3.5.1.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-migrate-3.3.0.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery-ui.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jquery/js/jquery.ui.touch-punch.min.js", | ||||
|                         "node_modules/marked/marked.min.js", | ||||
|                         "node_modules/dompurify/dist/purify.min.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/d3/d3.v3.min.js", | ||||
|                         "node_modules/i18next/i18next.min.js", | ||||
|                         "node_modules/i18next-http-backend/i18nextHttpBackend.min.js", | ||||
|                         "node_modules/jquery-i18next/jquery-i18next.min.js", | ||||
|                         "node_modules/jsonata/jsonata-es5.min.js", | ||||
|                         "editor/vendor/jsonata/formatter.js" | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jsonata/formatter.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/ace/ace.js", | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/ace/ext-language_tools.js", | ||||
|                     ], | ||||
|                     "public/vendor/ace/worker-jsonata.js": [ | ||||
|                     // "packages/node_modules/@node-red/editor-client/public/vendor/vendor.css": [ | ||||
|                     //     // TODO: resolve relative resource paths in | ||||
|                     //     //       bootstrap/FA/jquery | ||||
|                     // ], | ||||
|                     "packages/node_modules/@node-red/editor-client/public/vendor/ace/worker-jsonata.js": [ | ||||
|                         "node_modules/jsonata/jsonata-es5.min.js", | ||||
|                         "editor/vendor/jsonata/worker-jsonata.js" | ||||
|                         "packages/node_modules/@node-red/editor-client/src/vendor/jsonata/worker-jsonata.js" | ||||
|                     ] | ||||
|                 } | ||||
|             } | ||||
| @@ -184,63 +239,62 @@ module.exports = function(grunt) { | ||||
|         uglify: { | ||||
|             build: { | ||||
|                 files: { | ||||
|                     'public/red/red.min.js': 'public/red/red.js', | ||||
|                     'public/red/main.min.js': 'public/red/main.js', | ||||
|                     'public/vendor/ace/mode-jsonata.js': 'editor/vendor/jsonata/mode-jsonata.js', | ||||
|                     'public/vendor/ace/snippets/jsonata.js': 'editor/vendor/jsonata/snippets-jsonata.js' | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/red.min.js': 'packages/node_modules/@node-red/editor-client/public/red/red.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/main.min.js': 'packages/node_modules/@node-red/editor-client/public/red/main.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/vendor/ace/mode-jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/mode-jsonata.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/vendor/ace/snippets/jsonata.js': 'packages/node_modules/@node-red/editor-client/src/vendor/jsonata/snippets-jsonata.js' | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         sass: { | ||||
|             build: { | ||||
|                 options: { | ||||
|                     implementation: sass, | ||||
|                     outputStyle: 'compressed' | ||||
|                 }, | ||||
|                 files: [{ | ||||
|                     dest: 'public/red/style.min.css', | ||||
|                     src: 'editor/sass/style.scss' | ||||
|                 }, | ||||
|                 { | ||||
|                     dest: 'public/vendor/bootstrap/css/bootstrap.min.css', | ||||
|                     src: 'editor/vendor/bootstrap/css/bootstrap.css' | ||||
|                     dest: 'packages/node_modules/@node-red/editor-client/public/red/style.min.css', | ||||
|                     src: 'packages/node_modules/@node-red/editor-client/src/sass/style.scss' | ||||
|                 }] | ||||
|             } | ||||
|         }, | ||||
|         jsonlint: { | ||||
|             messages: { | ||||
|                 src: [ | ||||
|                     'nodes/core/locales/en-US/messages.json', | ||||
|                     'red/api/locales/en-US/editor.json', | ||||
|                     'red/runtime/locales/en-US/runtime.json' | ||||
|                     'packages/node_modules/@node-red/nodes/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/editor-client/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/runtime/locales/**/*.json' | ||||
|                 ] | ||||
|             }, | ||||
|             keymaps: { | ||||
|                 src: [ | ||||
|                     'editor/js/keymap.json' | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js/keymap.json' | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         attachCopyright: { | ||||
|             js: { | ||||
|                 src: [ | ||||
|                     'public/red/red.min.js', | ||||
|                     'public/red/main.min.js' | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/red.min.js', | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/main.min.js' | ||||
|                 ] | ||||
|             }, | ||||
|             css: { | ||||
|                 src: [ | ||||
|                     'public/red/style.min.css' | ||||
|                     'packages/node_modules/@node-red/editor-client/public/red/style.min.css' | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         clean: { | ||||
|             build: { | ||||
|                 src: [ | ||||
|                     "public/red", | ||||
|                     "public/index.html", | ||||
|                     "public/favicon.ico", | ||||
|                     "public/icons", | ||||
|                     "public/vendor" | ||||
|                     "packages/node_modules/@node-red/editor-client/public/red", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/index.html", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/favicon.ico", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/icons", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/vendor", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/types/node", | ||||
|                     "packages/node_modules/@node-red/editor-client/public/types/node-red", | ||||
|                 ] | ||||
|             }, | ||||
|             release: { | ||||
| @@ -252,30 +306,36 @@ module.exports = function(grunt) { | ||||
|         watch: { | ||||
|             js: { | ||||
|                 files: [ | ||||
|                     'editor/js/**/*.js' | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js/**/*.js' | ||||
|                 ], | ||||
|                 tasks: ['copy:build','concat','uglify','attachCopyright:js'] | ||||
|                 tasks: ['copy:build','concat',/*'uglify',*/ 'attachCopyright:js'] | ||||
|             }, | ||||
|             sass: { | ||||
|                 files: [ | ||||
|                     'editor/sass/**/*.scss' | ||||
|                     'packages/node_modules/@node-red/editor-client/src/sass/**/*.scss' | ||||
|                 ], | ||||
|                 tasks: ['sass','attachCopyright:css'] | ||||
|             }, | ||||
|             json: { | ||||
|                 files: [ | ||||
|                     'nodes/core/locales/en-US/messages.json', | ||||
|                     'red/api/locales/en-US/editor.json', | ||||
|                     'red/runtime/locales/en-US/runtime.json' | ||||
|                     'packages/node_modules/@node-red/nodes/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/editor-client/locales/**/*.json', | ||||
|                     'packages/node_modules/@node-red/runtime/locales/**/*.json' | ||||
|                 ], | ||||
|                 tasks: ['jsonlint:messages'] | ||||
|             }, | ||||
|             keymaps: { | ||||
|                 files: [ | ||||
|                     'editor/js/keymap.json' | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js/keymap.json' | ||||
|                 ], | ||||
|                 tasks: ['jsonlint:keymaps','copy:build'] | ||||
|             }, | ||||
|             tours: { | ||||
|                 files: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/tours/**/*.js' | ||||
|                 ], | ||||
|                 tasks: ['copy:build'] | ||||
|             }, | ||||
|             misc: { | ||||
|                 files: [ | ||||
|                     'CHANGELOG.md' | ||||
| @@ -287,12 +347,13 @@ module.exports = function(grunt) { | ||||
|         nodemon: { | ||||
|             /* uses .nodemonignore */ | ||||
|             dev: { | ||||
|                 script: 'red.js', | ||||
|                 script: 'packages/node_modules/node-red/red.js', | ||||
|                 options: { | ||||
|                     args: nodemonArgs, | ||||
|                     ext: 'js,html,json', | ||||
|                     watch: [ | ||||
|                         'red','nodes' | ||||
|                         'packages/node_modules', | ||||
|                         '!packages/node_modules/@node-red/editor-client' | ||||
|                     ] | ||||
|                 } | ||||
|             } | ||||
| @@ -311,69 +372,75 @@ module.exports = function(grunt) { | ||||
|             build: { | ||||
|                 files:[ | ||||
|                     { | ||||
|                         src: 'editor/js/main.js', | ||||
|                         dest: 'public/red/main.js' | ||||
|                         src: 'packages/node_modules/@node-red/editor-client/src/js/main.js', | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/main.js' | ||||
|                     }, | ||||
|                     { | ||||
|                         src: 'editor/js/keymap.json', | ||||
|                         dest: 'public/red/keymap.json' | ||||
|                         src: 'packages/node_modules/@node-red/editor-client/src/js/keymap.json', | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/keymap.json' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'editor/images', | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/images', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'public/red/images/' | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/images/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'editor/vendor', | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/vendor', | ||||
|                         src: [ | ||||
|                             'ace/**', | ||||
|                             //'bootstrap/css/**', | ||||
|                             'bootstrap/img/**', | ||||
|                             'jquery/css/**', | ||||
|                             'font-awesome/**' | ||||
|                             'jquery/css/base/**', | ||||
|                             'font-awesome/**', | ||||
|                             'monaco/dist/**', | ||||
|                             'monaco/types/extraLibs.js', | ||||
|                             'monaco/style.css', | ||||
|                             'monaco/monaco-bootstrap.js' | ||||
|                         ], | ||||
|                         expand: true, | ||||
|                         dest: 'public/vendor/' | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/vendor/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'editor/icons', | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src', | ||||
|                         src: [ | ||||
|                             'types/node/*.ts', | ||||
|                             'types/node-red/*.ts', | ||||
|                         ], | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/icons', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'public/icons/' | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/icons/' | ||||
|                     }, | ||||
|                     { | ||||
|                         expand: true, | ||||
|                         src: ['editor/index.html','editor/favicon.ico'], | ||||
|                         dest: 'public/', | ||||
|                         src: ['packages/node_modules/@node-red/editor-client/src/index.html','packages/node_modules/@node-red/editor-client/src/favicon.ico'], | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/', | ||||
|                         flatten: true | ||||
|                     }, | ||||
|                     { | ||||
|                         src: 'CHANGELOG.md', | ||||
|                         dest: 'public/red/about' | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/about' | ||||
|                     }, | ||||
|                     { | ||||
|                         src: 'CHANGELOG.md', | ||||
|                         dest: 'packages/node_modules/node-red/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/ace/bin/', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/vendor/ace/' | ||||
|                     }, | ||||
|                     { | ||||
|                         cwd: 'packages/node_modules/@node-red/editor-client/src/tours', | ||||
|                         src: '**', | ||||
|                         expand: true, | ||||
|                         dest: 'packages/node_modules/@node-red/editor-client/public/red/tours/' | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             release: { | ||||
|                 files: [{ | ||||
|                     mode: true, | ||||
|                     expand: true, | ||||
|                     src: [ | ||||
|                         '*.md', | ||||
|                         'LICENSE', | ||||
|                         'package.json', | ||||
|                         'settings.js', | ||||
|                         'red.js', | ||||
|                         'lib/.gitignore', | ||||
|                         'nodes/*.demo', | ||||
|                         'nodes/core/**', | ||||
|                         'red/**', | ||||
|                         'public/**', | ||||
|                         'editor/templates/**', | ||||
|                         'bin/**' | ||||
|                     ], | ||||
|                     dest: path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>') | ||||
|                 }] | ||||
|             } | ||||
|         }, | ||||
|         chmod: { | ||||
| @@ -381,20 +448,96 @@ module.exports = function(grunt) { | ||||
|                 mode: '755' | ||||
|             }, | ||||
|             release: { | ||||
|                 // Target-specific file/dir lists and/or options go here. | ||||
|                 src: [ | ||||
|                     path.resolve('<%= paths.dist %>/node-red-<%= pkg.version %>/nodes/core/hardware/nrgpio*') | ||||
|                     "packages/node_modules/@node-red/nodes/core/hardware/nrgpio", | ||||
|                     "packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/node-red-*sh" | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         'npm-command': { | ||||
|             options: { | ||||
|                 cmd: "pack", | ||||
|                 cwd: "<%= paths.dist %>/modules" | ||||
|             }, | ||||
|             'node-red': { options: { args: [__dirname+'/packages/node_modules/node-red'] } }, | ||||
|             '@node-red/editor-api': { options: { args: [__dirname+'/packages/node_modules/@node-red/editor-api'] } }, | ||||
|             '@node-red/editor-client': { options: { args: [__dirname+'/packages/node_modules/@node-red/editor-client'] } }, | ||||
|             '@node-red/nodes': { options: { args: [__dirname+'/packages/node_modules/@node-red/nodes'] } }, | ||||
|             '@node-red/registry': { options: { args: [__dirname+'/packages/node_modules/@node-red/registry'] } }, | ||||
|             '@node-red/runtime': { options: { args: [__dirname+'/packages/node_modules/@node-red/runtime'] } }, | ||||
|             '@node-red/util': { options: { args: [__dirname+'/packages/node_modules/@node-red/util'] } } | ||||
|  | ||||
|  | ||||
|         }, | ||||
|         mkdir: { | ||||
|             release: { | ||||
|                 options: { | ||||
|                     create: ['<%= paths.dist %>/modules'] | ||||
|                 }, | ||||
|             }, | ||||
|         }, | ||||
|         compress: { | ||||
|             release: { | ||||
|                 options: { | ||||
|                     archive: '<%= paths.dist %>/node-red-<%= pkg.version %>.zip' | ||||
|                 }, | ||||
|                 expand: true, | ||||
|                 cwd: '<%= paths.dist %>/', | ||||
|                 src: ['node-red-<%= pkg.version %>/**'] | ||||
|                 cwd: 'packages/node_modules/', | ||||
|                 src: [ | ||||
|                     '**', | ||||
|                     '!@node-red/editor-client/src/**' | ||||
|                 ] | ||||
|             } | ||||
|         }, | ||||
|         jsdoc : { | ||||
|             modules: { | ||||
|                 src: [ | ||||
|                     'API.md', | ||||
|                     'packages/node_modules/node-red/lib/red.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/index.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/api/*.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/events.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/hooks.js', | ||||
|                     'packages/node_modules/@node-red/util/**/*.js', | ||||
|                     'packages/node_modules/@node-red/editor-api/lib/index.js', | ||||
|                     'packages/node_modules/@node-red/editor-api/lib/auth/index.js', | ||||
|                     'packages/node_modules/@node-red/registry/lib/index.js' | ||||
|                 ], | ||||
|                 options: { | ||||
|                     destination: 'docs', | ||||
|                     configure: './jsdoc.json', | ||||
|                     fred: "hi there" | ||||
|                 } | ||||
|             }, | ||||
|             _editor: { | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/editor-client/src/js' | ||||
|                     ], | ||||
|                 options: { | ||||
|                     destination: 'packages/node_modules/@node-red/editor-client/docs', | ||||
|                     configure: './jsdoc.json' | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         }, | ||||
|         jsdoc2md: { | ||||
|             runtimeAPI: { | ||||
|                 options: { | ||||
|                     separators: true | ||||
|                 }, | ||||
|                 src: [ | ||||
|                     'packages/node_modules/@node-red/runtime/lib/index.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/api/*.js', | ||||
|                     'packages/node_modules/@node-red/runtime/lib/events.js' | ||||
|                 ], | ||||
|                 dest: 'packages/node_modules/@node-red/runtime/docs/api.md' | ||||
|             }, | ||||
|             nodeREDUtil: { | ||||
|                 options: { | ||||
|                     separators: true | ||||
|                 }, | ||||
|                 src: 'packages/node_modules/@node-red/util/**/*.js', | ||||
|                 dest: 'packages/node_modules/@node-red/util/docs/api.md' | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| @@ -407,17 +550,42 @@ module.exports = function(grunt) { | ||||
|     grunt.loadNpmTasks('grunt-contrib-watch'); | ||||
|     grunt.loadNpmTasks('grunt-concurrent'); | ||||
|     grunt.loadNpmTasks('grunt-sass'); | ||||
|     grunt.loadNpmTasks('grunt-nodemon'); | ||||
|     grunt.loadNpmTasks('grunt-contrib-compress'); | ||||
|     grunt.loadNpmTasks('grunt-contrib-copy'); | ||||
|     grunt.loadNpmTasks('grunt-chmod'); | ||||
|     grunt.loadNpmTasks('grunt-jsonlint'); | ||||
|     grunt.loadNpmTasks('grunt-mocha-istanbul'); | ||||
|     if (fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { | ||||
|         grunt.loadNpmTasks('grunt-webdriver'); | ||||
|     } | ||||
|     grunt.loadNpmTasks('grunt-jsdoc'); | ||||
|     grunt.loadNpmTasks('grunt-jsdoc-to-markdown'); | ||||
|     grunt.loadNpmTasks('grunt-npm-command'); | ||||
|     grunt.loadNpmTasks('grunt-mkdir'); | ||||
|     grunt.loadNpmTasks('grunt-simple-nyc'); | ||||
|  | ||||
|     grunt.registerMultiTask('nodemon', 'Runs a nodemon monitor of your node.js server.', function () { | ||||
|         const nodemon = require('nodemon'); | ||||
|         this.async(); | ||||
|         const options = this.options(); | ||||
|         options.script = this.data.script; | ||||
|         let callback; | ||||
|         if (options.callback) { | ||||
|             callback = options.callback; | ||||
|             delete options.callback; | ||||
|         } else { | ||||
|             callback = function(nodemonApp) { | ||||
|                 nodemonApp.on('log', function (event) { | ||||
|                     console.log(event.colour); | ||||
|                 }); | ||||
|             }; | ||||
|         } | ||||
|         callback(nodemon(options)); | ||||
|     }); | ||||
|  | ||||
|     grunt.registerMultiTask('attachCopyright', function() { | ||||
|         var files = this.data.src; | ||||
|         var copyright = "/**\n"+ | ||||
|             " * Copyright JS Foundation and other contributors, http://js.foundation\n"+ | ||||
|             " * Copyright OpenJS Foundation and other contributors, https://openjsf.org/\n"+ | ||||
|             " *\n"+ | ||||
|             " * Licensed under the Apache License, Version 2.0 (the \"License\");\n"+ | ||||
|             " * you may not use this file except in compliance with the License.\n"+ | ||||
| @@ -454,6 +622,38 @@ module.exports = function(grunt) { | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     grunt.registerTask('verifyPackageDependencies', function() { | ||||
|         var done = this.async(); | ||||
|         var verifyDependencies = require("./scripts/verify-package-dependencies.js"); | ||||
|         verifyDependencies().then(function(failures) { | ||||
|             if (failures.length > 0) { | ||||
|                 failures.forEach(f => grunt.log.error(f)); | ||||
|                 grunt.fail.fatal("Failed to verify package dependencies"); | ||||
|             } | ||||
|             done(); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     grunt.registerTask('verifyUiTestDependencies', function() { | ||||
|         if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { | ||||
|             grunt.fail.fatal('You need to install the UI test dependencies first.\nUse the script in "scripts/install-ui-test-dependencies.sh"'); | ||||
|             return false; | ||||
|         } | ||||
|     }); | ||||
|     grunt.registerTask('generatePublishScript', | ||||
|         'Generates a script to publish build output to npm', | ||||
|             function () { | ||||
|                 const done = this.async(); | ||||
|                 const generatePublishScript = require("./scripts/generate-publish-script.js"); | ||||
|                 generatePublishScript().then(function(output) { | ||||
|                     grunt.log.writeln(output); | ||||
|  | ||||
|                     const filePath = path.join(grunt.config.get('paths.dist'),"modules","publish.sh"); | ||||
|                     grunt.file.write(filePath,output); | ||||
|  | ||||
|                     done(); | ||||
|                 }); | ||||
|             }); | ||||
|     grunt.registerTask('setDevEnv', | ||||
|         'Sets NODE_ENV=development so non-minified assets are used', | ||||
|             function () { | ||||
| @@ -462,33 +662,61 @@ module.exports = function(grunt) { | ||||
|  | ||||
|     grunt.registerTask('default', | ||||
|         'Builds editor content then runs code style checks and unit tests on all components', | ||||
|         ['build','test-core','test-editor','test-nodes']); | ||||
|         ['build','verifyPackageDependencies','jshint:editor','nyc:all']); | ||||
|  | ||||
|     grunt.registerTask('no-coverage', | ||||
|         'Builds editor content then runs code style checks and unit tests on all components without code coverage', | ||||
|         ['build','verifyPackageDependencies','jshint:editor','simplemocha:all']); | ||||
|  | ||||
|  | ||||
|     grunt.registerTask('test-core', | ||||
|         'Runs code style check and unit tests on core runtime code', | ||||
|         ['jshint:core','simplemocha:core']); | ||||
|         ['build','nyc:core']); | ||||
|  | ||||
|     grunt.registerTask('test-editor', | ||||
|         'Runs code style check on editor code', | ||||
|         ['jshint:editor']); | ||||
|  | ||||
|     if (!fs.existsSync(path.join("node_modules", "grunt-webdriver"))) { | ||||
|         grunt.registerTask('test-ui', | ||||
|             'Builds editor content then runs unit tests on editor ui', | ||||
|             ['verifyUiTestDependencies']); | ||||
|     } else { | ||||
|         grunt.registerTask('test-ui', | ||||
|             'Builds editor content then runs unit tests on editor ui', | ||||
|             ['verifyUiTestDependencies','build','jshint:editor','webdriver:all']); | ||||
|     } | ||||
|  | ||||
|     grunt.registerTask('test-nodes', | ||||
|         'Runs unit tests on core nodes', | ||||
|         ['simplemocha:nodes']); | ||||
|         ['build','nyc:nodes']); | ||||
|  | ||||
|     grunt.registerTask('build', | ||||
|         'Builds editor content', | ||||
|         ['clean:build','jsonlint','concat:build','concat:vendor','copy:build','uglify:build','sass:build','attachCopyright']); | ||||
|  | ||||
|     grunt.registerTask('build-dev', | ||||
|         'Developer mode: build dev version', | ||||
|         ['clean:build','concat:build','concat:vendor','copy:build','sass:build','setDevEnv']); | ||||
|  | ||||
|     grunt.registerTask('dev', | ||||
|         'Developer mode: run node-red, watch for source changes and build/restart', | ||||
|         ['build','setDevEnv','concurrent:dev']); | ||||
|  | ||||
|     grunt.registerTask('release', | ||||
|         'Create distribution zip file', | ||||
|         ['build','clean:release','copy:release','chmod:release','compress:release']); | ||||
|         ['build','verifyPackageDependencies','clean:release','mkdir:release','chmod:release','compress:release','pack-modules','generatePublishScript']); | ||||
|  | ||||
|     grunt.registerTask('pack-modules', | ||||
|         'Create module pack files for release', | ||||
|         ['mkdir:release','npm-command']); | ||||
|  | ||||
|  | ||||
|     grunt.registerTask('coverage', | ||||
|         'Run Istanbul code test coverage task', | ||||
|         ['build','mocha_istanbul']); | ||||
|         ['build','nyc:all']); | ||||
|  | ||||
|     grunt.registerTask('docs', | ||||
|         'Generates API documentation', | ||||
|         ['jsdoc']); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						| @@ -1,4 +1,4 @@ | ||||
| Copyright JS Foundation and other contributors, http://js.foundation | ||||
| Copyright OpenJS Foundation and other contributors, https://openjsf.org/ | ||||
|  | ||||
|                                  Apache License | ||||
|                            Version 2.0, January 2004 | ||||
|   | ||||
							
								
								
									
										28
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -2,19 +2,19 @@ | ||||
|  | ||||
| http://nodered.org | ||||
|  | ||||
| [](https://travis-ci.org/node-red/node-red) | ||||
| [](https://travis-ci.org/node-red/node-red) | ||||
| [](https://coveralls.io/r/node-red/node-red?branch=master) | ||||
|  | ||||
| A visual tool for wiring the Internet of Things. | ||||
| Low-code programming for event-driven applications. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Quick Start | ||||
|  | ||||
| Check out http://nodered.org/docs/getting-started/ for full instructions on getting | ||||
| started. | ||||
|  | ||||
| 1. `sudo npm install -g node-red` | ||||
| 1. `sudo npm install -g --unsafe-perm node-red` | ||||
| 2. `node-red` | ||||
| 3. Open <http://localhost:1880> | ||||
|  | ||||
| @@ -22,8 +22,7 @@ started. | ||||
|  | ||||
| More documentation can be found [here](http://nodered.org/docs). | ||||
|  | ||||
| For further help, or general discussion, please use the | ||||
| [mailing list](https://groups.google.com/forum/#!forum/node-red). | ||||
| For further help, or general discussion, please use the [Node-RED Forum](https://discourse.nodered.org) or [slack team](https://nodered.org/slack). | ||||
|  | ||||
| ## Developers | ||||
|  | ||||
| @@ -45,9 +44,6 @@ If you want to run the latest code from git, here's how to get started: | ||||
| 4. Run | ||||
|  | ||||
|         npm start | ||||
|    or | ||||
|  | ||||
|         node red.js | ||||
|  | ||||
| ## Contributing | ||||
|  | ||||
| @@ -56,19 +52,19 @@ Before raising a pull-request, please read our | ||||
|  | ||||
| This project adheres to the [Contributor Covenant 1.4](http://contributor-covenant.org/version/1/4/). | ||||
|  By participating, you are expected to uphold this code. Please report unacceptable | ||||
|  behavior to any of the [project's core team](https://github.com/orgs/node-red/teams/core). | ||||
|  behavior to any of the project's core team at team@nodered.org. | ||||
|  | ||||
| ## Authors | ||||
|  | ||||
| Node-RED is a project of the [JS Foundation](http://js.foundation). | ||||
| Node-RED is a project of the [OpenJS Foundation](http://openjsf.org). | ||||
|  | ||||
| It was created by [IBM Emerging Technology](https://www.ibm.com/blogs/emerging-technology/). | ||||
|  | ||||
| * Nick O'Leary [@knolleary](http://twitter.com/knolleary) | ||||
| * Dave Conway-Jones [@ceejay](http://twitter.com/ceejay) | ||||
| It is maintained by: | ||||
|  | ||||
|  * Nick O'Leary [@knolleary](http://twitter.com/knolleary) | ||||
|  * Dave Conway-Jones [@ceejay](http://twitter.com/ceejay) | ||||
|  * And many others... | ||||
|  | ||||
|  | ||||
| ## Copyright and license | ||||
|  | ||||
| Copyright JS Foundation and other contributors, http://js.foundation under [the Apache 2.0 license](LICENSE). | ||||
| Copyright OpenJS Foundation and other contributors, https://openjsf.org under [the Apache 2.0 license](LICENSE). | ||||
|   | ||||
							
								
								
									
										5
									
								
								SECURITY.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,5 @@ | ||||
| # Security Policy | ||||
|  | ||||
| ## Reporting a Vulnerability | ||||
|  | ||||
| Please report any potential security issues to `team@nodered.org`. This will notify the core project team who will respond accordingly. | ||||
| Before Width: | Height: | Size: 308 B | 
| Before Width: | Height: | Size: 508 B | 
| Before Width: | Height: | Size: 575 B | 
| Before Width: | Height: | Size: 493 B | 
| Before Width: | Height: | Size: 601 B | 
| Before Width: | Height: | Size: 459 B | 
| Before Width: | Height: | Size: 218 B | 
| Before Width: | Height: | Size: 324 B | 
| Before Width: | Height: | Size: 378 B | 
| Before Width: | Height: | Size: 255 B | 
| Before Width: | Height: | Size: 457 B | 
| Before Width: | Height: | Size: 502 B | 
| Before Width: | Height: | Size: 449 B | 
| Before Width: | Height: | Size: 253 B | 
| Before Width: | Height: | Size: 639 B | 
| Before Width: | Height: | Size: 402 B | 
| Before Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 413 B | 
| Before Width: | Height: | Size: 393 B | 
| Before Width: | Height: | Size: 467 B | 
| Before Width: | Height: | Size: 393 B | 
| Before Width: | Height: | Size: 423 B | 
| Before Width: | Height: | Size: 360 B | 
| Before Width: | Height: | Size: 482 B | 
| Before Width: | Height: | Size: 273 B | 
| Before Width: | Height: | Size: 256 B | 
| Before Width: | Height: | Size: 439 B | 
| Before Width: | Height: | Size: 592 B | 
| Before Width: | Height: | Size: 509 B | 
| Before Width: | Height: | Size: 488 B | 
| Before Width: | Height: | Size: 628 B | 
| Before Width: | Height: | Size: 258 B | 
| Before Width: | Height: | Size: 404 B | 
| Before Width: | Height: | Size: 591 B | 
| Before Width: | Height: | Size: 707 B | 
| Before Width: | Height: | Size: 291 B | 
| Before Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 289 B | 
| Before Width: | Height: | Size: 368 B | 
| Before Width: | Height: | Size: 290 B | 
| Before Width: | Height: | Size: 392 B | 
| Before Width: | Height: | Size: 192 B | 
| Before Width: | Height: | Size: 1019 B | 
| Before Width: | Height: | Size: 600 B | 
| Before Width: | Height: | Size: 410 B | 
| Before Width: | Height: | Size: 638 B | 
| Before Width: | Height: | Size: 546 B | 
| Before Width: | Height: | Size: 638 B | 
| Before Width: | Height: | Size: 646 B | 
| Before Width: | Height: | Size: 563 B | 
| Before Width: | Height: | Size: 588 B | 
| Before Width: | Height: | Size: 502 B | 
| @@ -1,327 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.history = (function() { | ||||
|     var undo_history = []; | ||||
|  | ||||
|     function undoEvent(ev) { | ||||
|         var i; | ||||
|         var len; | ||||
|         var node; | ||||
|         var subflow; | ||||
|         var modifiedTabs = {}; | ||||
|         if (ev) { | ||||
|             if (ev.t == 'multi') { | ||||
|                 len = ev.events.length; | ||||
|                 for (i=len-1;i>=0;i--) { | ||||
|                     undoEvent(ev.events[i]); | ||||
|                 } | ||||
|             } else if (ev.t == 'replace') { | ||||
|                 RED.nodes.clear(); | ||||
|                 var imported = RED.nodes.import(ev.config); | ||||
|                 imported[0].forEach(function(n) { | ||||
|                     if (ev.changed[n.id]) { | ||||
|                         n.changed = true; | ||||
|                     } | ||||
|                 }) | ||||
|  | ||||
|                 RED.nodes.version(ev.rev); | ||||
|             } else if (ev.t == 'add') { | ||||
|                 if (ev.nodes) { | ||||
|                     for (i=0;i<ev.nodes.length;i++) { | ||||
|                         node = RED.nodes.node(ev.nodes[i]); | ||||
|                         if (node.z) { | ||||
|                             modifiedTabs[node.z] = true; | ||||
|                         } | ||||
|                         RED.nodes.remove(ev.nodes[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.removeLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.workspaces) { | ||||
|                     for (i=0;i<ev.workspaces.length;i++) { | ||||
|                         RED.nodes.removeWorkspace(ev.workspaces[i].id); | ||||
|                         RED.workspaces.remove(ev.workspaces[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflows) { | ||||
|                     for (i=0;i<ev.subflows.length;i++) { | ||||
|                         RED.nodes.removeSubflow(ev.subflows[i]); | ||||
|                         RED.workspaces.remove(ev.subflows[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow) { | ||||
|                     if (ev.subflow.instances) { | ||||
|                         ev.subflow.instances.forEach(function(n) { | ||||
|                             var node = RED.nodes.node(n.id); | ||||
|                             if (node) { | ||||
|                                 node.changed = n.changed; | ||||
|                                 node.dirty = true; | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                     if (ev.subflow.hasOwnProperty('changed')) { | ||||
|                         subflow = RED.nodes.subflow(ev.subflow.id); | ||||
|                         if (subflow) { | ||||
|                             subflow.changed = ev.subflow.changed; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.removedLinks) { | ||||
|                     for (i=0;i<ev.removedLinks.length;i++) { | ||||
|                         RED.nodes.addLink(ev.removedLinks[i]); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } else if (ev.t == "delete") { | ||||
|                 if (ev.workspaces) { | ||||
|                     for (i=0;i<ev.workspaces.length;i++) { | ||||
|                         RED.nodes.addWorkspace(ev.workspaces[i]); | ||||
|                         RED.workspaces.add(ev.workspaces[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow && ev.subflow.subflow) { | ||||
|                     RED.nodes.addSubflow(ev.subflow.subflow); | ||||
|                 } | ||||
|                 if (ev.subflowInputs && ev.subflowInputs.length > 0) { | ||||
|                     subflow = RED.nodes.subflow(ev.subflowInputs[0].z); | ||||
|                     subflow.in.push(ev.subflowInputs[0]); | ||||
|                     subflow.in[0].dirty = true; | ||||
|                 } | ||||
|                 if (ev.subflowOutputs && ev.subflowOutputs.length > 0) { | ||||
|                     subflow = RED.nodes.subflow(ev.subflowOutputs[0].z); | ||||
|                     ev.subflowOutputs.sort(function(a,b) { return a.i-b.i}); | ||||
|                     for (i=0;i<ev.subflowOutputs.length;i++) { | ||||
|                         var output = ev.subflowOutputs[i]; | ||||
|                         subflow.out.splice(output.i,0,output); | ||||
|                         for (var j=output.i+1;j<subflow.out.length;j++) { | ||||
|                             subflow.out[j].i++; | ||||
|                             subflow.out[j].dirty = true; | ||||
|                         } | ||||
|                         RED.nodes.eachLink(function(l) { | ||||
|                             if (l.source.type == "subflow:"+subflow.id) { | ||||
|                                 if (l.sourcePort >= output.i) { | ||||
|                                     l.sourcePort++; | ||||
|                                 } | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow && ev.subflow.hasOwnProperty('instances')) { | ||||
|                     ev.subflow.instances.forEach(function(n) { | ||||
|                         var node = RED.nodes.node(n.id); | ||||
|                         if (node) { | ||||
|                             node.changed = n.changed; | ||||
|                             node.dirty = true; | ||||
|                         } | ||||
|                     }); | ||||
|                 } | ||||
|                 if (subflow) { | ||||
|                     RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) { | ||||
|                         n.inputs = subflow.in.length; | ||||
|                         n.outputs = subflow.out.length; | ||||
|                         while (n.outputs > n.ports.length) { | ||||
|                             n.ports.push(n.ports.length); | ||||
|                         } | ||||
|                         n.resize = true; | ||||
|                         n.dirty = true; | ||||
|                     }); | ||||
|                 } | ||||
|                 if (ev.nodes) { | ||||
|                     for (i=0;i<ev.nodes.length;i++) { | ||||
|                         RED.nodes.add(ev.nodes[i]); | ||||
|                         modifiedTabs[ev.nodes[i].z] = true; | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.addLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.changes) { | ||||
|                     for (i in ev.changes) { | ||||
|                         if (ev.changes.hasOwnProperty(i)) { | ||||
|                             node = RED.nodes.node(i); | ||||
|                             if (node) { | ||||
|                                 for (var d in ev.changes[i]) { | ||||
|                                     if (ev.changes[i].hasOwnProperty(d)) { | ||||
|                                         node[d] = ev.changes[i][d]; | ||||
|                                     } | ||||
|                                 } | ||||
|                                 node.dirty = true; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|             } else if (ev.t == "move") { | ||||
|                 for (i=0;i<ev.nodes.length;i++) { | ||||
|                     var n = ev.nodes[i]; | ||||
|                     n.n.x = n.ox; | ||||
|                     n.n.y = n.oy; | ||||
|                     n.n.dirty = true; | ||||
|                     n.n.moved = n.moved; | ||||
|                 } | ||||
|                 // A move could have caused a link splice | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.removeLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.removedLinks) { | ||||
|                     for (i=0;i<ev.removedLinks.length;i++) { | ||||
|                         RED.nodes.addLink(ev.removedLinks[i]); | ||||
|                     } | ||||
|                 } | ||||
|             } else if (ev.t == "edit") { | ||||
|                 for (i in ev.changes) { | ||||
|                     if (ev.changes.hasOwnProperty(i)) { | ||||
|                         if (ev.node._def.defaults[i] && ev.node._def.defaults[i].type) { | ||||
|                             // This is a config node property | ||||
|                             var currentConfigNode = RED.nodes.node(ev.node[i]); | ||||
|                             if (currentConfigNode) { | ||||
|                                 currentConfigNode.users.splice(currentConfigNode.users.indexOf(ev.node),1); | ||||
|                             } | ||||
|                             var newConfigNode = RED.nodes.node(ev.changes[i]); | ||||
|                             if (newConfigNode) { | ||||
|                                 newConfigNode.users.push(ev.node); | ||||
|                             } | ||||
|                         } | ||||
|                         ev.node[i] = ev.changes[i]; | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.subflow) { | ||||
|                     if (ev.subflow.hasOwnProperty('inputCount')) { | ||||
|                         if (ev.node.in.length > ev.subflow.inputCount) { | ||||
|                             ev.node.in.splice(ev.subflow.inputCount); | ||||
|                         } else if (ev.subflow.inputs.length > 0) { | ||||
|                             ev.node.in = ev.node.in.concat(ev.subflow.inputs); | ||||
|                         } | ||||
|                     } | ||||
|                     if (ev.subflow.hasOwnProperty('outputCount')) { | ||||
|                         if (ev.node.out.length > ev.subflow.outputCount) { | ||||
|                             ev.node.out.splice(ev.subflow.outputCount); | ||||
|                         } else if (ev.subflow.outputs.length > 0) { | ||||
|                             ev.node.out = ev.node.out.concat(ev.subflow.outputs); | ||||
|                         } | ||||
|                     } | ||||
|                     if (ev.subflow.hasOwnProperty('instances')) { | ||||
|                         ev.subflow.instances.forEach(function(n) { | ||||
|                             var node = RED.nodes.node(n.id); | ||||
|                             if (node) { | ||||
|                                 node.changed = n.changed; | ||||
|                                 node.dirty = true; | ||||
|                             } | ||||
|                         }); | ||||
|                     } | ||||
|                     RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) { | ||||
|                         n.inputs = ev.node.in.length; | ||||
|                         n.outputs = ev.node.out.length; | ||||
|                         RED.editor.updateNodeProperties(n); | ||||
|                     }); | ||||
|                 } else { | ||||
|                     var outputMap; | ||||
|                     if (ev.outputMap) { | ||||
|                         outputMap = {}; | ||||
|                         for (var port in ev.outputMap) { | ||||
|                             if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== "-1") { | ||||
|                                 outputMap[ev.outputMap[port]] = port; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     RED.editor.updateNodeProperties(ev.node,outputMap); | ||||
|                     RED.editor.validateNode(ev.node); | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.addLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 ev.node.dirty = true; | ||||
|                 ev.node.changed = ev.changed; | ||||
|             } else if (ev.t == "createSubflow") { | ||||
|                 if (ev.nodes) { | ||||
|                     RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) { | ||||
|                         n.z = ev.activeWorkspace; | ||||
|                         n.dirty = true; | ||||
|                     }); | ||||
|                     for (i=0;i<ev.nodes.length;i++) { | ||||
|                         RED.nodes.remove(ev.nodes[i]); | ||||
|                     } | ||||
|                 } | ||||
|                 if (ev.links) { | ||||
|                     for (i=0;i<ev.links.length;i++) { | ||||
|                         RED.nodes.removeLink(ev.links[i]); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 RED.nodes.removeSubflow(ev.subflow.subflow); | ||||
|                 RED.workspaces.remove(ev.subflow.subflow); | ||||
|  | ||||
|                 if (ev.removedLinks) { | ||||
|                     for (i=0;i<ev.removedLinks.length;i++) { | ||||
|                         RED.nodes.addLink(ev.removedLinks[i]); | ||||
|                     } | ||||
|                 } | ||||
|             } else if (ev.t == "reorder") { | ||||
|                 if (ev.order) { | ||||
|                     RED.workspaces.order(ev.order); | ||||
|                 } | ||||
|             } | ||||
|             Object.keys(modifiedTabs).forEach(function(id) { | ||||
|                 var subflow = RED.nodes.subflow(id); | ||||
|                 if (subflow) { | ||||
|                     RED.editor.validateNode(subflow); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             RED.nodes.dirty(ev.dirty); | ||||
|             RED.view.redraw(true); | ||||
|             RED.palette.refresh(); | ||||
|             RED.workspaces.refresh(); | ||||
|             RED.sidebar.config.refresh(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         //TODO: this function is a placeholder until there is a 'save' event that can be listened to | ||||
|         markAllDirty: function() { | ||||
|             for (var i=0;i<undo_history.length;i++) { | ||||
|                 undo_history[i].dirty = true; | ||||
|             } | ||||
|         }, | ||||
|         list: function() { | ||||
|             return undo_history | ||||
|         }, | ||||
|         depth: function() { | ||||
|             return undo_history.length; | ||||
|         }, | ||||
|         push: function(ev) { | ||||
|             undo_history.push(ev); | ||||
|         }, | ||||
|         pop: function() { | ||||
|             var ev = undo_history.pop(); | ||||
|             undoEvent(ev); | ||||
|         }, | ||||
|         peek: function() { | ||||
|             return undo_history[undo_history.length-1]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| })(); | ||||
| @@ -1,86 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| RED.i18n = (function() { | ||||
|  | ||||
|     return { | ||||
|         init: function(done) { | ||||
|             i18n.init({ | ||||
|                 resGetPath: 'locales/__ns__?lng=__lng__', | ||||
|                 dynamicLoad: false, | ||||
|                 load:'current', | ||||
|                 ns: { | ||||
|                     namespaces: ["editor","node-red","jsonata","infotips"], | ||||
|                     defaultNs: "editor" | ||||
|                 }, | ||||
|                 fallbackLng: ['en-US'], | ||||
|                 useCookie: false | ||||
|             },function() { | ||||
|                 done(); | ||||
|             }); | ||||
|             RED["_"] = function() { | ||||
|                 return i18n.t.apply(null,arguments); | ||||
|             } | ||||
|  | ||||
|         }, | ||||
|         loadCatalog: function(namespace,done) { | ||||
|             var languageList = i18n.functions.toLanguages(i18n.detectLanguage()); | ||||
|             var toLoad = languageList.length; | ||||
|             languageList.forEach(function(lang) { | ||||
|                 $.ajax({ | ||||
|                     headers: { | ||||
|                         "Accept":"application/json" | ||||
|                     }, | ||||
|                     cache: false, | ||||
|                     url: 'locales/'+namespace+'?lng='+lang, | ||||
|                     success: function(data) { | ||||
|                         i18n.addResourceBundle(lang,namespace,data); | ||||
|                         toLoad--; | ||||
|                         if (toLoad === 0) { | ||||
|                             done(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             }) | ||||
|  | ||||
|         }, | ||||
|  | ||||
|         loadNodeCatalogs: function(done) { | ||||
|             var languageList = i18n.functions.toLanguages(i18n.detectLanguage()); | ||||
|             var toLoad = languageList.length; | ||||
|  | ||||
|             languageList.forEach(function(lang) { | ||||
|                 $.ajax({ | ||||
|                     headers: { | ||||
|                         "Accept":"application/json" | ||||
|                     }, | ||||
|                     cache: false, | ||||
|                     url: 'locales/nodes?lng='+lang, | ||||
|                     success: function(data) { | ||||
|                         var namespaces = Object.keys(data); | ||||
|                         namespaces.forEach(function(ns) { | ||||
|                             i18n.addResourceBundle(lang,ns,data[ns]); | ||||
|                         }); | ||||
|                         toLoad--; | ||||
|                         if (toLoad === 0) { | ||||
|                             done(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|             }) | ||||
|         } | ||||
|     } | ||||
| })(); | ||||
| @@ -1,39 +0,0 @@ | ||||
| { | ||||
|     "*": { | ||||
|         "ctrl-shift-p":"core:manage-palette", | ||||
|         "ctrl-f": "core:search", | ||||
|         "ctrl-=": "core:zoom-in", | ||||
|         "ctrl--": "core:zoom-out", | ||||
|         "ctrl-0": "core:zoom-reset", | ||||
|         "ctrl-enter": "core:confirm-edit-tray", | ||||
|         "ctrl-escape": "core:cancel-edit-tray", | ||||
|         "ctrl-g i": "core:show-info-tab", | ||||
|         "ctrl-g d": "core:show-debug-tab", | ||||
|         "ctrl-g c": "core:show-config-tab", | ||||
|         "ctrl-e": "core:show-export-dialog", | ||||
|         "ctrl-i": "core:show-import-dialog", | ||||
|         "ctrl-space": "core:toggle-sidebar", | ||||
|         "ctrl-,": "core:show-user-settings" | ||||
|     }, | ||||
|     "workspace": { | ||||
|         "backspace": "core:delete-selection", | ||||
|         "delete": "core:delete-selection", | ||||
|         "enter": "core:edit-selected-node", | ||||
|         "ctrl-c": "core:copy-selection-to-internal-clipboard", | ||||
|         "ctrl-x": "core:cut-selection-to-internal-clipboard", | ||||
|         "ctrl-v": "core:paste-from-internal-clipboard", | ||||
|         "ctrl-z": "core:undo", | ||||
|         "ctrl-a": "core:select-all-nodes", | ||||
|         "shift-?": "core:show-help", | ||||
|         "up": "core:move-selection-up", | ||||
|         "right": "core:move-selection-right", | ||||
|         "down": "core:move-selection-down", | ||||
|         "left": "core:move-selection-left", | ||||
|         "shift-up": "core:step-selection-up", | ||||
|         "shift-right": "core:step-selection-right", | ||||
|         "shift-down": "core:step-selection-down", | ||||
|         "shift-left": "core:step-selection-left", | ||||
|         "ctrl-shift-j": "core:show-previous-tab", | ||||
|         "ctrl-shift-k": "core:show-next-tab" | ||||
|      } | ||||
| } | ||||
| @@ -1,277 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| (function() { | ||||
|  | ||||
|     function loadNodeList() { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"application/json" | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'nodes', | ||||
|             success: function(data) { | ||||
|                 RED.nodes.setNodeList(data); | ||||
|                 RED.i18n.loadNodeCatalogs(loadNodes); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadNodes() { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"text/html" | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'nodes', | ||||
|             success: function(data) { | ||||
|                 $("body").append(data); | ||||
|                 $("body").i18n(); | ||||
|                 $("#palette > .palette-spinner").hide(); | ||||
|                 $(".palette-scroll").removeClass("hide"); | ||||
|                 $("#palette-search").removeClass("hide"); | ||||
|                 loadFlows(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadFlows() { | ||||
|         $.ajax({ | ||||
|             headers: { | ||||
|                 "Accept":"application/json", | ||||
|             }, | ||||
|             cache: false, | ||||
|             url: 'flows', | ||||
|             success: function(nodes) { | ||||
|                 var currentHash = window.location.hash; | ||||
|                 RED.nodes.version(nodes.rev); | ||||
|                 RED.nodes.import(nodes.flows); | ||||
|                 RED.nodes.dirty(false); | ||||
|                 RED.view.redraw(true); | ||||
|                 if (/^#flow\/.+$/.test(currentHash)) { | ||||
|                     RED.workspaces.show(currentHash.substring(6)); | ||||
|                 } | ||||
|  | ||||
|                 var persistentNotifications = {}; | ||||
|                 RED.comms.subscribe("notification/#",function(topic,msg) { | ||||
|                     var parts = topic.split("/"); | ||||
|                     var notificationId = parts[1]; | ||||
|                     if (notificationId === "runtime-deploy") { | ||||
|                         // handled in ui/deploy.js | ||||
|                         return; | ||||
|                     } | ||||
|                     if (notificationId === "node") { | ||||
|                         // handled below | ||||
|                         return; | ||||
|                     } | ||||
|                     if (msg.text) { | ||||
|                         var text = RED._(msg.text,{default:msg.text}); | ||||
|                         if (!persistentNotifications.hasOwnProperty(notificationId)) { | ||||
|                             persistentNotifications[notificationId] = RED.notify(text,msg.type,msg.timeout === undefined,msg.timeout); | ||||
|                         } else { | ||||
|                             persistentNotifications[notificationId].update(text,msg.timeout); | ||||
|                         } | ||||
|                     } else if (persistentNotifications.hasOwnProperty(notificationId)) { | ||||
|                         persistentNotifications[notificationId].close(); | ||||
|                         delete persistentNotifications[notificationId]; | ||||
|                     } | ||||
|                 }); | ||||
|                 RED.comms.subscribe("status/#",function(topic,msg) { | ||||
|                     var parts = topic.split("/"); | ||||
|                     var node = RED.nodes.node(parts[1]); | ||||
|                     if (node) { | ||||
|                         if (msg.hasOwnProperty("text")) { | ||||
|                             if (msg.text[0] !== ".") { | ||||
|                                 msg.text = node._(msg.text.toString(),{defaultValue:msg.text.toString()}); | ||||
|                             } | ||||
|                         } | ||||
|                         node.status = msg; | ||||
|                         node.dirty = true; | ||||
|                         RED.view.redraw(); | ||||
|                     } | ||||
|                 }); | ||||
|                 RED.comms.subscribe("notification/node/#",function(topic,msg) { | ||||
|                     var i,m; | ||||
|                     var typeList; | ||||
|                     var info; | ||||
|                     if (topic == "notification/node/added") { | ||||
|                         var addedTypes = []; | ||||
|                         msg.forEach(function(m) { | ||||
|                             var id = m.id; | ||||
|                             RED.nodes.addNodeSet(m); | ||||
|                             addedTypes = addedTypes.concat(m.types); | ||||
|                             RED.i18n.loadCatalog(id, function() { | ||||
|                                 $.get('nodes/'+id, function(data) { | ||||
|                                     $("body").append(data); | ||||
|                                 }); | ||||
|                             }); | ||||
|                         }); | ||||
|                         if (addedTypes.length) { | ||||
|                             typeList = "<ul><li>"+addedTypes.join("</li><li>")+"</li></ul>"; | ||||
|                             RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success"); | ||||
|                         } | ||||
|                     } else if (topic == "notification/node/removed") { | ||||
|                         for (i=0;i<msg.length;i++) { | ||||
|                             m = msg[i]; | ||||
|                             info = RED.nodes.removeNodeSet(m.id); | ||||
|                             if (info.added) { | ||||
|                                 typeList = "<ul><li>"+m.types.join("</li><li>")+"</li></ul>"; | ||||
|                                 RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success"); | ||||
|                             } | ||||
|                         } | ||||
|                     } else if (topic == "notification/node/enabled") { | ||||
|                         if (msg.types) { | ||||
|                             info = RED.nodes.getNodeSet(msg.id); | ||||
|                             if (info.added) { | ||||
|                                 RED.nodes.enableNodeSet(msg.id); | ||||
|                                 typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                                 RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success"); | ||||
|                             } else { | ||||
|                                 $.get('nodes/'+msg.id, function(data) { | ||||
|                                     $("body").append(data); | ||||
|                                     typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                                     RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success"); | ||||
|                                 }); | ||||
|                             } | ||||
|                         } | ||||
|                     } else if (topic == "notification/node/disabled") { | ||||
|                         if (msg.types) { | ||||
|                             RED.nodes.disableNodeSet(msg.id); | ||||
|                             typeList = "<ul><li>"+msg.types.join("</li><li>")+"</li></ul>"; | ||||
|                             RED.notify(RED._("palette.event.nodeDisabled", {count:msg.types.length})+typeList,"success"); | ||||
|                         } | ||||
|                     } else if (topic == "node/upgraded") { | ||||
|                         RED.notify(RED._("palette.event.nodeUpgraded", {module:msg.module,version:msg.version}),"success"); | ||||
|                         RED.nodes.registry.setModulePendingUpdated(msg.module,msg.version); | ||||
|                     } | ||||
|                     // Refresh flow library to ensure any examples are updated | ||||
|                     RED.library.loadFlowLibrary(); | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function showAbout() { | ||||
|         $.get('red/about', function(data) { | ||||
|             var aboutHeader = '<div style="text-align:center;">'+ | ||||
|                                 '<img width="50px" src="red/images/node-red-icon.svg" />'+ | ||||
|                               '</div>'; | ||||
|  | ||||
|             RED.sidebar.info.set(aboutHeader+marked(data)); | ||||
|             RED.sidebar.info.show(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function loadEditor() { | ||||
|         var menuOptions = []; | ||||
|         menuOptions.push({id:"menu-item-view-menu",label:RED._("menu.label.view.view"),options:[ | ||||
|             // {id:"menu-item-view-show-grid",setting:"view-show-grid",label:RED._("menu.label.view.showGrid"),toggle:true,onselect:"core:toggle-show-grid"}, | ||||
|             // {id:"menu-item-view-snap-grid",setting:"view-snap-grid",label:RED._("menu.label.view.snapGrid"),toggle:true,onselect:"core:toggle-snap-grid"}, | ||||
|             // {id:"menu-item-status",setting:"node-show-status",label:RED._("menu.label.displayStatus"),toggle:true,onselect:"core:toggle-status", selected: true}, | ||||
|             //null, | ||||
|             // {id:"menu-item-bidi",label:RED._("menu.label.view.textDir"),options:[ | ||||
|             //     {id:"menu-item-bidi-default",toggle:"text-direction",label:RED._("menu.label.view.defaultDir"),selected: true, onselect:function(s) { if(s){RED.text.bidi.setTextDirection("")}}}, | ||||
|             //     {id:"menu-item-bidi-ltr",toggle:"text-direction",label:RED._("menu.label.view.ltr"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("ltr")}}}, | ||||
|             //     {id:"menu-item-bidi-rtl",toggle:"text-direction",label:RED._("menu.label.view.rtl"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("rtl")}}}, | ||||
|             //     {id:"menu-item-bidi-auto",toggle:"text-direction",label:RED._("menu.label.view.auto"), onselect:function(s) { if(s){RED.text.bidi.setTextDirection("auto")}}} | ||||
|             // ]}, | ||||
|             // null, | ||||
|             {id:"menu-item-sidebar",label:RED._("menu.label.sidebar.show"),toggle:true,onselect:"core:toggle-sidebar", selected: true}, | ||||
|             null | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
|         menuOptions.push({id:"menu-item-import",label:RED._("menu.label.import"),options:[ | ||||
|             {id:"menu-item-import-clipboard",label:RED._("menu.label.clipboard"),onselect:"core:show-import-dialog"}, | ||||
|             {id:"menu-item-import-library",label:RED._("menu.label.library"),options:[]} | ||||
|         ]}); | ||||
|         menuOptions.push({id:"menu-item-export",label:RED._("menu.label.export"),disabled:true,options:[ | ||||
|             {id:"menu-item-export-clipboard",label:RED._("menu.label.clipboard"),disabled:true,onselect:"core:show-export-dialog"}, | ||||
|             {id:"menu-item-export-library",label:RED._("menu.label.library"),disabled:true,onselect:"core:library-export"} | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
|         menuOptions.push({id:"menu-item-search",label:RED._("menu.label.search"),onselect:"core:search"}); | ||||
|         menuOptions.push(null); | ||||
|         menuOptions.push({id:"menu-item-config-nodes",label:RED._("menu.label.displayConfig"),onselect:"core:show-config-tab"}); | ||||
|         menuOptions.push({id:"menu-item-workspace",label:RED._("menu.label.flows"),options:[ | ||||
|             {id:"menu-item-workspace-add",label:RED._("menu.label.add"),onselect:"core:add-flow"}, | ||||
|             {id:"menu-item-workspace-edit",label:RED._("menu.label.rename"),onselect:"core:edit-flow"}, | ||||
|             {id:"menu-item-workspace-delete",label:RED._("menu.label.delete"),onselect:"core:remove-flow"} | ||||
|         ]}); | ||||
|         menuOptions.push({id:"menu-item-subflow",label:RED._("menu.label.subflows"), options: [ | ||||
|             {id:"menu-item-subflow-create",label:RED._("menu.label.createSubflow"),onselect:"core:create-subflow"}, | ||||
|             {id:"menu-item-subflow-convert",label:RED._("menu.label.selectionToSubflow"),disabled:true,onselect:"core:convert-to-subflow"}, | ||||
|         ]}); | ||||
|         menuOptions.push(null); | ||||
|         if (RED.settings.theme('palette.editable') !== false) { | ||||
|             menuOptions.push({id:"menu-item-edit-palette",label:RED._("menu.label.editPalette"),onselect:"core:manage-palette"}); | ||||
|             menuOptions.push(null); | ||||
|         } | ||||
|  | ||||
|         menuOptions.push({id:"menu-item-user-settings",label:RED._("menu.label.settings"),onselect:"core:show-user-settings"}); | ||||
|         menuOptions.push(null); | ||||
|  | ||||
|         menuOptions.push({id:"menu-item-keyboard-shortcuts",label:RED._("menu.label.keyboardShortcuts"),onselect:"core:show-help"}); | ||||
|         menuOptions.push({id:"menu-item-help", | ||||
|             label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")), | ||||
|             href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs") | ||||
|         }); | ||||
|         menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" }); | ||||
|  | ||||
|  | ||||
|         RED.view.init(); | ||||
|         RED.userSettings.init(); | ||||
|         RED.user.init(); | ||||
|         RED.library.init(); | ||||
|         RED.keyboard.init(); | ||||
|         RED.palette.init(); | ||||
|         if (RED.settings.theme('palette.editable') !== false) { | ||||
|             RED.palette.editor.init(); | ||||
|         } | ||||
|  | ||||
|         RED.sidebar.init(); | ||||
|         RED.subflow.init(); | ||||
|         RED.workspaces.init(); | ||||
|         RED.clipboard.init(); | ||||
|         RED.search.init(); | ||||
|         RED.editor.init(); | ||||
|         RED.diff.init(); | ||||
|  | ||||
|         RED.menu.init({id:"btn-sidemenu",options: menuOptions}); | ||||
|  | ||||
|         RED.deploy.init(RED.settings.theme("deployButton",null)); | ||||
|  | ||||
|         RED.actions.add("core:show-about", showAbout); | ||||
|         RED.nodes.init(); | ||||
|         RED.comms.connect(); | ||||
|  | ||||
|         $("#main-container").show(); | ||||
|         $(".header-toolbar").show(); | ||||
|  | ||||
|         loadNodeList(); | ||||
|     } | ||||
|  | ||||
|     $(function() { | ||||
|  | ||||
|         if ((window.location.hostname !== "localhost") && (window.location.hostname !== "127.0.0.1")) { | ||||
|             document.title = document.title+" : "+window.location.hostname; | ||||
|         } | ||||
|  | ||||
|         ace.require("ace/ext/language_tools"); | ||||
|  | ||||
|         RED.i18n.init(function() { | ||||
|             RED.settings.init(loadEditor); | ||||
|         }) | ||||
|     }); | ||||
| })(); | ||||
							
								
								
									
										1356
									
								
								editor/js/nodes.js
									
									
									
									
									
								
							
							
						
						| @@ -1,35 +0,0 @@ | ||||
| RED.actions = (function() { | ||||
|     var actions = { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function addAction(name,handler) { | ||||
|         actions[name] = handler; | ||||
|     } | ||||
|     function removeAction(name) { | ||||
|         delete actions[name]; | ||||
|     } | ||||
|     function getAction(name) { | ||||
|         return actions[name]; | ||||
|     } | ||||
|     function invokeAction(name) { | ||||
|         if (actions.hasOwnProperty(name)) { | ||||
|             actions[name](); | ||||
|         } | ||||
|     } | ||||
|     function listActions() { | ||||
|         var result = []; | ||||
|         Object.keys(actions).forEach(function(action) { | ||||
|             var shortcut = RED.keyboard.getShortcut(action); | ||||
|             result.push({id:action,scope:shortcut?shortcut.scope:undefined,key:shortcut?shortcut.key:undefined,user:shortcut?shortcut.user:undefined}) | ||||
|         }) | ||||
|         return result; | ||||
|     } | ||||
|     return { | ||||
|         add: addAction, | ||||
|         remove: removeAction, | ||||
|         get: getAction, | ||||
|         invoke: invokeAction, | ||||
|         list: listActions | ||||
|     } | ||||
| })(); | ||||
| @@ -1,380 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
|  | ||||
| RED.clipboard = (function() { | ||||
|  | ||||
|     var dialog; | ||||
|     var dialogContainer; | ||||
|     var exportNodesDialog; | ||||
|     var importNodesDialog; | ||||
|     var disabled = false; | ||||
|  | ||||
|     function setupDialogs() { | ||||
|         dialog = $('<div id="clipboard-dialog" class="hide node-red-dialog"><form class="dialog-form form-horizontal"></form></div>') | ||||
|             .appendTo("body") | ||||
|             .dialog({ | ||||
|                 modal: true, | ||||
|                 autoOpen: false, | ||||
|                 width: 500, | ||||
|                 resizable: false, | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         id: "clipboard-dialog-cancel", | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "clipboard-dialog-close", | ||||
|                         class: "primary", | ||||
|                         text: RED._("common.label.close"), | ||||
|                         click: function() { | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "clipboard-dialog-copy", | ||||
|                         class: "primary", | ||||
|                         text: RED._("clipboard.export.copy"), | ||||
|                         click: function() { | ||||
|                             $("#clipboard-export").select(); | ||||
|                             document.execCommand("copy"); | ||||
|                             document.getSelection().removeAllRanges(); | ||||
|                             RED.notify(RED._("clipboard.nodesExported")); | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "clipboard-dialog-ok", | ||||
|                         class: "primary", | ||||
|                         text: RED._("common.label.import"), | ||||
|                         click: function() { | ||||
|                             RED.view.importNodes($("#clipboard-import").val(),$("#import-tab > a.selected").attr('id') === 'import-tab-new'); | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 open: function(e) { | ||||
|                     $(this).parent().find(".ui-dialog-titlebar-close").hide(); | ||||
|                 }, | ||||
|                 close: function(e) { | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         dialogContainer = dialog.children(".dialog-form"); | ||||
|  | ||||
|         exportNodesDialog = | ||||
|             '<div class="form-row">'+ | ||||
|                 '<label style="width:auto;margin-right: 10px;" data-i18n="clipboard.export.copy"></label>'+ | ||||
|                 '<span id="export-range-group" class="button-group">'+ | ||||
|                     '<a id="export-range-selected" class="editor-button toggle" href="#" data-i18n="clipboard.export.selected"></a>'+ | ||||
|                     '<a id="export-range-flow" class="editor-button toggle" href="#" data-i18n="clipboard.export.current"></a>'+ | ||||
|                     '<a id="export-range-full" class="editor-button toggle" href="#" data-i18n="clipboard.export.all"></a>'+ | ||||
|                 '</span>'+ | ||||
|                 '</div>'+ | ||||
|             '<div class="form-row">'+ | ||||
|                 '<textarea readonly style="resize: none; width: 100%; border-radius: 4px;font-family: monospace; font-size: 12px; background:#f3f3f3; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-export" rows="5"></textarea>'+ | ||||
|             '</div>'+ | ||||
|             '<div class="form-row" style="text-align: right;">'+ | ||||
|                 '<span id="export-format-group" class="button-group">'+ | ||||
|                     '<a id="export-format-mini" class="editor-button editor-button-small toggle" href="#" data-i18n="clipboard.export.compact"></a>'+ | ||||
|                     '<a id="export-format-full" class="editor-button editor-button-small toggle" href="#" data-i18n="clipboard.export.formatted"></a>'+ | ||||
|                 '</span>'+ | ||||
|             '</div>'; | ||||
|  | ||||
|         importNodesDialog = '<div class="form-row">'+ | ||||
|             '<textarea style="resize: none; width: 100%; border-radius: 0px;font-family: monospace; font-size: 12px; background:#eee; padding-left: 0.5em; box-sizing:border-box;" id="clipboard-import" rows="5" placeholder="'+ | ||||
|             RED._("clipboard.pasteNodes")+ | ||||
|             '"></textarea>'+ | ||||
|             '</div>'+ | ||||
|             '<div class="form-row">'+ | ||||
|             '<label style="width:auto;margin-right: 10px;" data-i18n="clipboard.import.import"></label>'+ | ||||
|             '<span id="import-tab" class="button-group">'+ | ||||
|                 '<a id="import-tab-current" class="editor-button toggle selected" href="#" data-i18n="clipboard.export.current"></a>'+ | ||||
|                 '<a id="import-tab-new" class="editor-button toggle" href="#" data-i18n="clipboard.import.newFlow"></a>'+ | ||||
|             '</span>'+ | ||||
|             '</div>'; | ||||
|     } | ||||
|  | ||||
|     function validateImport() { | ||||
|         var importInput = $("#clipboard-import"); | ||||
|         var v = importInput.val(); | ||||
|         v = v.substring(v.indexOf('['),v.lastIndexOf(']')+1); | ||||
|         try { | ||||
|             JSON.parse(v); | ||||
|             importInput.removeClass("input-error"); | ||||
|             importInput.val(v); | ||||
|             $("#clipboard-dialog-ok").button("enable"); | ||||
|         } catch(err) { | ||||
|             if (v !== "") { | ||||
|                 importInput.addClass("input-error"); | ||||
|             } | ||||
|             $("#clipboard-dialog-ok").button("disable"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function importNodes() { | ||||
|         if (disabled) { | ||||
|             return; | ||||
|         } | ||||
|         dialogContainer.empty(); | ||||
|         dialogContainer.append($(importNodesDialog)); | ||||
|         dialogContainer.i18n(); | ||||
|  | ||||
|         $("#clipboard-dialog-ok").show(); | ||||
|         $("#clipboard-dialog-cancel").show(); | ||||
|         $("#clipboard-dialog-close").hide(); | ||||
|         $("#clipboard-dialog-copy").hide(); | ||||
|         $("#clipboard-dialog-ok").button("disable"); | ||||
|         $("#clipboard-import").keyup(validateImport); | ||||
|         $("#clipboard-import").on('paste',function() { setTimeout(validateImport,10)}); | ||||
|  | ||||
|         $("#import-tab > a").click(function(evt) { | ||||
|             evt.preventDefault(); | ||||
|             if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { | ||||
|                 return; | ||||
|             } | ||||
|             $(this).parent().children().removeClass('selected'); | ||||
|             $(this).addClass('selected'); | ||||
|         }); | ||||
|  | ||||
|         dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open"); | ||||
|     } | ||||
|  | ||||
|     function exportNodes() { | ||||
|         if (disabled) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         dialogContainer.empty(); | ||||
|         dialogContainer.append($(exportNodesDialog)); | ||||
|         dialogContainer.i18n(); | ||||
|         var format = RED.settings.flowFilePretty ? "export-format-full" : "export-format-mini"; | ||||
|  | ||||
|         $("#export-format-group > a").click(function(evt) { | ||||
|             evt.preventDefault(); | ||||
|             if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { | ||||
|                 $("#clipboard-export").focus(); | ||||
|                 return; | ||||
|             } | ||||
|             $(this).parent().children().removeClass('selected'); | ||||
|             $(this).addClass('selected'); | ||||
|  | ||||
|             var flow = $("#clipboard-export").val(); | ||||
|             if (flow.length > 0) { | ||||
|                 var nodes = JSON.parse(flow); | ||||
|  | ||||
|                 format = $(this).attr('id'); | ||||
|                 if (format === 'export-format-full') { | ||||
|                     flow = JSON.stringify(nodes,null,4); | ||||
|                 } else { | ||||
|                     flow = JSON.stringify(nodes); | ||||
|                 } | ||||
|                 $("#clipboard-export").val(flow); | ||||
|                 $("#clipboard-export").focus(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         $("#export-range-group > a").click(function(evt) { | ||||
|             evt.preventDefault(); | ||||
|             if ($(this).hasClass('disabled') || $(this).hasClass('selected')) { | ||||
|                 $("#clipboard-export").focus(); | ||||
|                 return; | ||||
|             } | ||||
|             $(this).parent().children().removeClass('selected'); | ||||
|             $(this).addClass('selected'); | ||||
|             var type = $(this).attr('id'); | ||||
|             var flow = ""; | ||||
|             var nodes = null; | ||||
|             if (type === 'export-range-selected') { | ||||
|                 var selection = RED.view.selection(); | ||||
|                 // Don't include the subflow meta-port nodes in the exported selection | ||||
|                 nodes = RED.nodes.createExportableNodeSet(selection.nodes.filter(function(n) { return n.type !== 'subflow'})); | ||||
|             } else if (type === 'export-range-flow') { | ||||
|                 var activeWorkspace = RED.workspaces.active(); | ||||
|                 nodes = RED.nodes.filterNodes({z:activeWorkspace}); | ||||
|                 var parentNode = RED.nodes.workspace(activeWorkspace)||RED.nodes.subflow(activeWorkspace); | ||||
|                 nodes.unshift(parentNode); | ||||
|                 nodes = RED.nodes.createExportableNodeSet(nodes); | ||||
|             } else if (type === 'export-range-full') { | ||||
|                 nodes = RED.nodes.createCompleteNodeSet(false); | ||||
|             } | ||||
|             if (nodes !== null) { | ||||
|                 if (format === "export-format-full") { | ||||
|                     flow = JSON.stringify(nodes,null,4); | ||||
|                 } else { | ||||
|                     flow = JSON.stringify(nodes); | ||||
|                 } | ||||
|             } | ||||
|             if (flow.length > 0) { | ||||
|                 $("#export-copy").removeClass('disabled'); | ||||
|             } else { | ||||
|                 $("#export-copy").addClass('disabled'); | ||||
|             } | ||||
|             $("#clipboard-export").val(flow); | ||||
|             $("#clipboard-export").focus(); | ||||
|         }) | ||||
|  | ||||
|         $("#clipboard-dialog-ok").hide(); | ||||
|         $("#clipboard-dialog-cancel").hide(); | ||||
|         $("#clipboard-dialog-copy").hide(); | ||||
|         $("#clipboard-dialog-close").hide(); | ||||
|         var selection = RED.view.selection(); | ||||
|         if (selection.nodes) { | ||||
|             $("#export-range-selected").click(); | ||||
|         } else { | ||||
|             $("#export-range-selected").addClass('disabled').removeClass('selected'); | ||||
|             $("#export-range-flow").click(); | ||||
|         } | ||||
|         if (format === "export-format-full") { | ||||
|             $("#export-format-full").click(); | ||||
|         } else { | ||||
|             $("#export-format-mini").click(); | ||||
|         } | ||||
|         $("#clipboard-export") | ||||
|             .focus(function() { | ||||
|                 var textarea = $(this); | ||||
|                 textarea.select(); | ||||
|                 textarea.mouseup(function() { | ||||
|                     textarea.unbind("mouseup"); | ||||
|                     return false; | ||||
|                 }) | ||||
|             }); | ||||
|         dialog.dialog("option","title",RED._("clipboard.exportNodes")).dialog( "open" ); | ||||
|  | ||||
|         $("#clipboard-export").focus(); | ||||
|         if (!document.queryCommandSupported("copy")) { | ||||
|             $("#clipboard-dialog-cancel").hide(); | ||||
|             $("#clipboard-dialog-close").show(); | ||||
|         } else { | ||||
|             $("#clipboard-dialog-cancel").show(); | ||||
|             $("#clipboard-dialog-copy").show(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function hideDropTarget() { | ||||
|         $("#dropTarget").hide(); | ||||
|         RED.keyboard.remove("escape"); | ||||
|     } | ||||
|     function copyText(value,element,msg) { | ||||
|         var truncated = false; | ||||
|         if (typeof value !== "string" ) { | ||||
|             value = JSON.stringify(value, function(key,value) { | ||||
|                 if (value !== null && typeof value === 'object') { | ||||
|                     if (value.__encoded__ && value.hasOwnProperty('data') && value.hasOwnProperty('length')) { | ||||
|                         truncated = value.data.length !== value.length; | ||||
|                         return value.data; | ||||
|                     } | ||||
|                 } | ||||
|                 return value; | ||||
|             }); | ||||
|         } | ||||
|         if (truncated) { | ||||
|             msg += "_truncated"; | ||||
|         } | ||||
|         $("#clipboard-hidden").val(value).select(); | ||||
|         var result =  document.execCommand("copy"); | ||||
|         if (result && element) { | ||||
|             var popover = RED.popover.create({ | ||||
|                 target: element, | ||||
|                 direction: 'left', | ||||
|                 size: 'small', | ||||
|                 content: RED._(msg) | ||||
|             }); | ||||
|             setTimeout(function() { | ||||
|                 popover.close(); | ||||
|             },1000); | ||||
|             popover.open(); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     return { | ||||
|         init: function() { | ||||
|             setupDialogs(); | ||||
|  | ||||
|             $('<input type="text" id="clipboard-hidden">').appendTo("body"); | ||||
|  | ||||
|             RED.events.on("view:selection-changed",function(selection) { | ||||
|                 if (!selection.nodes) { | ||||
|                     RED.menu.setDisabled("menu-item-export",true); | ||||
|                     RED.menu.setDisabled("menu-item-export-clipboard",true); | ||||
|                     RED.menu.setDisabled("menu-item-export-library",true); | ||||
|                 } else { | ||||
|                     RED.menu.setDisabled("menu-item-export",false); | ||||
|                     RED.menu.setDisabled("menu-item-export-clipboard",false); | ||||
|                     RED.menu.setDisabled("menu-item-export-library",false); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             RED.actions.add("core:show-export-dialog",exportNodes); | ||||
|             RED.actions.add("core:show-import-dialog",importNodes); | ||||
|  | ||||
|  | ||||
|             RED.events.on("editor:open",function() { disabled = true; }); | ||||
|             RED.events.on("editor:close",function() { disabled = false; }); | ||||
|             RED.events.on("search:open",function() { disabled = true; }); | ||||
|             RED.events.on("search:close",function() { disabled = false; }); | ||||
|             RED.events.on("type-search:open",function() { disabled = true; }); | ||||
|             RED.events.on("type-search:close",function() { disabled = false; }); | ||||
|  | ||||
|  | ||||
|             $('#chart').on("dragenter",function(event) { | ||||
|                 if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 || | ||||
|                      $.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { | ||||
|                     $("#dropTarget").css({display:'table'}); | ||||
|                     RED.keyboard.add("*", "escape" ,hideDropTarget); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             $('#dropTarget').on("dragover",function(event) { | ||||
|                 if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1 || | ||||
|                      $.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { | ||||
|                     event.preventDefault(); | ||||
|                 } | ||||
|             }) | ||||
|             .on("dragleave",function(event) { | ||||
|                 hideDropTarget(); | ||||
|             }) | ||||
|             .on("drop",function(event) { | ||||
|                 if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { | ||||
|                     var data = event.originalEvent.dataTransfer.getData("text/plain"); | ||||
|                     data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1); | ||||
|                     RED.view.importNodes(data); | ||||
|                 } else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { | ||||
|                     var files = event.originalEvent.dataTransfer.files; | ||||
|                     if (files.length === 1) { | ||||
|                         var file = files[0]; | ||||
|                         var reader = new FileReader(); | ||||
|                         reader.onload = (function(theFile) { | ||||
|                             return function(e) { | ||||
|                                 RED.view.importNodes(e.target.result); | ||||
|                             }; | ||||
|                         })(file); | ||||
|                         reader.readAsText(file); | ||||
|                     } | ||||
|                 } | ||||
|                 hideDropTarget(); | ||||
|                 event.preventDefault(); | ||||
|             }); | ||||
|  | ||||
|         }, | ||||
|         import: importNodes, | ||||
|         export: exportNodes, | ||||
|         copyText: copyText | ||||
|     } | ||||
| })(); | ||||
| @@ -1,267 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.menu = (function() { | ||||
|  | ||||
|     var menuItems = {}; | ||||
|  | ||||
|     function createMenuItem(opt) { | ||||
|         var item; | ||||
|  | ||||
|         if (opt !== null && opt.id) { | ||||
|             var themeSetting = RED.settings.theme("menu."+opt.id); | ||||
|             if (themeSetting === false) { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         function setInitialState() { | ||||
|             var savedStateActive = RED.settings.get("menu-" + opt.id); | ||||
|             if (opt.setting) { | ||||
|                 // May need to migrate pre-0.17 setting | ||||
|  | ||||
|                 if (savedStateActive !== null) { | ||||
|                     RED.settings.set(opt.setting,savedStateActive); | ||||
|                     RED.settings.remove("menu-" + opt.id); | ||||
|                 } else { | ||||
|                     savedStateActive = RED.settings.get(opt.setting); | ||||
|                 } | ||||
|             } | ||||
|             if (savedStateActive) { | ||||
|                 link.addClass("active"); | ||||
|                 triggerAction(opt.id,true); | ||||
|             } else if (savedStateActive === false) { | ||||
|                 link.removeClass("active"); | ||||
|                 triggerAction(opt.id,false); | ||||
|             } else if (opt.hasOwnProperty("selected")) { | ||||
|                 if (opt.selected) { | ||||
|                     link.addClass("active"); | ||||
|                 } else { | ||||
|                     link.removeClass("active"); | ||||
|                 } | ||||
|                 triggerAction(opt.id,opt.selected); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (opt === null) { | ||||
|             item = $('<li class="divider"></li>'); | ||||
|         } else { | ||||
|             item = $('<li></li>'); | ||||
|  | ||||
|             if (opt.group) { | ||||
|                 item.addClass("menu-group-"+opt.group); | ||||
|  | ||||
|             } | ||||
|             var linkContent = '<a '+(opt.id?'id="'+opt.id+'" ':'')+'tabindex="-1" href="#">'; | ||||
|             if (opt.toggle) { | ||||
|                 linkContent += '<i class="fa fa-square pull-left"></i>'; | ||||
|                 linkContent += '<i class="fa fa-check-square pull-left"></i>'; | ||||
|  | ||||
|             } | ||||
|             if (opt.icon !== undefined) { | ||||
|                 if (/\.png/.test(opt.icon)) { | ||||
|                     linkContent += '<img src="'+opt.icon+'"/> '; | ||||
|                 } else { | ||||
|                     linkContent += '<i class="'+(opt.icon?opt.icon:'" style="display: inline-block;"')+'"></i> '; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (opt.sublabel) { | ||||
|                 linkContent += '<span class="menu-label-container"><span class="menu-label">'+opt.label+'</span>'+ | ||||
|                                '<span class="menu-sublabel">'+opt.sublabel+'</span></span>' | ||||
|             } else { | ||||
|                 linkContent += '<span class="menu-label">'+opt.label+'</span>' | ||||
|             } | ||||
|  | ||||
|             linkContent += '</a>'; | ||||
|  | ||||
|             var link = $(linkContent).appendTo(item); | ||||
|  | ||||
|             menuItems[opt.id] = opt; | ||||
|  | ||||
|             if (opt.onselect) { | ||||
|                 link.click(function(e) { | ||||
|                     e.preventDefault(); | ||||
|                     if ($(this).parent().hasClass("disabled")) { | ||||
|                         return; | ||||
|                     } | ||||
|                     if (opt.toggle) { | ||||
|                         var selected = isSelected(opt.id); | ||||
|                         if (typeof opt.toggle === "string") { | ||||
|                             if (!selected) { | ||||
|                                 for (var m in menuItems) { | ||||
|                                     if (menuItems.hasOwnProperty(m)) { | ||||
|                                         var mi = menuItems[m]; | ||||
|                                         if (mi.id != opt.id && opt.toggle == mi.toggle) { | ||||
|                                             setSelected(mi.id,false); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                                 setSelected(opt.id,true); | ||||
|                             } | ||||
|                         } else { | ||||
|                             setSelected(opt.id, !selected); | ||||
|                         } | ||||
|                     } else { | ||||
|                         triggerAction(opt.id); | ||||
|                     } | ||||
|                 }); | ||||
|                 if (opt.toggle) { | ||||
|                     setInitialState(); | ||||
|                 } | ||||
|             } else if (opt.href) { | ||||
|                 link.attr("target","_blank").attr("href",opt.href); | ||||
|             } else if (!opt.options) { | ||||
|                 item.addClass("disabled"); | ||||
|                 link.click(function(event) { | ||||
|                     event.preventDefault(); | ||||
|                 }); | ||||
|             } | ||||
|             if (opt.options) { | ||||
|                 item.addClass("dropdown-submenu pull-left"); | ||||
|                 var submenu = $('<ul id="'+opt.id+'-submenu" class="dropdown-menu"></ul>').appendTo(item); | ||||
|  | ||||
|                 for (var i=0;i<opt.options.length;i++) { | ||||
|                     var li = createMenuItem(opt.options[i]); | ||||
|                     if (li) { | ||||
|                         li.appendTo(submenu); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             if (opt.disabled) { | ||||
|                 item.addClass("disabled"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|         return item; | ||||
|  | ||||
|     } | ||||
|     function createMenu(options) { | ||||
|  | ||||
|         var menuParent = $("#"+options.id); | ||||
|  | ||||
|         var topMenu = $("<ul/>",{id:options.id+"-submenu", class:"dropdown-menu pull-right"}); | ||||
|  | ||||
|         if (menuParent.length === 1) { | ||||
|             topMenu.insertAfter(menuParent); | ||||
|         } | ||||
|  | ||||
|         var lastAddedSeparator = false; | ||||
|         for (var i=0;i<options.options.length;i++) { | ||||
|             var opt = options.options[i]; | ||||
|             if (opt !== null || !lastAddedSeparator) { | ||||
|                 var li = createMenuItem(opt); | ||||
|                 if (li) { | ||||
|                     li.appendTo(topMenu); | ||||
|                     lastAddedSeparator = (opt === null); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return topMenu; | ||||
|     } | ||||
|  | ||||
|     function triggerAction(id, args) { | ||||
|         var opt = menuItems[id]; | ||||
|         var callback = opt.onselect; | ||||
|         if (typeof opt.onselect === 'string') { | ||||
|             callback = RED.actions.get(opt.onselect); | ||||
|         } | ||||
|         if (callback) { | ||||
|             callback.call(opt,args); | ||||
|         } else { | ||||
|             console.log("No callback for",id,opt.onselect); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function isSelected(id) { | ||||
|         return $("#" + id).hasClass("active"); | ||||
|     } | ||||
|  | ||||
|     function setSelected(id,state) { | ||||
|         if (isSelected(id) == state) { | ||||
|             return; | ||||
|         } | ||||
|         var opt = menuItems[id]; | ||||
|         if (state) { | ||||
|             $("#"+id).addClass("active"); | ||||
|         } else { | ||||
|             $("#"+id).removeClass("active"); | ||||
|         } | ||||
|         if (opt && opt.onselect) { | ||||
|             triggerAction(opt.id,state); | ||||
|         } | ||||
|         RED.settings.set(opt.setting||("menu-"+opt.id), state); | ||||
|     } | ||||
|  | ||||
|     function toggleSelected(id) { | ||||
|         setSelected(id,!isSelected(id)); | ||||
|     } | ||||
|  | ||||
|     function setDisabled(id,state) { | ||||
|         if (state) { | ||||
|             $("#"+id).parent().addClass("disabled"); | ||||
|         } else { | ||||
|             $("#"+id).parent().removeClass("disabled"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function addItem(id,opt) { | ||||
|         var item = createMenuItem(opt); | ||||
|         if (opt.group) { | ||||
|             var groupItems = $("#"+id+"-submenu").children(".menu-group-"+opt.group); | ||||
|             if (groupItems.length === 0) { | ||||
|                 item.appendTo("#"+id+"-submenu"); | ||||
|             } else { | ||||
|                 for (var i=0;i<groupItems.length;i++) { | ||||
|                     var groupItem = groupItems[i]; | ||||
|                     var label = $(groupItem).find(".menu-label").html(); | ||||
|                     if (opt.label < label) { | ||||
|                         $(groupItem).before(item); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 if (i === groupItems.length) { | ||||
|                     item.appendTo("#"+id+"-submenu"); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             item.appendTo("#"+id+"-submenu"); | ||||
|         } | ||||
|     } | ||||
|     function removeItem(id) { | ||||
|         $("#"+id).parent().remove(); | ||||
|     } | ||||
|  | ||||
|     function setAction(id,action) { | ||||
|         var opt = menuItems[id]; | ||||
|         if (opt) { | ||||
|             opt.onselect = action; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: createMenu, | ||||
|         setSelected: setSelected, | ||||
|         isSelected: isSelected, | ||||
|         toggleSelected: toggleSelected, | ||||
|         setDisabled: setDisabled, | ||||
|         addItem: addItem, | ||||
|         removeItem: removeItem, | ||||
|         setAction: setAction | ||||
|         //TODO: add an api for replacing a submenu - see library.js:loadFlowLibrary | ||||
|     } | ||||
| })(); | ||||
| @@ -1,81 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
|  | ||||
| RED.panels = (function() { | ||||
|  | ||||
|     function createPanel(options) { | ||||
|         var container = options.container || $("#"+options.id); | ||||
|         var children = container.children(); | ||||
|         if (children.length !== 2) { | ||||
|             throw new Error("Container must have exactly two children"); | ||||
|         } | ||||
|  | ||||
|         container.addClass("red-ui-panels"); | ||||
|         var separator = $('<div class="red-ui-panels-separator"></div>').insertAfter(children[0]); | ||||
|         var startPosition; | ||||
|         var panelHeights = []; | ||||
|         var modifiedHeights = false; | ||||
|         var panelRatio; | ||||
|  | ||||
|         separator.draggable({ | ||||
|                 axis: "y", | ||||
|                 containment: container, | ||||
|                 scroll: false, | ||||
|                 start:function(event,ui) { | ||||
|                     var height = container.height(); | ||||
|                     startPosition = ui.position.top; | ||||
|                     panelHeights = [$(children[0]).height(),$(children[1]).height()]; | ||||
|                 }, | ||||
|                 drag: function(event,ui) { | ||||
|                     var height = container.height(); | ||||
|                     var delta = ui.position.top-startPosition; | ||||
|                     var newHeights = [panelHeights[0]+delta,panelHeights[1]-delta]; | ||||
|                     $(children[0]).height(newHeights[0]); | ||||
|                     $(children[1]).height(newHeights[1]); | ||||
|                     if (options.resize) { | ||||
|                         options.resize(newHeights[0],newHeights[1]); | ||||
|                     } | ||||
|                     ui.position.top -= delta; | ||||
|                     panelRatio = newHeights[0]/height; | ||||
|                 }, | ||||
|                 stop:function(event,ui) { | ||||
|                     modifiedHeights = true; | ||||
|                 } | ||||
|         }); | ||||
|  | ||||
|         return { | ||||
|             resize: function(height) { | ||||
|                 var panelHeights = [$(children[0]).height(),$(children[1]).height()]; | ||||
|                 container.height(height); | ||||
|                 if (modifiedHeights) { | ||||
|                     var topPanelHeight = panelRatio*height; | ||||
|                     var bottomPanelHeight = height - topPanelHeight - 48; | ||||
|                     panelHeights = [topPanelHeight,bottomPanelHeight]; | ||||
|                     $(children[0]).height(panelHeights[0]); | ||||
|                     $(children[1]).height(panelHeights[1]); | ||||
|                 } | ||||
|                 if (options.resize) { | ||||
|                     options.resize(panelHeights[0],panelHeights[1]); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         create: createPanel | ||||
|     } | ||||
| })(); | ||||
| @@ -1,135 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| RED.popover = (function() { | ||||
|     var deltaSizes = { | ||||
|         "default": { | ||||
|             top: 10, | ||||
|             leftRight: 17, | ||||
|             leftLeft: 25 | ||||
|         }, | ||||
|         "small": { | ||||
|             top: 5, | ||||
|             leftRight: 8, | ||||
|             leftLeft: 16 | ||||
|         } | ||||
|     } | ||||
|     function createPopover(options) { | ||||
|         var target = options.target; | ||||
|         var direction = options.direction || "right"; | ||||
|         var trigger = options.trigger; | ||||
|         var content = options.content; | ||||
|         var delay = options.delay; | ||||
|         var width = options.width||"auto"; | ||||
|         var size = options.size||"default"; | ||||
|         if (!deltaSizes[size]) { | ||||
|             throw new Error("Invalid RED.popover size value:",size); | ||||
|         } | ||||
|  | ||||
|         var timer = null; | ||||
|         var active; | ||||
|         var div; | ||||
|  | ||||
|         var openPopup = function() { | ||||
|             if (active) { | ||||
|                 div = $('<div class="red-ui-popover red-ui-popover-'+direction+'"></div>').appendTo("body"); | ||||
|                 if (size !== "default") { | ||||
|                     div.addClass("red-ui-popover-size-"+size); | ||||
|                 } | ||||
|                 if (typeof content === 'function') { | ||||
|                     content.call(res).appendTo(div); | ||||
|                 } else { | ||||
|                     div.html(content); | ||||
|                 } | ||||
|                 if (width !== "auto") { | ||||
|                     div.width(width); | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 var targetPos = target.offset(); | ||||
|                 var targetWidth = target.width(); | ||||
|                 var targetHeight = target.height(); | ||||
|  | ||||
|                 var divHeight = div.height(); | ||||
|                 var divWidth = div.width(); | ||||
|                 if (direction === 'right') { | ||||
|                     div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left+targetWidth+deltaSizes[size].leftRight}); | ||||
|                 } else if (direction === 'left') { | ||||
|                     div.css({top: targetPos.top+targetHeight/2-divHeight/2-deltaSizes[size].top,left:targetPos.left-deltaSizes[size].leftLeft-divWidth}); | ||||
|                 } | ||||
|  | ||||
|                 div.fadeIn("fast"); | ||||
|             } | ||||
|         } | ||||
|         var closePopup = function() { | ||||
|             if (!active) { | ||||
|                 if (div) { | ||||
|                     div.fadeOut("fast",function() { | ||||
|                         $(this).remove(); | ||||
|                     }); | ||||
|                     div = null; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (trigger === 'hover') { | ||||
|  | ||||
|             target.on('mouseenter',function(e) { | ||||
|                 clearTimeout(timer); | ||||
|                 active = true; | ||||
|                 timer = setTimeout(openPopup,delay.show); | ||||
|             }); | ||||
|             target.on('mouseleave', function(e) { | ||||
|                 if (timer) { | ||||
|                     clearTimeout(timer); | ||||
|                 } | ||||
|                 active = false; | ||||
|                 setTimeout(closePopup,delay.hide); | ||||
|             }); | ||||
|         } else if (trigger === 'click') { | ||||
|             target.click(function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 e.stopPropagation(); | ||||
|                 active = !active; | ||||
|                 if (!active) { | ||||
|                     closePopup(); | ||||
|                 } else { | ||||
|                     openPopup(); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         var res = { | ||||
|             setContent: function(_content) { | ||||
|                 content = _content; | ||||
|             }, | ||||
|             open: function () { | ||||
|                 active = true; | ||||
|                 openPopup(); | ||||
|             }, | ||||
|             close: function () { | ||||
|                 active = false; | ||||
|                 closePopup(); | ||||
|             } | ||||
|         } | ||||
|         return res; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         create: createPopover | ||||
|     } | ||||
|  | ||||
| })(); | ||||
| @@ -1,99 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| (function($) { | ||||
|  | ||||
|     $.widget( "nodered.searchBox", { | ||||
|         _create: function() { | ||||
|             var that = this; | ||||
|  | ||||
|             this.currentTimeout = null; | ||||
|             this.lastSent = ""; | ||||
|             this.element.val(""); | ||||
|             this.uiContainer = this.element.wrap("<div>").parent(); | ||||
|             this.uiContainer.addClass("red-ui-searchBox-container"); | ||||
|  | ||||
|             $('<i class="fa fa-search"></i>').prependTo(this.uiContainer); | ||||
|             this.clearButton = $('<a href="#"><i class="fa fa-times"></i></a>').appendTo(this.uiContainer); | ||||
|             this.clearButton.on("click",function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 that.element.val(""); | ||||
|                 that._change("",true); | ||||
|                 that.element.focus(); | ||||
|             }); | ||||
|  | ||||
|             this.resultCount = $('<span>',{class:"red-ui-searchBox-resultCount hide"}).appendTo(this.uiContainer); | ||||
|  | ||||
|             this.element.val(""); | ||||
|             this.element.on("keydown",function(evt) { | ||||
|                 if (evt.keyCode === 27) { | ||||
|                     that.element.val(""); | ||||
|                 } | ||||
|             }) | ||||
|             this.element.on("keyup",function(evt) { | ||||
|                 that._change($(this).val()); | ||||
|             }); | ||||
|  | ||||
|             this.element.on("focus",function() { | ||||
|                 $("body").one("mousedown",function() { | ||||
|                     that.element.blur(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }, | ||||
|         _change: function(val,instant) { | ||||
|             var fireEvent = false; | ||||
|             if (val === "") { | ||||
|                 this.clearButton.hide(); | ||||
|                 fireEvent = true; | ||||
|             } else { | ||||
|                 this.clearButton.show(); | ||||
|                 fireEvent = (val.length >= (this.options.minimumLength||0)); | ||||
|             } | ||||
|             var current = this.element.val(); | ||||
|             fireEvent = fireEvent && current !== this.lastSent; | ||||
|             if (fireEvent) { | ||||
|                 if (!instant && this.options.delay > 0) { | ||||
|                     clearTimeout(this.currentTimeout); | ||||
|                     var that = this; | ||||
|                     this.currentTimeout = setTimeout(function() { | ||||
|                         that.lastSent = that.element.val(); | ||||
|                         that._trigger("change"); | ||||
|                     },this.options.delay); | ||||
|                 } else { | ||||
|                     this._trigger("change"); | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         value: function(val) { | ||||
|             if (val === undefined) { | ||||
|                 return this.element.val(); | ||||
|             } else { | ||||
|                 this.element.val(val); | ||||
|                 this._change(val); | ||||
|             } | ||||
|         }, | ||||
|         count: function(val) { | ||||
|             if (val === undefined || val === null || val === "") { | ||||
|                 this.resultCount.text("").hide(); | ||||
|             } else { | ||||
|                 this.resultCount.text(val).show(); | ||||
|             } | ||||
|         }, | ||||
|         change: function() { | ||||
|             this._trigger("change"); | ||||
|         } | ||||
|     }); | ||||
| })(jQuery); | ||||
| @@ -1,379 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
|  | ||||
|  | ||||
| RED.tabs = (function() { | ||||
|     function createTabs(options) { | ||||
|         var tabs = {}; | ||||
|         var currentTabWidth; | ||||
|         var currentActiveTabWidth = 0; | ||||
|  | ||||
|         var ul = options.element || $("#"+options.id); | ||||
|         var wrapper = ul.wrap( "<div>" ).parent(); | ||||
|         var scrollContainer = ul.wrap( "<div>" ).parent(); | ||||
|         wrapper.addClass("red-ui-tabs"); | ||||
|         if (options.vertical) { | ||||
|             wrapper.addClass("red-ui-tabs-vertical"); | ||||
|         } | ||||
|         if (options.addButton && typeof options.addButton === 'function') { | ||||
|             wrapper.addClass("red-ui-tabs-add"); | ||||
|             var addButton = $('<div class="red-ui-tab-button"><a href="#"><i class="fa fa-plus"></i></a></div>').appendTo(wrapper); | ||||
|             addButton.find('a').click(function(evt) { | ||||
|                 evt.preventDefault(); | ||||
|                 options.addButton(); | ||||
|             }) | ||||
|  | ||||
|         } | ||||
|         var scrollLeft; | ||||
|         var scrollRight; | ||||
|  | ||||
|         if (options.scrollable) { | ||||
|             wrapper.addClass("red-ui-tabs-scrollable"); | ||||
|             scrollContainer.addClass("red-ui-tabs-scroll-container"); | ||||
|             scrollContainer.scroll(updateScroll); | ||||
|             scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a"); | ||||
|             scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();}); | ||||
|             scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a"); | ||||
|             scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();}); | ||||
|         } | ||||
|         function scrollEventHandler(evt,dir) { | ||||
|             evt.preventDefault(); | ||||
|             if ($(this).hasClass('disabled')) { | ||||
|                 return; | ||||
|             } | ||||
|             var currentScrollLeft = scrollContainer.scrollLeft(); | ||||
|             scrollContainer.animate( { scrollLeft: dir }, 100); | ||||
|             var interval = setInterval(function() { | ||||
|                 var newScrollLeft = scrollContainer.scrollLeft() | ||||
|                 if (newScrollLeft === currentScrollLeft) { | ||||
|                     clearInterval(interval); | ||||
|                     return; | ||||
|                 } | ||||
|                 currentScrollLeft = newScrollLeft; | ||||
|                 scrollContainer.animate( { scrollLeft: dir }, 100); | ||||
|             },100); | ||||
|             $(this).one('mouseup',function() { | ||||
|                 clearInterval(interval); | ||||
|             }) | ||||
|         } | ||||
|  | ||||
|  | ||||
|         ul.children().first().addClass("active"); | ||||
|         ul.children().addClass("red-ui-tab"); | ||||
|  | ||||
|         function onTabClick() { | ||||
|             if (options.onclick) { | ||||
|                 options.onclick(tabs[$(this).attr('href').slice(1)]); | ||||
|             } | ||||
|             activateTab($(this)); | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         function updateScroll() { | ||||
|             if (ul.children().length !== 0) { | ||||
|                 var sl = scrollContainer.scrollLeft(); | ||||
|                 var scWidth = scrollContainer.width(); | ||||
|                 var ulWidth = ul.width(); | ||||
|                 if (sl === 0) { | ||||
|                     scrollLeft.hide(); | ||||
|                 } else { | ||||
|                     scrollLeft.show(); | ||||
|                 } | ||||
|                 if (sl === ulWidth-scWidth) { | ||||
|                     scrollRight.hide(); | ||||
|                 } else { | ||||
|                     scrollRight.show(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         function onTabDblClick() { | ||||
|             if (options.ondblclick) { | ||||
|                 options.ondblclick(tabs[$(this).attr('href').slice(1)]); | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         function activateTab(link) { | ||||
|             if (typeof link === "string") { | ||||
|                 link = ul.find("a[href='#"+link+"']"); | ||||
|             } | ||||
|             if (link.length === 0) { | ||||
|                 return; | ||||
|             } | ||||
|             if (!link.parent().hasClass("active")) { | ||||
|                 ul.children().removeClass("active"); | ||||
|                 ul.children().css({"transition": "width 100ms"}); | ||||
|                 link.parent().addClass("active"); | ||||
|                 if (options.scrollable) { | ||||
|                     var pos = link.parent().position().left; | ||||
|                     if (pos-21 < 0) { | ||||
|                         scrollContainer.animate( { scrollLeft: '+='+(pos-50) }, 300); | ||||
|                     } else if (pos + 120 > scrollContainer.width()) { | ||||
|                         scrollContainer.animate( { scrollLeft: '+='+(pos + 140-scrollContainer.width()) }, 300); | ||||
|                     } | ||||
|                 } | ||||
|                 if (options.onchange) { | ||||
|                     options.onchange(tabs[link.attr('href').slice(1)]); | ||||
|                 } | ||||
|                 updateTabWidths(); | ||||
|                 setTimeout(function() { | ||||
|                     ul.children().css({"transition": ""}); | ||||
|                 },100); | ||||
|             } | ||||
|         } | ||||
|         function activatePreviousTab() { | ||||
|             var previous = ul.find("li.active").prev(); | ||||
|             if (previous.length > 0) { | ||||
|                 activateTab(previous.find("a")); | ||||
|             } | ||||
|         } | ||||
|         function activateNextTab() { | ||||
|             var next = ul.find("li.active").next(); | ||||
|             if (next.length > 0) { | ||||
|                 activateTab(next.find("a")); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         function updateTabWidths() { | ||||
|             if (options.vertical) { | ||||
|                 return; | ||||
|             } | ||||
|             var tabs = ul.find("li.red-ui-tab"); | ||||
|             var width = wrapper.width(); | ||||
|             var tabCount = tabs.size(); | ||||
|             var tabWidth = (width-12-(tabCount*6))/tabCount; | ||||
|             currentTabWidth = (100*tabWidth/width)+"%"; | ||||
|             currentActiveTabWidth = currentTabWidth+"%"; | ||||
|             if (options.scrollable) { | ||||
|                 tabWidth = Math.max(tabWidth,140); | ||||
|                 currentTabWidth = tabWidth+"px"; | ||||
|                 currentActiveTabWidth = 0; | ||||
|                 var listWidth = Math.max(wrapper.width(),12+(tabWidth+6)*tabCount); | ||||
|                 ul.width(listWidth); | ||||
|                 updateScroll(); | ||||
|             } else if (options.hasOwnProperty("minimumActiveTabWidth")) { | ||||
|                 if (tabWidth < options.minimumActiveTabWidth) { | ||||
|                     tabCount -= 1; | ||||
|                     tabWidth = (width-12-options.minimumActiveTabWidth-(tabCount*6))/tabCount; | ||||
|                     currentTabWidth = (100*tabWidth/width)+"%"; | ||||
|                     currentActiveTabWidth = options.minimumActiveTabWidth+"px"; | ||||
|                 } else { | ||||
|                     currentActiveTabWidth = 0; | ||||
|                 } | ||||
|             } | ||||
|             tabs.css({width:currentTabWidth}); | ||||
|             if (tabWidth < 50) { | ||||
|                 ul.find(".red-ui-tab-close").hide(); | ||||
|                 ul.find(".red-ui-tab-icon").hide(); | ||||
|                 ul.find(".red-ui-tab-label").css({paddingLeft:Math.min(12,Math.max(0,tabWidth-38))+"px"}) | ||||
|             } else { | ||||
|                 ul.find(".red-ui-tab-close").show(); | ||||
|                 ul.find(".red-ui-tab-icon").show(); | ||||
|                 ul.find(".red-ui-tab-label").css({paddingLeft:""}) | ||||
|             } | ||||
|             if (currentActiveTabWidth !== 0) { | ||||
|                 ul.find("li.red-ui-tab.active").css({"width":options.minimumActiveTabWidth}); | ||||
|                 ul.find("li.red-ui-tab.active .red-ui-tab-close").show(); | ||||
|                 ul.find("li.red-ui-tab.active .red-ui-tab-icon").show(); | ||||
|                 ul.find("li.red-ui-tab.active .red-ui-tab-label").css({paddingLeft:""}) | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         ul.find("li.red-ui-tab a").on("click",onTabClick).on("dblclick",onTabDblClick); | ||||
|         setTimeout(function() { | ||||
|             updateTabWidths(); | ||||
|         },0); | ||||
|  | ||||
|  | ||||
|         function removeTab(id) { | ||||
|             var li = ul.find("a[href='#"+id+"']").parent(); | ||||
|             if (li.hasClass("active")) { | ||||
|                 var tab = li.prev(); | ||||
|                 if (tab.size() === 0) { | ||||
|                     tab = li.next(); | ||||
|                 } | ||||
|                 activateTab(tab.find("a")); | ||||
|             } | ||||
|             li.remove(); | ||||
|             if (options.onremove) { | ||||
|                 options.onremove(tabs[id]); | ||||
|             } | ||||
|             delete tabs[id]; | ||||
|             updateTabWidths(); | ||||
|         } | ||||
|  | ||||
|         return { | ||||
|             addTab: function(tab) { | ||||
|                 tabs[tab.id] = tab; | ||||
|                 var li = $("<li/>",{class:"red-ui-tab"}).appendTo(ul); | ||||
|                 li.attr('id',"red-ui-tab-"+(tab.id.replace(".","-"))); | ||||
|                 li.data("tabId",tab.id); | ||||
|                 var link = $("<a/>",{href:"#"+tab.id, class:"red-ui-tab-label"}).appendTo(li); | ||||
|                 if (tab.icon) { | ||||
|                     $('<img src="'+tab.icon+'" class="red-ui-tab-icon"/>').appendTo(link); | ||||
|                 } | ||||
|                 var span = $('<span/>',{class:"bidiAware"}).text(tab.label).appendTo(link); | ||||
|                 span.attr('dir', RED.text.bidi.resolveBaseTextDir(tab.label)); | ||||
|  | ||||
|                 link.on("click",onTabClick); | ||||
|                 link.on("dblclick",onTabDblClick); | ||||
|                 if (tab.closeable) { | ||||
|                     var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li); | ||||
|                     closeLink.append('<i class="fa fa-times" />'); | ||||
|  | ||||
|                     closeLink.on("click",function(event) { | ||||
|                         event.preventDefault(); | ||||
|                         removeTab(tab.id); | ||||
|                     }); | ||||
|                 } | ||||
|                 updateTabWidths(); | ||||
|                 if (options.onadd) { | ||||
|                     options.onadd(tab); | ||||
|                 } | ||||
|                 link.attr("title",tab.label); | ||||
|                 if (ul.find("li.red-ui-tab").size() == 1) { | ||||
|                     activateTab(link); | ||||
|                 } | ||||
|                 if (options.onreorder) { | ||||
|                     var originalTabOrder; | ||||
|                     var tabDragIndex; | ||||
|                     var tabElements = []; | ||||
|                     var startDragIndex; | ||||
|  | ||||
|                     li.draggable({ | ||||
|                         axis:"x", | ||||
|                         distance: 20, | ||||
|                         start: function(event,ui) { | ||||
|                             originalTabOrder = []; | ||||
|                             tabElements = []; | ||||
|                             ul.children().each(function(i) { | ||||
|                                 tabElements[i] = { | ||||
|                                     el:$(this), | ||||
|                                     text: $(this).text(), | ||||
|                                     left: $(this).position().left, | ||||
|                                     width: $(this).width() | ||||
|                                 }; | ||||
|                                 if ($(this).is(li)) { | ||||
|                                     tabDragIndex = i; | ||||
|                                     startDragIndex = i; | ||||
|                                 } | ||||
|                                 originalTabOrder.push($(this).data("tabId")); | ||||
|                             }); | ||||
|                             ul.children().each(function(i) { | ||||
|                                 if (i!==tabDragIndex) { | ||||
|                                     $(this).css({ | ||||
|                                         position: 'absolute', | ||||
|                                         left: tabElements[i].left+"px", | ||||
|                                         width: tabElements[i].width+2, | ||||
|                                         transition: "left 0.3s" | ||||
|                                     }); | ||||
|                                 } | ||||
|  | ||||
|                             }) | ||||
|                             if (!li.hasClass('active')) { | ||||
|                                 li.css({'zIndex':1}); | ||||
|                             } | ||||
|                         }, | ||||
|                         drag: function(event,ui) { | ||||
|                             ui.position.left += tabElements[tabDragIndex].left+scrollContainer.scrollLeft(); | ||||
|                             var tabCenter = ui.position.left + tabElements[tabDragIndex].width/2 - scrollContainer.scrollLeft(); | ||||
|                             for (var i=0;i<tabElements.length;i++) { | ||||
|                                 if (i === tabDragIndex) { | ||||
|                                     continue; | ||||
|                                 } | ||||
|                                 if (tabCenter > tabElements[i].left && tabCenter < tabElements[i].left+tabElements[i].width) { | ||||
|                                     if (i < tabDragIndex) { | ||||
|                                         tabElements[i].left += tabElements[tabDragIndex].width+8; | ||||
|                                         tabElements[tabDragIndex].el.detach().insertBefore(tabElements[i].el); | ||||
|                                     } else { | ||||
|                                         tabElements[i].left -= tabElements[tabDragIndex].width+8; | ||||
|                                         tabElements[tabDragIndex].el.detach().insertAfter(tabElements[i].el); | ||||
|                                     } | ||||
|                                     tabElements[i].el.css({left:tabElements[i].left+"px"}); | ||||
|  | ||||
|                                     tabElements.splice(i, 0, tabElements.splice(tabDragIndex, 1)[0]); | ||||
|  | ||||
|                                     tabDragIndex = i; | ||||
|                                     break; | ||||
|                                 } | ||||
|                             } | ||||
|                         }, | ||||
|                         stop: function(event,ui) { | ||||
|                             ul.children().css({position:"relative",left:"",transition:""}); | ||||
|                             if (!li.hasClass('active')) { | ||||
|                                 li.css({zIndex:""}); | ||||
|                             } | ||||
|                             updateTabWidths(); | ||||
|                             if (startDragIndex !== tabDragIndex) { | ||||
|                                 options.onreorder(originalTabOrder, $.makeArray(ul.children().map(function() { return $(this).data('tabId');}))); | ||||
|                             } | ||||
|                             activateTab(tabElements[tabDragIndex].el.data('tabId')); | ||||
|                         } | ||||
|                     }) | ||||
|                 } | ||||
|             }, | ||||
|             removeTab: removeTab, | ||||
|             activateTab: activateTab, | ||||
|             nextTab: activateNextTab, | ||||
|             previousTab: activatePreviousTab, | ||||
|             resize: updateTabWidths, | ||||
|             count: function() { | ||||
|                 return ul.find("li.red-ui-tab").size(); | ||||
|             }, | ||||
|             contains: function(id) { | ||||
|                 return ul.find("a[href='#"+id+"']").length > 0; | ||||
|             }, | ||||
|             renameTab: function(id,label) { | ||||
|                 tabs[id].label = label; | ||||
|                 var tab = ul.find("a[href='#"+id+"']"); | ||||
|                 tab.attr("title",label); | ||||
|                 tab.find("span.bidiAware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label)); | ||||
|                 updateTabWidths(); | ||||
|             }, | ||||
|             order: function(order) { | ||||
|                 var existingTabOrder = $.makeArray(ul.children().map(function() { return $(this).data('tabId');})); | ||||
|                 if (existingTabOrder.length !== order.length) { | ||||
|                     return | ||||
|                 } | ||||
|                 var i; | ||||
|                 var match = true; | ||||
|                 for (i=0;i<order.length;i++) { | ||||
|                     if (order[i] !== existingTabOrder[i]) { | ||||
|                         match = false; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 if (match) { | ||||
|                     return; | ||||
|                 } | ||||
|                 var existingTabMap = {}; | ||||
|                 var existingTabs = ul.children().detach().each(function() { | ||||
|                     existingTabMap[$(this).data("tabId")] = $(this); | ||||
|                 }); | ||||
|                 for (i=0;i<order.length;i++) { | ||||
|                     existingTabMap[order[i]].appendTo(ul); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         create: createTabs | ||||
|     } | ||||
| })(); | ||||
| @@ -1,472 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| (function($) { | ||||
|     var allOptions = { | ||||
|         msg: {value:"msg",label:"msg.",validate:RED.utils.validatePropertyExpression}, | ||||
|         flow: {value:"flow",label:"flow.",validate:RED.utils.validatePropertyExpression}, | ||||
|         global: {value:"global",label:"global.",validate:RED.utils.validatePropertyExpression}, | ||||
|         str: {value:"str",label:"string",icon:"red/images/typedInput/az.png"}, | ||||
|         num: {value:"num",label:"number",icon:"red/images/typedInput/09.png",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/}, | ||||
|         bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.png",options:["true","false"]}, | ||||
|         json: { | ||||
|             value:"json", | ||||
|             label:"JSON", | ||||
|             icon:"red/images/typedInput/json.png", | ||||
|             validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}}, | ||||
|             expand: function() { | ||||
|                 var that = this; | ||||
|                 var value = this.value(); | ||||
|                 try { | ||||
|                     value = JSON.stringify(JSON.parse(value),null,4); | ||||
|                 } catch(err) { | ||||
|                 } | ||||
|                 RED.editor.editJSON({ | ||||
|                     value: value, | ||||
|                     complete: function(v) { | ||||
|                         var value = v; | ||||
|                         try { | ||||
|                             value = JSON.stringify(JSON.parse(v)); | ||||
|                         } catch(err) { | ||||
|                         } | ||||
|                         that.value(value); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|         }, | ||||
|         re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.png"}, | ||||
|         date: {value:"date",label:"timestamp",hasValue:false}, | ||||
|         jsonata: { | ||||
|             value: "jsonata", | ||||
|             label: "expression", | ||||
|             icon: "red/images/typedInput/expr.png", | ||||
|             validate: function(v) { try{jsonata(v);return true;}catch(e){return false;}}, | ||||
|             expand:function() { | ||||
|                 var that = this; | ||||
|                 RED.editor.editExpression({ | ||||
|                     value: this.value().replace(/\t/g,"\n"), | ||||
|                     complete: function(v) { | ||||
|                         that.value(v.replace(/\n/g,"\t")); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|         }, | ||||
|         bin: { | ||||
|             value: "bin", | ||||
|             label: "buffer", | ||||
|             icon: "red/images/typedInput/bin.png", | ||||
|             expand: function() { | ||||
|                 var that = this; | ||||
|                 RED.editor.editBuffer({ | ||||
|                     value: this.value(), | ||||
|                     complete: function(v) { | ||||
|                         that.value(v); | ||||
|                     } | ||||
|                 }) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|     var nlsd = false; | ||||
|  | ||||
|     $.widget( "nodered.typedInput", { | ||||
|         _create: function() { | ||||
|             if (!nlsd && RED && RED._) { | ||||
|                 for (var i in allOptions) { | ||||
|                     if (allOptions.hasOwnProperty(i)) { | ||||
|                         allOptions[i].label = RED._("typedInput.type."+i,{defaultValue:allOptions[i].label}); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             nlsd = true; | ||||
|             var that = this; | ||||
|  | ||||
|             this.disarmClick = false; | ||||
|             this.element.addClass('red-ui-typedInput'); | ||||
|             this.uiWidth = this.element.outerWidth(); | ||||
|             this.elementDiv = this.element.wrap("<div>").parent().addClass('red-ui-typedInput-input'); | ||||
|             this.uiSelect = this.elementDiv.wrap( "<div>" ).parent(); | ||||
|             var attrStyle = this.element.attr('style'); | ||||
|             var m; | ||||
|             if ((m = /width\s*:\s*(\d+(%|px))/i.exec(attrStyle)) !== null) { | ||||
|                 this.element.css('width','100%'); | ||||
|                 this.uiSelect.width(m[1]); | ||||
|                 this.uiWidth = null; | ||||
|             } else { | ||||
|                 this.uiSelect.width(this.uiWidth); | ||||
|             } | ||||
|             ["Right","Left"].forEach(function(d) { | ||||
|                 var m = that.element.css("margin"+d); | ||||
|                 that.uiSelect.css("margin"+d,m); | ||||
|                 that.element.css("margin"+d,0); | ||||
|             }); | ||||
|             this.uiSelect.addClass("red-ui-typedInput-container"); | ||||
|  | ||||
|             this.options.types = this.options.types||Object.keys(allOptions); | ||||
|  | ||||
|             this.selectTrigger = $('<button tabindex="0"></button>').prependTo(this.uiSelect); | ||||
|             $('<i class="fa fa-sort-desc"></i>').appendTo(this.selectTrigger); | ||||
|             this.selectLabel = $('<span></span>').appendTo(this.selectTrigger); | ||||
|  | ||||
|             this.types(this.options.types); | ||||
|  | ||||
|             if (this.options.typeField) { | ||||
|                 this.typeField = $(this.options.typeField).hide(); | ||||
|                 var t = this.typeField.val(); | ||||
|                 if (t && this.typeMap[t]) { | ||||
|                     this.options.default = t; | ||||
|                 } | ||||
|             } else { | ||||
|                 this.typeField = $("<input>",{type:'hidden'}).appendTo(this.uiSelect); | ||||
|             } | ||||
|  | ||||
|             this.element.on('focus', function() { | ||||
|                 that.uiSelect.addClass('red-ui-typedInput-focus'); | ||||
|             }); | ||||
|             this.element.on('blur', function() { | ||||
|                 that.uiSelect.removeClass('red-ui-typedInput-focus'); | ||||
|             }); | ||||
|             this.element.on('change', function() { | ||||
|                 that.validate(); | ||||
|             }) | ||||
|             this.selectTrigger.click(function(event) { | ||||
|                 event.preventDefault(); | ||||
|                 that._showTypeMenu(); | ||||
|             }); | ||||
|             this.selectTrigger.on('keydown',function(evt) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // Down | ||||
|                     that._showTypeMenu(); | ||||
|                 } | ||||
|             }).on('focus', function() { | ||||
|                 that.uiSelect.addClass('red-ui-typedInput-focus'); | ||||
|             }) | ||||
|  | ||||
|             // explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline' | ||||
|             this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="fa fa-sort-desc"></i></span></button>').appendTo(this.uiSelect); | ||||
|             this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger); | ||||
|             this.optionSelectTrigger.click(function(event) { | ||||
|                 event.preventDefault(); | ||||
|                 that._showOptionSelectMenu(); | ||||
|             }).on('keydown', function(evt) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // Down | ||||
|                     that._showOptionSelectMenu(); | ||||
|                 } | ||||
|             }).on('blur', function() { | ||||
|                 that.uiSelect.removeClass('red-ui-typedInput-focus'); | ||||
|             }).on('focus', function() { | ||||
|                 that.uiSelect.addClass('red-ui-typedInput-focus'); | ||||
|             }); | ||||
|  | ||||
|             this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"><i class="fa fa-ellipsis-h"></i></button>').appendTo(this.uiSelect); | ||||
|  | ||||
|  | ||||
|             this.type(this.options.default||this.typeList[0].value); | ||||
|         }, | ||||
|         _showTypeMenu: function() { | ||||
|             if (this.typeList.length > 1) { | ||||
|                 this._showMenu(this.menu,this.selectTrigger); | ||||
|                 this.menu.find("[value='"+this.propertyType+"']").focus(); | ||||
|             } else { | ||||
|                 this.element.focus(); | ||||
|             } | ||||
|         }, | ||||
|         _showOptionSelectMenu: function() { | ||||
|             if (this.optionMenu) { | ||||
|                 this.optionMenu.css({ | ||||
|                     minWidth:this.optionSelectLabel.width() | ||||
|                 }); | ||||
|  | ||||
|                 this._showMenu(this.optionMenu,this.optionSelectLabel); | ||||
|                 var selectedOption = this.optionMenu.find("[value='"+this.value()+"']"); | ||||
|                 if (selectedOption.length === 0) { | ||||
|                     selectedOption = this.optionMenu.children(":first"); | ||||
|                 } | ||||
|                 selectedOption.focus(); | ||||
|  | ||||
|             } | ||||
|         }, | ||||
|         _hideMenu: function(menu) { | ||||
|             $(document).off("mousedown.close-property-select"); | ||||
|             menu.hide(); | ||||
|             if (this.elementDiv.is(":visible")) { | ||||
|                 this.element.focus(); | ||||
|             } else if (this.optionSelectTrigger.is(":visible")){ | ||||
|                 this.optionSelectTrigger.focus(); | ||||
|             } else { | ||||
|                 this.selectTrigger.focus(); | ||||
|             } | ||||
|         }, | ||||
|         _createMenu: function(opts,callback) { | ||||
|             var that = this; | ||||
|             var menu = $("<div>").addClass("red-ui-typedInput-options"); | ||||
|             opts.forEach(function(opt) { | ||||
|                 if (typeof opt === 'string') { | ||||
|                     opt = {value:opt,label:opt}; | ||||
|                 } | ||||
|                 var op = $('<a href="#"></a>').attr("value",opt.value).appendTo(menu); | ||||
|                 if (opt.label) { | ||||
|                     op.text(opt.label); | ||||
|                 } | ||||
|                 if (opt.icon) { | ||||
|                     $('<img>',{src:opt.icon,style:"margin-right: 4px; height: 18px;"}).prependTo(op); | ||||
|                 } else { | ||||
|                     op.css({paddingLeft: "18px"}); | ||||
|                 } | ||||
|  | ||||
|                 op.click(function(event) { | ||||
|                     event.preventDefault(); | ||||
|                     callback(opt.value); | ||||
|                     that._hideMenu(menu); | ||||
|                 }); | ||||
|             }); | ||||
|             menu.css({ | ||||
|                 display: "none", | ||||
|             }); | ||||
|             menu.appendTo(document.body); | ||||
|  | ||||
|             menu.on('keydown', function(evt) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // DOWN | ||||
|                     $(this).children(":focus").next().focus(); | ||||
|                 } else if (evt.keyCode === 38) { | ||||
|                     // UP | ||||
|                     $(this).children(":focus").prev().focus(); | ||||
|                 } else if (evt.keyCode === 27) { | ||||
|                     that._hideMenu(menu); | ||||
|                 } | ||||
|             }) | ||||
|  | ||||
|  | ||||
|  | ||||
|             return menu; | ||||
|  | ||||
|         }, | ||||
|         _showMenu: function(menu,relativeTo) { | ||||
|             if (this.disarmClick) { | ||||
|                 this.disarmClick = false; | ||||
|                 return | ||||
|             } | ||||
|             var that = this; | ||||
|             var pos = relativeTo.offset(); | ||||
|             var height = relativeTo.height(); | ||||
|             var menuHeight = menu.height(); | ||||
|             var top = (height+pos.top-3); | ||||
|             if (top+menuHeight > $(window).height()) { | ||||
|                 top -= (top+menuHeight)-$(window).height()+5; | ||||
|             } | ||||
|             menu.css({ | ||||
|                 top: top+"px", | ||||
|                 left: (2+pos.left)+"px", | ||||
|             }); | ||||
|             menu.slideDown(100); | ||||
|             this._delay(function() { | ||||
|                 that.uiSelect.addClass('red-ui-typedInput-focus'); | ||||
|                 $(document).on("mousedown.close-property-select", function(event) { | ||||
|                     if(!$(event.target).closest(menu).length) { | ||||
|                         that._hideMenu(menu); | ||||
|                     } | ||||
|                     if ($(event.target).closest(relativeTo).length) { | ||||
|                         that.disarmClick = true; | ||||
|                         event.preventDefault(); | ||||
|                     } | ||||
|                 }) | ||||
|             }); | ||||
|         }, | ||||
|         _getLabelWidth: function(label) { | ||||
|             var labelWidth = label.outerWidth(); | ||||
|             if (labelWidth === 0) { | ||||
|                 var container = $('<div class="red-ui-typedInput-container"></div>').css({ | ||||
|                     position:"absolute", | ||||
|                     top:0, | ||||
|                     left:-1000 | ||||
|                 }).appendTo(document.body); | ||||
|                 var newTrigger = label.clone().appendTo(container); | ||||
|                 labelWidth = newTrigger.outerWidth(); | ||||
|                 container.remove(); | ||||
|             } | ||||
|             return labelWidth; | ||||
|         }, | ||||
|         _resize: function() { | ||||
|             if (this.uiWidth !== null) { | ||||
|                 this.uiSelect.width(this.uiWidth); | ||||
|             } | ||||
|             if (this.typeMap[this.propertyType] && this.typeMap[this.propertyType].hasValue === false) { | ||||
|                 this.selectTrigger.addClass("red-ui-typedInput-full-width"); | ||||
|             } else { | ||||
|                 this.selectTrigger.removeClass("red-ui-typedInput-full-width"); | ||||
|                 var labelWidth = this._getLabelWidth(this.selectTrigger); | ||||
|                 this.elementDiv.css('left',labelWidth+"px"); | ||||
|                 if (this.optionExpandButton.is(":visible")) { | ||||
|                     this.elementDiv.css('right',"22px"); | ||||
|                 } else { | ||||
|                     this.elementDiv.css('right','0'); | ||||
|                 } | ||||
|                 if (this.optionSelectTrigger) { | ||||
|                     this.optionSelectTrigger.css({'left':(labelWidth)+"px",'width':'calc( 100% - '+labelWidth+'px )'}); | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         _destroy: function() { | ||||
|             this.menu.remove(); | ||||
|         }, | ||||
|         types: function(types) { | ||||
|             var that = this; | ||||
|             var currentType = this.type(); | ||||
|             this.typeMap = {}; | ||||
|             this.typeList = types.map(function(opt) { | ||||
|                 var result; | ||||
|                 if (typeof opt === 'string') { | ||||
|                     result = allOptions[opt]; | ||||
|                 } else { | ||||
|                     result = opt; | ||||
|                 } | ||||
|                 that.typeMap[result.value] = result; | ||||
|                 return result; | ||||
|             }); | ||||
|             this.selectTrigger.toggleClass("disabled", this.typeList.length === 1); | ||||
|             if (this.menu) { | ||||
|                 this.menu.remove(); | ||||
|             } | ||||
|             this.menu = this._createMenu(this.typeList, function(v) { that.type(v) }); | ||||
|             if (currentType && !this.typeMap.hasOwnProperty(currentType)) { | ||||
|                 this.type(this.typeList[0].value); | ||||
|             } | ||||
|         }, | ||||
|         width: function(desiredWidth) { | ||||
|             this.uiWidth = desiredWidth; | ||||
|             this._resize(); | ||||
|         }, | ||||
|         value: function(value) { | ||||
|             if (!arguments.length) { | ||||
|                 return this.element.val(); | ||||
|             } else { | ||||
|                 if (this.typeMap[this.propertyType].options) { | ||||
|                     if (this.typeMap[this.propertyType].options.indexOf(value) === -1) { | ||||
|                         value = ""; | ||||
|                     } | ||||
|                     this.optionSelectLabel.text(value); | ||||
|                 } | ||||
|                 this.element.val(value); | ||||
|                 this.element.trigger('change',this.type(),value); | ||||
|             } | ||||
|         }, | ||||
|         type: function(type) { | ||||
|             if (!arguments.length) { | ||||
|                 return this.propertyType; | ||||
|             } else { | ||||
|                 var that = this; | ||||
|                 var opt = this.typeMap[type]; | ||||
|                 if (opt && this.propertyType !== type) { | ||||
|                     this.propertyType = type; | ||||
|                     this.typeField.val(type); | ||||
|                     this.selectLabel.empty(); | ||||
|                     var image; | ||||
|                     if (opt.icon) { | ||||
|                         image = new Image(); | ||||
|                         image.name = opt.icon; | ||||
|                         image.src = opt.icon; | ||||
|                         $('<img>',{src:opt.icon,style:"margin-right: 4px;height: 18px;"}).prependTo(this.selectLabel); | ||||
|                     } else { | ||||
|                         this.selectLabel.text(opt.label); | ||||
|                     } | ||||
|                     if (opt.options) { | ||||
|                         if (this.optionExpandButton) { | ||||
|                             this.optionExpandButton.hide(); | ||||
|                         } | ||||
|                         if (this.optionSelectTrigger) { | ||||
|                             this.optionSelectTrigger.show(); | ||||
|                             this.elementDiv.hide(); | ||||
|                             this.optionMenu = this._createMenu(opt.options,function(v){ | ||||
|                                 that.optionSelectLabel.text(v); | ||||
|                                 that.value(v); | ||||
|                             }); | ||||
|                             var currentVal = this.element.val(); | ||||
|                             if (opt.options.indexOf(currentVal) !== -1) { | ||||
|                                 this.optionSelectLabel.text(currentVal); | ||||
|                             } else { | ||||
|                                 this.value(opt.options[0]); | ||||
|                             } | ||||
|                         } | ||||
|                     } else { | ||||
|                         if (this.optionMenu) { | ||||
|                             this.optionMenu.remove(); | ||||
|                             this.optionMenu = null; | ||||
|                         } | ||||
|                         if (this.optionSelectTrigger) { | ||||
|                             this.optionSelectTrigger.hide(); | ||||
|                         } | ||||
|                         if (opt.hasValue === false) { | ||||
|                             this.oldValue = this.element.val(); | ||||
|                             this.element.val(""); | ||||
|                             this.elementDiv.hide(); | ||||
|                         } else { | ||||
|                             if (this.oldValue !== undefined) { | ||||
|                                 this.element.val(this.oldValue); | ||||
|                                 delete this.oldValue; | ||||
|                             } | ||||
|                             this.elementDiv.show(); | ||||
|                         } | ||||
|                         if (opt.expand && typeof opt.expand === 'function') { | ||||
|                             this.optionExpandButton.show(); | ||||
|                             this.optionExpandButton.off('click'); | ||||
|                             this.optionExpandButton.on('click',function(evt) { | ||||
|                                 evt.preventDefault(); | ||||
|                                 opt.expand.call(that); | ||||
|                             }) | ||||
|                         } else { | ||||
|                             this.optionExpandButton.hide(); | ||||
|                         } | ||||
|                         this.element.trigger('change',this.propertyType,this.value()); | ||||
|                     } | ||||
|                     if (image) { | ||||
|                         image.onload = function() { that._resize(); } | ||||
|                         image.onerror = function() { that._resize(); } | ||||
|                     } else { | ||||
|                         this._resize(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         validate: function() { | ||||
|             var result; | ||||
|             var value = this.value(); | ||||
|             var type = this.type(); | ||||
|             if (this.typeMap[type] && this.typeMap[type].validate) { | ||||
|                 var val = this.typeMap[type].validate; | ||||
|                 if (typeof val === 'function') { | ||||
|                     result = val(value); | ||||
|                 } else { | ||||
|                     result = val.test(value); | ||||
|                 } | ||||
|             } else { | ||||
|                 result = true; | ||||
|             } | ||||
|             if (result) { | ||||
|                 this.uiSelect.removeClass('input-error'); | ||||
|             } else { | ||||
|                 this.uiSelect.addClass('input-error'); | ||||
|             } | ||||
|             return result; | ||||
|         }, | ||||
|         show: function() { | ||||
|             this.uiSelect.show(); | ||||
|             this._resize(); | ||||
|         }, | ||||
|         hide: function() { | ||||
|             this.uiSelect.hide(); | ||||
|         } | ||||
|     }); | ||||
| })(jQuery); | ||||
| @@ -1,442 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| RED.deploy = (function() { | ||||
|  | ||||
|     var deploymentTypes = { | ||||
|         "full":{img:"red/images/deploy-full-o.png"}, | ||||
|         "nodes":{img:"red/images/deploy-nodes-o.png"}, | ||||
|         "flows":{img:"red/images/deploy-flows-o.png"} | ||||
|     } | ||||
|  | ||||
|     var ignoreDeployWarnings = { | ||||
|         unknown: false, | ||||
|         unusedConfig: false, | ||||
|         invalid: false | ||||
|     } | ||||
|  | ||||
|     var deploymentType = "full"; | ||||
|  | ||||
|     var deployInflight = false; | ||||
|  | ||||
|     var currentDiff = null; | ||||
|  | ||||
|     function changeDeploymentType(type) { | ||||
|         deploymentType = type; | ||||
|         $("#btn-deploy-icon").attr("src",deploymentTypes[type].img); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * options: | ||||
|      *   type: "default" - Button with drop-down options - no further customisation available | ||||
|      *   type: "simple"  - Button without dropdown. Customisations: | ||||
|      *      label: the text to display - default: "Deploy" | ||||
|      *      icon : the icon to use. Null removes the icon. default: "red/images/deploy-full-o.png" | ||||
|      */ | ||||
|     function init(options) { | ||||
|         options = options || {}; | ||||
|         var type = options.type || "default"; | ||||
|  | ||||
|         if (type == "default") { | ||||
|             $('<li><span class="deploy-button-group button-group">'+ | ||||
|               '<a id="btn-deploy" class="deploy-button disabled" href="#">'+ | ||||
|                 '<span class="deploy-button-content">'+ | ||||
|                  '<img id="btn-deploy-icon" src="red/images/deploy-full-o.png"> '+ | ||||
|                  '<span>'+RED._("deploy.deploy")+'</span>'+ | ||||
|                 '</span>'+ | ||||
|                 '<span class="deploy-button-spinner hide">'+ | ||||
|                  '<img src="red/images/spin.svg"/>'+ | ||||
|                 '</span>'+ | ||||
|               '</a>'+ | ||||
|               '<a id="btn-deploy-options" data-toggle="dropdown" class="deploy-button" href="#"><i class="fa fa-caret-down"></i></a>'+ | ||||
|               '</span></li>').prependTo(".header-toolbar"); | ||||
|               RED.menu.init({id:"btn-deploy-options", | ||||
|                   options: [ | ||||
|                       {id:"deploymenu-item-full",toggle:"deploy-type",icon:"red/images/deploy-full.png",label:RED._("deploy.full"),sublabel:RED._("deploy.fullDesc"),selected: true, onselect:function(s) { if(s){changeDeploymentType("full")}}}, | ||||
|                       {id:"deploymenu-item-flow",toggle:"deploy-type",icon:"red/images/deploy-flows.png",label:RED._("deploy.modifiedFlows"),sublabel:RED._("deploy.modifiedFlowsDesc"), onselect:function(s) {if(s){changeDeploymentType("flows")}}}, | ||||
|                       {id:"deploymenu-item-node",toggle:"deploy-type",icon:"red/images/deploy-nodes.png",label:RED._("deploy.modifiedNodes"),sublabel:RED._("deploy.modifiedNodesDesc"),onselect:function(s) { if(s){changeDeploymentType("nodes")}}} | ||||
|                   ] | ||||
|               }); | ||||
|         } else if (type == "simple") { | ||||
|             var label = options.label || RED._("deploy.deploy"); | ||||
|             var icon = 'red/images/deploy-full-o.png'; | ||||
|             if (options.hasOwnProperty('icon')) { | ||||
|                 icon = options.icon; | ||||
|             } | ||||
|  | ||||
|             $('<li><span class="deploy-button-group button-group">'+ | ||||
|               '<a id="btn-deploy" class="deploy-button disabled" href="#">'+ | ||||
|                 '<span class="deploy-button-content">'+ | ||||
|                   (icon?'<img id="btn-deploy-icon" src="'+icon+'"> ':'')+ | ||||
|                   '<span>'+label+'</span>'+ | ||||
|                 '</span>'+ | ||||
|                 '<span class="deploy-button-spinner hide">'+ | ||||
|                  '<img src="red/images/spin.svg"/>'+ | ||||
|                 '</span>'+ | ||||
|               '</a>'+ | ||||
|               '</span></li>').prependTo(".header-toolbar"); | ||||
|         } | ||||
|  | ||||
|         $('#btn-deploy').click(function(event) { | ||||
|             event.preventDefault(); | ||||
|             save(); | ||||
|         }); | ||||
|  | ||||
|         RED.actions.add("core:deploy-flows",save); | ||||
|  | ||||
|         $( "#node-dialog-confirm-deploy" ).dialog({ | ||||
|                 title: RED._('deploy.confirm.button.confirm'), | ||||
|                 modal: true, | ||||
|                 autoOpen: false, | ||||
|                 width: 550, | ||||
|                 height: "auto", | ||||
|                 buttons: [ | ||||
|                     { | ||||
|                         text: RED._("common.label.cancel"), | ||||
|                         click: function() { | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-confirm-deploy-review", | ||||
|                         text: RED._("deploy.confirm.button.review"), | ||||
|                         class: "primary disabled", | ||||
|                         click: function() { | ||||
|                             if (!$("#node-dialog-confirm-deploy-review").hasClass('disabled')) { | ||||
|                                 RED.diff.showRemoteDiff(); | ||||
|                                 $( this ).dialog( "close" ); | ||||
|                             } | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-confirm-deploy-merge", | ||||
|                         text: RED._("deploy.confirm.button.merge"), | ||||
|                         class: "primary disabled", | ||||
|                         click: function() { | ||||
|                             RED.diff.mergeDiff(currentDiff); | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-confirm-deploy-deploy", | ||||
|                         text: RED._("deploy.confirm.button.confirm"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|  | ||||
|                             var ignoreChecked = $( "#node-dialog-confirm-deploy-hide" ).prop("checked"); | ||||
|                             if (ignoreChecked) { | ||||
|                                 ignoreDeployWarnings[$( "#node-dialog-confirm-deploy-type" ).val()] = true; | ||||
|                             } | ||||
|                             save(true,/conflict/.test($("#node-dialog-confirm-deploy-type" ).val())); | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         id: "node-dialog-confirm-deploy-overwrite", | ||||
|                         text: RED._("deploy.confirm.button.overwrite"), | ||||
|                         class: "primary", | ||||
|                         click: function() { | ||||
|                             save(true,/conflict/.test($("#node-dialog-confirm-deploy-type" ).val())); | ||||
|                             $( this ).dialog( "close" ); | ||||
|                         } | ||||
|                     } | ||||
|                 ], | ||||
|                 create: function() { | ||||
|                     $("#node-dialog-confirm-deploy").parent().find("div.ui-dialog-buttonpane") | ||||
|                         .prepend('<div style="height:0; vertical-align: middle; display:inline-block; margin-top: 13px; float:left;">'+ | ||||
|                                    '<input style="vertical-align:top;" type="checkbox" id="node-dialog-confirm-deploy-hide"> '+ | ||||
|                                    '<label style="display:inline;" for="node-dialog-confirm-deploy-hide" data-i18n="deploy.confirm.doNotWarn"></label>'+ | ||||
|                                    '<input type="hidden" id="node-dialog-confirm-deploy-type">'+ | ||||
|                                    '</div>'); | ||||
|                 }, | ||||
|                 open: function() { | ||||
|                     var deployType = $("#node-dialog-confirm-deploy-type" ).val(); | ||||
|                     if (/conflict/.test(deployType)) { | ||||
|                         $( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.review')); | ||||
|                         $("#node-dialog-confirm-deploy-deploy").hide(); | ||||
|                         $("#node-dialog-confirm-deploy-review").addClass('disabled').show(); | ||||
|                         $("#node-dialog-confirm-deploy-merge").addClass('disabled').show(); | ||||
|                         $("#node-dialog-confirm-deploy-overwrite").toggle(deployType === "deploy-conflict"); | ||||
|                         currentDiff = null; | ||||
|                         $("#node-dialog-confirm-deploy-conflict-checking").show(); | ||||
|                         $("#node-dialog-confirm-deploy-conflict-auto-merge").hide(); | ||||
|                         $("#node-dialog-confirm-deploy-conflict-manual-merge").hide(); | ||||
|  | ||||
|                         var now = Date.now(); | ||||
|                         RED.diff.getRemoteDiff(function(diff) { | ||||
|                             var ellapsed = Math.max(1000 - (Date.now()-now), 0); | ||||
|                             currentDiff = diff; | ||||
|                             setTimeout(function() { | ||||
|                                 $("#node-dialog-confirm-deploy-conflict-checking").hide(); | ||||
|                                 var d = Object.keys(diff.conflicts); | ||||
|                                 if (d.length === 0) { | ||||
|                                     $("#node-dialog-confirm-deploy-conflict-auto-merge").show(); | ||||
|                                     $("#node-dialog-confirm-deploy-merge").removeClass('disabled') | ||||
|                                 } else { | ||||
|                                     $("#node-dialog-confirm-deploy-conflict-manual-merge").show(); | ||||
|                                 } | ||||
|                                 $("#node-dialog-confirm-deploy-review").removeClass('disabled') | ||||
|                             },ellapsed); | ||||
|                         }) | ||||
|  | ||||
|  | ||||
|                         $("#node-dialog-confirm-deploy-hide").parent().hide(); | ||||
|                     } else { | ||||
|                         $( "#node-dialog-confirm-deploy" ).dialog('option','title', RED._('deploy.confirm.button.confirm')); | ||||
|                         $("#node-dialog-confirm-deploy-deploy").show(); | ||||
|                         $("#node-dialog-confirm-deploy-overwrite").hide(); | ||||
|                         $("#node-dialog-confirm-deploy-review").hide(); | ||||
|                         $("#node-dialog-confirm-deploy-merge").hide(); | ||||
|                         $("#node-dialog-confirm-deploy-hide").parent().show(); | ||||
|                     } | ||||
|                 } | ||||
|         }); | ||||
|  | ||||
|         RED.events.on('nodes:change',function(state) { | ||||
|             if (state.dirty) { | ||||
|                 window.onbeforeunload = function() { | ||||
|                     return RED._("deploy.confirm.undeployedChanges"); | ||||
|                 } | ||||
|                 $("#btn-deploy").removeClass("disabled"); | ||||
|             } else { | ||||
|                 window.onbeforeunload = null; | ||||
|                 $("#btn-deploy").addClass("disabled"); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         var activeNotifyMessage; | ||||
|         RED.comms.subscribe("notification/runtime-deploy",function(topic,msg) { | ||||
|             if (!activeNotifyMessage) { | ||||
|                 var currentRev = RED.nodes.version(); | ||||
|                 if (currentRev === null || deployInflight || currentRev === msg.revision) { | ||||
|                     return; | ||||
|                 } | ||||
|                 var message = $('<div>'+RED._('deploy.confirm.backgroundUpdate')+ | ||||
|                     '<br><br><div class="ui-dialog-buttonset">'+ | ||||
|                     '<button>'+RED._('deploy.confirm.button.ignore')+'</button>'+ | ||||
|                     '<button class="primary">'+RED._('deploy.confirm.button.review')+'</button>'+ | ||||
|                     '</div></div>'); | ||||
|                 $(message.find('button')[0]).click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     activeNotifyMessage.close(); | ||||
|                     activeNotifyMessage = null; | ||||
|                 }) | ||||
|                 $(message.find('button')[1]).click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     activeNotifyMessage.close(); | ||||
|                     var nns = RED.nodes.createCompleteNodeSet(); | ||||
|                     resolveConflict(nns,false); | ||||
|                     activeNotifyMessage = null; | ||||
|                 }) | ||||
|                 activeNotifyMessage = RED.notify(message,null,true); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function getNodeInfo(node) { | ||||
|         var tabLabel = ""; | ||||
|         if (node.z) { | ||||
|             var tab = RED.nodes.workspace(node.z); | ||||
|             if (!tab) { | ||||
|                 tab = RED.nodes.subflow(node.z); | ||||
|                 tabLabel = tab.name; | ||||
|             } else { | ||||
|                 tabLabel = tab.label; | ||||
|             } | ||||
|         } | ||||
|         var label = RED.utils.getNodeLabel(node,node.id); | ||||
|         return {tab:tabLabel,type:node.type,label:label}; | ||||
|     } | ||||
|     function sortNodeInfo(A,B) { | ||||
|         if (A.tab < B.tab) { return -1;} | ||||
|         if (A.tab > B.tab) { return 1;} | ||||
|         if (A.type < B.type) { return -1;} | ||||
|         if (A.type > B.type) { return 1;} | ||||
|         if (A.name < B.name) { return -1;} | ||||
|         if (A.name > B.name) { return 1;} | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     function resolveConflict(currentNodes, activeDeploy) { | ||||
|         $( "#node-dialog-confirm-deploy-config" ).hide(); | ||||
|         $( "#node-dialog-confirm-deploy-unknown" ).hide(); | ||||
|         $( "#node-dialog-confirm-deploy-unused" ).hide(); | ||||
|         $( "#node-dialog-confirm-deploy-conflict" ).show(); | ||||
|         $( "#node-dialog-confirm-deploy-type" ).val(activeDeploy?"deploy-conflict":"background-conflict"); | ||||
|         $( "#node-dialog-confirm-deploy" ).dialog( "open" ); | ||||
|     } | ||||
|  | ||||
|     function save(skipValidation,force) { | ||||
|         if (!$("#btn-deploy").hasClass("disabled")) { | ||||
|             if (!skipValidation) { | ||||
|                 var hasUnknown = false; | ||||
|                 var hasInvalid = false; | ||||
|                 var hasUnusedConfig = false; | ||||
|  | ||||
|                 var unknownNodes = []; | ||||
|                 var invalidNodes = []; | ||||
|  | ||||
|                 RED.nodes.eachNode(function(node) { | ||||
|                     hasInvalid = hasInvalid || !node.valid; | ||||
|                     if (!node.valid) { | ||||
|                         invalidNodes.push(getNodeInfo(node)); | ||||
|                     } | ||||
|                     if (node.type === "unknown") { | ||||
|                         if (unknownNodes.indexOf(node.name) == -1) { | ||||
|                             unknownNodes.push(node.name); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|                 hasUnknown = unknownNodes.length > 0; | ||||
|  | ||||
|                 var unusedConfigNodes = []; | ||||
|                 RED.nodes.eachConfig(function(node) { | ||||
|                     if (node.users.length === 0 && (node._def.hasUsers !== false)) { | ||||
|                         unusedConfigNodes.push(getNodeInfo(node)); | ||||
|                         hasUnusedConfig = true; | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 $( "#node-dialog-confirm-deploy-config" ).hide(); | ||||
|                 $( "#node-dialog-confirm-deploy-unknown" ).hide(); | ||||
|                 $( "#node-dialog-confirm-deploy-unused" ).hide(); | ||||
|                 $( "#node-dialog-confirm-deploy-conflict" ).hide(); | ||||
|  | ||||
|                 var showWarning = false; | ||||
|  | ||||
|                 if (hasUnknown && !ignoreDeployWarnings.unknown) { | ||||
|                     showWarning = true; | ||||
|                     $( "#node-dialog-confirm-deploy-type" ).val("unknown"); | ||||
|                     $( "#node-dialog-confirm-deploy-unknown" ).show(); | ||||
|                     $( "#node-dialog-confirm-deploy-unknown-list" ) | ||||
|                         .html("<li>"+unknownNodes.join("</li><li>")+"</li>"); | ||||
|                 } else if (hasInvalid && !ignoreDeployWarnings.invalid) { | ||||
|                     showWarning = true; | ||||
|                     $( "#node-dialog-confirm-deploy-type" ).val("invalid"); | ||||
|                     $( "#node-dialog-confirm-deploy-config" ).show(); | ||||
|                     invalidNodes.sort(sortNodeInfo); | ||||
|                     $( "#node-dialog-confirm-deploy-invalid-list" ) | ||||
|                         .html("<li>"+invalidNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>"); | ||||
|  | ||||
|                 } else if (hasUnusedConfig && !ignoreDeployWarnings.unusedConfig) { | ||||
|                     // showWarning = true; | ||||
|                     // $( "#node-dialog-confirm-deploy-type" ).val("unusedConfig"); | ||||
|                     // $( "#node-dialog-confirm-deploy-unused" ).show(); | ||||
|                     // | ||||
|                     // unusedConfigNodes.sort(sortNodeInfo); | ||||
|                     // $( "#node-dialog-confirm-deploy-unused-list" ) | ||||
|                     //     .html("<li>"+unusedConfigNodes.map(function(A) { return (A.tab?"["+A.tab+"] ":"")+A.label+" ("+A.type+")"}).join("</li><li>")+"</li>"); | ||||
|                 } | ||||
|                 if (showWarning) { | ||||
|                     $( "#node-dialog-confirm-deploy-hide" ).prop("checked",false); | ||||
|                     $( "#node-dialog-confirm-deploy" ).dialog( "open" ); | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             var nns = RED.nodes.createCompleteNodeSet(); | ||||
|  | ||||
|             var startTime = Date.now(); | ||||
|             $(".deploy-button-content").css('opacity',0); | ||||
|             $(".deploy-button-spinner").show(); | ||||
|             $("#btn-deploy").addClass("disabled"); | ||||
|  | ||||
|             var data = {flows:nns}; | ||||
|  | ||||
|             if (!force) { | ||||
|                 data.rev = RED.nodes.version(); | ||||
|             } | ||||
|  | ||||
|             deployInflight = true; | ||||
|             $("#header-shade").show(); | ||||
|             $("#editor-shade").show(); | ||||
|             $("#palette-shade").show(); | ||||
|             $("#sidebar-shade").show(); | ||||
|             $.ajax({ | ||||
|                 url:"flows", | ||||
|                 type: "POST", | ||||
|                 data: JSON.stringify(data), | ||||
|                 contentType: "application/json; charset=utf-8", | ||||
|                 headers: { | ||||
|                     "Node-RED-Deployment-Type":deploymentType | ||||
|                 } | ||||
|             }).done(function(data,textStatus,xhr) { | ||||
|                 RED.nodes.dirty(false); | ||||
|                 RED.nodes.version(data.rev); | ||||
|                 RED.nodes.originalFlow(nns); | ||||
|                 if (hasUnusedConfig) { | ||||
|                     RED.notify( | ||||
|                     '<p>'+RED._("deploy.successfulDeploy")+'</p>'+ | ||||
|                     '<p>'+RED._("deploy.unusedConfigNodes")+' <a href="#" onclick="RED.sidebar.config.show(true); return false;">'+RED._("deploy.unusedConfigNodesLink")+'</a></p>',"success",false,6000); | ||||
|                 } else { | ||||
|                     RED.notify(RED._("deploy.successfulDeploy"),"success"); | ||||
|                 } | ||||
|                 RED.nodes.eachNode(function(node) { | ||||
|                     if (node.changed) { | ||||
|                         node.dirty = true; | ||||
|                         node.changed = false; | ||||
|                     } | ||||
|                     if (node.moved) { | ||||
|                         node.dirty = true; | ||||
|                         node.moved = false; | ||||
|                     } | ||||
|                     if(node.credentials) { | ||||
|                         delete node.credentials; | ||||
|                     } | ||||
|                 }); | ||||
|                 RED.nodes.eachConfig(function (confNode) { | ||||
|                     confNode.changed = false; | ||||
|                     if (confNode.credentials) { | ||||
|                         delete confNode.credentials; | ||||
|                     } | ||||
|                 }); | ||||
|                 RED.nodes.eachWorkspace(function(ws) { | ||||
|                     ws.changed = false; | ||||
|                 }) | ||||
|                 // Once deployed, cannot undo back to a clean state | ||||
|                 RED.history.markAllDirty(); | ||||
|                 RED.view.redraw(); | ||||
|                 RED.events.emit("deploy"); | ||||
|             }).fail(function(xhr,textStatus,err) { | ||||
|                 RED.nodes.dirty(true); | ||||
|                 $("#btn-deploy").removeClass("disabled"); | ||||
|                 if (xhr.status === 401) { | ||||
|                     RED.notify(RED._("deploy.deployFailed",{message:RED._("user.notAuthorized")}),"error"); | ||||
|                 } else if (xhr.status === 409) { | ||||
|                     resolveConflict(nns, true); | ||||
|                 } else if (xhr.responseText) { | ||||
|                     RED.notify(RED._("deploy.deployFailed",{message:xhr.responseText}),"error"); | ||||
|                 } else { | ||||
|                     RED.notify(RED._("deploy.deployFailed",{message:RED._("deploy.errors.noResponse")}),"error"); | ||||
|                 } | ||||
|             }).always(function() { | ||||
|                 deployInflight = false; | ||||
|                 var delta = Math.max(0,300-(Date.now()-startTime)); | ||||
|                 setTimeout(function() { | ||||
|                     $(".deploy-button-content").css('opacity',1); | ||||
|                     $(".deploy-button-spinner").hide(); | ||||
|                     $("#header-shade").hide(); | ||||
|                     $("#editor-shade").hide(); | ||||
|                     $("#palette-shade").hide(); | ||||
|                     $("#sidebar-shade").hide(); | ||||
|                 },delta); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|     return { | ||||
|         init: init | ||||
|     } | ||||
| })(); | ||||
							
								
								
									
										1342
									
								
								editor/js/ui/diff.js
									
									
									
									
									
								
							
							
						
						| @@ -1,493 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.library = (function() { | ||||
|  | ||||
|  | ||||
|     var exportToLibraryDialog; | ||||
|  | ||||
|     function loadFlowLibrary() { | ||||
|         $.getJSON("library/flows",function(data) { | ||||
|             //console.log(data); | ||||
|  | ||||
|             var buildMenu = function(data,root) { | ||||
|                 var i; | ||||
|                 var li; | ||||
|                 var a; | ||||
|                 var ul = document.createElement("ul"); | ||||
|                 if (root === "") { | ||||
|                     ul.id = "menu-item-import-library-submenu"; | ||||
|                 } | ||||
|                 ul.className = "dropdown-menu"; | ||||
|                 if (data.d) { | ||||
|                     for (i in data.d) { | ||||
|                         if (data.d.hasOwnProperty(i)) { | ||||
|                             li = document.createElement("li"); | ||||
|                             li.className = "dropdown-submenu pull-left"; | ||||
|                             a = document.createElement("a"); | ||||
|                             a.href="#"; | ||||
|                             var label = i.replace(/^node-red-contrib-/,"").replace(/^node-red-node-/,"").replace(/-/," ").replace(/_/," "); | ||||
|                             a.innerHTML = label; | ||||
|                             li.appendChild(a); | ||||
|                             li.appendChild(buildMenu(data.d[i],root+(root!==""?"/":"")+i)); | ||||
|                             ul.appendChild(li); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 if (data.f) { | ||||
|                     for (i in data.f) { | ||||
|                         if (data.f.hasOwnProperty(i)) { | ||||
|                             li = document.createElement("li"); | ||||
|                             a = document.createElement("a"); | ||||
|                             a.href="#"; | ||||
|                             a.innerHTML = data.f[i]; | ||||
|                             a.flowName = root+(root!==""?"/":"")+data.f[i]; | ||||
|                             a.onclick = function() { | ||||
|                                 $.get('library/flows/'+this.flowName, function(data) { | ||||
|                                     RED.view.importNodes(data); | ||||
|                                 }); | ||||
|                             }; | ||||
|                             li.appendChild(a); | ||||
|                             ul.appendChild(li); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 return ul; | ||||
|             }; | ||||
|             var examples; | ||||
|             if (data.d && data.d._examples_) { | ||||
|                 examples = data.d._examples_; | ||||
|                 delete data.d._examples_; | ||||
|             } | ||||
|             var menu = buildMenu(data,""); | ||||
|             $("#menu-item-import-examples").remove(); | ||||
|             if (examples) { | ||||
|                 RED.menu.addItem("menu-item-import",{id:"menu-item-import-examples",label:RED._("menu.label.examples"),options:[]}) | ||||
|                 $("#menu-item-import-examples-submenu").replaceWith(buildMenu(examples,"_examples_")); | ||||
|             } | ||||
|             //TODO: need an api in RED.menu for this | ||||
|             $("#menu-item-import-library-submenu").replaceWith(menu); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function createUI(options) { | ||||
|         var libraryData = {}; | ||||
|         var selectedLibraryItem = null; | ||||
|         var libraryEditor = null; | ||||
|  | ||||
|         // Orion editor has set/getText | ||||
|         // ACE editor has set/getValue | ||||
|         // normalise to set/getValue | ||||
|         if (options.editor.setText) { | ||||
|             // Orion doesn't like having pos passed in, so proxy the call to drop it | ||||
|             options.editor.setValue = function(text,pos) { | ||||
|                 options.editor.setText.call(options.editor,text); | ||||
|             } | ||||
|         } | ||||
|         if (options.editor.getText) { | ||||
|             options.editor.getValue = options.editor.getText; | ||||
|         } | ||||
|  | ||||
|         function buildFileListItem(item) { | ||||
|             var li = document.createElement("li"); | ||||
|             li.onmouseover = function(e) { $(this).addClass("list-hover"); }; | ||||
|             li.onmouseout = function(e) { $(this).removeClass("list-hover"); }; | ||||
|             return li; | ||||
|         } | ||||
|  | ||||
|         function buildFileList(root,data) { | ||||
|             var ul = document.createElement("ul"); | ||||
|             var li; | ||||
|             for (var i=0; i<data.length; i++) { | ||||
|                 var v = data[i]; | ||||
|                 if (typeof v === "string") { | ||||
|                     // directory | ||||
|                     li = buildFileListItem(v); | ||||
|                     li.onclick = (function () { | ||||
|                         var dirName = v; | ||||
|                         return function(e) { | ||||
|                             var bcli = $('<li class="active"><span class="divider">/</span> <a href="#">'+dirName+'</a></li>'); | ||||
|                             $("a",bcli).click(function(e) { | ||||
|                                 $(this).parent().nextAll().remove(); | ||||
|                                 $.getJSON("library/"+options.url+root+dirName,function(data) { | ||||
|                                     $("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data)); | ||||
|                                 }); | ||||
|                                 e.stopPropagation(); | ||||
|                             }); | ||||
|                             var bc = $("#node-dialog-library-breadcrumbs"); | ||||
|                             $(".active",bc).removeClass("active"); | ||||
|                             bc.append(bcli); | ||||
|                             $.getJSON("library/"+options.url+root+dirName,function(data) { | ||||
|                                 $("#node-select-library").children().first().replaceWith(buildFileList(root+dirName+"/",data)); | ||||
|                             }); | ||||
|                         } | ||||
|                     })(); | ||||
|                     li.innerHTML = '<i class="fa fa-folder"></i> '+v+"</i>"; | ||||
|                     ul.appendChild(li); | ||||
|                 } else { | ||||
|                     // file | ||||
|                     li = buildFileListItem(v); | ||||
|                     li.innerHTML = v.name; | ||||
|                     li.onclick = (function() { | ||||
|                         var item = v; | ||||
|                         return function(e) { | ||||
|                             $(".list-selected",ul).removeClass("list-selected"); | ||||
|                             $(this).addClass("list-selected"); | ||||
|                             $.get("library/"+options.url+root+item.fn, function(data) { | ||||
|                                 selectedLibraryItem = item; | ||||
|                                 libraryEditor.setValue(data,-1); | ||||
|                             }); | ||||
|                         } | ||||
|                     })(); | ||||
|                     ul.appendChild(li); | ||||
|                 } | ||||
|             } | ||||
|             return ul; | ||||
|         } | ||||
|  | ||||
|         $('#node-input-name').css("width","66%").after( | ||||
|             '<div class="btn-group" style="margin-left: 5px;">'+ | ||||
|             '<a id="node-input-'+options.type+'-lookup" class="editor-button" data-toggle="dropdown"><i class="fa fa-book"></i> <i class="fa fa-caret-down"></i></a>'+ | ||||
|             '<ul class="dropdown-menu pull-right" role="menu">'+ | ||||
|             '<li><a id="node-input-'+options.type+'-menu-open-library" tabindex="-1" href="#">'+RED._("library.openLibrary")+'</a></li>'+ | ||||
|             '<li><a id="node-input-'+options.type+'-menu-save-library" tabindex="-1" href="#">'+RED._("library.saveToLibrary")+'</a></li>'+ | ||||
|             '</ul></div>' | ||||
|         ); | ||||
|  | ||||
|         $('#node-input-'+options.type+'-menu-open-library').click(function(e) { | ||||
|             $("#node-select-library").children().remove(); | ||||
|             var bc = $("#node-dialog-library-breadcrumbs"); | ||||
|             bc.children().first().nextAll().remove(); | ||||
|             libraryEditor.setValue('',-1); | ||||
|  | ||||
|             $.getJSON("library/"+options.url,function(data) { | ||||
|                 $("#node-select-library").append(buildFileList("/",data)); | ||||
|                 $("#node-dialog-library-breadcrumbs a").click(function(e) { | ||||
|                     $(this).parent().nextAll().remove(); | ||||
|                     $("#node-select-library").children().first().replaceWith(buildFileList("/",data)); | ||||
|                     e.stopPropagation(); | ||||
|                 }); | ||||
|                 $( "#node-dialog-library-lookup" ).dialog( "open" ); | ||||
|             }); | ||||
|  | ||||
|             e.preventDefault(); | ||||
|         }); | ||||
|  | ||||
|         $('#node-input-'+options.type+'-menu-save-library').click(function(e) { | ||||
|             //var found = false; | ||||
|             var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,""); | ||||
|  | ||||
|             //var buildPathList = function(data,root) { | ||||
|             //    var paths = []; | ||||
|             //    if (data.d) { | ||||
|             //        for (var i in data.d) { | ||||
|             //            var dn = root+(root==""?"":"/")+i; | ||||
|             //            var d = { | ||||
|             //                label:dn, | ||||
|             //                files:[] | ||||
|             //            }; | ||||
|             //            for (var f in data.d[i].f) { | ||||
|             //                d.files.push(data.d[i].f[f].fn.split("/").slice(-1)[0]); | ||||
|             //            } | ||||
|             //            paths.push(d); | ||||
|             //            paths = paths.concat(buildPathList(data.d[i],root+(root==""?"":"/")+i)); | ||||
|             //        } | ||||
|             //    } | ||||
|             //    return paths; | ||||
|             //}; | ||||
|             $("#node-dialog-library-save-folder").attr("value",""); | ||||
|  | ||||
|             var filename = name.replace(/[^\w-]/g,"-"); | ||||
|             if (filename === "") { | ||||
|                 filename = "unnamed-"+options.type; | ||||
|             } | ||||
|             $("#node-dialog-library-save-filename").attr("value",filename+".js"); | ||||
|  | ||||
|             //var paths = buildPathList(libraryData,""); | ||||
|             //$("#node-dialog-library-save-folder").autocomplete({ | ||||
|             //        minLength: 0, | ||||
|             //        source: paths, | ||||
|             //        select: function( event, ui ) { | ||||
|             //            $("#node-dialog-library-save-filename").autocomplete({ | ||||
|             //                    minLength: 0, | ||||
|             //                    source: ui.item.files | ||||
|             //            }); | ||||
|             //        } | ||||
|             //}); | ||||
|  | ||||
|             $( "#node-dialog-library-save" ).dialog( "open" ); | ||||
|             e.preventDefault(); | ||||
|         }); | ||||
|  | ||||
|         libraryEditor = ace.edit('node-select-library-text'); | ||||
|         libraryEditor.setTheme("ace/theme/tomorrow"); | ||||
|         if (options.mode) { | ||||
|             libraryEditor.getSession().setMode(options.mode); | ||||
|         } | ||||
|         libraryEditor.setOptions({ | ||||
|             readOnly: true, | ||||
|             highlightActiveLine: false, | ||||
|             highlightGutterLine: false | ||||
|         }); | ||||
|         libraryEditor.renderer.$cursorLayer.element.style.opacity=0; | ||||
|         libraryEditor.$blockScrolling = Infinity; | ||||
|  | ||||
|         $( "#node-dialog-library-lookup" ).dialog({ | ||||
|             title: RED._("library.typeLibrary", {type:options.type}), | ||||
|             modal: true, | ||||
|             autoOpen: false, | ||||
|             width: 800, | ||||
|             height: 450, | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("common.label.load"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         if (selectedLibraryItem) { | ||||
|                             for (var i=0; i<options.fields.length; i++) { | ||||
|                                 var field = options.fields[i]; | ||||
|                                 $("#node-input-"+field).val(selectedLibraryItem[field]); | ||||
|                             } | ||||
|                             options.editor.setValue(libraryEditor.getValue(),-1); | ||||
|                         } | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 } | ||||
|             ], | ||||
|             open: function(e) { | ||||
|                 var form = $("form",this); | ||||
|                 form.height(form.parent().height()-30); | ||||
|                 $("#node-select-library-text").height("100%"); | ||||
|                 $(".form-row:last-child",form).children().height(form.height()-60); | ||||
|             }, | ||||
|             resize: function(e) { | ||||
|                 var form = $("form",this); | ||||
|                 form.height(form.parent().height()-30); | ||||
|                 $(".form-row:last-child",form).children().height(form.height()-60); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         function saveToLibrary(overwrite) { | ||||
|             var name = $("#node-input-name").val().replace(/(^\s*)|(\s*$)/g,""); | ||||
|             if (name === "") { | ||||
|                 name = RED._("library.unnamedType",{type:options.type}); | ||||
|             } | ||||
|             var filename = $("#node-dialog-library-save-filename").val().replace(/(^\s*)|(\s*$)/g,""); | ||||
|             var pathname = $("#node-dialog-library-save-folder").val().replace(/(^\s*)|(\s*$)/g,""); | ||||
|             if (filename === "" || !/.+\.js$/.test(filename)) { | ||||
|                 RED.notify(RED._("library.invalidFilename"),"warning"); | ||||
|                 return; | ||||
|             } | ||||
|             var fullpath = pathname+(pathname===""?"":"/")+filename; | ||||
|             if (!overwrite) { | ||||
|                 //var pathnameParts = pathname.split("/"); | ||||
|                 //var exists = false; | ||||
|                 //var ds = libraryData; | ||||
|                 //for (var pnp in pathnameParts) { | ||||
|                 //    if (ds.d && pathnameParts[pnp] in ds.d) { | ||||
|                 //        ds = ds.d[pathnameParts[pnp]]; | ||||
|                 //    } else { | ||||
|                 //        ds = null; | ||||
|                 //        break; | ||||
|                 //    } | ||||
|                 //} | ||||
|                 //if (ds && ds.f) { | ||||
|                 //    for (var f in ds.f) { | ||||
|                 //        if (ds.f[f].fn == fullpath) { | ||||
|                 //            exists = true; | ||||
|                 //            break; | ||||
|                 //        } | ||||
|                 //    } | ||||
|                 //} | ||||
|                 //if (exists) { | ||||
|                 //    $("#node-dialog-library-save-content").html(RED._("library.dialogSaveOverwrite",{libraryType:options.type,libraryName:fullpath})); | ||||
|                 //    $("#node-dialog-library-save-confirm").dialog( "open" ); | ||||
|                 //    return; | ||||
|                 //} | ||||
|             } | ||||
|             var queryArgs = []; | ||||
|             var data = {}; | ||||
|             for (var i=0; i<options.fields.length; i++) { | ||||
|                 var field = options.fields[i]; | ||||
|                 if (field == "name") { | ||||
|                     data.name = name; | ||||
|                 } else { | ||||
|                     data[field] = $("#node-input-"+field).val(); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             data.text = options.editor.getValue(); | ||||
|             $.ajax({ | ||||
|                 url:"library/"+options.url+'/'+fullpath, | ||||
|                 type: "POST", | ||||
|                 data: JSON.stringify(data), | ||||
|                 contentType: "application/json; charset=utf-8" | ||||
|             }).done(function(data,textStatus,xhr) { | ||||
|                 RED.notify(RED._("library.savedType", {type:options.type}),"success"); | ||||
|             }).fail(function(xhr,textStatus,err) { | ||||
|                 if (xhr.status === 401) { | ||||
|                     RED.notify(RED._("library.saveFailed",{message:RED._("user.notAuthorized")}),"error"); | ||||
|                 } else { | ||||
|                     RED.notify(RED._("library.saveFailed",{message:xhr.responseText}),"error"); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|         $( "#node-dialog-library-save-confirm" ).dialog({ | ||||
|             title: RED._("library.saveToLibrary"), | ||||
|             modal: true, | ||||
|             autoOpen: false, | ||||
|             width: 530, | ||||
|             height: 230, | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("common.label.save"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         saveToLibrary(true); | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 } | ||||
|             ] | ||||
|         }); | ||||
|         $( "#node-dialog-library-save" ).dialog({ | ||||
|             title: RED._("library.saveToLibrary"), | ||||
|             modal: true, | ||||
|             autoOpen: false, | ||||
|             width: 530, | ||||
|             height: 230, | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("common.label.save"), | ||||
|                     class: "primary", | ||||
|                     click: function() { | ||||
|                         saveToLibrary(false); | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 } | ||||
|             ] | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function exportFlow() { | ||||
|         //TODO: don't rely on the main dialog | ||||
|         var nns = RED.nodes.createExportableNodeSet(RED.view.selection().nodes); | ||||
|         $("#node-input-library-filename").attr('nodes',JSON.stringify(nns)); | ||||
|         exportToLibraryDialog.dialog( "open" ); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|  | ||||
|             RED.actions.add("core:library-export",exportFlow); | ||||
|  | ||||
|             RED.events.on("view:selection-changed",function(selection) { | ||||
|                 if (!selection.nodes) { | ||||
|                     RED.menu.setDisabled("menu-item-export",true); | ||||
|                     RED.menu.setDisabled("menu-item-export-clipboard",true); | ||||
|                     RED.menu.setDisabled("menu-item-export-library",true); | ||||
|                 } else { | ||||
|                     RED.menu.setDisabled("menu-item-export",false); | ||||
|                     RED.menu.setDisabled("menu-item-export-clipboard",false); | ||||
|                     RED.menu.setDisabled("menu-item-export-library",false); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (RED.settings.theme("menu.menu-item-import-library") !== false) { | ||||
|                 loadFlowLibrary(); | ||||
|             } | ||||
|  | ||||
|             exportToLibraryDialog = $('<div id="library-dialog" class="hide"><form class="dialog-form form-horizontal"></form></div>') | ||||
|                 .appendTo("body") | ||||
|                 .dialog({ | ||||
|                     modal: true, | ||||
|                     autoOpen: false, | ||||
|                     width: 500, | ||||
|                     resizable: false, | ||||
|                     title: RED._("library.exportToLibrary"), | ||||
|                     buttons: [ | ||||
|                         { | ||||
|                             id: "library-dialog-cancel", | ||||
|                             text: RED._("common.label.cancel"), | ||||
|                             click: function() { | ||||
|                                 $( this ).dialog( "close" ); | ||||
|                             } | ||||
|                         }, | ||||
|                         { | ||||
|                             id: "library-dialog-ok", | ||||
|                             class: "primary", | ||||
|                             text: RED._("common.label.export"), | ||||
|                             click: function() { | ||||
|                                 //TODO: move this to RED.library | ||||
|                                 var flowName = $("#node-input-library-filename").val(); | ||||
|                                 if (!/^\s*$/.test(flowName)) { | ||||
|                                     $.ajax({ | ||||
|                                         url:'library/flows/'+flowName, | ||||
|                                         type: "POST", | ||||
|                                         data: $("#node-input-library-filename").attr('nodes'), | ||||
|                                         contentType: "application/json; charset=utf-8" | ||||
|                                     }).done(function() { | ||||
|                                         RED.library.loadFlowLibrary(); | ||||
|                                         RED.notify(RED._("library.savedNodes"),"success"); | ||||
|                                     }).fail(function(xhr,textStatus,err) { | ||||
|                                         if (xhr.status === 401) { | ||||
|                                             RED.notify(RED._("library.saveFailed",{message:RED._("user.notAuthorized")}),"error"); | ||||
|                                         } else { | ||||
|                                             RED.notify(RED._("library.saveFailed",{message:xhr.responseText}),"error"); | ||||
|                                         } | ||||
|                                     }); | ||||
|                                 } | ||||
|                                 $( this ).dialog( "close" ); | ||||
|                             } | ||||
|                         } | ||||
|                     ], | ||||
|                     open: function(e) { | ||||
|                         $(this).parent().find(".ui-dialog-titlebar-close").hide(); | ||||
|                     }, | ||||
|                     close: function(e) { | ||||
|                     } | ||||
|                 }); | ||||
|             exportToLibraryDialog.children(".dialog-form").append($( | ||||
|                 '<div class="form-row">'+ | ||||
|                 '<label for="node-input-library-filename" data-i18n="[append]editor:library.filename"><i class="fa fa-file"></i> </label>'+ | ||||
|                 '<input type="text" id="node-input-library-filename" data-i18n="[placeholder]editor:library.fullFilenamePlaceholder">'+ | ||||
|                 '<input type="text" style="display: none;" />'+ // Second hidden input to prevent submit on Enter | ||||
|                 '</div>' | ||||
|             )); | ||||
|         }, | ||||
|         create: createUI, | ||||
|         loadFlowLibrary: loadFlowLibrary, | ||||
|  | ||||
|         export: exportFlow | ||||
|     } | ||||
| })(); | ||||
| @@ -1,87 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.notify = (function() { | ||||
|     var currentNotifications = []; | ||||
|     var c = 0; | ||||
|     return function(msg,type,fixed,timeout) { | ||||
|         if (currentNotifications.length > 4) { | ||||
|             var ll = currentNotifications.length; | ||||
|             for (var i = 0;ll > 4 && i<currentNotifications.length;i+=1) { | ||||
|                 var notifiction = currentNotifications[i]; | ||||
|                 if (!notifiction.fixed) { | ||||
|                     window.clearTimeout(notifiction.timeoutid); | ||||
|                     notifiction.close(); | ||||
|                     ll -= 1; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         var n = document.createElement("div"); | ||||
|         n.id="red-notification-"+c; | ||||
|         n.className = "notification"; | ||||
|         n.fixed = fixed; | ||||
|         if (type) { | ||||
|             n.className = "notification notification-"+type; | ||||
|         } | ||||
|         n.style.display = "none"; | ||||
|         if (typeof msg === "string") { | ||||
|             n.innerHTML = msg; | ||||
|         } else { | ||||
|             $(n).append(msg); | ||||
|         } | ||||
|         $("#notifications").append(n); | ||||
|         $(n).slideDown(300); | ||||
|         n.close = (function() { | ||||
|             var nn = n; | ||||
|             return function() { | ||||
|                 currentNotifications.splice(currentNotifications.indexOf(nn),1); | ||||
|                 $(nn).slideUp(300, function() { | ||||
|                     nn.parentNode.removeChild(nn); | ||||
|                 }); | ||||
|             }; | ||||
|         })(); | ||||
|  | ||||
|         n.update = (function() { | ||||
|             var nn = n; | ||||
|             return function(msg,timeout) { | ||||
|                 if (typeof msg === "string") { | ||||
|                     nn.innerHTML = msg; | ||||
|                 } else { | ||||
|                     $(nn).empty().append(msg); | ||||
|                 } | ||||
|                 if (timeout !== undefined && timeout > 0) { | ||||
|                     window.clearTimeout(nn.timeoutid); | ||||
|                     nn.timeoutid = window.setTimeout(nn.close,timeout); | ||||
|                 } else { | ||||
|                     window.clearTimeout(nn.timeoutid); | ||||
|                 } | ||||
|             } | ||||
|         })(); | ||||
|  | ||||
|         if (!fixed) { | ||||
|             $(n).click((function() { | ||||
|                 var nn = n; | ||||
|                 return function() { | ||||
|                     nn.close(); | ||||
|                     window.clearTimeout(nn.timeoutid); | ||||
|                 }; | ||||
|             })()); | ||||
|             n.timeoutid = window.setTimeout(n.close,timeout||3000); | ||||
|         } | ||||
|         currentNotifications.push(n); | ||||
|         c+=1; | ||||
|         return n; | ||||
|     } | ||||
| })(); | ||||
| @@ -1,956 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.palette.editor = (function() { | ||||
|  | ||||
|     var disabled = false; | ||||
|  | ||||
|     var editorTabs; | ||||
|     var filterInput; | ||||
|     var searchInput; | ||||
|     var nodeList; | ||||
|     var packageList; | ||||
|     var loadedList = []; | ||||
|     var filteredList = []; | ||||
|     var loadedIndex = {}; | ||||
|  | ||||
|     var typesInUse = {}; | ||||
|     var nodeEntries = {}; | ||||
|     var eventTimers = {}; | ||||
|     var activeFilter = ""; | ||||
|  | ||||
|     function semVerCompare(A,B) { | ||||
|         var aParts = A.split(".").map(function(m) { return parseInt(m);}); | ||||
|         var bParts = B.split(".").map(function(m) { return parseInt(m);}); | ||||
|         for (var i=0;i<3;i++) { | ||||
|             var j = aParts[i]-bParts[i]; | ||||
|             if (j<0) { return -1 } | ||||
|             if (j>0) { return 1 } | ||||
|         } | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     function delayCallback(start,callback) { | ||||
|         var delta = Date.now() - start; | ||||
|         if (delta < 300) { | ||||
|             delta = 300; | ||||
|         } else { | ||||
|             delta = 0; | ||||
|         } | ||||
|         setTimeout(function() { | ||||
|             callback(); | ||||
|         },delta); | ||||
|     } | ||||
|     function changeNodeState(id,state,shade,callback) { | ||||
|         shade.show(); | ||||
|         var start = Date.now(); | ||||
|         $.ajax({ | ||||
|             url:"nodes/"+id, | ||||
|             type: "PUT", | ||||
|             data: JSON.stringify({ | ||||
|                 enabled: state | ||||
|             }), | ||||
|             contentType: "application/json; charset=utf-8" | ||||
|         }).done(function(data,textStatus,xhr) { | ||||
|             delayCallback(start,function() { | ||||
|                 shade.hide(); | ||||
|                 callback(); | ||||
|             }); | ||||
|         }).fail(function(xhr,textStatus,err) { | ||||
|             delayCallback(start,function() { | ||||
|                 shade.hide(); | ||||
|                 callback(xhr); | ||||
|             }); | ||||
|         }) | ||||
|     } | ||||
|     function installNodeModule(id,version,shade,callback) { | ||||
|         var requestBody = { | ||||
|             module: id | ||||
|         }; | ||||
|         if (callback === undefined) { | ||||
|             callback = shade; | ||||
|             shade = version; | ||||
|         } else { | ||||
|             requestBody.version = version; | ||||
|         } | ||||
|         shade.show(); | ||||
|         $.ajax({ | ||||
|             url:"nodes", | ||||
|             type: "POST", | ||||
|             data: JSON.stringify(requestBody), | ||||
|             contentType: "application/json; charset=utf-8" | ||||
|         }).done(function(data,textStatus,xhr) { | ||||
|             shade.hide(); | ||||
|             callback(); | ||||
|         }).fail(function(xhr,textStatus,err) { | ||||
|             shade.hide(); | ||||
|             callback(xhr); | ||||
|         }); | ||||
|     } | ||||
|     function removeNodeModule(id,callback) { | ||||
|         $.ajax({ | ||||
|             url:"nodes/"+id, | ||||
|             type: "DELETE" | ||||
|         }).done(function(data,textStatus,xhr) { | ||||
|             callback(); | ||||
|         }).fail(function(xhr,textStatus,err) { | ||||
|             callback(xhr); | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     function refreshNodeModuleList() { | ||||
|         for (var id in nodeEntries) { | ||||
|             if (nodeEntries.hasOwnProperty(id)) { | ||||
|                 _refreshNodeModule(id); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function refreshNodeModule(module) { | ||||
|         if (!eventTimers.hasOwnProperty(module)) { | ||||
|             eventTimers[module] = setTimeout(function() { | ||||
|                 delete eventTimers[module]; | ||||
|                 _refreshNodeModule(module); | ||||
|             },100); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function getContrastingBorder(rgbColor){ | ||||
|         var parts = /^rgba?\(\s*(\d+),\s*(\d+),\s*(\d+)[,)]/.exec(rgbColor); | ||||
|         if (parts) { | ||||
|             var r = parseInt(parts[1]); | ||||
|             var g = parseInt(parts[2]); | ||||
|             var b = parseInt(parts[3]); | ||||
|             var yiq = ((r*299)+(g*587)+(b*114))/1000; | ||||
|             if (yiq > 160) { | ||||
|                 r = Math.floor(r*0.8); | ||||
|                 g = Math.floor(g*0.8); | ||||
|                 b = Math.floor(b*0.8); | ||||
|                 return "rgb("+r+","+g+","+b+")"; | ||||
|             } | ||||
|         } | ||||
|         return rgbColor; | ||||
|     } | ||||
|  | ||||
|     function formatUpdatedAt(dateString) { | ||||
|         var now = new Date(); | ||||
|         var d = new Date(dateString); | ||||
|         var delta = (Date.now() - new Date(dateString).getTime())/1000; | ||||
|  | ||||
|         if (delta < 60) { | ||||
|             return RED._('palette.editor.times.seconds'); | ||||
|         } | ||||
|         delta = Math.floor(delta/60); | ||||
|         if (delta < 10) { | ||||
|             return RED._('palette.editor.times.minutes'); | ||||
|         } | ||||
|         if (delta < 60) { | ||||
|             return RED._('palette.editor.times.minutesV',{count:delta}); | ||||
|         } | ||||
|  | ||||
|         delta = Math.floor(delta/60); | ||||
|  | ||||
|         if (delta < 24) { | ||||
|             return RED._('palette.editor.times.hoursV',{count:delta}); | ||||
|         } | ||||
|  | ||||
|         delta = Math.floor(delta/24); | ||||
|  | ||||
|         if (delta < 7) { | ||||
|             return RED._('palette.editor.times.daysV',{count:delta}) | ||||
|         } | ||||
|         var weeks = Math.floor(delta/7); | ||||
|         var days = delta%7; | ||||
|  | ||||
|         if (weeks < 4) { | ||||
|             return RED._('palette.editor.times.weeksV',{count:weeks}) | ||||
|         } | ||||
|  | ||||
|         var months = Math.floor(weeks/4); | ||||
|         weeks = weeks%4; | ||||
|  | ||||
|         if (months < 12) { | ||||
|             return RED._('palette.editor.times.monthsV',{count:months}) | ||||
|         } | ||||
|         var years = Math.floor(months/12); | ||||
|         months = months%12; | ||||
|  | ||||
|         if (months === 0) { | ||||
|             return RED._('palette.editor.times.yearsV',{count:years}) | ||||
|         } else { | ||||
|             return RED._('palette.editor.times.year'+(years>1?'s':'')+'MonthsV',{y:years,count:months}) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function _refreshNodeModule(module) { | ||||
|         if (!nodeEntries.hasOwnProperty(module)) { | ||||
|             nodeEntries[module] = {info:RED.nodes.registry.getModule(module)}; | ||||
|             var index = [module]; | ||||
|             for (var s in nodeEntries[module].info.sets) { | ||||
|                 if (nodeEntries[module].info.sets.hasOwnProperty(s)) { | ||||
|                     index.push(s); | ||||
|                     index = index.concat(nodeEntries[module].info.sets[s].types) | ||||
|                 } | ||||
|             } | ||||
|             nodeEntries[module].index = index.join(",").toLowerCase(); | ||||
|             nodeList.editableList('addItem', nodeEntries[module]); | ||||
|         } else { | ||||
|             var moduleInfo = nodeEntries[module].info; | ||||
|             var nodeEntry = nodeEntries[module].elements; | ||||
|             if (nodeEntry) { | ||||
|                 var activeTypeCount = 0; | ||||
|                 var typeCount = 0; | ||||
|                 nodeEntries[module].totalUseCount = 0; | ||||
|                 nodeEntries[module].setUseCount = {}; | ||||
|  | ||||
|                 for (var setName in moduleInfo.sets) { | ||||
|                     if (moduleInfo.sets.hasOwnProperty(setName)) { | ||||
|                         var inUseCount = 0; | ||||
|                         var set = moduleInfo.sets[setName]; | ||||
|                         var setElements = nodeEntry.sets[setName]; | ||||
|  | ||||
|                         if (set.enabled) { | ||||
|                             activeTypeCount += set.types.length; | ||||
|                         } | ||||
|                         typeCount += set.types.length; | ||||
|                         for (var i=0;i<moduleInfo.sets[setName].types.length;i++) { | ||||
|                             var t = moduleInfo.sets[setName].types[i]; | ||||
|                             inUseCount += (typesInUse[t]||0); | ||||
|                             var swatch = setElements.swatches[t]; | ||||
|                             if (set.enabled) { | ||||
|                                 var def = RED.nodes.getType(t); | ||||
|                                 if (def && def.color) { | ||||
|                                     swatch.css({background:def.color}); | ||||
|                                     swatch.css({border: "1px solid "+getContrastingBorder(swatch.css('backgroundColor'))}) | ||||
|  | ||||
|                                 } else { | ||||
|                                     swatch.css({background:"#eee",border:"1px dashed #999"}) | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 swatch.css({background:"#eee",border:"1px dashed #999"}) | ||||
|                             } | ||||
|                         } | ||||
|                         nodeEntries[module].setUseCount[setName] = inUseCount; | ||||
|                         nodeEntries[module].totalUseCount += inUseCount; | ||||
|  | ||||
|                         if (inUseCount > 0) { | ||||
|                             setElements.enableButton.html(RED._('palette.editor.inuse')); | ||||
|                             setElements.enableButton.addClass('disabled'); | ||||
|                         } else { | ||||
|                             setElements.enableButton.removeClass('disabled'); | ||||
|                             if (set.enabled) { | ||||
|                                 setElements.enableButton.html(RED._('palette.editor.disable')); | ||||
|                             } else { | ||||
|                                 setElements.enableButton.html(RED._('palette.editor.enable')); | ||||
|                             } | ||||
|                         } | ||||
|                         setElements.setRow.toggleClass("palette-module-set-disabled",!set.enabled); | ||||
|                     } | ||||
|                 } | ||||
|                 var nodeCount = (activeTypeCount === typeCount)?typeCount:activeTypeCount+" / "+typeCount; | ||||
|                 nodeEntry.setCount.html(RED._('palette.editor.nodeCount',{count:typeCount,label:nodeCount})); | ||||
|  | ||||
|                 if (nodeEntries[module].totalUseCount > 0) { | ||||
|                     nodeEntry.enableButton.html(RED._('palette.editor.inuse')); | ||||
|                     nodeEntry.enableButton.addClass('disabled'); | ||||
|                     nodeEntry.removeButton.hide(); | ||||
|                 } else { | ||||
|                     nodeEntry.enableButton.removeClass('disabled'); | ||||
|                     if (moduleInfo.local) { | ||||
|                         nodeEntry.removeButton.css('display', 'inline-block'); | ||||
|                     } | ||||
|                     if (activeTypeCount === 0) { | ||||
|                         nodeEntry.enableButton.html(RED._('palette.editor.enableall')); | ||||
|                     } else { | ||||
|                         nodeEntry.enableButton.html(RED._('palette.editor.disableall')); | ||||
|                     } | ||||
|                     nodeEntry.container.toggleClass("disabled",(activeTypeCount === 0)); | ||||
|                 } | ||||
|             } | ||||
|             if (moduleInfo.pending_version) { | ||||
|                 nodeEntry.versionSpan.html(moduleInfo.version+' <i class="fa fa-long-arrow-right"></i> '+moduleInfo.pending_version).appendTo(nodeEntry.metaRow) | ||||
|                 nodeEntry.updateButton.html(RED._('palette.editor.updated')).addClass('disabled').show(); | ||||
|             } else if (loadedIndex.hasOwnProperty(module)) { | ||||
|                 if (semVerCompare(loadedIndex[module].version,moduleInfo.version) === 1) { | ||||
|                     nodeEntry.updateButton.show(); | ||||
|                     nodeEntry.updateButton.html(RED._('palette.editor.update',{version:loadedIndex[module].version})); | ||||
|                 } else { | ||||
|                     nodeEntry.updateButton.hide(); | ||||
|                 } | ||||
|             } else { | ||||
|                 nodeEntry.updateButton.hide(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function filterChange(val) { | ||||
|         activeFilter = val.toLowerCase(); | ||||
|         var visible = nodeList.editableList('filter'); | ||||
|         var size = nodeList.editableList('length'); | ||||
|         if (val === "") { | ||||
|             filterInput.searchBox('count'); | ||||
|         } else { | ||||
|             filterInput.searchBox('count',visible+" / "+size); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     var catalogueCount; | ||||
|     var catalogueLoadStatus = []; | ||||
|     var catalogueLoadStart; | ||||
|     var catalogueLoadErrors = false; | ||||
|  | ||||
|     var activeSort = sortModulesAZ; | ||||
|  | ||||
|     function handleCatalogResponse(err,catalog,index,v) { | ||||
|         catalogueLoadStatus.push(err||v); | ||||
|         if (!err) { | ||||
|             if (v.modules) { | ||||
|                 v.modules.forEach(function(m) { | ||||
|                     loadedIndex[m.id] = m; | ||||
|                     m.index = [m.id]; | ||||
|                     if (m.keywords) { | ||||
|                         m.index = m.index.concat(m.keywords); | ||||
|                     } | ||||
|                     if (m.updated_at) { | ||||
|                         m.timestamp = new Date(m.updated_at).getTime(); | ||||
|                     } else { | ||||
|                         m.timestamp = 0; | ||||
|                     } | ||||
|                     m.index = m.index.join(",").toLowerCase(); | ||||
|                 }) | ||||
|                 loadedList = loadedList.concat(v.modules); | ||||
|             } | ||||
|             searchInput.searchBox('count',loadedList.length); | ||||
|         } else { | ||||
|             catalogueLoadErrors = true; | ||||
|         } | ||||
|         if (catalogueCount > 1) { | ||||
|             $(".palette-module-shade-status").html(RED._('palette.editor.loading')+"<br>"+catalogueLoadStatus.length+"/"+catalogueCount); | ||||
|         } | ||||
|         if (catalogueLoadStatus.length === catalogueCount) { | ||||
|             if (catalogueLoadErrors) { | ||||
|                 RED.notify(RED._('palette.editor.errors.catalogLoadFailed',{url: catalog}),"error",false,8000); | ||||
|             } | ||||
|             var delta = 250-(Date.now() - catalogueLoadStart); | ||||
|             setTimeout(function() { | ||||
|                 $("#palette-module-install-shade").hide(); | ||||
|             },Math.max(delta,0)); | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function initInstallTab() { | ||||
|         if (loadedList.length === 0) { | ||||
|             loadedList = []; | ||||
|             loadedIndex = {}; | ||||
|             packageList.editableList('empty'); | ||||
|  | ||||
|             $(".palette-module-shade-status").html(RED._('palette.editor.loading')); | ||||
|             var catalogues = RED.settings.theme('palette.catalogues')||['https://catalogue.nodered.org/catalogue.json']; | ||||
|             catalogueLoadStatus = []; | ||||
|             catalogueLoadErrors = false; | ||||
|             catalogueCount = catalogues.length; | ||||
|             if (catalogues.length > 1) { | ||||
|                 $(".palette-module-shade-status").html(RED._('palette.editor.loading')+"<br>0/"+catalogues.length); | ||||
|             } | ||||
|             $("#palette-module-install-shade").show(); | ||||
|             catalogueLoadStart = Date.now(); | ||||
|             var handled = 0; | ||||
|             catalogues.forEach(function(catalog,index) { | ||||
|                 $.getJSON(catalog, {_: new Date().getTime()},function(v) { | ||||
|                     handleCatalogResponse(null,catalog,index,v); | ||||
|                     refreshNodeModuleList(); | ||||
|                 }).fail(function(jqxhr, textStatus, error) { | ||||
|                     handleCatalogResponse(jqxhr,catalog,index); | ||||
|                 }).always(function() { | ||||
|                     handled++; | ||||
|                     if (handled === catalogueCount) { | ||||
|                         searchInput.searchBox('change'); | ||||
|                     } | ||||
|                 }) | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function refreshFilteredItems() { | ||||
|         packageList.editableList('empty'); | ||||
|         var currentFilter = searchInput.searchBox('value').trim(); | ||||
|         if (currentFilter === ""){ | ||||
|             packageList.editableList('addItem',{count:loadedList.length}) | ||||
|             return; | ||||
|         } | ||||
|         filteredList.sort(activeSort); | ||||
|         for (var i=0;i<Math.min(10,filteredList.length);i++) { | ||||
|             packageList.editableList('addItem',filteredList[i]); | ||||
|         } | ||||
|         if (filteredList.length === 0) { | ||||
|             packageList.editableList('addItem',{}); | ||||
|         } | ||||
|  | ||||
|         if (filteredList.length > 10) { | ||||
|             packageList.editableList('addItem',{start:10,more:filteredList.length-10}) | ||||
|         } | ||||
|     } | ||||
|     function sortModulesAZ(A,B) { | ||||
|         return A.info.id.localeCompare(B.info.id); | ||||
|     } | ||||
|     function sortModulesRecent(A,B) { | ||||
|         return -1 * (A.info.timestamp-B.info.timestamp); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     function init() { | ||||
|         if (RED.settings.theme('palette.editable') === false) { | ||||
|             return; | ||||
|         } | ||||
|         createSettingsPane(); | ||||
|  | ||||
|         RED.userSettings.add({ | ||||
|             id:'palette', | ||||
|             title: RED._("palette.editor.palette"), | ||||
|             get: getSettingsPane, | ||||
|             close: function() { | ||||
|                 settingsPane.detach(); | ||||
|             }, | ||||
|             focus: function() { | ||||
|                 editorTabs.resize(); | ||||
|                 setTimeout(function() { | ||||
|                     filterInput.focus(); | ||||
|                 },200); | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|         RED.actions.add("core:manage-palette",function() { | ||||
|                 RED.userSettings.show('palette'); | ||||
|             }); | ||||
|  | ||||
|         RED.events.on('registry:module-updated', function(ns) { | ||||
|             refreshNodeModule(ns.module); | ||||
|         }); | ||||
|         RED.events.on('registry:node-set-enabled', function(ns) { | ||||
|             refreshNodeModule(ns.module); | ||||
|         }); | ||||
|         RED.events.on('registry:node-set-disabled', function(ns) { | ||||
|             refreshNodeModule(ns.module); | ||||
|         }); | ||||
|         RED.events.on('registry:node-type-added', function(nodeType) { | ||||
|             if (!/^subflow:/.test(nodeType)) { | ||||
|                 var ns = RED.nodes.registry.getNodeSetForType(nodeType); | ||||
|                 refreshNodeModule(ns.module); | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('registry:node-type-removed', function(nodeType) { | ||||
|             if (!/^subflow:/.test(nodeType)) { | ||||
|                 var ns = RED.nodes.registry.getNodeSetForType(nodeType); | ||||
|                 refreshNodeModule(ns.module); | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('registry:node-set-added', function(ns) { | ||||
|             refreshNodeModule(ns.module); | ||||
|             for (var i=0;i<filteredList.length;i++) { | ||||
|                 if (filteredList[i].info.id === ns.module) { | ||||
|                     var installButton = filteredList[i].elements.installButton; | ||||
|                     installButton.addClass('disabled'); | ||||
|                     installButton.html(RED._('palette.editor.installed')); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('registry:node-set-removed', function(ns) { | ||||
|             var module = RED.nodes.registry.getModule(ns.module); | ||||
|             if (!module) { | ||||
|                 var entry = nodeEntries[ns.module]; | ||||
|                 if (entry) { | ||||
|                     nodeList.editableList('removeItem', entry); | ||||
|                     delete nodeEntries[ns.module]; | ||||
|                     for (var i=0;i<filteredList.length;i++) { | ||||
|                         if (filteredList[i].info.id === ns.module) { | ||||
|                             var installButton = filteredList[i].elements.installButton; | ||||
|                             installButton.removeClass('disabled'); | ||||
|                             installButton.html(RED._('palette.editor.install')); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('nodes:add', function(n) { | ||||
|             if (!/^subflow:/.test(n.type)) { | ||||
|                 typesInUse[n.type] = (typesInUse[n.type]||0)+1; | ||||
|                 if (typesInUse[n.type] === 1) { | ||||
|                     var ns = RED.nodes.registry.getNodeSetForType(n.type); | ||||
|                     refreshNodeModule(ns.module); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         RED.events.on('nodes:remove', function(n) { | ||||
|             if (typesInUse.hasOwnProperty(n.type)) { | ||||
|                 typesInUse[n.type]--; | ||||
|                 if (typesInUse[n.type] === 0) { | ||||
|                     delete typesInUse[n.type]; | ||||
|                     var ns = RED.nodes.registry.getNodeSetForType(n.type); | ||||
|                     refreshNodeModule(ns.module); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     var settingsPane; | ||||
|  | ||||
|     function getSettingsPane() { | ||||
|         initInstallTab(); | ||||
|         editorTabs.activateTab('nodes'); | ||||
|         return settingsPane; | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     function createSettingsPane() { | ||||
|         settingsPane = $('<div id="user-settings-tab-palette"></div>'); | ||||
|         var content = $('<div id="palette-editor">'+ | ||||
|             '<ul id="palette-editor-tabs"></ul>'+ | ||||
|         '</div>').appendTo(settingsPane); | ||||
|  | ||||
|         editorTabs = RED.tabs.create({ | ||||
|             element: settingsPane.find('#palette-editor-tabs'), | ||||
|             onchange:function(tab) { | ||||
|                 content.find(".palette-editor-tab").hide(); | ||||
|                 tab.content.show(); | ||||
|                 if (filterInput) { | ||||
|                     filterInput.searchBox('value',""); | ||||
|                 } | ||||
|                 if (searchInput) { | ||||
|                     searchInput.searchBox('value',""); | ||||
|                 } | ||||
|                 if (tab.id === 'install') { | ||||
|                     if (searchInput) { | ||||
|                         searchInput.focus(); | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (filterInput) { | ||||
|                         filterInput.focus(); | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             minimumActiveTabWidth: 110 | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         var modulesTab = $('<div>',{class:"palette-editor-tab"}).appendTo(content); | ||||
|  | ||||
|         editorTabs.addTab({ | ||||
|             id: 'nodes', | ||||
|             label: RED._('palette.editor.tab-nodes'), | ||||
|             content: modulesTab | ||||
|         }) | ||||
|  | ||||
|         var filterDiv = $('<div>',{class:"palette-search"}).appendTo(modulesTab); | ||||
|         filterInput = $('<input type="text" data-i18n="[placeholder]palette.filter"></input>') | ||||
|             .appendTo(filterDiv) | ||||
|             .searchBox({ | ||||
|                 delay: 200, | ||||
|                 change: function() { | ||||
|                     filterChange($(this).val()); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|  | ||||
|         nodeList = $('<ol>',{id:"palette-module-list", style:"position: absolute;top: 35px;bottom: 0;left: 0;right: 0px;"}).appendTo(modulesTab).editableList({ | ||||
|             addButton: false, | ||||
|             scrollOnAdd: false, | ||||
|             sort: function(A,B) { | ||||
|                 return A.info.name.localeCompare(B.info.name); | ||||
|             }, | ||||
|             filter: function(data) { | ||||
|                 if (activeFilter === "" ) { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1); | ||||
|             }, | ||||
|             addItem: function(container,i,object) { | ||||
|                 var entry = object.info; | ||||
|                 if (entry) { | ||||
|                     var headerRow = $('<div>',{class:"palette-module-header"}).appendTo(container); | ||||
|                     var titleRow = $('<div class="palette-module-meta palette-module-name"><i class="fa fa-cube"></i></div>').appendTo(headerRow); | ||||
|                     $('<span>').html(entry.name).appendTo(titleRow); | ||||
|                     var metaRow = $('<div class="palette-module-meta palette-module-version"><i class="fa fa-tag"></i></div>').appendTo(headerRow); | ||||
|                     var versionSpan = $('<span>').html(entry.version).appendTo(metaRow); | ||||
|                     var buttonRow = $('<div>',{class:"palette-module-meta"}).appendTo(headerRow); | ||||
|                     var setButton = $('<a href="#" class="editor-button editor-button-small palette-module-set-button"><i class="fa fa-angle-right palette-module-node-chevron"></i> </a>').appendTo(buttonRow); | ||||
|                     var setCount = $('<span>').appendTo(setButton); | ||||
|                     var buttonGroup = $('<div>',{class:"palette-module-button-group"}).appendTo(buttonRow); | ||||
|  | ||||
|                     var updateButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.update')).appendTo(buttonGroup); | ||||
|                     updateButton.attr('id','up_'+Math.floor(Math.random()*1000000000)); | ||||
|                     updateButton.click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         if ($(this).hasClass('disabled')) { | ||||
|                             return; | ||||
|                         } | ||||
|                         $("#palette-module-install-confirm").data('module',entry.name); | ||||
|                         $("#palette-module-install-confirm").data('version',loadedIndex[entry.name].version); | ||||
|                         $("#palette-module-install-confirm").data('shade',shade); | ||||
|  | ||||
|                         $("#palette-module-install-confirm-body").html(entry.local? | ||||
|                             RED._("palette.editor.confirm.update.body"): | ||||
|                             RED._("palette.editor.confirm.cannotUpdate.body") | ||||
|                         ); | ||||
|                         $(".palette-module-install-confirm-button-install").hide(); | ||||
|                         $(".palette-module-install-confirm-button-remove").hide(); | ||||
|                         if (entry.local) { | ||||
|                             $(".palette-module-install-confirm-button-update").show(); | ||||
|                         } else { | ||||
|                             $(".palette-module-install-confirm-button-update").hide(); | ||||
|                         } | ||||
|                         $("#palette-module-install-confirm") | ||||
|                             .dialog('option', 'title',RED._("palette.editor.confirm.update.title")) | ||||
|                             .dialog('open'); | ||||
|                     }) | ||||
|  | ||||
|  | ||||
|                     var removeButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.remove')).appendTo(buttonGroup); | ||||
|                     removeButton.attr('id','up_'+Math.floor(Math.random()*1000000000)); | ||||
|                     removeButton.click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|  | ||||
|                         $("#palette-module-install-confirm").data('module',entry.name); | ||||
|                         $("#palette-module-install-confirm").data('shade',shade); | ||||
|                         $("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.remove.body")); | ||||
|                         $(".palette-module-install-confirm-button-install").hide(); | ||||
|                         $(".palette-module-install-confirm-button-remove").show(); | ||||
|                         $(".palette-module-install-confirm-button-update").hide(); | ||||
|                         $("#palette-module-install-confirm") | ||||
|                             .dialog('option', 'title', RED._("palette.editor.confirm.remove.title")) | ||||
|                             .dialog('open'); | ||||
|                     }) | ||||
|                     if (!entry.local) { | ||||
|                         removeButton.hide(); | ||||
|                     } | ||||
|                     var enableButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.disableall')).appendTo(buttonGroup); | ||||
|  | ||||
|                     var contentRow = $('<div>',{class:"palette-module-content"}).appendTo(container); | ||||
|                     var shade = $('<div class="palette-module-shade hide"><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(container); | ||||
|  | ||||
|                     object.elements = { | ||||
|                         updateButton: updateButton, | ||||
|                         removeButton: removeButton, | ||||
|                         enableButton: enableButton, | ||||
|                         setCount: setCount, | ||||
|                         container: container, | ||||
|                         shade: shade, | ||||
|                         versionSpan: versionSpan, | ||||
|                         sets: {} | ||||
|                     } | ||||
|                     setButton.click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         if (container.hasClass('expanded')) { | ||||
|                             container.removeClass('expanded'); | ||||
|                             contentRow.slideUp(); | ||||
|                         } else { | ||||
|                             container.addClass('expanded'); | ||||
|                             contentRow.slideDown(); | ||||
|                         } | ||||
|                     }) | ||||
|  | ||||
|                     var setList = Object.keys(entry.sets) | ||||
|                     setList.sort(function(A,B) { | ||||
|                         return A.toLowerCase().localeCompare(B.toLowerCase()); | ||||
|                     }); | ||||
|                     setList.forEach(function(setName) { | ||||
|                         var set = entry.sets[setName]; | ||||
|                         var setRow = $('<div>',{class:"palette-module-set"}).appendTo(contentRow); | ||||
|                         var buttonGroup = $('<div>',{class:"palette-module-set-button-group"}).appendTo(setRow); | ||||
|                         var typeSwatches = {}; | ||||
|                         set.types.forEach(function(t) { | ||||
|                             var typeDiv = $('<div>',{class:"palette-module-type"}).appendTo(setRow); | ||||
|                             typeSwatches[t] = $('<span>',{class:"palette-module-type-swatch"}).appendTo(typeDiv); | ||||
|                             $('<span>',{class:"palette-module-type-node"}).html(t).appendTo(typeDiv); | ||||
|                         }) | ||||
|  | ||||
|                         var enableButton = $('<a href="#" class="editor-button editor-button-small"></a>').appendTo(buttonGroup); | ||||
|                         enableButton.click(function(evt) { | ||||
|                             evt.preventDefault(); | ||||
|                             if (object.setUseCount[setName] === 0) { | ||||
|                                 var currentSet = RED.nodes.registry.getNodeSet(set.id); | ||||
|                                 shade.show(); | ||||
|                                 var newState = !currentSet.enabled | ||||
|                                 changeNodeState(set.id,newState,shade,function(xhr){ | ||||
|                                     if (xhr) { | ||||
|                                         if (xhr.responseJSON) { | ||||
|                                             RED.notify(RED._('palette.editor.errors.'+(newState?'enable':'disable')+'Failed',{module: id,message:xhr.responseJSON.message})); | ||||
|                                         } | ||||
|                                     } | ||||
|                                 }); | ||||
|                             } | ||||
|                         }) | ||||
|  | ||||
|                         object.elements.sets[set.name] = { | ||||
|                             setRow: setRow, | ||||
|                             enableButton: enableButton, | ||||
|                             swatches: typeSwatches | ||||
|                         }; | ||||
|                     }); | ||||
|                     enableButton.click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         if (object.totalUseCount === 0) { | ||||
|                             changeNodeState(entry.name,(container.hasClass('disabled')),shade,function(xhr){ | ||||
|                                 if (xhr) { | ||||
|                                     if (xhr.responseJSON) { | ||||
|                                         RED.notify(RED._('palette.editor.errors.installFailed',{module: id,message:xhr.responseJSON.message})); | ||||
|                                     } | ||||
|                                 } | ||||
|                             }); | ||||
|                         } | ||||
|                     }) | ||||
|                     refreshNodeModule(entry.name); | ||||
|                 } else { | ||||
|                     $('<div>',{class:"red-ui-search-empty"}).html(RED._('search.empty')).appendTo(container); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|  | ||||
|         var installTab = $('<div>',{class:"palette-editor-tab hide"}).appendTo(content); | ||||
|  | ||||
|         editorTabs.addTab({ | ||||
|             id: 'install', | ||||
|             label: RED._('palette.editor.tab-install'), | ||||
|             content: installTab | ||||
|         }) | ||||
|  | ||||
|         var toolBar = $('<div>',{class:"palette-editor-toolbar"}).appendTo(installTab); | ||||
|  | ||||
|         var searchDiv = $('<div>',{class:"palette-search"}).appendTo(installTab); | ||||
|         searchInput = $('<input type="text" data-i18n="[placeholder]palette.search"></input>') | ||||
|             .appendTo(searchDiv) | ||||
|             .searchBox({ | ||||
|                 delay: 300, | ||||
|                 change: function() { | ||||
|                     var searchTerm = $(this).val().trim().toLowerCase(); | ||||
|                     if (searchTerm.length > 0) { | ||||
|                         filteredList = loadedList.filter(function(m) { | ||||
|                             return (m.index.indexOf(searchTerm) > -1); | ||||
|                         }).map(function(f) { return {info:f}}); | ||||
|                         refreshFilteredItems(); | ||||
|                         searchInput.searchBox('count',filteredList.length+" / "+loadedList.length); | ||||
|                     } else { | ||||
|                         searchInput.searchBox('count',loadedList.length); | ||||
|                         packageList.editableList('empty'); | ||||
|                         packageList.editableList('addItem',{count:loadedList.length}); | ||||
|  | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|  | ||||
|         $('<span>').html(RED._("palette.editor.sort")+' ').appendTo(toolBar); | ||||
|         var sortGroup = $('<span class="button-group"></span>').appendTo(toolBar); | ||||
|         var sortAZ = $('<a href="#" class="sidebar-header-button-toggle selected" data-i18n="palette.editor.sortAZ"></a>').appendTo(sortGroup); | ||||
|         var sortRecent = $('<a href="#" class="sidebar-header-button-toggle" data-i18n="palette.editor.sortRecent"></a>').appendTo(sortGroup); | ||||
|  | ||||
|         sortAZ.click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             if ($(this).hasClass("selected")) { | ||||
|                 return; | ||||
|             } | ||||
|             $(this).addClass("selected"); | ||||
|             sortRecent.removeClass("selected"); | ||||
|             activeSort = sortModulesAZ; | ||||
|             refreshFilteredItems(); | ||||
|         }); | ||||
|  | ||||
|         sortRecent.click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             if ($(this).hasClass("selected")) { | ||||
|                 return; | ||||
|             } | ||||
|             $(this).addClass("selected"); | ||||
|             sortAZ.removeClass("selected"); | ||||
|             activeSort = sortModulesRecent; | ||||
|             refreshFilteredItems(); | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         var refreshSpan = $('<span>').appendTo(toolBar); | ||||
|         var refreshButton = $('<a href="#" class="sidebar-header-button"><i class="fa fa-refresh"></i></a>').appendTo(refreshSpan); | ||||
|         refreshButton.click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             loadedList = []; | ||||
|             loadedIndex = {}; | ||||
|             initInstallTab(); | ||||
|         }) | ||||
|  | ||||
|         packageList = $('<ol>',{style:"position: absolute;top: 78px;bottom: 0;left: 0;right: 0px;"}).appendTo(installTab).editableList({ | ||||
|             addButton: false, | ||||
|             scrollOnAdd: false, | ||||
|             addItem: function(container,i,object) { | ||||
|                 if (object.count) { | ||||
|                     $('<div>',{class:"red-ui-search-empty"}).html(RED._('palette.editor.moduleCount',{count:object.count})).appendTo(container); | ||||
|                     return | ||||
|                 } | ||||
|                 if (object.more) { | ||||
|                     container.addClass('palette-module-more'); | ||||
|                     var moreRow = $('<div>',{class:"palette-module-header palette-module"}).appendTo(container); | ||||
|                     var moreLink = $('<a href="#"></a>').html(RED._('palette.editor.more',{count:object.more})).appendTo(moreRow); | ||||
|                     moreLink.click(function(e) { | ||||
|                         e.preventDefault(); | ||||
|                         packageList.editableList('removeItem',object); | ||||
|                         for (var i=object.start;i<Math.min(object.start+10,object.start+object.more);i++) { | ||||
|                             packageList.editableList('addItem',filteredList[i]); | ||||
|                         } | ||||
|                         if (object.more > 10) { | ||||
|                             packageList.editableList('addItem',{start:object.start+10, more:object.more-10}) | ||||
|                         } | ||||
|                     }) | ||||
|                     return; | ||||
|                 } | ||||
|                 if (object.info) { | ||||
|                     var entry = object.info; | ||||
|                     var headerRow = $('<div>',{class:"palette-module-header"}).appendTo(container); | ||||
|                     var titleRow = $('<div class="palette-module-meta"><i class="fa fa-cube"></i></div>').appendTo(headerRow); | ||||
|                     $('<span>',{class:"palette-module-name"}).html(entry.name||entry.id).appendTo(titleRow); | ||||
|                     $('<a target="_blank" class="palette-module-link"><i class="fa fa-external-link"></i></a>').attr('href',entry.url).appendTo(titleRow); | ||||
|                     var descRow = $('<div class="palette-module-meta"></div>').appendTo(headerRow); | ||||
|                     $('<div>',{class:"palette-module-description"}).html(entry.description).appendTo(descRow); | ||||
|  | ||||
|                     var metaRow = $('<div class="palette-module-meta"></div>').appendTo(headerRow); | ||||
|                     $('<span class="palette-module-version"><i class="fa fa-tag"></i> '+entry.version+'</span>').appendTo(metaRow); | ||||
|                     $('<span class="palette-module-updated"><i class="fa fa-calendar"></i> '+formatUpdatedAt(entry.updated_at)+'</span>').appendTo(metaRow); | ||||
|                     var buttonRow = $('<div>',{class:"palette-module-meta"}).appendTo(headerRow); | ||||
|                     var buttonGroup = $('<div>',{class:"palette-module-button-group"}).appendTo(buttonRow); | ||||
|                     var shade = $('<div class="palette-module-shade hide"><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(container); | ||||
|                     var installButton = $('<a href="#" class="editor-button editor-button-small"></a>').html(RED._('palette.editor.install')).appendTo(buttonGroup); | ||||
|                     installButton.click(function(e) { | ||||
|                         e.preventDefault(); | ||||
|                         if (!$(this).hasClass('disabled')) { | ||||
|                             $("#palette-module-install-confirm").data('module',entry.id); | ||||
|                             $("#palette-module-install-confirm").data('version',entry.version); | ||||
|                             $("#palette-module-install-confirm").data('url',entry.url); | ||||
|                             $("#palette-module-install-confirm").data('shade',shade); | ||||
|                             $("#palette-module-install-confirm-body").html(RED._("palette.editor.confirm.install.body")); | ||||
|                             $(".palette-module-install-confirm-button-install").show(); | ||||
|                             $(".palette-module-install-confirm-button-remove").hide(); | ||||
|                             $(".palette-module-install-confirm-button-update").hide(); | ||||
|                             $("#palette-module-install-confirm") | ||||
|                                 .dialog('option', 'title', RED._("palette.editor.confirm.install.title")) | ||||
|                                 .dialog('open'); | ||||
|                         } | ||||
|                     }) | ||||
|                     if (nodeEntries.hasOwnProperty(entry.id)) { | ||||
|                         installButton.addClass('disabled'); | ||||
|                         installButton.html(RED._('palette.editor.installed')); | ||||
|                     } | ||||
|  | ||||
|                     object.elements = { | ||||
|                         installButton:installButton | ||||
|                     } | ||||
|                 } else { | ||||
|                     $('<div>',{class:"red-ui-search-empty"}).html(RED._('search.empty')).appendTo(container); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         $('<div id="palette-module-install-shade" class="palette-module-shade hide"><div class="palette-module-shade-status"></div><img src="red/images/spin.svg" class="palette-spinner"/></div>').appendTo(installTab); | ||||
|  | ||||
|         $('<div id="palette-module-install-confirm" class="hide"><form class="form-horizontal"><div id="palette-module-install-confirm-body" class="node-dialog-confirm-row"></div></form></div>').appendTo(document.body); | ||||
|         $("#palette-module-install-confirm").dialog({ | ||||
|             title: RED._('palette.editor.confirm.title'), | ||||
|             modal: true, | ||||
|             autoOpen: false, | ||||
|             width: 550, | ||||
|             height: "auto", | ||||
|             buttons: [ | ||||
|                 { | ||||
|                     text: RED._("common.label.cancel"), | ||||
|                     click: function() { | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("palette.editor.confirm.button.review"), | ||||
|                     class: "primary palette-module-install-confirm-button-install", | ||||
|                     click: function() { | ||||
|                         var url = $(this).data('url'); | ||||
|                         window.open(url); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("palette.editor.confirm.button.install"), | ||||
|                     class: "primary palette-module-install-confirm-button-install", | ||||
|                     click: function() { | ||||
|                         var id = $(this).data('module'); | ||||
|                         var version = $(this).data('version'); | ||||
|                         var shade = $(this).data('shade'); | ||||
|                         installNodeModule(id,version,shade,function(xhr) { | ||||
|                              if (xhr) { | ||||
|                                  if (xhr.responseJSON) { | ||||
|                                      RED.notify(RED._('palette.editor.errors.installFailed',{module: id,message:xhr.responseJSON.message})); | ||||
|                                  } | ||||
|                              } | ||||
|                         }); | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("palette.editor.confirm.button.remove"), | ||||
|                     class: "primary palette-module-install-confirm-button-remove", | ||||
|                     click: function() { | ||||
|                         var id = $(this).data('module'); | ||||
|                         var shade = $(this).data('shade'); | ||||
|                         shade.show(); | ||||
|                         removeNodeModule(id, function(xhr) { | ||||
|                             shade.hide(); | ||||
|                             if (xhr) { | ||||
|                                 if (xhr.responseJSON) { | ||||
|                                     RED.notify(RED._('palette.editor.errors.removeFailed',{module: id,message:xhr.responseJSON.message})); | ||||
|                                 } | ||||
|                             } | ||||
|                         }) | ||||
|  | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     text: RED._("palette.editor.confirm.button.update"), | ||||
|                     class: "primary palette-module-install-confirm-button-update", | ||||
|                     click: function() { | ||||
|                         var id = $(this).data('module'); | ||||
|                         var version = $(this).data('version'); | ||||
|                         var shade = $(this).data('shade'); | ||||
|                         shade.show(); | ||||
|                         installNodeModule(id,version,shade,function(xhr) { | ||||
|                              if (xhr) { | ||||
|                                  if (xhr.responseJSON) { | ||||
|                                      RED.notify(RED._('palette.editor.errors.updateFailed',{module: id,message:xhr.responseJSON.message})); | ||||
|                                  } | ||||
|                              } | ||||
|                         }); | ||||
|                         $( this ).dialog( "close" ); | ||||
|                     } | ||||
|                 } | ||||
|             ] | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init | ||||
|     } | ||||
| })(); | ||||
| @@ -1,479 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| RED.palette = (function() { | ||||
|  | ||||
|     var exclusion = ['config','unknown','deprecated']; | ||||
|     var coreCategories = ['subflows', 'input', 'output', 'function', 'social', 'mobile', 'storage', 'analysis', 'advanced']; | ||||
|  | ||||
|     var categoryContainers = {}; | ||||
|  | ||||
|     function createCategoryContainer(category, label){ | ||||
|         label = (label || category).replace(/_/g, " "); | ||||
|         var catDiv = $('<div id="palette-container-'+category+'" class="palette-category palette-close hide">'+ | ||||
|             '<div id="palette-header-'+category+'" class="palette-header"><i class="expanded fa fa-angle-down"></i><span>'+label+'</span></div>'+ | ||||
|             '<div class="palette-content" id="palette-base-category-'+category+'">'+ | ||||
|             '<div id="palette-'+category+'-input"></div>'+ | ||||
|             '<div id="palette-'+category+'-output"></div>'+ | ||||
|             '<div id="palette-'+category+'-function"></div>'+ | ||||
|             '</div>'+ | ||||
|             '</div>').appendTo("#palette-container"); | ||||
|  | ||||
|         categoryContainers[category] = { | ||||
|             container: catDiv, | ||||
|             close: function() { | ||||
|                 catDiv.removeClass("palette-open"); | ||||
|                 catDiv.addClass("palette-closed"); | ||||
|                 $("#palette-base-category-"+category).slideUp(); | ||||
|                 $("#palette-header-"+category+" i").removeClass("expanded"); | ||||
|             }, | ||||
|             open: function() { | ||||
|                 catDiv.addClass("palette-open"); | ||||
|                 catDiv.removeClass("palette-closed"); | ||||
|                 $("#palette-base-category-"+category).slideDown(); | ||||
|                 $("#palette-header-"+category+" i").addClass("expanded"); | ||||
|             }, | ||||
|             toggle: function() { | ||||
|                 if (catDiv.hasClass("palette-open")) { | ||||
|                     categoryContainers[category].close(); | ||||
|                 } else { | ||||
|                     categoryContainers[category].open(); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         $("#palette-header-"+category).on('click', function(e) { | ||||
|             categoryContainers[category].toggle(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function setLabel(type, el,label, info) { | ||||
|         var nodeWidth = 82; | ||||
|         var nodeHeight = 25; | ||||
|         var lineHeight = 20; | ||||
|         var portHeight = 10; | ||||
|  | ||||
|         var words = label.split(/[ -]/); | ||||
|  | ||||
|         var displayLines = []; | ||||
|  | ||||
|         var currentLine = words[0]; | ||||
|         var currentLineWidth = RED.view.calculateTextWidth(currentLine, "palette_label", 0); | ||||
|  | ||||
|         for (var i=1;i<words.length;i++) { | ||||
|             var newWidth = RED.view.calculateTextWidth(currentLine+" "+words[i], "palette_label", 0); | ||||
|             if (newWidth < nodeWidth) { | ||||
|                 currentLine += " "+words[i]; | ||||
|                 currentLineWidth = newWidth; | ||||
|             } else { | ||||
|                 displayLines.push(currentLine); | ||||
|                 currentLine = words[i]; | ||||
|                 currentLineWidth = RED.view.calculateTextWidth(currentLine, "palette_label", 0); | ||||
|             } | ||||
|         } | ||||
|         displayLines.push(currentLine); | ||||
|  | ||||
|         var lines = displayLines.join("<br/>"); | ||||
|         var multiLineNodeHeight = 8+(lineHeight*displayLines.length); | ||||
|         el.css({height:multiLineNodeHeight+"px"}); | ||||
|  | ||||
|         var labelElement = el.find(".palette_label"); | ||||
|         labelElement.html(lines).attr('dir', RED.text.bidi.resolveBaseTextDir(lines)); | ||||
|  | ||||
|         el.find(".palette_port").css({top:(multiLineNodeHeight/2-5)+"px"}); | ||||
|  | ||||
|         var popOverContent; | ||||
|         try { | ||||
|             var l = "<p><b>"+RED.text.bidi.enforceTextDirectionWithUCC(label)+"</b></p>"; | ||||
|             if (label != type) { | ||||
|                 l = "<p><b>"+RED.text.bidi.enforceTextDirectionWithUCC(label)+"</b><br/><i>"+type+"</i></p>"; | ||||
|             } | ||||
|             popOverContent = $(l+(info?info:$("script[data-help-name='"+type+"']").html()||"<p>"+RED._("palette.noInfo")+"</p>").trim()) | ||||
|                                 .filter(function(n) { | ||||
|                                     return (this.nodeType == 1 && this.nodeName == "P") || (this.nodeType == 3 && this.textContent.trim().length > 0) | ||||
|                                 }).slice(0,2); | ||||
|         } catch(err) { | ||||
|             // Malformed HTML may cause errors. TODO: need to understand what can break | ||||
|             // NON-NLS: internal debug | ||||
|             console.log("Error generating pop-over label for ",type); | ||||
|             console.log(err.toString()); | ||||
|             popOverContent = "<p><b>"+label+"</b></p><p>"+RED._("palette.noInfo")+"</p>"; | ||||
|         } | ||||
|  | ||||
|         el.data('popover').setContent(popOverContent); | ||||
|     } | ||||
|  | ||||
|     function escapeNodeType(nt) { | ||||
|         return nt.replace(" ","_").replace(".","_").replace(":","_"); | ||||
|     } | ||||
|  | ||||
|     function addNodeType(nt,def) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         if ($("#palette_node_"+nodeTypeId).length) { | ||||
|             return; | ||||
|         } | ||||
|         if (exclusion.indexOf(def.category)===-1) { | ||||
|  | ||||
|             var category = def.category.replace(/ /g,"_"); | ||||
|             var rootCategory = category.split("-")[0]; | ||||
|  | ||||
|             var d = document.createElement("div"); | ||||
|             d.id = "palette_node_"+nodeTypeId; | ||||
|             d.type = nt; | ||||
|  | ||||
|             var label = /^(.*?)([ -]in|[ -]out)?$/.exec(nt)[1]; | ||||
|             if (typeof def.paletteLabel !== "undefined") { | ||||
|                 try { | ||||
|                     label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||""; | ||||
|                 } catch(err) { | ||||
|                     console.log("Definition error: "+nt+".paletteLabel",err); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $('<div/>',{class:"palette_label"+(def.align=="right"?" palette_label_right":"")}).appendTo(d); | ||||
|  | ||||
|             d.className="palette_node"; | ||||
|  | ||||
|  | ||||
|             if (def.icon) { | ||||
|                 var icon_url = RED.utils.getNodeIcon(def); | ||||
|                 var iconContainer = $('<div/>',{class:"palette_icon_container"+(def.align=="right"?" palette_icon_container_right":"")}).appendTo(d); | ||||
|                 $('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); | ||||
|             } | ||||
|  | ||||
|             d.style.backgroundColor = def.color; | ||||
|  | ||||
|             if (def.outputs > 0) { | ||||
|                 var portOut = document.createElement("div"); | ||||
|                 portOut.className = "palette_port palette_port_output"; | ||||
|                 d.appendChild(portOut); | ||||
|             } | ||||
|  | ||||
|             if (def.inputs > 0) { | ||||
|                 var portIn = document.createElement("div"); | ||||
|                 portIn.className = "palette_port palette_port_input"; | ||||
|                 d.appendChild(portIn); | ||||
|             } | ||||
|  | ||||
|             if ($("#palette-base-category-"+rootCategory).length === 0) { | ||||
|                 if(coreCategories.indexOf(rootCategory) !== -1){ | ||||
|                     createCategoryContainer(rootCategory, RED._("node-red:palette.label."+rootCategory, {defaultValue:rootCategory})); | ||||
|                 } else { | ||||
|                     var ns = def.set.id; | ||||
|                     createCategoryContainer(rootCategory, RED._(ns+":palette.label."+rootCategory, {defaultValue:rootCategory})); | ||||
|                 } | ||||
|             } | ||||
|             $("#palette-container-"+rootCategory).show(); | ||||
|  | ||||
|             if ($("#palette-"+category).length === 0) { | ||||
|                 $("#palette-base-category-"+rootCategory).append('<div id="palette-'+category+'"></div>'); | ||||
|             } | ||||
|  | ||||
|             $("#palette-"+category).append(d); | ||||
|             d.onmousedown = function(e) { e.preventDefault(); }; | ||||
|  | ||||
|             var popover = RED.popover.create({ | ||||
|                 target:$(d), | ||||
|                 trigger: "hover", | ||||
|                 width: "300px", | ||||
|                 content: "hi", | ||||
|                 delay: { show: 750, hide: 50 } | ||||
|             }); | ||||
|             $(d).data('popover',popover); | ||||
|  | ||||
|             // $(d).popover({ | ||||
|             //     title:d.type, | ||||
|             //     placement:"right", | ||||
|             //     trigger: "hover", | ||||
|             //     delay: { show: 750, hide: 50 }, | ||||
|             //     html: true, | ||||
|             //     container:'body' | ||||
|             // }); | ||||
|             $(d).click(function() { | ||||
|                 RED.view.focus(); | ||||
|                 var helpText; | ||||
|                 if (nt.indexOf("subflow:") === 0) { | ||||
|                     helpText = marked(RED.nodes.subflow(nt.substring(8)).info||""); | ||||
|                 } else { | ||||
|                     helpText = $("script[data-help-name='"+d.type+"']").html()||""; | ||||
|                 } | ||||
|                 RED.sidebar.info.set(helpText); | ||||
|             }); | ||||
|             var chart = $("#chart"); | ||||
|             var chartOffset = chart.offset(); | ||||
|             var chartSVG = $("#chart>svg").get(0); | ||||
|             var activeSpliceLink; | ||||
|             var mouseX; | ||||
|             var mouseY; | ||||
|             var spliceTimer; | ||||
|             $(d).draggable({ | ||||
|                 helper: 'clone', | ||||
|                 appendTo: 'body', | ||||
|                 revert: true, | ||||
|                 revertDuration: 50, | ||||
|                 containment:'#main-container', | ||||
|                 start: function() {RED.view.focus();}, | ||||
|                 stop: function() { d3.select('.link_splice').classed('link_splice',false); if (spliceTimer) { clearTimeout(spliceTimer); spliceTimer = null;}}, | ||||
|                 drag: function(e,ui) { | ||||
|  | ||||
|                     // TODO: this is the margin-left of palette node. Hard coding | ||||
|                     // it here makes me sad | ||||
|                     //console.log(ui.helper.position()); | ||||
|                     ui.position.left += 17.5; | ||||
|  | ||||
|                     if (def.inputs > 0 && def.outputs > 0) { | ||||
|                         mouseX = ui.position.left+(ui.helper.width()/2) - chartOffset.left + chart.scrollLeft(); | ||||
|                         mouseY = ui.position.top+(ui.helper.height()/2) - chartOffset.top + chart.scrollTop(); | ||||
|  | ||||
|                         if (!spliceTimer) { | ||||
|                             spliceTimer = setTimeout(function() { | ||||
|                                 var nodes = []; | ||||
|                                 var bestDistance = Infinity; | ||||
|                                 var bestLink = null; | ||||
|                                 if (chartSVG.getIntersectionList) { | ||||
|                                     var svgRect = chartSVG.createSVGRect(); | ||||
|                                     svgRect.x = mouseX; | ||||
|                                     svgRect.y = mouseY; | ||||
|                                     svgRect.width = 1; | ||||
|                                     svgRect.height = 1; | ||||
|                                     nodes = chartSVG.getIntersectionList(svgRect,chartSVG); | ||||
|                                     mouseX /= RED.view.scale(); | ||||
|                                     mouseY /= RED.view.scale(); | ||||
|                                 } else { | ||||
|                                     // Firefox doesn't do getIntersectionList and that | ||||
|                                     // makes us sad | ||||
|                                     mouseX /= RED.view.scale(); | ||||
|                                     mouseY /= RED.view.scale(); | ||||
|                                     nodes = RED.view.getLinksAtPoint(mouseX,mouseY); | ||||
|                                 } | ||||
|                                 for (var i=0;i<nodes.length;i++) { | ||||
|                                     if (d3.select(nodes[i]).classed('link_background')) { | ||||
|                                         var length = nodes[i].getTotalLength(); | ||||
|                                         for (var j=0;j<length;j+=10) { | ||||
|                                             var p = nodes[i].getPointAtLength(j); | ||||
|                                             var d2 = ((p.x-mouseX)*(p.x-mouseX))+((p.y-mouseY)*(p.y-mouseY)); | ||||
|                                             if (d2 < 200 && d2 < bestDistance) { | ||||
|                                                 bestDistance = d2; | ||||
|                                                 bestLink = nodes[i]; | ||||
|                                             } | ||||
|                                         } | ||||
|                                     } | ||||
|                                 } | ||||
|                                 if (activeSpliceLink && activeSpliceLink !== bestLink) { | ||||
|                                     d3.select(activeSpliceLink.parentNode).classed('link_splice',false); | ||||
|                                 } | ||||
|                                 if (bestLink) { | ||||
|                                     d3.select(bestLink.parentNode).classed('link_splice',true) | ||||
|                                 } else { | ||||
|                                     d3.select('.link_splice').classed('link_splice',false); | ||||
|                                 } | ||||
|                                 if (activeSpliceLink !== bestLink) { | ||||
|                                     if (bestLink) { | ||||
|                                         $(ui.helper).data('splice',d3.select(bestLink).data()[0]); | ||||
|                                     } else { | ||||
|                                         $(ui.helper).removeData('splice'); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 activeSpliceLink = bestLink; | ||||
|                                 spliceTimer = null; | ||||
|                             },200); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             var nodeInfo = null; | ||||
|             if (def.category == "subflows") { | ||||
|                 $(d).dblclick(function(e) { | ||||
|                     RED.workspaces.show(nt.substring(8)); | ||||
|                     e.preventDefault(); | ||||
|                 }); | ||||
|                 nodeInfo = marked(def.info||""); | ||||
|             } | ||||
|             setLabel(nt,$(d),label,nodeInfo); | ||||
|  | ||||
|             var categoryNode = $("#palette-container-"+category); | ||||
|             if (categoryNode.find(".palette_node").length === 1) { | ||||
|                 categoryContainers[category].open(); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function removeNodeType(nt) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         var paletteNode = $("#palette_node_"+nodeTypeId); | ||||
|         var categoryNode = paletteNode.closest(".palette-category"); | ||||
|         paletteNode.remove(); | ||||
|         if (categoryNode.find(".palette_node").length === 0) { | ||||
|             if (categoryNode.find("i").hasClass("expanded")) { | ||||
|                 categoryNode.find(".palette-content").slideToggle(); | ||||
|                 categoryNode.find("i").toggleClass("expanded"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     function hideNodeType(nt) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         $("#palette_node_"+nodeTypeId).hide(); | ||||
|     } | ||||
|  | ||||
|     function showNodeType(nt) { | ||||
|         var nodeTypeId = escapeNodeType(nt); | ||||
|         $("#palette_node_"+nodeTypeId).show(); | ||||
|     } | ||||
|  | ||||
|     function refreshNodeTypes() { | ||||
|         RED.nodes.eachSubflow(function(sf) { | ||||
|             var paletteNode = $("#palette_node_subflow_"+sf.id.replace(".","_")); | ||||
|             var portInput = paletteNode.find(".palette_port_input"); | ||||
|             var portOutput = paletteNode.find(".palette_port_output"); | ||||
|  | ||||
|             if (portInput.length === 0 && sf.in.length > 0) { | ||||
|                 var portIn = document.createElement("div"); | ||||
|                 portIn.className = "palette_port palette_port_input"; | ||||
|                 paletteNode.append(portIn); | ||||
|             } else if (portInput.length !== 0 && sf.in.length === 0) { | ||||
|                 portInput.remove(); | ||||
|             } | ||||
|  | ||||
|             if (portOutput.length === 0 && sf.out.length > 0) { | ||||
|                 var portOut = document.createElement("div"); | ||||
|                 portOut.className = "palette_port palette_port_output"; | ||||
|                 paletteNode.append(portOut); | ||||
|             } else if (portOutput.length !== 0 && sf.out.length === 0) { | ||||
|                 portOutput.remove(); | ||||
|             } | ||||
|             setLabel(sf.type+":"+sf.id,paletteNode,sf.name,marked(sf.info||"")); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     function filterChange(val) { | ||||
|         var re = new RegExp(val.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'),'i'); | ||||
|         $("#palette-container .palette_node").each(function(i,el) { | ||||
|             var currentLabel = $(el).find(".palette_label").text(); | ||||
|             if (val === "" || re.test(el.id) || re.test(currentLabel)) { | ||||
|                 $(this).show(); | ||||
|             } else { | ||||
|                 $(this).hide(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         for (var category in categoryContainers) { | ||||
|             if (categoryContainers.hasOwnProperty(category)) { | ||||
|                 if (categoryContainers[category].container | ||||
|                         .find(".palette_node") | ||||
|                         .filter(function() { return $(this).css('display') !== 'none'}).length === 0) { | ||||
|                     categoryContainers[category].close(); | ||||
|                 } else { | ||||
|                     categoryContainers[category].open(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function init() { | ||||
|  | ||||
|         RED.events.on('registry:node-type-added', function(nodeType) { | ||||
|             var def = RED.nodes.getType(nodeType); | ||||
|             addNodeType(nodeType,def); | ||||
|             if (def.onpaletteadd && typeof def.onpaletteadd === "function") { | ||||
|                 def.onpaletteadd.call(def); | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('registry:node-type-removed', function(nodeType) { | ||||
|             removeNodeType(nodeType); | ||||
|         }); | ||||
|  | ||||
|         RED.events.on('registry:node-set-enabled', function(nodeSet) { | ||||
|             for (var j=0;j<nodeSet.types.length;j++) { | ||||
|                 showNodeType(nodeSet.types[j]); | ||||
|                 var def = RED.nodes.getType(nodeSet.types[j]); | ||||
|                 if (def.onpaletteadd && typeof def.onpaletteadd === "function") { | ||||
|                     def.onpaletteadd.call(def); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('registry:node-set-disabled', function(nodeSet) { | ||||
|             for (var j=0;j<nodeSet.types.length;j++) { | ||||
|                 hideNodeType(nodeSet.types[j]); | ||||
|                 var def = RED.nodes.getType(nodeSet.types[j]); | ||||
|                 if (def.onpaletteremove && typeof def.onpaletteremove === "function") { | ||||
|                     def.onpaletteremove.call(def); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on('registry:node-set-removed', function(nodeSet) { | ||||
|             if (nodeSet.added) { | ||||
|                 for (var j=0;j<nodeSet.types.length;j++) { | ||||
|                     removeNodeType(nodeSet.types[j]); | ||||
|                     var def = RED.nodes.getType(nodeSet.types[j]); | ||||
|                     if (def.onpaletteremove && typeof def.onpaletteremove === "function") { | ||||
|                         def.onpaletteremove.call(def); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|         $("#palette > .palette-spinner").show(); | ||||
|  | ||||
|         $("#palette-search input").searchBox({ | ||||
|             delay: 100, | ||||
|             change: function() { | ||||
|                 filterChange($(this).val()); | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|         var categoryList = coreCategories; | ||||
|         if (RED.settings.paletteCategories) { | ||||
|             categoryList = RED.settings.paletteCategories; | ||||
|         } else if (RED.settings.theme('palette.categories')) { | ||||
|             categoryList = RED.settings.theme('palette.categories'); | ||||
|         } | ||||
|         if (!Array.isArray(categoryList)) { | ||||
|             categoryList = coreCategories | ||||
|         } | ||||
|         categoryList.forEach(function(category){ | ||||
|             createCategoryContainer(category, RED._("palette.label."+category,{defaultValue:category})); | ||||
|         }); | ||||
|  | ||||
|         $("#palette-collapse-all").on("click", function(e) { | ||||
|             e.preventDefault(); | ||||
|             for (var cat in categoryContainers) { | ||||
|                 if (categoryContainers.hasOwnProperty(cat)) { | ||||
|                     categoryContainers[cat].close(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         $("#palette-expand-all").on("click", function(e) { | ||||
|             e.preventDefault(); | ||||
|             for (var cat in categoryContainers) { | ||||
|                 if (categoryContainers.hasOwnProperty(cat)) { | ||||
|                     categoryContainers[cat].open(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         add:addNodeType, | ||||
|         remove:removeNodeType, | ||||
|         hide:hideNodeType, | ||||
|         show:showNodeType, | ||||
|         refresh:refreshNodeTypes | ||||
|     }; | ||||
| })(); | ||||
| @@ -1,286 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.search = (function() { | ||||
|  | ||||
|     var disabled = false; | ||||
|     var dialog = null; | ||||
|     var searchInput; | ||||
|     var searchResults; | ||||
|     var selected = -1; | ||||
|     var visible = false; | ||||
|  | ||||
|     var index = {}; | ||||
|     var keys = []; | ||||
|     var results = []; | ||||
|  | ||||
|     function indexNode(n) { | ||||
|         var l = RED.utils.getNodeLabel(n); | ||||
|         if (l) { | ||||
|             l = (""+l).toLowerCase(); | ||||
|             index[l] = index[l] || {}; | ||||
|             index[l][n.id] = {node:n,label:l} | ||||
|         } | ||||
|         l = l||n.label||n.name||n.id||""; | ||||
|  | ||||
|  | ||||
|         var properties = ['id','type','name','label','info']; | ||||
|         if (n._def && n._def.defaults) { | ||||
|             properties = properties.concat(Object.keys(n._def.defaults)); | ||||
|         } | ||||
|         for (var i=0;i<properties.length;i++) { | ||||
|             if (n.hasOwnProperty(properties[i])) { | ||||
|                 var v = n[properties[i]]; | ||||
|                 if (typeof v === 'string' || typeof v === 'number') { | ||||
|                     v = (""+v).toLowerCase(); | ||||
|                     index[v] = index[v] || {}; | ||||
|                     index[v][n.id] = {node:n,label:l}; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|     } | ||||
|     function indexWorkspace() { | ||||
|         index = {}; | ||||
|         RED.nodes.eachWorkspace(indexNode); | ||||
|         RED.nodes.eachSubflow(indexNode); | ||||
|         RED.nodes.eachConfig(indexNode); | ||||
|         RED.nodes.eachNode(indexNode); | ||||
|         keys = Object.keys(index); | ||||
|         keys.sort(); | ||||
|         keys.forEach(function(key) { | ||||
|             index[key] = Object.keys(index[key]).map(function(id) { | ||||
|                 return index[key][id]; | ||||
|             }) | ||||
|         }) | ||||
|     } | ||||
|  | ||||
|     function search(val) { | ||||
|         searchResults.editableList('empty'); | ||||
|         selected = -1; | ||||
|         results = []; | ||||
|         if (val.length > 0) { | ||||
|             val = val.toLowerCase(); | ||||
|             var i; | ||||
|             var j; | ||||
|             var list = []; | ||||
|             var nodes = {}; | ||||
|             for (i=0;i<keys.length;i++) { | ||||
|                 var key = keys[i]; | ||||
|                 var kpos = keys[i].indexOf(val); | ||||
|                 if (kpos > -1) { | ||||
|                     for (j=0;j<index[key].length;j++) { | ||||
|                         var node = index[key][j]; | ||||
|                         nodes[node.node.id] = nodes[node.node.id] = node; | ||||
|                         nodes[node.node.id].index = Math.min(nodes[node.node.id].index||Infinity,kpos); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             list = Object.keys(nodes); | ||||
|             list.sort(function(A,B) { | ||||
|                 return nodes[A].index - nodes[B].index; | ||||
|             }); | ||||
|  | ||||
|             for (i=0;i<list.length;i++) { | ||||
|                 results.push(nodes[list[i]]); | ||||
|             } | ||||
|             if (results.length > 0) { | ||||
|                 for (i=0;i<Math.min(results.length,25);i++) { | ||||
|                     searchResults.editableList('addItem',results[i]) | ||||
|                 } | ||||
|             } else { | ||||
|                 searchResults.editableList('addItem',{}); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     function ensureSelectedIsVisible() { | ||||
|         var selectedEntry = searchResults.find("li.selected"); | ||||
|         if (selectedEntry.length === 1) { | ||||
|             var scrollWindow = searchResults.parent(); | ||||
|             var scrollHeight = scrollWindow.height(); | ||||
|             var scrollOffset = scrollWindow.scrollTop(); | ||||
|             var y = selectedEntry.position().top; | ||||
|             var h = selectedEntry.height(); | ||||
|             if (y+h > scrollHeight) { | ||||
|                 scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50); | ||||
|             } else if (y<0) { | ||||
|                 scrollWindow.animate({scrollTop: '+='+(y-10)},50); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function createDialog() { | ||||
|         dialog = $("<div>",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#main-container"); | ||||
|         var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); | ||||
|         searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({ | ||||
|             delay: 200, | ||||
|             change: function() { | ||||
|                 search($(this).val()); | ||||
|             } | ||||
|         }); | ||||
|         searchInput.on('keydown',function(evt) { | ||||
|             var children; | ||||
|             if (results.length > 0) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // Down | ||||
|                     children = searchResults.children(); | ||||
|                     if (selected < children.length-1) { | ||||
|                         if (selected > -1) { | ||||
|                             $(children[selected]).removeClass('selected'); | ||||
|                         } | ||||
|                         selected++; | ||||
|                     } | ||||
|                     $(children[selected]).addClass('selected'); | ||||
|                     ensureSelectedIsVisible(); | ||||
|                     evt.preventDefault(); | ||||
|                 } else if (evt.keyCode === 38) { | ||||
|                     // Up | ||||
|                     children = searchResults.children(); | ||||
|                     if (selected > 0) { | ||||
|                         if (selected < children.length) { | ||||
|                             $(children[selected]).removeClass('selected'); | ||||
|                         } | ||||
|                         selected--; | ||||
|                     } | ||||
|                     $(children[selected]).addClass('selected'); | ||||
|                     ensureSelectedIsVisible(); | ||||
|                     evt.preventDefault(); | ||||
|                 } else if (evt.keyCode === 13) { | ||||
|                     // Enter | ||||
|                     if (results.length > 0) { | ||||
|                         reveal(results[Math.max(0,selected)].node); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         searchInput.i18n(); | ||||
|  | ||||
|         var searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog); | ||||
|         searchResults = $('<ol>',{id:"search-result-list", style:"position: absolute;top: 5px;bottom: 5px;left: 5px;right: 5px;"}).appendTo(searchResultsDiv).editableList({ | ||||
|             addButton: false, | ||||
|             addItem: function(container,i,object) { | ||||
|                 var node = object.node; | ||||
|                 if (node === undefined) { | ||||
|                     $('<div>',{class:"red-ui-search-empty"}).html(RED._('search.empty')).appendTo(container); | ||||
|  | ||||
|                 } else { | ||||
|                     var def = node._def; | ||||
|                     var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container); | ||||
|  | ||||
|                     var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div); | ||||
|                     var colour = def.color; | ||||
|                     var icon_url = RED.utils.getNodeIcon(def,node); | ||||
|                     if (node.type === 'tab') { | ||||
|                         colour = "#C0DEED"; | ||||
|                     } | ||||
|                     nodeDiv.css('backgroundColor',colour); | ||||
|  | ||||
|                     var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv); | ||||
|                     $('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); | ||||
|  | ||||
|                     var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div); | ||||
|                     if (node.z) { | ||||
|                         var workspace = RED.nodes.workspace(node.z); | ||||
|                         if (!workspace) { | ||||
|                             workspace = RED.nodes.subflow(node.z); | ||||
|                             workspace = "subflow:"+workspace.name; | ||||
|                         } else { | ||||
|                             workspace = "flow:"+workspace.label; | ||||
|                         } | ||||
|                         $('<div>',{class:"red-ui-search-result-node-flow"}).html(workspace).appendTo(contentDiv); | ||||
|                     } | ||||
|  | ||||
|                     $('<div>',{class:"red-ui-search-result-node-label"}).html(object.label || node.id).appendTo(contentDiv); | ||||
|                     $('<div>',{class:"red-ui-search-result-node-type"}).html(node.type).appendTo(contentDiv); | ||||
|                     $('<div>',{class:"red-ui-search-result-node-id"}).html(node.id).appendTo(contentDiv); | ||||
|  | ||||
|                     div.click(function(evt) { | ||||
|                         evt.preventDefault(); | ||||
|                         reveal(node); | ||||
|                     }); | ||||
|                 } | ||||
|             }, | ||||
|             scrollOnAdd: false | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|     function reveal(node) { | ||||
|         hide(); | ||||
|         RED.view.reveal(node.id); | ||||
|     } | ||||
|  | ||||
|     function show() { | ||||
|         if (disabled) { | ||||
|             return; | ||||
|         } | ||||
|         if (!visible) { | ||||
|             RED.keyboard.add("*","escape",function(){hide()}); | ||||
|             $("#header-shade").show(); | ||||
|             $("#editor-shade").show(); | ||||
|             $("#palette-shade").show(); | ||||
|             $("#sidebar-shade").show(); | ||||
|             $("#sidebar-separator").hide(); | ||||
|             indexWorkspace(); | ||||
|             if (dialog === null) { | ||||
|                 createDialog(); | ||||
|             } | ||||
|             dialog.slideDown(300); | ||||
|             RED.events.emit("search:open"); | ||||
|             visible = true; | ||||
|         } | ||||
|         searchInput.focus(); | ||||
|     } | ||||
|     function hide() { | ||||
|         if (visible) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             visible = false; | ||||
|             $("#header-shade").hide(); | ||||
|             $("#editor-shade").hide(); | ||||
|             $("#palette-shade").hide(); | ||||
|             $("#sidebar-shade").hide(); | ||||
|             $("#sidebar-separator").show(); | ||||
|             if (dialog !== null) { | ||||
|                 dialog.slideUp(200,function() { | ||||
|                     searchInput.searchBox('value',''); | ||||
|                 }); | ||||
|             } | ||||
|             RED.events.emit("search:close"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function init() { | ||||
|         RED.actions.add("core:search",show); | ||||
|  | ||||
|         RED.events.on("editor:open",function() { disabled = true; }); | ||||
|         RED.events.on("editor:close",function() { disabled = false; }); | ||||
|         RED.events.on("type-search:open",function() { disabled = true; }); | ||||
|         RED.events.on("type-search:close",function() { disabled = false; }); | ||||
|  | ||||
|  | ||||
|  | ||||
|         $("#header-shade").on('mousedown',hide); | ||||
|         $("#editor-shade").on('mousedown',hide); | ||||
|         $("#palette-shade").on('mousedown',hide); | ||||
|         $("#sidebar-shade").on('mousedown',hide); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         show: show, | ||||
|         hide: hide | ||||
|     }; | ||||
|  | ||||
| })(); | ||||
| @@ -1,228 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.sidebar = (function() { | ||||
|  | ||||
|     //$('#sidebar').tabs(); | ||||
|     var sidebar_tabs = RED.tabs.create({ | ||||
|         id:"sidebar-tabs", | ||||
|         onchange:function(tab) { | ||||
|             $("#sidebar-content").children().hide(); | ||||
|             $("#sidebar-footer").children().hide(); | ||||
|             if (tab.onchange) { | ||||
|                 tab.onchange.call(tab); | ||||
|             } | ||||
|             $(tab.wrapper).show(); | ||||
|             if (tab.toolbar) { | ||||
|                 $(tab.toolbar).show(); | ||||
|             } | ||||
|         }, | ||||
|         onremove: function(tab) { | ||||
|             $(tab.wrapper).hide(); | ||||
|             if (tab.onremove) { | ||||
|                 tab.onremove.call(tab); | ||||
|             } | ||||
|         }, | ||||
|         minimumActiveTabWidth: 110 | ||||
|     }); | ||||
|  | ||||
|     var knownTabs = { | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     function addTab(title,content,closeable,visible) { | ||||
|         var options; | ||||
|         if (typeof title === "string") { | ||||
|             // TODO: legacy support in case anyone uses this... | ||||
|             options = { | ||||
|                 id: content.id, | ||||
|                 label: title, | ||||
|                 name: title, | ||||
|                 content: content, | ||||
|                 closeable: closeable, | ||||
|                 visible: visible | ||||
|             } | ||||
|         } else if (typeof title === "object") { | ||||
|             options = title; | ||||
|         } | ||||
|  | ||||
|         options.wrapper = $('<div>',{style:"height:100%"}).appendTo("#sidebar-content") | ||||
|         options.wrapper.append(options.content); | ||||
|         options.wrapper.hide(); | ||||
|  | ||||
|         if (!options.enableOnEdit) { | ||||
|             options.shade = $('<div>',{class:"sidebar-shade hide"}).appendTo(options.wrapper); | ||||
|         } | ||||
|  | ||||
|         if (options.toolbar) { | ||||
|             $("#sidebar-footer").append(options.toolbar); | ||||
|             $(options.toolbar).hide(); | ||||
|         } | ||||
|         var id = options.id; | ||||
|  | ||||
|         RED.menu.addItem("menu-item-view-menu",{ | ||||
|             id:"menu-item-view-menu-"+options.id, | ||||
|             label:options.name, | ||||
|             onselect:function() { | ||||
|                 showSidebar(options.id); | ||||
|             }, | ||||
|             group: "sidebar-tabs" | ||||
|         }); | ||||
|  | ||||
|         knownTabs[options.id] = options; | ||||
|  | ||||
|         if (options.visible !== false) { | ||||
|             sidebar_tabs.addTab(knownTabs[options.id]); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function removeTab(id) { | ||||
|         sidebar_tabs.removeTab(id); | ||||
|         $(knownTabs[id].wrapper).remove(); | ||||
|         if (knownTabs[id].footer) { | ||||
|             knownTabs[id].footer.remove(); | ||||
|         } | ||||
|         delete knownTabs[id]; | ||||
|         RED.menu.removeItem("menu-item-view-menu-"+id); | ||||
|     } | ||||
|  | ||||
|     var sidebarSeparator =  {}; | ||||
|     $("#sidebar-separator").draggable({ | ||||
|             axis: "x", | ||||
|             start:function(event,ui) { | ||||
|                 sidebarSeparator.closing = false; | ||||
|                 sidebarSeparator.opening = false; | ||||
|                 var winWidth = $(window).width(); | ||||
|                 sidebarSeparator.start = ui.position.left; | ||||
|                 sidebarSeparator.chartWidth = $("#workspace").width(); | ||||
|                 sidebarSeparator.chartRight = winWidth-$("#workspace").width()-$("#workspace").offset().left-2; | ||||
|  | ||||
|                 if (!RED.menu.isSelected("menu-item-sidebar")) { | ||||
|                     sidebarSeparator.opening = true; | ||||
|                     var newChartRight = 7; | ||||
|                     $("#sidebar").addClass("closing"); | ||||
|                     $("#workspace").css("right",newChartRight); | ||||
|                     $("#editor-stack").css("right",newChartRight+1); | ||||
|                     $("#sidebar").width(0); | ||||
|                     RED.menu.setSelected("menu-item-sidebar",true); | ||||
|                     RED.events.emit("sidebar:resize"); | ||||
|                 } | ||||
|                 sidebarSeparator.width = $("#sidebar").width(); | ||||
|             }, | ||||
|             drag: function(event,ui) { | ||||
|                 var d = ui.position.left-sidebarSeparator.start; | ||||
|                 var newSidebarWidth = sidebarSeparator.width-d; | ||||
|                 if (sidebarSeparator.opening) { | ||||
|                     newSidebarWidth -= 3; | ||||
|                 } | ||||
|  | ||||
|                 if (newSidebarWidth > 150) { | ||||
|                     if (sidebarSeparator.chartWidth+d < 200) { | ||||
|                         ui.position.left = 200+sidebarSeparator.start-sidebarSeparator.chartWidth; | ||||
|                         d = ui.position.left-sidebarSeparator.start; | ||||
|                         newSidebarWidth = sidebarSeparator.width-d; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (newSidebarWidth < 150) { | ||||
|                     if (!sidebarSeparator.closing) { | ||||
|                         $("#sidebar").addClass("closing"); | ||||
|                         sidebarSeparator.closing = true; | ||||
|                     } | ||||
|                     if (!sidebarSeparator.opening) { | ||||
|                         newSidebarWidth = 150; | ||||
|                         ui.position.left = sidebarSeparator.width-(150 - sidebarSeparator.start); | ||||
|                         d = ui.position.left-sidebarSeparator.start; | ||||
|                     } | ||||
|                 } else if (newSidebarWidth > 150 && (sidebarSeparator.closing || sidebarSeparator.opening)) { | ||||
|                     sidebarSeparator.closing = false; | ||||
|                     $("#sidebar").removeClass("closing"); | ||||
|                 } | ||||
|  | ||||
|                 var newChartRight = sidebarSeparator.chartRight-d; | ||||
|                 $("#workspace").css("right",newChartRight); | ||||
|                 $("#editor-stack").css("right",newChartRight+1); | ||||
|                 $("#sidebar").width(newSidebarWidth); | ||||
|  | ||||
|                 sidebar_tabs.resize(); | ||||
|                 RED.events.emit("sidebar:resize"); | ||||
|             }, | ||||
|             stop:function(event,ui) { | ||||
|                 if (sidebarSeparator.closing) { | ||||
|                     $("#sidebar").removeClass("closing"); | ||||
|                     RED.menu.setSelected("menu-item-sidebar",false); | ||||
|                     if ($("#sidebar").width() < 180) { | ||||
|                         $("#sidebar").width(180); | ||||
|                         $("#workspace").css("right",187); | ||||
|                         $("#editor-stack").css("right",188); | ||||
|                     } | ||||
|                 } | ||||
|                 $("#sidebar-separator").css("left","auto"); | ||||
|                 $("#sidebar-separator").css("right",($("#sidebar").width()+2)+"px"); | ||||
|                 RED.events.emit("sidebar:resize"); | ||||
|             } | ||||
|     }); | ||||
|  | ||||
|     function toggleSidebar(state) { | ||||
|         if (!state) { | ||||
|             $("#main-container").addClass("sidebar-closed"); | ||||
|         } else { | ||||
|             $("#main-container").removeClass("sidebar-closed"); | ||||
|             sidebar_tabs.resize(); | ||||
|         } | ||||
|         RED.events.emit("sidebar:resize"); | ||||
|     } | ||||
|  | ||||
|     function showSidebar(id) { | ||||
|         if (id) { | ||||
|             if (!containsTab(id)) { | ||||
|                 sidebar_tabs.addTab(knownTabs[id]); | ||||
|             } | ||||
|             sidebar_tabs.activateTab(id); | ||||
|             if (!RED.menu.isSelected("menu-item-sidebar")) { | ||||
|                 RED.menu.setSelected("menu-item-sidebar",true); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function containsTab(id) { | ||||
|         return sidebar_tabs.contains(id); | ||||
|     } | ||||
|  | ||||
|     function init () { | ||||
|         RED.actions.add("core:toggle-sidebar",function(state){ | ||||
|             if (state === undefined) { | ||||
|                 RED.menu.toggleSelected("menu-item-sidebar"); | ||||
|             } else { | ||||
|                 toggleSidebar(state); | ||||
|             } | ||||
|         }); | ||||
|         showSidebar(); | ||||
|         RED.sidebar.info.init(); | ||||
|         RED.sidebar.config.init(); | ||||
|         // hide info bar at start if screen rather narrow... | ||||
|         if ($(window).width() < 600) { RED.menu.setSelected("menu-item-sidebar",false); } | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         addTab: addTab, | ||||
|         removeTab: removeTab, | ||||
|         show: showSidebar, | ||||
|         containsTab: containsTab, | ||||
|         toggleSidebar: toggleSidebar, | ||||
|     } | ||||
|  | ||||
| })(); | ||||
| @@ -1,631 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| RED.subflow = (function() { | ||||
|  | ||||
|  | ||||
|     function getSubflow() { | ||||
|         return RED.nodes.subflow(RED.workspaces.active()); | ||||
|     } | ||||
|  | ||||
|     function findAvailableSubflowIOPosition(subflow,isInput) { | ||||
|         var pos = {x:50,y:30}; | ||||
|         if (!isInput) { | ||||
|             pos.x += 110; | ||||
|         } | ||||
|         for (var i=0;i<subflow.out.length+subflow.in.length;i++) { | ||||
|             var port; | ||||
|             if (i < subflow.out.length) { | ||||
|                 port = subflow.out[i]; | ||||
|             } else { | ||||
|                 port = subflow.in[i-subflow.out.length]; | ||||
|             } | ||||
|             if (port.x == pos.x && port.y == pos.y) { | ||||
|                 pos.x += 55; | ||||
|                 i=0; | ||||
|             } | ||||
|         } | ||||
|         return pos; | ||||
|     } | ||||
|  | ||||
|     function addSubflowInput() { | ||||
|         var subflow = RED.nodes.subflow(RED.workspaces.active()); | ||||
|         if (subflow.in.length === 1) { | ||||
|             return; | ||||
|         } | ||||
|         var position = findAvailableSubflowIOPosition(subflow,true); | ||||
|         var newInput = { | ||||
|             type:"subflow", | ||||
|             direction:"in", | ||||
|             z:subflow.id, | ||||
|             i:subflow.in.length, | ||||
|             x:position.x, | ||||
|             y:position.y, | ||||
|             id:RED.nodes.id() | ||||
|         }; | ||||
|         var oldInCount = subflow.in.length; | ||||
|         subflow.in.push(newInput); | ||||
|         subflow.dirty = true; | ||||
|         var wasDirty = RED.nodes.dirty(); | ||||
|         var wasChanged = subflow.changed; | ||||
|         subflow.changed = true; | ||||
|         var result = refresh(true); | ||||
|         var historyEvent = { | ||||
|             t:'edit', | ||||
|             node:subflow, | ||||
|             dirty:wasDirty, | ||||
|             changed:wasChanged, | ||||
|             subflow: { | ||||
|                 inputCount: oldInCount, | ||||
|                 instances: result.instances | ||||
|             } | ||||
|         }; | ||||
|         RED.history.push(historyEvent); | ||||
|         RED.view.select(); | ||||
|         RED.nodes.dirty(true); | ||||
|         RED.view.redraw(); | ||||
|         $("#workspace-subflow-input-add").addClass("active"); | ||||
|         $("#workspace-subflow-input-remove").removeClass("active"); | ||||
|     } | ||||
|  | ||||
|     function removeSubflowInput() { | ||||
|         var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); | ||||
|         if (activeSubflow.in.length === 0) { | ||||
|             return; | ||||
|         } | ||||
|         var removedInput = activeSubflow.in[0]; | ||||
|         var removedInputLinks = []; | ||||
|         RED.nodes.eachLink(function(l) { | ||||
|             if (l.source.type == "subflow" && l.source.z == activeSubflow.id && l.source.i == removedInput.i) { | ||||
|                 removedInputLinks.push(l); | ||||
|             } else if (l.target.type == "subflow:"+activeSubflow.id) { | ||||
|                 removedInputLinks.push(l); | ||||
|             } | ||||
|         }); | ||||
|         removedInputLinks.forEach(function(l) { RED.nodes.removeLink(l)}); | ||||
|         activeSubflow.in = []; | ||||
|         $("#workspace-subflow-input-add").removeClass("active"); | ||||
|         $("#workspace-subflow-input-remove").addClass("active"); | ||||
|         activeSubflow.changed = true; | ||||
|         return {subflowInputs: [ removedInput ], links:removedInputLinks}; | ||||
|     } | ||||
|  | ||||
|     function addSubflowOutput(id) { | ||||
|         var subflow = RED.nodes.subflow(RED.workspaces.active()); | ||||
|         var position = findAvailableSubflowIOPosition(subflow,false); | ||||
|  | ||||
|         var newOutput = { | ||||
|             type:"subflow", | ||||
|             direction:"out", | ||||
|             z:subflow.id, | ||||
|             i:subflow.out.length, | ||||
|             x:position.x, | ||||
|             y:position.y, | ||||
|             id:RED.nodes.id() | ||||
|         }; | ||||
|         var oldOutCount = subflow.out.length; | ||||
|         subflow.out.push(newOutput); | ||||
|         subflow.dirty = true; | ||||
|         var wasDirty = RED.nodes.dirty(); | ||||
|         var wasChanged = subflow.changed; | ||||
|         subflow.changed = true; | ||||
|  | ||||
|         var result = refresh(true); | ||||
|  | ||||
|         var historyEvent = { | ||||
|             t:'edit', | ||||
|             node:subflow, | ||||
|             dirty:wasDirty, | ||||
|             changed:wasChanged, | ||||
|             subflow: { | ||||
|                 outputCount: oldOutCount, | ||||
|                 instances: result.instances | ||||
|             } | ||||
|         }; | ||||
|         RED.history.push(historyEvent); | ||||
|         RED.view.select(); | ||||
|         RED.nodes.dirty(true); | ||||
|         RED.view.redraw(); | ||||
|         $("#workspace-subflow-output .spinner-value").html(subflow.out.length); | ||||
|     } | ||||
|  | ||||
|     function removeSubflowOutput(removedSubflowOutputs) { | ||||
|         var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); | ||||
|         if (activeSubflow.out.length === 0) { | ||||
|             return; | ||||
|         } | ||||
|         if (typeof removedSubflowOutputs === "undefined") { | ||||
|             removedSubflowOutputs = [activeSubflow.out[activeSubflow.out.length-1]]; | ||||
|         } | ||||
|         var removedLinks = []; | ||||
|         removedSubflowOutputs.sort(function(a,b) { return b.i-a.i}); | ||||
|         for (i=0;i<removedSubflowOutputs.length;i++) { | ||||
|             var output = removedSubflowOutputs[i]; | ||||
|             activeSubflow.out.splice(output.i,1); | ||||
|             var subflowRemovedLinks = []; | ||||
|             var subflowMovedLinks = []; | ||||
|             RED.nodes.eachLink(function(l) { | ||||
|                 if (l.target.type == "subflow" && l.target.z == activeSubflow.id && l.target.i == output.i) { | ||||
|                     subflowRemovedLinks.push(l); | ||||
|                 } | ||||
|                 if (l.source.type == "subflow:"+activeSubflow.id) { | ||||
|                     if (l.sourcePort == output.i) { | ||||
|                         subflowRemovedLinks.push(l); | ||||
|                     } else if (l.sourcePort > output.i) { | ||||
|                         subflowMovedLinks.push(l); | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|             subflowRemovedLinks.forEach(function(l) { RED.nodes.removeLink(l)}); | ||||
|             subflowMovedLinks.forEach(function(l) { l.sourcePort--; }); | ||||
|  | ||||
|             removedLinks = removedLinks.concat(subflowRemovedLinks); | ||||
|             for (var j=output.i;j<activeSubflow.out.length;j++) { | ||||
|                 activeSubflow.out[j].i--; | ||||
|                 activeSubflow.out[j].dirty = true; | ||||
|             } | ||||
|         } | ||||
|         activeSubflow.changed = true; | ||||
|  | ||||
|         return {subflowOutputs: removedSubflowOutputs, links: removedLinks} | ||||
|     } | ||||
|  | ||||
|     function refresh(markChange) { | ||||
|         var activeSubflow = RED.nodes.subflow(RED.workspaces.active()); | ||||
|         refreshToolbar(activeSubflow); | ||||
|         var subflowInstances = []; | ||||
|         if (activeSubflow) { | ||||
|             RED.nodes.filterNodes({type:"subflow:"+activeSubflow.id}).forEach(function(n) { | ||||
|                 subflowInstances.push({ | ||||
|                     id: n.id, | ||||
|                     changed: n.changed | ||||
|                 }); | ||||
|                 if (markChange) { | ||||
|                     n.changed = true; | ||||
|                 } | ||||
|                 n.inputs = activeSubflow.in.length; | ||||
|                 n.outputs = activeSubflow.out.length; | ||||
|                 while (n.outputs < n.ports.length) { | ||||
|                     n.ports.pop(); | ||||
|                 } | ||||
|                 n.resize = true; | ||||
|                 n.dirty = true; | ||||
|                 RED.editor.updateNodeProperties(n); | ||||
|             }); | ||||
|             RED.editor.validateNode(activeSubflow); | ||||
|             return { | ||||
|                 instances: subflowInstances | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     function refreshToolbar(activeSubflow) { | ||||
|         if (activeSubflow) { | ||||
|             $("#workspace-subflow-input-add").toggleClass("active", activeSubflow.in.length !== 0); | ||||
|             $("#workspace-subflow-input-remove").toggleClass("active",activeSubflow.in.length === 0); | ||||
|  | ||||
|             $("#workspace-subflow-output .spinner-value").html(activeSubflow.out.length); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function showWorkspaceToolbar(activeSubflow) { | ||||
|         var toolbar = $("#workspace-toolbar"); | ||||
|         toolbar.empty(); | ||||
|  | ||||
|         $('<a class="button" id="workspace-subflow-edit" href="#" data-i18n="[append]subflow.editSubflowProperties"><i class="fa fa-pencil"></i> </a>').appendTo(toolbar); | ||||
|         $('<span style="margin-left: 5px;" data-i18n="subflow.input"></span> '+ | ||||
|             '<div style="display: inline-block;" class="button-group">'+ | ||||
|             '<a id="workspace-subflow-input-remove" class="button active" href="#">0</a>'+ | ||||
|             '<a id="workspace-subflow-input-add" class="button" href="#">1</a>'+ | ||||
|             '</div>').appendTo(toolbar); | ||||
|  | ||||
|         $('<span style="margin-left: 5px;" data-i18n="subflow.output"></span> <div id="workspace-subflow-output" style="display: inline-block;" class="button-group spinner-group">'+ | ||||
|             '<a id="workspace-subflow-output-remove" class="button" href="#"><i class="fa fa-minus"></i></a>'+ | ||||
|             '<div class="spinner-value">3</div>'+ | ||||
|             '<a id="workspace-subflow-output-add" class="button" href="#"><i class="fa fa-plus"></i></a>'+ | ||||
|             '</div>').appendTo(toolbar); | ||||
|  | ||||
|         // $('<a class="button disabled" id="workspace-subflow-add-input" href="#" data-i18n="[append]subflow.input"><i class="fa fa-plus"></i> </a>').appendTo(toolbar); | ||||
|         // $('<a class="button" id="workspace-subflow-add-output" href="#" data-i18n="[append]subflow.output"><i class="fa fa-plus"></i> </a>').appendTo(toolbar); | ||||
|         $('<a class="button" id="workspace-subflow-delete" href="#" data-i18n="[append]subflow.deleteSubflow"><i class="fa fa-trash"></i> </a>').appendTo(toolbar); | ||||
|         toolbar.i18n(); | ||||
|  | ||||
|  | ||||
|         $("#workspace-subflow-output-remove").click(function(event) { | ||||
|             event.preventDefault(); | ||||
|             var wasDirty = RED.nodes.dirty(); | ||||
|             var wasChanged = activeSubflow.changed; | ||||
|             var result = removeSubflowOutput(); | ||||
|             if (result) { | ||||
|                 var inst = refresh(true); | ||||
|                 RED.history.push({ | ||||
|                     t:'delete', | ||||
|                     links:result.links, | ||||
|                     subflowOutputs: result.subflowOutputs, | ||||
|                     changed: wasChanged, | ||||
|                     dirty:wasDirty, | ||||
|                     subflow: { | ||||
|                         instances: inst.instances | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|                 RED.view.select(); | ||||
|                 RED.nodes.dirty(true); | ||||
|                 RED.view.redraw(true); | ||||
|             } | ||||
|         }); | ||||
|         $("#workspace-subflow-output-add").click(function(event) { | ||||
|             event.preventDefault(); | ||||
|             addSubflowOutput(); | ||||
|         }); | ||||
|  | ||||
|         $("#workspace-subflow-input-add").click(function(event) { | ||||
|             event.preventDefault(); | ||||
|             addSubflowInput(); | ||||
|         }); | ||||
|         $("#workspace-subflow-input-remove").click(function(event) { | ||||
|             event.preventDefault(); | ||||
|             var wasDirty = RED.nodes.dirty(); | ||||
|             var wasChanged = activeSubflow.changed; | ||||
|             activeSubflow.changed = true; | ||||
|             var result = removeSubflowInput(); | ||||
|             if (result) { | ||||
|                 var inst = refresh(true); | ||||
|                 RED.history.push({ | ||||
|                     t:'delete', | ||||
|                     links:result.links, | ||||
|                     changed: wasChanged, | ||||
|                     subflowInputs: result.subflowInputs, | ||||
|                     dirty:wasDirty, | ||||
|                     subflow: { | ||||
|                         instances: inst.instances | ||||
|                     } | ||||
|                 }); | ||||
|                 RED.view.select(); | ||||
|                 RED.nodes.dirty(true); | ||||
|                 RED.view.redraw(true); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         $("#workspace-subflow-edit").click(function(event) { | ||||
|             RED.editor.editSubflow(RED.nodes.subflow(RED.workspaces.active())); | ||||
|             event.preventDefault(); | ||||
|         }); | ||||
|  | ||||
|         $("#workspace-subflow-delete").click(function(event) { | ||||
|             event.preventDefault(); | ||||
|             var startDirty = RED.nodes.dirty(); | ||||
|             var historyEvent = removeSubflow(RED.workspaces.active()); | ||||
|             historyEvent.t = 'delete'; | ||||
|             historyEvent.dirty = startDirty; | ||||
|  | ||||
|             RED.history.push(historyEvent); | ||||
|  | ||||
|         }); | ||||
|  | ||||
|         refreshToolbar(activeSubflow); | ||||
|  | ||||
|         $("#chart").css({"margin-top": "40px"}); | ||||
|         $("#workspace-toolbar").show(); | ||||
|     } | ||||
|     function hideWorkspaceToolbar() { | ||||
|         $("#workspace-toolbar").hide().empty(); | ||||
|         $("#chart").css({"margin-top": "0"}); | ||||
|     } | ||||
|  | ||||
|     function removeSubflow(id) { | ||||
|         var removedNodes = []; | ||||
|         var removedLinks = []; | ||||
|  | ||||
|         var activeSubflow = RED.nodes.subflow(id); | ||||
|  | ||||
|         RED.nodes.eachNode(function(n) { | ||||
|             if (n.type == "subflow:"+activeSubflow.id) { | ||||
|                 removedNodes.push(n); | ||||
|             } | ||||
|             if (n.z == activeSubflow.id) { | ||||
|                 removedNodes.push(n); | ||||
|             } | ||||
|         }); | ||||
|         RED.nodes.eachConfig(function(n) { | ||||
|             if (n.z == activeSubflow.id) { | ||||
|                 removedNodes.push(n); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         var removedConfigNodes = []; | ||||
|         for (var i=0;i<removedNodes.length;i++) { | ||||
|             var removedEntities = RED.nodes.remove(removedNodes[i].id); | ||||
|             removedLinks = removedLinks.concat(removedEntities.links); | ||||
|             removedConfigNodes = removedConfigNodes.concat(removedEntities.nodes); | ||||
|         } | ||||
|         // TODO: this whole delete logic should be in RED.nodes.removeSubflow.. | ||||
|         removedNodes = removedNodes.concat(removedConfigNodes); | ||||
|  | ||||
|         RED.nodes.removeSubflow(activeSubflow); | ||||
|         RED.workspaces.remove(activeSubflow); | ||||
|         RED.nodes.dirty(true); | ||||
|         RED.view.redraw(); | ||||
|  | ||||
|         return { | ||||
|             nodes:removedNodes, | ||||
|             links:removedLinks, | ||||
|             subflow: { | ||||
|                 subflow: activeSubflow | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     function init() { | ||||
|         RED.events.on("workspace:change",function(event) { | ||||
|             var activeSubflow = RED.nodes.subflow(event.workspace); | ||||
|             if (activeSubflow) { | ||||
|                 showWorkspaceToolbar(activeSubflow); | ||||
|             } else { | ||||
|                 hideWorkspaceToolbar(); | ||||
|             } | ||||
|         }); | ||||
|         RED.events.on("view:selection-changed",function(selection) { | ||||
|             if (!selection.nodes) { | ||||
|                 RED.menu.setDisabled("menu-item-subflow-convert",true); | ||||
|             } else { | ||||
|                 RED.menu.setDisabled("menu-item-subflow-convert",false); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         RED.actions.add("core:create-subflow",createSubflow); | ||||
|         RED.actions.add("core:convert-to-subflow",convertToSubflow); | ||||
|     } | ||||
|  | ||||
|     function createSubflow() { | ||||
|         var lastIndex = 0; | ||||
|         RED.nodes.eachSubflow(function(sf) { | ||||
|            var m = (new RegExp("^Subflow (\\d+)$")).exec(sf.name); | ||||
|            if (m) { | ||||
|                lastIndex = Math.max(lastIndex,m[1]); | ||||
|            } | ||||
|         }); | ||||
|  | ||||
|         var name = "Subflow "+(lastIndex+1); | ||||
|  | ||||
|         var subflowId = RED.nodes.id(); | ||||
|         var subflow = { | ||||
|             type:"subflow", | ||||
|             id:subflowId, | ||||
|             name:name, | ||||
|             info:"", | ||||
|             in: [], | ||||
|             out: [] | ||||
|         }; | ||||
|         RED.nodes.addSubflow(subflow); | ||||
|         RED.history.push({ | ||||
|             t:'createSubflow', | ||||
|             subflow: { | ||||
|                 subflow:subflow | ||||
|             }, | ||||
|             dirty:RED.nodes.dirty() | ||||
|         }); | ||||
|         RED.workspaces.show(subflowId); | ||||
|         RED.nodes.dirty(true); | ||||
|     } | ||||
|  | ||||
|     function convertToSubflow() { | ||||
|         var selection = RED.view.selection(); | ||||
|         if (!selection.nodes) { | ||||
|             RED.notify(RED._("subflow.errors.noNodesSelected"),"error"); | ||||
|             return; | ||||
|         } | ||||
|         var i,n; | ||||
|         var nodes = {}; | ||||
|         var new_links = []; | ||||
|         var removedLinks = []; | ||||
|  | ||||
|         var candidateInputs = []; | ||||
|         var candidateOutputs = []; | ||||
|         var candidateInputNodes = {}; | ||||
|  | ||||
|  | ||||
|         var boundingBox = [selection.nodes[0].x, | ||||
|             selection.nodes[0].y, | ||||
|             selection.nodes[0].x, | ||||
|             selection.nodes[0].y]; | ||||
|  | ||||
|         for (i=0;i<selection.nodes.length;i++) { | ||||
|             n = selection.nodes[i]; | ||||
|             nodes[n.id] = {n:n,outputs:{}}; | ||||
|             boundingBox = [ | ||||
|                 Math.min(boundingBox[0],n.x), | ||||
|                 Math.min(boundingBox[1],n.y), | ||||
|                 Math.max(boundingBox[2],n.x), | ||||
|                 Math.max(boundingBox[3],n.y) | ||||
|             ] | ||||
|         } | ||||
|  | ||||
|         var center = [(boundingBox[2]+boundingBox[0]) / 2,(boundingBox[3]+boundingBox[1]) / 2]; | ||||
|  | ||||
|         RED.nodes.eachLink(function(link) { | ||||
|             if (nodes[link.source.id] && nodes[link.target.id]) { | ||||
|                 // A link wholely within the selection | ||||
|             } | ||||
|  | ||||
|             if (nodes[link.source.id] && !nodes[link.target.id]) { | ||||
|                 // An outbound link from the selection | ||||
|                 candidateOutputs.push(link); | ||||
|                 removedLinks.push(link); | ||||
|             } | ||||
|             if (!nodes[link.source.id] && nodes[link.target.id]) { | ||||
|                 // An inbound link | ||||
|                 candidateInputs.push(link); | ||||
|                 candidateInputNodes[link.target.id] = link.target; | ||||
|                 removedLinks.push(link); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         var outputs = {}; | ||||
|         candidateOutputs = candidateOutputs.filter(function(v) { | ||||
|              if (outputs[v.source.id+":"+v.sourcePort]) { | ||||
|                  outputs[v.source.id+":"+v.sourcePort].targets.push(v.target); | ||||
|                  return false; | ||||
|              } | ||||
|              v.targets = []; | ||||
|              v.targets.push(v.target); | ||||
|              outputs[v.source.id+":"+v.sourcePort] = v; | ||||
|              return true; | ||||
|         }); | ||||
|         candidateOutputs.sort(function(a,b) { return a.source.y-b.source.y}); | ||||
|  | ||||
|         if (Object.keys(candidateInputNodes).length > 1) { | ||||
|              RED.notify(RED._("subflow.errors.multipleInputsToSelection"),"error"); | ||||
|              return; | ||||
|         } | ||||
|  | ||||
|         var lastIndex = 0; | ||||
|         RED.nodes.eachSubflow(function(sf) { | ||||
|            var m = (new RegExp("^Subflow (\\d+)$")).exec(sf.name); | ||||
|            if (m) { | ||||
|                lastIndex = Math.max(lastIndex,m[1]); | ||||
|            } | ||||
|         }); | ||||
|  | ||||
|         var name = "Subflow "+(lastIndex+1); | ||||
|  | ||||
|         var subflowId = RED.nodes.id(); | ||||
|         var subflow = { | ||||
|             type:"subflow", | ||||
|             id:subflowId, | ||||
|             name:name, | ||||
|             info:"", | ||||
|             in: Object.keys(candidateInputNodes).map(function(v,i) { var index = i; return { | ||||
|                 type:"subflow", | ||||
|                 direction:"in", | ||||
|                 x:candidateInputNodes[v].x-(candidateInputNodes[v].w/2)-80, | ||||
|                 y:candidateInputNodes[v].y, | ||||
|                 z:subflowId, | ||||
|                 i:index, | ||||
|                 id:RED.nodes.id(), | ||||
|                 wires:[{id:candidateInputNodes[v].id}] | ||||
|             }}), | ||||
|             out: candidateOutputs.map(function(v,i) { var index = i; return { | ||||
|                 type:"subflow", | ||||
|                 direction:"in", | ||||
|                 x:v.source.x+(v.source.w/2)+80, | ||||
|                 y:v.source.y, | ||||
|                 z:subflowId, | ||||
|                 i:index, | ||||
|                 id:RED.nodes.id(), | ||||
|                 wires:[{id:v.source.id,port:v.sourcePort}] | ||||
|             }}) | ||||
|         }; | ||||
|  | ||||
|         RED.nodes.addSubflow(subflow); | ||||
|  | ||||
|         var subflowInstance = { | ||||
|             id:RED.nodes.id(), | ||||
|             type:"subflow:"+subflow.id, | ||||
|             x: center[0], | ||||
|             y: center[1], | ||||
|             z: RED.workspaces.active(), | ||||
|             inputs: subflow.in.length, | ||||
|             outputs: subflow.out.length, | ||||
|             h: Math.max(30/*node_height*/,(subflow.out.length||0) * 15), | ||||
|             changed:true | ||||
|         } | ||||
|         subflowInstance._def = RED.nodes.getType(subflowInstance.type); | ||||
|         RED.editor.validateNode(subflowInstance); | ||||
|         RED.nodes.add(subflowInstance); | ||||
|  | ||||
|         candidateInputs.forEach(function(l) { | ||||
|             var link = {source:l.source, sourcePort:l.sourcePort, target: subflowInstance}; | ||||
|             new_links.push(link); | ||||
|             RED.nodes.addLink(link); | ||||
|         }); | ||||
|  | ||||
|         candidateOutputs.forEach(function(output,i) { | ||||
|             output.targets.forEach(function(target) { | ||||
|                 var link = {source:subflowInstance, sourcePort:i, target: target}; | ||||
|                 new_links.push(link); | ||||
|                 RED.nodes.addLink(link); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         subflow.in.forEach(function(input) { | ||||
|             input.wires.forEach(function(wire) { | ||||
|                 var link = {source: input, sourcePort: 0, target: RED.nodes.node(wire.id) } | ||||
|                 new_links.push(link); | ||||
|                 RED.nodes.addLink(link); | ||||
|             }); | ||||
|         }); | ||||
|         subflow.out.forEach(function(output,i) { | ||||
|             output.wires.forEach(function(wire) { | ||||
|                 var link = {source: RED.nodes.node(wire.id), sourcePort: wire.port , target: output } | ||||
|                 new_links.push(link); | ||||
|                 RED.nodes.addLink(link); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         for (i=0;i<removedLinks.length;i++) { | ||||
|             RED.nodes.removeLink(removedLinks[i]); | ||||
|         } | ||||
|  | ||||
|         for (i=0;i<selection.nodes.length;i++) { | ||||
|             n = selection.nodes[i]; | ||||
|             if (/^link /.test(n.type)) { | ||||
|                 n.links = n.links.filter(function(id) { | ||||
|                     var isLocalLink = nodes.hasOwnProperty(id); | ||||
|                     if (!isLocalLink) { | ||||
|                         var otherNode = RED.nodes.node(id); | ||||
|                         if (otherNode && otherNode.links) { | ||||
|                             var i = otherNode.links.indexOf(n.id); | ||||
|                             if (i > -1) { | ||||
|                                 otherNode.links.splice(i,1); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     return isLocalLink; | ||||
|                 }); | ||||
|             } | ||||
|             n.z = subflow.id; | ||||
|         } | ||||
|  | ||||
|         RED.history.push({ | ||||
|             t:'createSubflow', | ||||
|             nodes:[subflowInstance.id], | ||||
|             links:new_links, | ||||
|             subflow: { | ||||
|                 subflow: subflow | ||||
|             }, | ||||
|  | ||||
|             activeWorkspace: RED.workspaces.active(), | ||||
|             removedLinks: removedLinks, | ||||
|  | ||||
|             dirty:RED.nodes.dirty() | ||||
|         }); | ||||
|         RED.view.select(null); | ||||
|         RED.editor.validateNode(subflow); | ||||
|         RED.nodes.dirty(true); | ||||
|         RED.view.redraw(true); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         createSubflow: createSubflow, | ||||
|         convertToSubflow: convertToSubflow, | ||||
|         removeSubflow: removeSubflow, | ||||
|         refresh: refresh, | ||||
|         removeInput: removeSubflowInput, | ||||
|         removeOutput: removeSubflowOutput | ||||
|     } | ||||
| })(); | ||||
| @@ -1,315 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.sidebar.config = (function() { | ||||
|  | ||||
|  | ||||
|     var content = document.createElement("div"); | ||||
|     content.className = "sidebar-node-config"; | ||||
|  | ||||
|     $('<div class="button-group sidebar-header">'+ | ||||
|       '<a class="sidebar-header-button-toggle selected" id="workspace-config-node-filter-all" href="#"><span data-i18n="sidebar.config.filterAll"></span></a>'+ | ||||
|       '<a class="sidebar-header-button-toggle" id="workspace-config-node-filter-unused" href="#"><span data-i18n="sidebar.config.filterUnused"></span></a> '+ | ||||
|       '</div>' | ||||
|     ).appendTo(content); | ||||
|  | ||||
|  | ||||
|     var toolbar = $('<div>'+ | ||||
|         '<a class="sidebar-footer-button" id="workspace-config-node-collapse-all" href="#"><i class="fa fa-angle-double-up"></i></a> '+ | ||||
|         '<a class="sidebar-footer-button" id="workspace-config-node-expand-all" href="#"><i class="fa fa-angle-double-down"></i></a>'+ | ||||
|         '</div>'); | ||||
|  | ||||
|     var globalCategories = $("<div>").appendTo(content); | ||||
|     var flowCategories = $("<div>").appendTo(content); | ||||
|     var subflowCategories = $("<div>").appendTo(content); | ||||
|  | ||||
|     var showUnusedOnly = false; | ||||
|  | ||||
|     var categories = {}; | ||||
|  | ||||
|     function getOrCreateCategory(name,parent,label) { | ||||
|         name = name.replace(/\./i,"-"); | ||||
|         if (!categories[name]) { | ||||
|             var container = $('<div class="palette-category workspace-config-node-category" id="workspace-config-node-category-'+name+'"></div>').appendTo(parent); | ||||
|             var header = $('<div class="workspace-config-node-tray-header palette-header"><i class="fa fa-angle-down expanded"></i></div>').appendTo(container); | ||||
|             if (label) { | ||||
|                 $('<span class="config-node-label"/>').text(label).appendTo(header); | ||||
|             } else { | ||||
|                 $('<span class="config-node-label" data-i18n="sidebar.config.'+name+'">').appendTo(header); | ||||
|             } | ||||
|             $('<span class="config-node-filter-info"></span>').appendTo(header); | ||||
|             category = $('<ul class="palette-content config-node-list"></ul>').appendTo(container); | ||||
|             container.i18n(); | ||||
|             var icon = header.find("i"); | ||||
|             var result = { | ||||
|                 label: label, | ||||
|                 list: category, | ||||
|                 size: function() { | ||||
|                     return result.list.find("li:not(.config_node_none)").length | ||||
|                 }, | ||||
|                 open: function(snap) { | ||||
|                     if (!icon.hasClass("expanded")) { | ||||
|                         icon.addClass("expanded"); | ||||
|                         if (snap) { | ||||
|                             result.list.show(); | ||||
|                         } else { | ||||
|                             result.list.slideDown(); | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 close: function(snap) { | ||||
|                     if (icon.hasClass("expanded")) { | ||||
|                         icon.removeClass("expanded"); | ||||
|                         if (snap) { | ||||
|                             result.list.hide(); | ||||
|                         } else { | ||||
|                             result.list.slideUp(); | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 isOpen: function() { | ||||
|                     return icon.hasClass("expanded"); | ||||
|                 } | ||||
|             }; | ||||
|  | ||||
|             header.on('click', function(e) { | ||||
|                 if (result.isOpen()) { | ||||
|                     result.close(); | ||||
|                 } else { | ||||
|                     result.open(); | ||||
|                 } | ||||
|             }); | ||||
|             categories[name] = result; | ||||
|         } else { | ||||
|             if (categories[name].label !== label) { | ||||
|                 categories[name].list.parent().find('.config-node-label').text(label); | ||||
|                 categories[name].label = label; | ||||
|             } | ||||
|         } | ||||
|         return categories[name]; | ||||
|     } | ||||
|  | ||||
|     function createConfigNodeList(id,nodes) { | ||||
|         var category = getOrCreateCategory(id.replace(/\./i,"-")) | ||||
|         var list = category.list; | ||||
|  | ||||
|         nodes.sort(function(A,B) { | ||||
|             if (A.type < B.type) { return -1;} | ||||
|             if (A.type > B.type) { return 1;} | ||||
|             return 0; | ||||
|         }); | ||||
|         if (showUnusedOnly) { | ||||
|             var hiddenCount = nodes.length; | ||||
|             nodes = nodes.filter(function(n) { | ||||
|                 return n._def.hasUsers!==false && n.users.length === 0; | ||||
|             }) | ||||
|             hiddenCount = hiddenCount - nodes.length; | ||||
|             if (hiddenCount > 0) { | ||||
|                 list.parent().find('.config-node-filter-info').text(RED._('sidebar.config.filtered',{count:hiddenCount})).show(); | ||||
|             } else { | ||||
|                 list.parent().find('.config-node-filter-info').hide(); | ||||
|             } | ||||
|         } else { | ||||
|             list.parent().find('.config-node-filter-info').hide(); | ||||
|         } | ||||
|         list.empty(); | ||||
|         if (nodes.length === 0) { | ||||
|             $('<li class="config_node_none" data-i18n="sidebar.config.none">NONE</li>').i18n().appendTo(list); | ||||
|             category.close(true); | ||||
|         } else { | ||||
|             var currentType = ""; | ||||
|             nodes.forEach(function(node) { | ||||
|                 var label = RED.utils.getNodeLabel(node,node.id); | ||||
|                 if (node.type != currentType) { | ||||
|                     $('<li class="config_node_type">'+node.type+'</li>').appendTo(list); | ||||
|                     currentType = node.type; | ||||
|                 } | ||||
|  | ||||
|                 var entry = $('<li class="palette_node config_node palette_node_id_'+node.id.replace(/\./g,"-")+'"></li>').appendTo(list); | ||||
|                 $('<div class="palette_label"></div>').text(label).appendTo(entry); | ||||
|                 if (node._def.hasUsers !== false) { | ||||
|                     var iconContainer = $('<div/>',{class:"palette_icon_container  palette_icon_container_right"}).text(node.users.length).appendTo(entry); | ||||
|                     if (node.users.length === 0) { | ||||
|                         entry.addClass("config_node_unused"); | ||||
|                     } | ||||
|                 } | ||||
|                 entry.on('click',function(e) { | ||||
|                     RED.sidebar.info.refresh(node); | ||||
|                 }); | ||||
|                 entry.on('dblclick',function(e) { | ||||
|                     RED.editor.editConfig("", node.type, node.id); | ||||
|                 }); | ||||
|                 var userArray = node.users.map(function(n) { return n.id }); | ||||
|                 entry.on('mouseover',function(e) { | ||||
|                     RED.nodes.eachNode(function(node) { | ||||
|                         if( userArray.indexOf(node.id) != -1) { | ||||
|                             node.highlighted = true; | ||||
|                             node.dirty = true; | ||||
|                         } | ||||
|                     }); | ||||
|                     RED.view.redraw(); | ||||
|                 }); | ||||
|  | ||||
|                 entry.on('mouseout',function(e) { | ||||
|                     RED.nodes.eachNode(function(node) { | ||||
|                         if(node.highlighted) { | ||||
|                             node.highlighted = false; | ||||
|                             node.dirty = true; | ||||
|                         } | ||||
|                     }); | ||||
|                     RED.view.redraw(); | ||||
|                 }); | ||||
|             }); | ||||
|             category.open(true); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function refreshConfigNodeList() { | ||||
|         var validList = {"global":true}; | ||||
|  | ||||
|         getOrCreateCategory("global",globalCategories); | ||||
|  | ||||
|         RED.nodes.eachWorkspace(function(ws) { | ||||
|             validList[ws.id.replace(/\./g,"-")] = true; | ||||
|             getOrCreateCategory(ws.id,flowCategories,ws.label); | ||||
|         }) | ||||
|         RED.nodes.eachSubflow(function(sf) { | ||||
|             validList[sf.id.replace(/\./g,"-")] = true; | ||||
|             getOrCreateCategory(sf.id,subflowCategories,sf.name); | ||||
|         }) | ||||
|         $(".workspace-config-node-category").each(function() { | ||||
|             var id = $(this).attr('id').substring("workspace-config-node-category-".length); | ||||
|             if (!validList[id]) { | ||||
|                 $(this).remove(); | ||||
|                 delete categories[id]; | ||||
|             } | ||||
|         }) | ||||
|         var globalConfigNodes = []; | ||||
|         var configList = {}; | ||||
|         RED.nodes.eachConfig(function(cn) { | ||||
|             if (cn.z) {//} == RED.workspaces.active()) { | ||||
|                 configList[cn.z.replace(/\./g,"-")] = configList[cn.z.replace(/\./g,"-")]||[]; | ||||
|                 configList[cn.z.replace(/\./g,"-")].push(cn); | ||||
|             } else if (!cn.z) { | ||||
|                 globalConfigNodes.push(cn); | ||||
|             } | ||||
|         }); | ||||
|         for (var id in validList) { | ||||
|             if (validList.hasOwnProperty(id)) { | ||||
|                 createConfigNodeList(id,configList[id]||[]); | ||||
|             } | ||||
|         } | ||||
|         createConfigNodeList('global',globalConfigNodes); | ||||
|     } | ||||
|  | ||||
|     function init() { | ||||
|         RED.sidebar.addTab({ | ||||
|             id: "config", | ||||
|             label: RED._("sidebar.config.label"), | ||||
|             name: RED._("sidebar.config.name"), | ||||
|             content: content, | ||||
|             toolbar: toolbar, | ||||
|             closeable: true, | ||||
|             visible: false, | ||||
|             onchange: function() { refreshConfigNodeList(); } | ||||
|         }); | ||||
|         RED.actions.add("core:show-config-tab",function() {RED.sidebar.show('config')}); | ||||
|  | ||||
|         $("#workspace-config-node-collapse-all").on("click", function(e) { | ||||
|             e.preventDefault(); | ||||
|             for (var cat in categories) { | ||||
|                 if (categories.hasOwnProperty(cat)) { | ||||
|                     categories[cat].close(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         $("#workspace-config-node-expand-all").on("click", function(e) { | ||||
|             e.preventDefault(); | ||||
|             for (var cat in categories) { | ||||
|                 if (categories.hasOwnProperty(cat)) { | ||||
|                     if (categories[cat].size() > 0) { | ||||
|                         categories[cat].open(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|         $('#workspace-config-node-filter-all').on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             if (showUnusedOnly) { | ||||
|                 $(this).addClass('selected'); | ||||
|                 $('#workspace-config-node-filter-unused').removeClass('selected'); | ||||
|                 showUnusedOnly = !showUnusedOnly; | ||||
|                 refreshConfigNodeList(); | ||||
|             } | ||||
|         }); | ||||
|         $('#workspace-config-node-filter-unused').on("click",function(e) { | ||||
|             e.preventDefault(); | ||||
|             if (!showUnusedOnly) { | ||||
|                 $(this).addClass('selected'); | ||||
|                 $('#workspace-config-node-filter-all').removeClass('selected'); | ||||
|                 showUnusedOnly = !showUnusedOnly; | ||||
|                 refreshConfigNodeList(); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|  | ||||
|     } | ||||
|     function show(id) { | ||||
|         if (typeof id === 'boolean') { | ||||
|             if (id) { | ||||
|                 $('#workspace-config-node-filter-unused').click(); | ||||
|             } else { | ||||
|                 $('#workspace-config-node-filter-all').click(); | ||||
|             } | ||||
|         } | ||||
|         refreshConfigNodeList(); | ||||
|         if (typeof id === "string") { | ||||
|             $('#workspace-config-node-filter-all').click(); | ||||
|             id = id.replace(/\./g,"-"); | ||||
|             setTimeout(function() { | ||||
|                 var node = $(".palette_node_id_"+id); | ||||
|                 var y = node.position().top; | ||||
|                 var h = node.height(); | ||||
|                 var scrollWindow = $(".sidebar-node-config"); | ||||
|                 var scrollHeight = scrollWindow.height(); | ||||
|  | ||||
|                 if (y+h > scrollHeight) { | ||||
|                     scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-30)},150); | ||||
|                 } else if (y<0) { | ||||
|                     scrollWindow.animate({scrollTop: '+='+(y-10)},150); | ||||
|                 } | ||||
|                 var flash = 21; | ||||
|                 var flashFunc = function() { | ||||
|                     if ((flash%2)===0) { | ||||
|                         node.removeClass('node_highlighted'); | ||||
|                     } else { | ||||
|                         node.addClass('node_highlighted'); | ||||
|                     } | ||||
|                     flash--; | ||||
|                     if (flash >= 0) { | ||||
|                         setTimeout(flashFunc,100); | ||||
|                     } | ||||
|                 } | ||||
|                 flashFunc(); | ||||
|             },100); | ||||
|         } | ||||
|         RED.sidebar.show("config"); | ||||
|     } | ||||
|     return { | ||||
|         init:init, | ||||
|         show:show, | ||||
|         refresh:refreshConfigNodeList | ||||
|     } | ||||
| })(); | ||||
| @@ -1,394 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
| RED.sidebar.info = (function() { | ||||
|  | ||||
|     marked.setOptions({ | ||||
|         renderer: new marked.Renderer(), | ||||
|         gfm: true, | ||||
|         tables: true, | ||||
|         breaks: false, | ||||
|         pedantic: false, | ||||
|         sanitize: true, | ||||
|         smartLists: true, | ||||
|         smartypants: false | ||||
|     }); | ||||
|  | ||||
|     var content; | ||||
|     var sections; | ||||
|     var nodeSection; | ||||
|     var infoSection; | ||||
|     var tipBox; | ||||
|  | ||||
|     var expandedSections = { | ||||
|         "property": false | ||||
|     }; | ||||
|  | ||||
|     function init() { | ||||
|  | ||||
|         content = document.createElement("div"); | ||||
|         content.className = "sidebar-node-info" | ||||
|  | ||||
|         RED.actions.add("core:show-info-tab",show); | ||||
|  | ||||
|         var stackContainer = $("<div>",{class:"sidebar-node-info-stack"}).appendTo(content); | ||||
|  | ||||
|         sections = RED.stack.create({ | ||||
|             container: stackContainer | ||||
|         }).hide(); | ||||
|  | ||||
|         nodeSection = sections.add({ | ||||
|             title: RED._("sidebar.info.node"), | ||||
|             collapsible: false | ||||
|         }); | ||||
|         infoSection = sections.add({ | ||||
|             title: RED._("sidebar.info.information"), | ||||
|             collapsible: false | ||||
|         }); | ||||
|         infoSection.content.css("padding","6px"); | ||||
|         infoSection.container.css("border-bottom","none"); | ||||
|  | ||||
|         var tipContainer = $('<div class="node-info-tips"></div>').appendTo(content); | ||||
|         tipBox = $('<div class="node-info-tip"></div>').appendTo(tipContainer); | ||||
|         var tipButtons = $('<div class="node-info-tips-buttons"></div>').appendTo(tipContainer); | ||||
|  | ||||
|         var tipRefresh = $('<a href="#" class="workspace-footer-button"><i class="fa fa-refresh"></a>').appendTo(tipButtons); | ||||
|         tipRefresh.click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             tips.next(); | ||||
|         }) | ||||
|  | ||||
|         var tipClose = $('<a href="#" class="workspace-footer-button"><i class="fa fa-times"></a>').appendTo(tipButtons); | ||||
|         tipClose.click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             RED.actions.invoke("core:toggle-show-tips"); | ||||
|             RED.notify(RED._("sidebar.info.showTips")); | ||||
|         }); | ||||
|  | ||||
|         RED.sidebar.addTab({ | ||||
|             id: "info", | ||||
|             label: RED._("sidebar.info.label"), | ||||
|             name: RED._("sidebar.info.name"), | ||||
|             content: content, | ||||
|             enableOnEdit: true | ||||
|         }); | ||||
|         if (tips.enabled()) { | ||||
|             tips.start(); | ||||
|         } else { | ||||
|             tips.stop(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function show() { | ||||
|         RED.sidebar.show("info"); | ||||
|     } | ||||
|  | ||||
|     function jsonFilter(key,value) { | ||||
|         if (key === "") { | ||||
|             return value; | ||||
|         } | ||||
|         var t = typeof value; | ||||
|         if ($.isArray(value)) { | ||||
|             return "[array:"+value.length+"]"; | ||||
|         } else if (t === "object") { | ||||
|             return "[object]" | ||||
|         } else if (t === "string") { | ||||
|             if (value.length > 30) { | ||||
|                 return value.substring(0,30)+" ..."; | ||||
|             } | ||||
|         } | ||||
|         return value; | ||||
|     } | ||||
|  | ||||
|     function addTargetToExternalLinks(el) { | ||||
|         $(el).find("a").each(function(el) { | ||||
|             var href = $(this).attr('href'); | ||||
|             if (/^https?:/.test(href)) { | ||||
|                 $(this).attr('target','_blank'); | ||||
|             } | ||||
|         }); | ||||
|         return el; | ||||
|     } | ||||
|     function refresh(node) { | ||||
|         sections.show(); | ||||
|         $(nodeSection.content).empty(); | ||||
|         $(infoSection.content).empty(); | ||||
|  | ||||
|         var table = $('<table class="node-info"></table>'); | ||||
|         var tableBody = $('<tbody>').appendTo(table); | ||||
|         var propRow; | ||||
|         var subflowNode; | ||||
|         if (node.type === "tab") { | ||||
|             nodeSection.title.html(RED._("sidebar.info.flow")); | ||||
|             propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.tabName")+'</td><td></td></tr>').appendTo(tableBody); | ||||
|             $(propRow.children()[1]).html(' '+(node.label||"")) | ||||
|             propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.id")+"</td><td></td></tr>").appendTo(tableBody); | ||||
|             RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]); | ||||
|             propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.status")+'</td><td></td></tr>').appendTo(tableBody); | ||||
|             $(propRow.children()[1]).html((!!!node.disabled)?RED._("sidebar.info.enabled"):RED._("sidebar.info.disabled")) | ||||
|         } else { | ||||
|             nodeSection.title.html(RED._("sidebar.info.node")); | ||||
|             if (node.type !== "subflow" && node.name) { | ||||
|                 $('<tr class="node-info-node-row"><td>'+RED._("common.label.name")+'</td><td> <span class="bidiAware" dir="'+RED.text.bidi.resolveBaseTextDir(node.name)+'">'+node.name+'</span></td></tr>').appendTo(tableBody); | ||||
|             } | ||||
|             $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.type")+"</td><td> "+node.type+"</td></tr>").appendTo(tableBody); | ||||
|             propRow = $('<tr class="node-info-node-row"><td>'+RED._("sidebar.info.id")+"</td><td></td></tr>").appendTo(tableBody); | ||||
|             RED.utils.createObjectElement(node.id).appendTo(propRow.children()[1]); | ||||
|  | ||||
|             var m = /^subflow(:(.+))?$/.exec(node.type); | ||||
|  | ||||
|             if (!m && node.type != "subflow" && node.type != "comment") { | ||||
|                 if (node._def) { | ||||
|                     var count = 0; | ||||
|                     var defaults = node._def.defaults; | ||||
|                     for (var n in defaults) { | ||||
|                         if (n != "name" && defaults.hasOwnProperty(n)) { | ||||
|                             var val = node[n]; | ||||
|                             var type = typeof val; | ||||
|                             count++; | ||||
|                             propRow = $('<tr class="node-info-property-row'+(expandedSections.property?"":" hide")+'"><td>'+n+"</td><td></td></tr>").appendTo(tableBody); | ||||
|                             if (defaults[n].type) { | ||||
|                                 var configNode = RED.nodes.node(val); | ||||
|                                 if (!configNode) { | ||||
|                                     RED.utils.createObjectElement(undefined).appendTo(propRow.children()[1]); | ||||
|                                 } else { | ||||
|                                     var configLabel = RED.utils.getNodeLabel(configNode,val); | ||||
|                                     var container = propRow.children()[1]; | ||||
|  | ||||
|                                     var div = $('<span>',{class:""}).appendTo(container); | ||||
|                                     var nodeDiv = $('<div>',{class:"palette_node palette_node_small"}).appendTo(div); | ||||
|                                     var colour = configNode._def.color; | ||||
|                                     var icon_url = RED.utils.getNodeIcon(configNode._def); | ||||
|                                     nodeDiv.css({'backgroundColor':colour, "cursor":"pointer"}); | ||||
|                                     var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv); | ||||
|                                     $('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); | ||||
|                                     var nodeContainer = $('<span></span>').css({"verticalAlign":"top","marginLeft":"6px"}).html(configLabel).appendTo(container); | ||||
|  | ||||
|                                     nodeDiv.on('dblclick',function() { | ||||
|                                         RED.editor.editConfig("", configNode.type, configNode.id); | ||||
|                                     }) | ||||
|  | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 RED.utils.createObjectElement(val).appendTo(propRow.children()[1]); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     if (count > 0) { | ||||
|                         $('<tr class="node-info-property-expand blank"><td colspan="2"><a href="#" class=" node-info-property-header'+(expandedSections.property?" expanded":"")+'"><span class="node-info-property-show-more">'+RED._("sidebar.info.showMore")+'</span><span class="node-info-property-show-less">'+RED._("sidebar.info.showLess")+'</span> <i class="fa fa-caret-down"></i></a></td></tr>').appendTo(tableBody); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (m) { | ||||
|                 if (m[2]) { | ||||
|                     subflowNode = RED.nodes.subflow(m[2]); | ||||
|                 } else { | ||||
|                     subflowNode = node; | ||||
|                 } | ||||
|  | ||||
|                 $('<tr class="blank"><th colspan="2">'+RED._("sidebar.info.subflow")+'</th></tr>').appendTo(tableBody); | ||||
|  | ||||
|                 var userCount = 0; | ||||
|                 var subflowType = "subflow:"+subflowNode.id; | ||||
|                 RED.nodes.eachNode(function(n) { | ||||
|                     if (n.type === subflowType) { | ||||
|                         userCount++; | ||||
|                     } | ||||
|                 }); | ||||
|                 $('<tr class="node-info-subflow-row"><td>'+RED._("common.label.name")+'</td><td><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(subflowNode.name)+'">'+subflowNode.name+'</span></td></tr>').appendTo(tableBody); | ||||
|                 $('<tr class="node-info-subflow-row"><td>'+RED._("sidebar.info.instances")+"</td><td>"+userCount+'</td></tr>').appendTo(tableBody); | ||||
|             } | ||||
|         } | ||||
|         $(table).appendTo(nodeSection.content); | ||||
|  | ||||
|         var infoText = ""; | ||||
|  | ||||
|         if (!subflowNode && node.type !== "comment" && node.type !== "tab") { | ||||
|             var helpText = $("script[data-help-name='"+node.type+"']").html()||""; | ||||
|             infoText = helpText; | ||||
|         } else if (node.type === "tab") { | ||||
|             infoText = marked(node.info||""); | ||||
|         } | ||||
|  | ||||
|         if (subflowNode) { | ||||
|             infoText = infoText + marked(subflowNode.info||""); | ||||
|         } else if (node._def && node._def.info) { | ||||
|             var info = node._def.info; | ||||
|             var textInfo = (typeof info === "function" ? info.call(node) : info); | ||||
|             // TODO: help | ||||
|             infoText = infoText + marked(textInfo); | ||||
|         } | ||||
|         if (infoText) { | ||||
|             setInfoText(infoText); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $(".node-info-property-header").click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             expandedSections["property"] = !expandedSections["property"]; | ||||
|             $(this).toggleClass("expanded",expandedSections["property"]); | ||||
|             $(".node-info-property-row").toggle(expandedSections["property"]); | ||||
|         }); | ||||
|     } | ||||
|     function setInfoText(infoText) { | ||||
|         var info = addTargetToExternalLinks($('<div class="node-help"><span class="bidiAware" dir=\"'+RED.text.bidi.resolveBaseTextDir(infoText)+'">'+infoText+'</span></div>')).appendTo(infoSection.content); | ||||
|         info.find(".bidiAware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" ); | ||||
|         var foldingHeader = "H3"; | ||||
|         info.find(foldingHeader).wrapInner('<a class="node-info-header expanded" href="#"></a>') | ||||
|             .find("a").prepend('<i class="fa fa-angle-right">').click(function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 var isExpanded = $(this).hasClass('expanded'); | ||||
|                 var el = $(this).parent().next(); | ||||
|                 while(el.length === 1 && el[0].nodeName !== foldingHeader) { | ||||
|                     el.toggle(!isExpanded); | ||||
|                     el = el.next(); | ||||
|                 } | ||||
|                 $(this).toggleClass('expanded',!isExpanded); | ||||
|             }) | ||||
|     } | ||||
|     var tips = (function() { | ||||
|         var enabled = true; | ||||
|         var startDelay = 1000; | ||||
|         var cycleDelay = 15000; | ||||
|         var startTimeout; | ||||
|         var refreshTimeout; | ||||
|         var tipCount = -1; | ||||
|  | ||||
|         RED.actions.add("core:toggle-show-tips",function(state) { | ||||
|             if (state === undefined) { | ||||
|                 RED.userSettings.toggle("view-show-tips"); | ||||
|             } else { | ||||
|                 enabled = state; | ||||
|                 if (enabled) { | ||||
|                     startTips(); | ||||
|                 } else { | ||||
|                     stopTips(); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         function setTip() { | ||||
|             var r = Math.floor(Math.random() * tipCount); | ||||
|             var tip = RED._("infotips:info.tip"+r); | ||||
|  | ||||
|             var m; | ||||
|             while ((m=/({{(.*?)}})/.exec(tip))) { | ||||
|                 var shortcut = RED.keyboard.getShortcut(m[2]); | ||||
|                 if (shortcut) { | ||||
|                     tip = tip.replace(m[1],RED.keyboard.formatKey(shortcut.key)); | ||||
|                 } else { | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|             while ((m=/(\[(.*?)\])/.exec(tip))) { | ||||
|                 tip = tip.replace(m[1],RED.keyboard.formatKey(m[2])); | ||||
|             } | ||||
|             tipBox.html(tip).fadeIn(200); | ||||
|             if (startTimeout) { | ||||
|                 startTimeout = null; | ||||
|                 refreshTimeout = setInterval(cycleTips,cycleDelay); | ||||
|             } | ||||
|         } | ||||
|         function cycleTips() { | ||||
|             tipBox.fadeOut(300,function() { | ||||
|                 setTip(); | ||||
|             }) | ||||
|         } | ||||
|         function startTips() { | ||||
|             $(".sidebar-node-info").addClass('show-tips'); | ||||
|             if (enabled) { | ||||
|                 if (!startTimeout && !refreshTimeout) { | ||||
|                     if (tipCount === -1) { | ||||
|                         do { | ||||
|                             tipCount++; | ||||
|                         } while(RED._("infotips:info.tip"+tipCount)!=="infotips:info.tip"+tipCount); | ||||
|                     } | ||||
|                     startTimeout = setTimeout(setTip,startDelay); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         function stopTips() { | ||||
|             $(".sidebar-node-info").removeClass('show-tips'); | ||||
|             clearInterval(refreshTimeout); | ||||
|             clearTimeout(startTimeout); | ||||
|             refreshTimeout = null; | ||||
|             startTimeout = null; | ||||
|         } | ||||
|         function nextTip() { | ||||
|             clearInterval(refreshTimeout); | ||||
|             startTimeout = true; | ||||
|             setTip(); | ||||
|         } | ||||
|         return { | ||||
|             start: startTips, | ||||
|             stop: stopTips, | ||||
|             next: nextTip, | ||||
|             enabled: function() { return enabled; } | ||||
|         } | ||||
|     })(); | ||||
|  | ||||
|     function clear() { | ||||
|         sections.hide(); | ||||
|         // | ||||
|     } | ||||
|  | ||||
|     function set(html) { | ||||
|         // tips.stop(); | ||||
|         sections.show(); | ||||
|         nodeSection.container.hide(); | ||||
|         $(infoSection.content).empty(); | ||||
|         setInfoText(html); | ||||
|         $(".sidebar-node-info-stack").scrollTop(0); | ||||
|     } | ||||
|  | ||||
|  | ||||
|  | ||||
|     RED.events.on("view:selection-changed",function(selection) { | ||||
|         if (selection.nodes) { | ||||
|             if (selection.nodes.length == 1) { | ||||
|                 var node = selection.nodes[0]; | ||||
|                 if (node.type === "subflow" && node.direction) { | ||||
|                     refresh(RED.nodes.subflow(node.z)); | ||||
|                 } else { | ||||
|                     refresh(node); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             var activeWS = RED.workspaces.active(); | ||||
|  | ||||
|             var flow = RED.nodes.workspace(activeWS) || RED.nodes.subflow(activeWS); | ||||
|             if (flow) { | ||||
|                 refresh(flow); | ||||
|             } else { | ||||
|                 var workspace = RED.nodes.workspace(RED.workspaces.active()); | ||||
|                 if (workspace && workspace.info) { | ||||
|                     refresh(workspace); | ||||
|                 } else { | ||||
|                     clear(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     return { | ||||
|         init: init, | ||||
|         show: show, | ||||
|         refresh: refresh, | ||||
|         clear: clear, | ||||
|         set: set | ||||
|     } | ||||
| })(); | ||||
| @@ -1,295 +0,0 @@ | ||||
| RED.typeSearch = (function() { | ||||
|  | ||||
|     var shade; | ||||
|  | ||||
|     var disabled = false; | ||||
|     var dialog = null; | ||||
|     var searchInput; | ||||
|     var searchResults; | ||||
|     var searchResultsDiv; | ||||
|     var selected = -1; | ||||
|     var visible = false; | ||||
|  | ||||
|     var activeFilter = ""; | ||||
|     var addCallback; | ||||
|  | ||||
|     var typesUsed = {}; | ||||
|  | ||||
|     function search(val) { | ||||
|         activeFilter = val.toLowerCase(); | ||||
|         var visible = searchResults.editableList('filter'); | ||||
|         setTimeout(function() { | ||||
|             selected = 0; | ||||
|             searchResults.children().removeClass('selected'); | ||||
|             searchResults.children(":visible:first").addClass('selected'); | ||||
|         },100); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function ensureSelectedIsVisible() { | ||||
|         var selectedEntry = searchResults.find("li.selected"); | ||||
|         if (selectedEntry.length === 1) { | ||||
|             var scrollWindow = searchResults.parent(); | ||||
|             var scrollHeight = scrollWindow.height(); | ||||
|             var scrollOffset = scrollWindow.scrollTop(); | ||||
|             var y = selectedEntry.position().top; | ||||
|             var h = selectedEntry.height(); | ||||
|             if (y+h > scrollHeight) { | ||||
|                 scrollWindow.animate({scrollTop: '-='+(scrollHeight-(y+h)-10)},50); | ||||
|             } else if (y<0) { | ||||
|                 scrollWindow.animate({scrollTop: '+='+(y-10)},50); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function createDialog() { | ||||
|         //shade = $('<div>',{class:"red-ui-type-search-shade"}).appendTo("#main-container"); | ||||
|         dialog = $("<div>",{id:"red-ui-type-search",class:"red-ui-search red-ui-type-search"}).appendTo("#main-container"); | ||||
|         var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog); | ||||
|         searchInput = $('<input type="text">').attr("placeholder",RED._("search.addNode")).appendTo(searchDiv).searchBox({ | ||||
|             delay: 50, | ||||
|             change: function() { | ||||
|                 search($(this).val()); | ||||
|             } | ||||
|         }); | ||||
|         searchInput.on('keydown',function(evt) { | ||||
|             var children = searchResults.children(":visible"); | ||||
|             if (children.length > 0) { | ||||
|                 if (evt.keyCode === 40) { | ||||
|                     // Down | ||||
|                     if (selected < children.length-1) { | ||||
|                         if (selected > -1) { | ||||
|                             $(children[selected]).removeClass('selected'); | ||||
|                         } | ||||
|                         selected++; | ||||
|                     } | ||||
|                     $(children[selected]).addClass('selected'); | ||||
|                     ensureSelectedIsVisible(); | ||||
|                     evt.preventDefault(); | ||||
|                 } else if (evt.keyCode === 38) { | ||||
|                     // Up | ||||
|                     if (selected > 0) { | ||||
|                         if (selected < children.length) { | ||||
|                             $(children[selected]).removeClass('selected'); | ||||
|                         } | ||||
|                         selected--; | ||||
|                     } | ||||
|                     $(children[selected]).addClass('selected'); | ||||
|                     ensureSelectedIsVisible(); | ||||
|                     evt.preventDefault(); | ||||
|                 } else if (evt.keyCode === 13) { | ||||
|                     // Enter | ||||
|                     var index = Math.max(0,selected); | ||||
|                     if (index < children.length) { | ||||
|                         // TODO: dips into editableList impl details | ||||
|                         confirm($(children[index]).find(".red-ui-editableList-item-content").data('data')); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         searchResultsDiv = $("<div>",{class:"red-ui-search-results-container"}).appendTo(dialog); | ||||
|         searchResults = $('<ol>',{id:"search-result-list", style:"position: absolute;top: 0;bottom: 0;left: 0;right: 0;"}).appendTo(searchResultsDiv).editableList({ | ||||
|             addButton: false, | ||||
|             filter: function(data) { | ||||
|                 if (activeFilter === "" ) { | ||||
|                     return true; | ||||
|                 } | ||||
|                 if (data.recent || data.common) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 return (activeFilter==="")||(data.index.indexOf(activeFilter) > -1); | ||||
|             }, | ||||
|             addItem: function(container,i,object) { | ||||
|                 var def = object.def; | ||||
|                 object.index = object.type.toLowerCase(); | ||||
|                 if (object.separator) { | ||||
|                     container.addClass("red-ui-search-result-separator") | ||||
|                 } | ||||
|                 var div = $('<a>',{href:'#',class:"red-ui-search-result"}).appendTo(container); | ||||
|  | ||||
|                 var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).appendTo(div); | ||||
|                 var colour = def.color; | ||||
|                 var icon_url = RED.utils.getNodeIcon(def); | ||||
|                 nodeDiv.css('backgroundColor',colour); | ||||
|  | ||||
|                 var iconContainer = $('<div/>',{class:"palette_icon_container"}).appendTo(nodeDiv); | ||||
|                 $('<div/>',{class:"palette_icon",style:"background-image: url("+icon_url+")"}).appendTo(iconContainer); | ||||
|  | ||||
|                 if (def.inputs > 0) { | ||||
|                     $('<div/>',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv); | ||||
|                 } | ||||
|                 if (def.outputs > 0) { | ||||
|                     $('<div/>',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv); | ||||
|                 } | ||||
|  | ||||
|                 var contentDiv = $('<div>',{class:"red-ui-search-result-description"}).appendTo(div); | ||||
|  | ||||
|                 var label = object.label; | ||||
|                 object.index += "|"+label.toLowerCase(); | ||||
|  | ||||
|                 $('<div>',{class:"red-ui-search-result-node-label"}).html(label).appendTo(contentDiv); | ||||
|  | ||||
|                 div.click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     confirm(object); | ||||
|                 }); | ||||
|             }, | ||||
|             scrollOnAdd: false | ||||
|         }); | ||||
|  | ||||
|     } | ||||
|     function confirm(def) { | ||||
|         hide(); | ||||
|         typesUsed[def.type] = Date.now(); | ||||
|         addCallback(def.type); | ||||
|     } | ||||
|  | ||||
|     function handleMouseActivity(evt) { | ||||
|         if (visible) { | ||||
|             var t = $(evt.target); | ||||
|             while (t.prop('nodeName').toLowerCase() !== 'body') { | ||||
|                 if (t.attr('id') === 'red-ui-type-search') { | ||||
|                     return; | ||||
|                 } | ||||
|                 t = t.parent(); | ||||
|             } | ||||
|             hide(true); | ||||
|         } | ||||
|     } | ||||
|     function show(opts) { | ||||
|         if (!visible) { | ||||
|             RED.keyboard.add("*","escape",function(){hide()}); | ||||
|             if (dialog === null) { | ||||
|                 createDialog(); | ||||
|             } | ||||
|             visible = true; | ||||
|             setTimeout(function() { | ||||
|                 $(document).on('mousedown.type-search',handleMouseActivity); | ||||
|                 $(document).on('mouseup.type-search',handleMouseActivity); | ||||
|                 $(document).on('click.type-search',handleMouseActivity); | ||||
|             },200); | ||||
|         } else { | ||||
|             dialog.hide(); | ||||
|             searchResultsDiv.hide(); | ||||
|         } | ||||
|         refreshTypeList(); | ||||
|         addCallback = opts.add; | ||||
|         RED.events.emit("type-search:open"); | ||||
|         //shade.show(); | ||||
|         dialog.css({left:opts.x+"px",top:opts.y+"px"}).show(); | ||||
|         searchResultsDiv.slideDown(300); | ||||
|         setTimeout(function() { | ||||
|             searchResultsDiv.find(".red-ui-editableList-container").scrollTop(0); | ||||
|             searchInput.focus(); | ||||
|         },100); | ||||
|     } | ||||
|     function hide(fast) { | ||||
|         if (visible) { | ||||
|             RED.keyboard.remove("escape"); | ||||
|             visible = false; | ||||
|             if (dialog !== null) { | ||||
|                 searchResultsDiv.slideUp(fast?50:200,function() { | ||||
|                     dialog.hide(); | ||||
|                     searchInput.searchBox('value',''); | ||||
|                 }); | ||||
|                 //shade.hide(); | ||||
|             } | ||||
|             RED.events.emit("type-search:close"); | ||||
|             RED.view.focus(); | ||||
|             $(document).off('mousedown.type-search'); | ||||
|             $(document).off('mouseup.type-search'); | ||||
|             $(document).off('click.type-search'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function getTypeLabel(type, def) { | ||||
|         var label = type; | ||||
|         if (typeof def.paletteLabel !== "undefined") { | ||||
|             try { | ||||
|                 label = (typeof def.paletteLabel === "function" ? def.paletteLabel.call(def) : def.paletteLabel)||""; | ||||
|                 label += " ("+type+")"; | ||||
|             } catch(err) { | ||||
|                 console.log("Definition error: "+type+".paletteLabel",err); | ||||
|             } | ||||
|         } | ||||
|         return label; | ||||
|     } | ||||
|  | ||||
|     function refreshTypeList() { | ||||
|         var i; | ||||
|         searchResults.editableList('empty'); | ||||
|         searchInput.searchBox('value',''); | ||||
|         selected = -1; | ||||
|         var common = [ | ||||
|             'inject','debug','function','change','switch' | ||||
|         ]; | ||||
|  | ||||
|         var recentlyUsed = Object.keys(typesUsed); | ||||
|         recentlyUsed.sort(function(a,b) { | ||||
|             return typesUsed[b]-typesUsed[a]; | ||||
|         }); | ||||
|         recentlyUsed = recentlyUsed.filter(function(t) { | ||||
|             return common.indexOf(t) === -1; | ||||
|         }); | ||||
|  | ||||
|         var items = []; | ||||
|         RED.nodes.registry.getNodeTypes().forEach(function(t) { | ||||
|             var def = RED.nodes.getType(t); | ||||
|             if (def.category !== 'config' && t !== 'unknown' && t !== 'tab') { | ||||
|                 items.push({type:t,def: def, label:getTypeLabel(t,def)}); | ||||
|             } | ||||
|         }); | ||||
|         items.sort(function(a,b) { | ||||
|             var al = a.label.toLowerCase(); | ||||
|             var bl = b.label.toLowerCase(); | ||||
|             if (al < bl) { | ||||
|                 return -1; | ||||
|             } else if (al === bl) { | ||||
|                 return 0; | ||||
|             } else { | ||||
|                 return 1; | ||||
|             } | ||||
|         }) | ||||
|  | ||||
|         var commonCount = 0; | ||||
|         var item; | ||||
|         for(i=0;i<common.length;i++) { | ||||
|             item = { | ||||
|                 type: common[i], | ||||
|                 common: true, | ||||
|                 def: RED.nodes.getType(common[i]) | ||||
|             }; | ||||
|             item.label = getTypeLabel(item.type,item.def); | ||||
|             if (i === common.length-1) { | ||||
|                 item.separator = true; | ||||
|             } | ||||
|             searchResults.editableList('addItem', item); | ||||
|         } | ||||
|         for(i=0;i<Math.min(5,recentlyUsed.length);i++) { | ||||
|             item = { | ||||
|                 type:recentlyUsed[i], | ||||
|                 def: RED.nodes.getType(recentlyUsed[i]), | ||||
|                 recent: true | ||||
|             }; | ||||
|             item.label = getTypeLabel(item.type,item.def); | ||||
|             if (i === recentlyUsed.length-1) { | ||||
|                 item.separator = true; | ||||
|             } | ||||
|             searchResults.editableList('addItem', item); | ||||
|         } | ||||
|         for (i=0;i<items.length;i++) { | ||||
|             searchResults.editableList('addItem', items[i]); | ||||
|         } | ||||
|         setTimeout(function() { | ||||
|             selected = 0; | ||||
|             searchResults.children(":first").addClass('selected'); | ||||
|         },100); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         show: show, | ||||
|         hide: hide | ||||
|     }; | ||||
|  | ||||
| })(); | ||||
| @@ -1,741 +0,0 @@ | ||||
| /** | ||||
|  * Copyright JS Foundation and other contributors, http://js.foundation | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  **/ | ||||
|  | ||||
| RED.utils = (function() { | ||||
|  | ||||
|     function formatString(str) { | ||||
|         return str.replace(/\r?\n/g,"↵").replace(/\t/g,"→"); | ||||
|     } | ||||
|     function sanitize(m) { | ||||
|         return m.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"); | ||||
|     } | ||||
|  | ||||
|     function buildMessageSummaryValue(value) { | ||||
|         var result; | ||||
|         if (Array.isArray(value)) { | ||||
|             result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').html('array['+value.length+']'); | ||||
|         } else if (value === null) { | ||||
|             result = $('<span class="debug-message-object-value debug-message-type-null">null</span>'); | ||||
|         } else if (typeof value === 'object') { | ||||
|             if (value.hasOwnProperty('type') && value.type === 'Buffer' && value.hasOwnProperty('data')) { | ||||
|                 result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').html('buffer['+value.length+']'); | ||||
|             } else if (value.hasOwnProperty('type') && value.type === 'array' && value.hasOwnProperty('data')) { | ||||
|                 result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').html('array['+value.length+']'); | ||||
|             } else { | ||||
|                 result = $('<span class="debug-message-object-value debug-message-type-meta">object</span>'); | ||||
|             } | ||||
|         } else if (typeof value === 'string') { | ||||
|             var subvalue; | ||||
|             if (value.length > 30) { | ||||
|                 subvalue = sanitize(value.substring(0,30))+"…"; | ||||
|             } else { | ||||
|                 subvalue = sanitize(value); | ||||
|             } | ||||
|             result = $('<span class="debug-message-object-value debug-message-type-string"></span>').html('"'+formatString(subvalue)+'"'); | ||||
|         } else { | ||||
|             result = $('<span class="debug-message-object-value debug-message-type-other"></span>').text(""+value); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     function makeExpandable(el,onbuild,ontoggle,expand) { | ||||
|         el.addClass("debug-message-expandable"); | ||||
|         el.prop('toggle',function() { | ||||
|             return function(state) { | ||||
|                 var parent = el.parent(); | ||||
|                 if (parent.hasClass('collapsed')) { | ||||
|                     if (state) { | ||||
|                         if (onbuild && !parent.hasClass('built')) { | ||||
|                             onbuild(); | ||||
|                             parent.addClass('built'); | ||||
|                         } | ||||
|                         parent.removeClass('collapsed'); | ||||
|                         return true; | ||||
|                     } | ||||
|                 } else { | ||||
|                     if (!state) { | ||||
|                         parent.addClass('collapsed'); | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|         }); | ||||
|         el.click(function(e) { | ||||
|             var parent = $(this).parent(); | ||||
|             var currentState = !parent.hasClass('collapsed'); | ||||
|             if ($(this).prop('toggle')(!currentState)) { | ||||
|                 if (ontoggle) { | ||||
|                     ontoggle(!currentState); | ||||
|                 } | ||||
|             } | ||||
|             // if (parent.hasClass('collapsed')) { | ||||
|             //     if (onbuild && !parent.hasClass('built')) { | ||||
|             //         onbuild(); | ||||
|             //         parent.addClass('built'); | ||||
|             //     } | ||||
|             //     if (ontoggle) { | ||||
|             //         ontoggle(true); | ||||
|             //     } | ||||
|             //     parent.removeClass('collapsed'); | ||||
|             // } else { | ||||
|             //     parent.addClass('collapsed'); | ||||
|             //     if (ontoggle) { | ||||
|             //         ontoggle(false); | ||||
|             //     } | ||||
|             // } | ||||
|             e.preventDefault(); | ||||
|         }); | ||||
|         if (expand) { | ||||
|             el.click(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     var pinnedPaths = {}; | ||||
|     var formattedPaths = {}; | ||||
|  | ||||
|     function addMessageControls(obj,sourceId,key,msg,rootPath,strippedKey) { | ||||
|         if (!pinnedPaths.hasOwnProperty(sourceId)) { | ||||
|             pinnedPaths[sourceId] = {} | ||||
|         } | ||||
|         var tools = $('<span class="debug-message-tools"></span>').appendTo(obj); | ||||
|         var copyTools = $('<span class="debug-message-tools-copy button-group"></span>').appendTo(tools); | ||||
|         if (!!key) { | ||||
|             var copyPath = $('<button class="editor-button editor-button-small"><i class="fa fa-terminal"></i></button>').appendTo(copyTools).click(function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 e.stopPropagation(); | ||||
|                 RED.clipboard.copyText(key,copyPath,"clipboard.copyMessagePath"); | ||||
|             }) | ||||
|         } | ||||
|         var copyPayload = $('<button class="editor-button editor-button-small"><i class="fa fa-clipboard"></i></button>').appendTo(copyTools).click(function(e) { | ||||
|             e.preventDefault(); | ||||
|             e.stopPropagation(); | ||||
|             RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue"); | ||||
|         }) | ||||
|         if (strippedKey !== '') { | ||||
|             var isPinned = pinnedPaths[sourceId].hasOwnProperty(strippedKey); | ||||
|  | ||||
|             var pinPath = $('<button class="editor-button editor-button-small debug-message-tools-pin"><i class="fa fa-map-pin"></i></button>').appendTo(tools).click(function(e) { | ||||
|                 e.preventDefault(); | ||||
|                 e.stopPropagation(); | ||||
|                 if (pinnedPaths[sourceId].hasOwnProperty(strippedKey)) { | ||||
|                     delete pinnedPaths[sourceId][strippedKey]; | ||||
|                     $(this).removeClass("selected"); | ||||
|                     obj.removeClass("debug-message-row-pinned"); | ||||
|                 } else { | ||||
|                     var rootedPath = "$"+(strippedKey[0] === '['?"":".")+strippedKey; | ||||
|                     pinnedPaths[sourceId][strippedKey] = normalisePropertyExpression(rootedPath); | ||||
|                     $(this).addClass("selected"); | ||||
|                     obj.addClass("debug-message-row-pinned"); | ||||
|                 } | ||||
|             }).toggleClass("selected",isPinned); | ||||
|             obj.toggleClass("debug-message-row-pinned",isPinned); | ||||
|         } | ||||
|     } | ||||
|     function checkExpanded(strippedKey,expandPaths,minRange,maxRange) { | ||||
|         if (expandPaths && expandPaths.length > 0) { | ||||
|             if (strippedKey === '' && minRange === undefined) { | ||||
|                 return true; | ||||
|             } | ||||
|             for (var i=0;i<expandPaths.length;i++) { | ||||
|                 var p = expandPaths[i]; | ||||
|                 if (p.indexOf(strippedKey) === 0 && (p[strippedKey.length] === "." ||  p[strippedKey.length] === "[") ) { | ||||
|  | ||||
|                     if (minRange !== undefined && p[strippedKey.length] === "[") { | ||||
|                         var subkey = p.substring(strippedKey.length); | ||||
|                         var m = (/\[(\d+)\]/.exec(subkey)); | ||||
|                         if (m) { | ||||
|                             var index = parseInt(m[1]); | ||||
|                             return minRange<=index && index<=maxRange; | ||||
|                         } | ||||
|                     } else { | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     function formatNumber(element,obj,sourceId,path,cycle,initialFormat) { | ||||
|         var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path]) || initialFormat || "dec"; | ||||
|         if (cycle) { | ||||
|             if (format === 'dec') { | ||||
|                 if ((obj.toString().length===13) && (obj<=2147483647000)) { | ||||
|                     format = 'dateMS'; | ||||
|                 } else if ((obj.toString().length===10) && (obj<=2147483647)) { | ||||
|                     format = 'dateS'; | ||||
|                 } else { | ||||
|                     format = 'hex' | ||||
|                 } | ||||
|             } else if (format === 'dateMS' || format == 'dateS') { | ||||
|                 format = 'hex'; | ||||
|             } else { | ||||
|                 format = 'dec'; | ||||
|             } | ||||
|             formattedPaths[sourceId] = formattedPaths[sourceId]||{}; | ||||
|             formattedPaths[sourceId][path] = format; | ||||
|         } else if (initialFormat !== undefined){ | ||||
|             formattedPaths[sourceId] = formattedPaths[sourceId]||{}; | ||||
|             formattedPaths[sourceId][path] = format; | ||||
|         } | ||||
|         if (format === 'dec') { | ||||
|             element.text(""+obj); | ||||
|         } else if (format === 'dateMS') { | ||||
|             element.text((new Date(obj)).toISOString()); | ||||
|         } else if (format === 'dateS') { | ||||
|             element.text((new Date(obj*1000)).toISOString()); | ||||
|         } else if (format === 'hex') { | ||||
|             element.text("0x"+(obj).toString(16)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function formatBuffer(element,button,sourceId,path,cycle) { | ||||
|         var format = (formattedPaths[sourceId] && formattedPaths[sourceId][path]) || "raw"; | ||||
|         if (cycle) { | ||||
|             if (format === 'raw') { | ||||
|                 format = 'string'; | ||||
|             } else { | ||||
|                 format = 'raw'; | ||||
|             } | ||||
|             formattedPaths[sourceId] = formattedPaths[sourceId]||{}; | ||||
|             formattedPaths[sourceId][path] = format; | ||||
|         } | ||||
|         if (format === 'raw') { | ||||
|             button.text('raw'); | ||||
|             element.removeClass('debug-message-buffer-string').addClass('debug-message-buffer-raw'); | ||||
|         } else if (format === 'string') { | ||||
|             button.text('string'); | ||||
|             element.addClass('debug-message-buffer-string').removeClass('debug-message-buffer-raw'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function buildMessageElement(obj,options) { | ||||
|         options = options || {}; | ||||
|         var key = options.key; | ||||
|         var typeHint = options.typeHint; | ||||
|         var hideKey = options.hideKey; | ||||
|         var path = options.path; | ||||
|         var sourceId = options.sourceId; | ||||
|         var rootPath = options.rootPath; | ||||
|         var expandPaths = options.expandPaths; | ||||
|         var ontoggle = options.ontoggle; | ||||
|         var exposeApi = options.exposeApi; | ||||
|  | ||||
|         var subElements = {}; | ||||
|         var i; | ||||
|         var e; | ||||
|         var entryObj; | ||||
|         var expandableHeader; | ||||
|         var header; | ||||
|         var headerHead; | ||||
|         var value; | ||||
|         var strippedKey; | ||||
|         if (path !== undefined && rootPath !== undefined) { | ||||
|              strippedKey = path.substring(rootPath.length+(path[rootPath.length]==="."?1:0)); | ||||
|         } | ||||
|         var element = $('<span class="debug-message-element"></span>'); | ||||
|         element.collapse = function() { | ||||
|             element.find(".debug-message-expandable").parent().addClass("collapsed"); | ||||
|         } | ||||
|         header = $('<span class="debug-message-row"></span>').appendTo(element); | ||||
|         if (sourceId) { | ||||
|             addMessageControls(header,sourceId,path,obj,rootPath,strippedKey); | ||||
|         } | ||||
|         if (!key) { | ||||
|             element.addClass("debug-message-top-level"); | ||||
|             if (sourceId) { | ||||
|                 var pinned = pinnedPaths[sourceId]; | ||||
|                 expandPaths = []; | ||||
|                 if (pinned) { | ||||
|                     for (var pinnedPath in pinned) { | ||||
|                         if (pinned.hasOwnProperty(pinnedPath)) { | ||||
|                             try { | ||||
|                                 var res = getMessageProperty({$:obj},pinned[pinnedPath]); | ||||
|                                 if (res !== undefined) { | ||||
|                                     expandPaths.push(pinnedPath); | ||||
|                                 } | ||||
|                             } catch(err) { | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     expandPaths.sort(); | ||||
|                 } | ||||
|                 element.clearPinned = function() { | ||||
|                     element.find(".debug-message-row-pinned").removeClass("debug-message-row-pinned"); | ||||
|                     pinnedPaths[sourceId] = {}; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             if (!hideKey) { | ||||
|                 $('<span class="debug-message-object-key"></span>').text(key).appendTo(header); | ||||
|                 $('<span>: </span>').appendTo(header); | ||||
|             } | ||||
|         } | ||||
|         entryObj = $('<span class="debug-message-object-value"></span>').appendTo(header); | ||||
|  | ||||
|         var isArray = Array.isArray(obj); | ||||
|         var isArrayObject = false; | ||||
|         if (obj && typeof obj === 'object' && obj.hasOwnProperty('type') && obj.hasOwnProperty('data') && ((obj.__encoded__ && obj.type === 'array') || obj.type === 'Buffer')) { | ||||
|             isArray = true; | ||||
|             isArrayObject = true; | ||||
|         } | ||||
|  | ||||
|         if (obj === null || obj === undefined) { | ||||
|             $('<span class="debug-message-type-null">'+obj+'</span>').appendTo(entryObj); | ||||
|         } else if (typeof obj === 'string') { | ||||
|             if (/[\t\n\r]/.test(obj)) { | ||||
|                 element.addClass('collapsed'); | ||||
|                 $('<i class="fa fa-caret-right debug-message-object-handle"></i> ').prependTo(header); | ||||
|                 makeExpandable(header, function() { | ||||
|                     $('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||'string').appendTo(header); | ||||
|                     var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element); | ||||
|                     $('<pre class="debug-message-type-string"></pre>').text(obj).appendTo(row); | ||||
|                 },function(state) {if (ontoggle) { ontoggle(path,state);}}, checkExpanded(strippedKey,expandPaths)); | ||||
|             } | ||||
|             e = $('<span class="debug-message-type-string debug-message-object-header"></span>').html('"'+formatString(sanitize(obj))+'"').appendTo(entryObj); | ||||
|             if (/^#[0-9a-f]{6}$/i.test(obj)) { | ||||
|                 $('<span class="debug-message-type-string-swatch"></span>').css('backgroundColor',obj).appendTo(e); | ||||
|             } | ||||
|  | ||||
|         } else if (typeof obj === 'number') { | ||||
|             e = $('<span class="debug-message-type-number"></span>').appendTo(entryObj); | ||||
|  | ||||
|             if (Number.isInteger(obj) && (obj >= 0)) { // if it's a +ve integer | ||||
|                 e.addClass("debug-message-type-number-toggle"); | ||||
|                 e.click(function(evt) { | ||||
|                     evt.preventDefault(); | ||||
|                     formatNumber($(this), obj, sourceId, path, true); | ||||
|                 }); | ||||
|             } | ||||
|             formatNumber(e,obj,sourceId,path,false,typeHint==='hex'?'hex':undefined); | ||||
|  | ||||
|         } else if (isArray) { | ||||
|             element.addClass('collapsed'); | ||||
|  | ||||
|             var originalLength = obj.length; | ||||
|             if (typeHint) { | ||||
|                 var m = /\[(\d+)\]/.exec(typeHint); | ||||
|                 if (m) { | ||||
|                     originalLength = parseInt(m[1]); | ||||
|                 } | ||||
|             } | ||||
|             var data = obj; | ||||
|             var type = 'array'; | ||||
|             if (isArrayObject) { | ||||
|                 data = obj.data; | ||||
|                 if (originalLength === undefined) { | ||||
|                     originalLength = data.length; | ||||
|                 } | ||||
|                 if (data.__encoded__) { | ||||
|                     data = data.data; | ||||
|                 } | ||||
|                 type = obj.type.toLowerCase(); | ||||
|             } else if (/buffer/.test(typeHint)) { | ||||
|                 type = 'buffer'; | ||||
|             } | ||||
|             var fullLength = data.length; | ||||
|  | ||||
|                 if (originalLength > 0) { | ||||
|                 $('<i class="fa fa-caret-right debug-message-object-handle"></i> ').prependTo(header); | ||||
|                 var arrayRows = $('<div class="debug-message-array-rows"></div>').appendTo(element); | ||||
|                 element.addClass('debug-message-buffer-raw'); | ||||
|             } | ||||
|             if (key) { | ||||
|                 headerHead = $('<span class="debug-message-type-meta"></span>').html(typeHint||(type+'['+originalLength+']')).appendTo(entryObj); | ||||
|             } else { | ||||
|                 headerHead = $('<span class="debug-message-object-header"></span>').appendTo(entryObj); | ||||
|                 $('<span>[ </span>').appendTo(headerHead); | ||||
|                 var arrayLength = Math.min(originalLength,10); | ||||
|                 for (i=0;i<arrayLength;i++) { | ||||
|                     buildMessageSummaryValue(data[i]).appendTo(headerHead); | ||||
|                     if (i < arrayLength-1) { | ||||
|                         $('<span>, </span>').appendTo(headerHead); | ||||
|                     } | ||||
|                 } | ||||
|                 if (originalLength > arrayLength) { | ||||
|                     $('<span> …</span>').appendTo(headerHead); | ||||
|                 } | ||||
|                 if (arrayLength === 0) { | ||||
|                     $('<span class="debug-message-type-meta">empty</span>').appendTo(headerHead); | ||||
|                 } | ||||
|                 $('<span> ]</span>').appendTo(headerHead); | ||||
|             } | ||||
|             if (originalLength > 0) { | ||||
|  | ||||
|                 makeExpandable(header,function() { | ||||
|                     if (!key) { | ||||
|                         headerHead = $('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html(typeHint||(type+'['+originalLength+']')).appendTo(header); | ||||
|                     } | ||||
|                     if (type === 'buffer') { | ||||
|                         var stringRow = $('<div class="debug-message-string-rows"></div>').appendTo(element); | ||||
|                         var sr = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(stringRow); | ||||
|                         var stringEncoding = ""; | ||||
|                         try { | ||||
|                             stringEncoding = String.fromCharCode.apply(null, new Uint16Array(data)) | ||||
|                         } catch(err) { | ||||
|                             console.log(err); | ||||
|                         } | ||||
|                         $('<pre class="debug-message-type-string"></pre>').text(stringEncoding).appendTo(sr); | ||||
|                         var bufferOpts = $('<span class="debug-message-buffer-opts"></span>').appendTo(headerHead); | ||||
|                         var switchFormat = $('<a href="#"></a>').addClass('selected').html('raw').appendTo(bufferOpts).click(function(e) { | ||||
|                             e.preventDefault(); | ||||
|                             e.stopPropagation(); | ||||
|                             formatBuffer(element,$(this),sourceId,path,true); | ||||
|                         }); | ||||
|                         formatBuffer(element,switchFormat,sourceId,path,false); | ||||
|  | ||||
|                     } | ||||
|                     var row; | ||||
|                     if (fullLength <= 10) { | ||||
|                         for (i=0;i<fullLength;i++) { | ||||
|                             row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(arrayRows); | ||||
|                             subElements[path+"["+i+"]"] = buildMessageElement( | ||||
|                                 data[i], | ||||
|                                 { | ||||
|                                     key: ""+i, | ||||
|                                     typeHint: type==='buffer'?'hex':false, | ||||
|                                     hideKey: false, | ||||
|                                     path: path+"["+i+"]", | ||||
|                                     sourceId: sourceId, | ||||
|                                     rootPath: rootPath, | ||||
|                                     expandPaths: expandPaths, | ||||
|                                     ontoggle: ontoggle, | ||||
|                                     exposeApi: exposeApi | ||||
|                                 } | ||||
|                             ).appendTo(row); | ||||
|                         } | ||||
|                     } else { | ||||
|                         for (i=0;i<fullLength;i+=10) { | ||||
|                             var minRange = i; | ||||
|                             row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(arrayRows); | ||||
|                             header = $('<span></span>').appendTo(row); | ||||
|                             $('<i class="fa fa-caret-right debug-message-object-handle"></i> ').appendTo(header); | ||||
|                             makeExpandable(header, (function() { | ||||
|                                 var min = minRange; | ||||
|                                 var max = Math.min(fullLength-1,(minRange+9)); | ||||
|                                 var parent = row; | ||||
|                                 return function() { | ||||
|                                     for (var i=min;i<=max;i++) { | ||||
|                                         var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(parent); | ||||
|                                         subElements[path+"["+i+"]"] = buildMessageElement( | ||||
|                                             data[i], | ||||
|                                             { | ||||
|                                                 key: ""+i, | ||||
|                                                 typeHint: type==='buffer'?'hex':false, | ||||
|                                                 hideKey: false, | ||||
|                                                 path: path+"["+i+"]", | ||||
|                                                 sourceId: sourceId, | ||||
|                                                 rootPath: rootPath, | ||||
|                                                 expandPaths: expandPaths, | ||||
|                                                 ontoggle: ontoggle, | ||||
|                                                 exposeApi: exposeApi | ||||
|  | ||||
|                                             } | ||||
|                                         ).appendTo(row); | ||||
|                                     } | ||||
|                                 } | ||||
|                             })(), | ||||
|                             (function() { var path = path+"["+i+"]"; return function(state) {if (ontoggle) { ontoggle(path,state);}}})(), | ||||
|                             checkExpanded(strippedKey,expandPaths,minRange,Math.min(fullLength-1,(minRange+9)))); | ||||
|                             $('<span class="debug-message-object-key"></span>').html("["+minRange+" … "+Math.min(fullLength-1,(minRange+9))+"]").appendTo(header); | ||||
|                         } | ||||
|                         if (fullLength < originalLength) { | ||||
|                              $('<div class="debug-message-object-entry collapsed"><span class="debug-message-object-key">['+fullLength+' … '+originalLength+']</span></div>').appendTo(arrayRows); | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 function(state) {if (ontoggle) { ontoggle(path,state);}}, | ||||
|                 checkExpanded(strippedKey,expandPaths)); | ||||
|             } | ||||
|         } else if (typeof obj === 'object') { | ||||
|             element.addClass('collapsed'); | ||||
|             var keys = Object.keys(obj); | ||||
|             if (key || keys.length > 0) { | ||||
|                 $('<i class="fa fa-caret-right debug-message-object-handle"></i> ').prependTo(header); | ||||
|                 makeExpandable(header, function() { | ||||
|                     if (!key) { | ||||
|                         $('<span class="debug-message-type-meta debug-message-object-type-header"></span>').html('object').appendTo(header); | ||||
|                     } | ||||
|                     for (i=0;i<keys.length;i++) { | ||||
|                         var row = $('<div class="debug-message-object-entry collapsed"></div>').appendTo(element); | ||||
|                         var newPath = path; | ||||
|                         if (newPath) { | ||||
|                             if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(keys[i])) { | ||||
|                                 newPath += (newPath.length > 0?".":"")+keys[i]; | ||||
|                             } else { | ||||
|                                 newPath += "[\""+keys[i].replace(/"/,"\\\"")+"\"]" | ||||
|                             } | ||||
|                         } | ||||
|                         subElements[newPath] = buildMessageElement( | ||||
|                             obj[keys[i]], | ||||
|                             { | ||||
|                                 key: keys[i], | ||||
|                                 typeHint: false, | ||||
|                                 hideKey: false, | ||||
|                                 path: newPath, | ||||
|                                 sourceId: sourceId, | ||||
|                                 rootPath: rootPath, | ||||
|                                 expandPaths: expandPaths, | ||||
|                                 ontoggle: ontoggle, | ||||
|                                 exposeApi: exposeApi | ||||
|  | ||||
|                             } | ||||
|                         ).appendTo(row); | ||||
|                     } | ||||
|                     if (keys.length === 0) { | ||||
|                         $('<div class="debug-message-object-entry debug-message-type-meta collapsed"></div>').text("empty").appendTo(element); | ||||
|                     } | ||||
|                 }, | ||||
|                 function(state) {if (ontoggle) { ontoggle(path,state);}}, | ||||
|                 checkExpanded(strippedKey,expandPaths)); | ||||
|             } | ||||
|             if (key) { | ||||
|                 $('<span class="debug-message-type-meta"></span>').html('object').appendTo(entryObj); | ||||
|             } else { | ||||
|                 headerHead = $('<span class="debug-message-object-header"></span>').appendTo(entryObj); | ||||
|                 $('<span>{ </span>').appendTo(headerHead); | ||||
|                 var keysLength = Math.min(keys.length,5); | ||||
|                 for (i=0;i<keysLength;i++) { | ||||
|                     $('<span class="debug-message-object-key"></span>').text(keys[i]).appendTo(headerHead); | ||||
|                     $('<span>: </span>').appendTo(headerHead); | ||||
|                     buildMessageSummaryValue(obj[keys[i]]).appendTo(headerHead); | ||||
|                     if (i < keysLength-1) { | ||||
|                         $('<span>, </span>').appendTo(headerHead); | ||||
|                     } | ||||
|                 } | ||||
|                 if (keys.length > keysLength) { | ||||
|                     $('<span> …</span>').appendTo(headerHead); | ||||
|                 } | ||||
|                 if (keysLength === 0) { | ||||
|                     $('<span class="debug-message-type-meta">empty</span>').appendTo(headerHead); | ||||
|                 } | ||||
|                 $('<span> }</span>').appendTo(headerHead); | ||||
|             } | ||||
|         } else { | ||||
|             $('<span class="debug-message-type-other"></span>').text(""+obj).appendTo(entryObj); | ||||
|         } | ||||
|         if (exposeApi) { | ||||
|             element.prop('expand', function() { return function(targetPath, state) { | ||||
|                 if (path === targetPath) { | ||||
|                     if (header.prop('toggle')) { | ||||
|                         header.prop('toggle')(state); | ||||
|                     } | ||||
|                 } else if (subElements[targetPath] && subElements[targetPath].prop('expand') ) { | ||||
|                     subElements[targetPath].prop('expand')(targetPath,state); | ||||
|                 } else { | ||||
|                     for (var p in subElements) { | ||||
|                         if (subElements.hasOwnProperty(p)) { | ||||
|                             if (targetPath.indexOf(p) === 0) { | ||||
|                                 if (subElements[p].prop('expand') ) { | ||||
|                                     subElements[p].prop('expand')(targetPath,state); | ||||
|                                 } | ||||
|                                 break; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }}); | ||||
|         } | ||||
|         return element; | ||||
|     } | ||||
|  | ||||
|     function normalisePropertyExpression(str) { | ||||
|         // This must be kept in sync with validatePropertyExpression | ||||
|         // in editor/js/ui/utils.js | ||||
|  | ||||
|         var length = str.length; | ||||
|         if (length === 0) { | ||||
|             throw new Error("Invalid property expression: zero-length"); | ||||
|         } | ||||
|         var parts = []; | ||||
|         var start = 0; | ||||
|         var inString = false; | ||||
|         var inBox = false; | ||||
|         var quoteChar; | ||||
|         var v; | ||||
|         for (var i=0;i<length;i++) { | ||||
|             var c = str[i]; | ||||
|             if (!inString) { | ||||
|                 if (c === "'" || c === '"') { | ||||
|                     if (i != start) { | ||||
|                         throw new Error("Invalid property expression: unexpected "+c+" at position "+i); | ||||
|                     } | ||||
|                     inString = true; | ||||
|                     quoteChar = c; | ||||
|                     start = i+1; | ||||
|                 } else if (c === '.') { | ||||
|                     if (i===0) { | ||||
|                         throw new Error("Invalid property expression: unexpected . at position 0"); | ||||
|                     } | ||||
|                     if (start != i) { | ||||
|                         v = str.substring(start,i); | ||||
|                         if (/^\d+$/.test(v)) { | ||||
|                             parts.push(parseInt(v)); | ||||
|                         } else { | ||||
|                             parts.push(v); | ||||
|                         } | ||||
|                     } | ||||
|                     if (i===length-1) { | ||||
|                         throw new Error("Invalid property expression: unterminated expression"); | ||||
|                     } | ||||
|                     // Next char is first char of an identifier: a-z 0-9 $ _ | ||||
|                     if (!/[a-z0-9\$\_]/i.test(str[i+1])) { | ||||
|                         throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1)); | ||||
|                     } | ||||
|                     start = i+1; | ||||
|                 } else if (c === '[') { | ||||
|                     if (i === 0) { | ||||
|                         throw new Error("Invalid property expression: unexpected "+c+" at position "+i); | ||||
|                     } | ||||
|                     if (start != i) { | ||||
|                         parts.push(str.substring(start,i)); | ||||
|                     } | ||||
|                     if (i===length-1) { | ||||
|                         throw new Error("Invalid property expression: unterminated expression"); | ||||
|                     } | ||||
|                     // Next char is either a quote or a number | ||||
|                     if (!/["'\d]/.test(str[i+1])) { | ||||
|                         throw new Error("Invalid property expression: unexpected "+str[i+1]+" at position "+(i+1)); | ||||
|                     } | ||||
|                     start = i+1; | ||||
|                     inBox = true; | ||||
|                 } else if (c === ']') { | ||||
|                     if (!inBox) { | ||||
|                         throw new Error("Invalid property expression: unexpected "+c+" at position "+i); | ||||
|                     } | ||||
|                     if (start != i) { | ||||
|                         v = str.substring(start,i); | ||||
|                         if (/^\d+$/.test(v)) { | ||||
|                             parts.push(parseInt(v)); | ||||
|                         } else { | ||||
|                             throw new Error("Invalid property expression: unexpected array expression at position "+start); | ||||
|                         } | ||||
|                     } | ||||
|                     start = i+1; | ||||
|                     inBox = false; | ||||
|                 } else if (c === ' ') { | ||||
|                     throw new Error("Invalid property expression: unexpected ' ' at position "+i); | ||||
|                 } | ||||
|             } else { | ||||
|                 if (c === quoteChar) { | ||||
|                     if (i-start === 0) { | ||||
|                         throw new Error("Invalid property expression: zero-length string at position "+start); | ||||
|                     } | ||||
|                     parts.push(str.substring(start,i)); | ||||
|                     // If inBox, next char must be a ]. Otherwise it may be [ or . | ||||
|                     if (inBox && !/\]/.test(str[i+1])) { | ||||
|                         throw new Error("Invalid property expression: unexpected array expression at position "+start); | ||||
|                     } else if (!inBox && i+1!==length && !/[\[\.]/.test(str[i+1])) { | ||||
|                         throw new Error("Invalid property expression: unexpected "+str[i+1]+" expression at position "+(i+1)); | ||||
|                     } | ||||
|                     start = i+1; | ||||
|                     inString = false; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         if (inBox || inString) { | ||||
|             throw new Error("Invalid property expression: unterminated expression"); | ||||
|         } | ||||
|         if (start < length) { | ||||
|             parts.push(str.substring(start)); | ||||
|         } | ||||
|         return parts; | ||||
|     } | ||||
|  | ||||
|     function validatePropertyExpression(str) { | ||||
|         try { | ||||
|             var parts = normalisePropertyExpression(str); | ||||
|             return true; | ||||
|         } catch(err) { | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     function getMessageProperty(msg,expr) { | ||||
|         var result = null; | ||||
|         var msgPropParts; | ||||
|  | ||||
|         if (typeof expr === 'string') { | ||||
|             if (expr.indexOf('msg.')===0) { | ||||
|                 expr = expr.substring(4); | ||||
|             } | ||||
|             msgPropParts = normalisePropertyExpression(expr); | ||||
|         } else { | ||||
|             msgPropParts = expr; | ||||
|         } | ||||
|         var m; | ||||
|         msgPropParts.reduce(function(obj, key) { | ||||
|             result = (typeof obj[key] !== "undefined" ? obj[key] : undefined); | ||||
|             if (result === undefined && obj.hasOwnProperty('type') && obj.hasOwnProperty('data')&& obj.hasOwnProperty('length')) { | ||||
|                 result = (typeof obj.data[key] !== "undefined" ? obj.data[key] : undefined); | ||||
|             } | ||||
|             return result; | ||||
|         }, msg); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     function getNodeIcon(def,node) { | ||||
|         if (def.category === 'config') { | ||||
|             return "icons/node-red/cog.png" | ||||
|         } else if (node && node.type === 'tab') { | ||||
|             return "icons/node-red/subflow.png" | ||||
|         } else if (node && node.type === 'unknown') { | ||||
|             return "icons/node-red/alert.png" | ||||
|         } else if (node && node.type === 'subflow') { | ||||
|             return "icons/node-red/subflow.png" | ||||
|         } | ||||
|         var icon_url; | ||||
|         if (typeof def.icon === "function") { | ||||
|             try { | ||||
|                 icon_url = def.icon.call(node); | ||||
|             } catch(err) { | ||||
|                 console.log("Definition error: "+def.type+".icon",err); | ||||
|                 icon_url = "arrow-in.png"; | ||||
|             } | ||||
|         } else { | ||||
|             icon_url = def.icon; | ||||
|         } | ||||
|         return "icons/"+def.set.module+"/"+icon_url; | ||||
|     } | ||||
|  | ||||
|     function getNodeLabel(node,defaultLabel) { | ||||
|         defaultLabel = defaultLabel||""; | ||||
|         var l; | ||||
|         if (node.type === 'tab') { | ||||
|             l = node.label || defaultLabel | ||||
|         } else { | ||||
|             l = node._def.label; | ||||
|             try { | ||||
|                 l = (typeof l === "function" ? l.call(node) : l)||defaultLabel; | ||||
|             } catch(err) { | ||||
|                 console.log("Definition error: "+node.type+".label",err); | ||||
|                 l = defaultLabel; | ||||
|             } | ||||
|         } | ||||
|         return RED.text.bidi.enforceTextDirectionWithUCC(l); | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         createObjectElement: buildMessageElement, | ||||
|         getMessageProperty: getMessageProperty, | ||||
|         normalisePropertyExpression: normalisePropertyExpression, | ||||
|         validatePropertyExpression: validatePropertyExpression, | ||||
|         getNodeIcon: getNodeIcon, | ||||
|         getNodeLabel: getNodeLabel, | ||||
|     } | ||||
| })(); | ||||