nitrogen 0.2.23 → 0.29.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. package/README.md +15 -109
  2. package/lib/Logger.d.ts +10 -0
  3. package/lib/Logger.js +56 -0
  4. package/lib/autolinking/Autolinking.d.ts +8 -0
  5. package/lib/autolinking/Autolinking.js +1 -0
  6. package/lib/autolinking/android/createCMakeExtension.d.ts +6 -0
  7. package/lib/autolinking/android/createCMakeExtension.js +106 -0
  8. package/lib/autolinking/android/createGradleExtension.d.ts +5 -0
  9. package/lib/autolinking/android/createGradleExtension.js +36 -0
  10. package/lib/autolinking/android/createHybridObjectInitializer.d.ts +2 -0
  11. package/lib/autolinking/android/createHybridObjectInitializer.js +159 -0
  12. package/lib/autolinking/createAndroidAutolinking.d.ts +11 -0
  13. package/lib/autolinking/createAndroidAutolinking.js +13 -0
  14. package/lib/autolinking/createIOSAutolinking.d.ts +5 -0
  15. package/lib/autolinking/createIOSAutolinking.js +19 -0
  16. package/lib/autolinking/ios/createHybridObjectInitializer.d.ts +9 -0
  17. package/lib/autolinking/ios/createHybridObjectInitializer.js +97 -0
  18. package/lib/autolinking/ios/createPodspecRubyExtension.d.ts +5 -0
  19. package/lib/autolinking/ios/createPodspecRubyExtension.js +69 -0
  20. package/lib/autolinking/ios/createSwiftCxxBridge.d.ts +2 -0
  21. package/lib/autolinking/ios/createSwiftCxxBridge.js +117 -0
  22. package/lib/autolinking/ios/createSwiftUmbrellaHeader.d.ts +3 -0
  23. package/lib/autolinking/ios/createSwiftUmbrellaHeader.js +74 -0
  24. package/lib/config/NitroConfig.d.ts +52 -0
  25. package/lib/config/NitroConfig.js +112 -0
  26. package/lib/config/NitroUserConfig.d.ts +22 -0
  27. package/lib/config/NitroUserConfig.js +88 -0
  28. package/lib/config/getConfig.d.ts +2 -0
  29. package/lib/config/getConfig.js +84 -0
  30. package/lib/createGitAttributes.d.ts +1 -0
  31. package/lib/createGitAttributes.js +11 -0
  32. package/lib/createPlatformSpec.d.ts +4 -0
  33. package/lib/createPlatformSpec.js +127 -0
  34. package/lib/getFiles.d.ts +1 -0
  35. package/lib/getFiles.js +28 -0
  36. package/lib/getPlatformSpecs.d.ts +17 -0
  37. package/lib/getPlatformSpecs.js +153 -0
  38. package/lib/index.d.ts +2 -0
  39. package/lib/index.js +113 -10
  40. package/lib/init.d.ts +1 -0
  41. package/lib/init.js +123 -0
  42. package/lib/nitrogen.d.ts +11 -0
  43. package/lib/nitrogen.js +165 -0
  44. package/lib/prettifyDirectory.d.ts +1 -0
  45. package/lib/prettifyDirectory.js +27 -0
  46. package/lib/syntax/BridgedType.d.ts +41 -0
  47. package/lib/syntax/BridgedType.js +1 -0
  48. package/lib/syntax/CodeNode.d.ts +23 -0
  49. package/lib/syntax/CodeNode.js +1 -0
  50. package/lib/syntax/HybridObjectSpec.d.ts +13 -0
  51. package/lib/syntax/HybridObjectSpec.js +1 -0
  52. package/lib/syntax/Method.d.ts +41 -0
  53. package/lib/syntax/Method.js +108 -0
  54. package/lib/syntax/Parameter.d.ts +15 -0
  55. package/lib/syntax/Parameter.js +65 -0
  56. package/lib/syntax/Property.d.ts +50 -0
  57. package/lib/syntax/Property.js +147 -0
  58. package/lib/syntax/SourceFile.d.ts +70 -0
  59. package/lib/syntax/SourceFile.js +7 -0
  60. package/lib/syntax/c++/CppEnum.d.ts +6 -0
  61. package/lib/syntax/c++/CppEnum.js +110 -0
  62. package/lib/syntax/c++/CppHybridObject.d.ts +3 -0
  63. package/lib/syntax/c++/CppHybridObject.js +146 -0
  64. package/lib/syntax/c++/CppHybridObjectRegistration.d.ts +17 -0
  65. package/lib/syntax/c++/CppHybridObjectRegistration.js +18 -0
  66. package/lib/syntax/c++/CppStruct.d.ts +3 -0
  67. package/lib/syntax/c++/CppStruct.js +108 -0
  68. package/lib/syntax/c++/CppUnion.d.ts +6 -0
  69. package/lib/syntax/c++/CppUnion.js +88 -0
  70. package/lib/syntax/c++/getForwardDeclaration.d.ts +3 -0
  71. package/lib/syntax/c++/getForwardDeclaration.js +14 -0
  72. package/lib/syntax/c++/includeNitroHeader.d.ts +7 -0
  73. package/lib/syntax/c++/includeNitroHeader.js +34 -0
  74. package/lib/syntax/createType.d.ts +15 -0
  75. package/lib/syntax/createType.js +303 -0
  76. package/lib/syntax/getAllTypes.d.ts +3 -0
  77. package/lib/syntax/getAllTypes.js +11 -0
  78. package/lib/syntax/getCustomTypeConfig.d.ts +8 -0
  79. package/lib/syntax/getCustomTypeConfig.js +53 -0
  80. package/lib/syntax/getHybridObjectName.d.ts +36 -0
  81. package/lib/syntax/getHybridObjectName.js +10 -0
  82. package/lib/syntax/getInterfaceProperties.d.ts +4 -0
  83. package/lib/syntax/getInterfaceProperties.js +9 -0
  84. package/lib/syntax/getReferencedTypes.d.ts +2 -0
  85. package/lib/syntax/getReferencedTypes.js +47 -0
  86. package/lib/syntax/helpers.d.ts +13 -0
  87. package/lib/syntax/helpers.js +53 -0
  88. package/lib/syntax/isCoreType.d.ts +9 -0
  89. package/lib/syntax/isCoreType.js +47 -0
  90. package/lib/syntax/kotlin/FbjniHybridObject.d.ts +3 -0
  91. package/lib/syntax/kotlin/FbjniHybridObject.js +261 -0
  92. package/lib/syntax/kotlin/JNINativeRegistrations.d.ts +8 -0
  93. package/lib/syntax/kotlin/JNINativeRegistrations.js +7 -0
  94. package/lib/syntax/kotlin/KotlinBoxedPrimitive.d.ts +7 -0
  95. package/lib/syntax/kotlin/KotlinBoxedPrimitive.js +17 -0
  96. package/lib/syntax/kotlin/KotlinCxxBridgedType.d.ts +19 -0
  97. package/lib/syntax/kotlin/KotlinCxxBridgedType.js +893 -0
  98. package/lib/syntax/kotlin/KotlinEnum.d.ts +3 -0
  99. package/lib/syntax/kotlin/KotlinEnum.js +113 -0
  100. package/lib/syntax/kotlin/KotlinFunction.d.ts +3 -0
  101. package/lib/syntax/kotlin/KotlinFunction.js +256 -0
  102. package/lib/syntax/kotlin/KotlinHybridObject.d.ts +3 -0
  103. package/lib/syntax/kotlin/KotlinHybridObject.js +177 -0
  104. package/lib/syntax/kotlin/KotlinHybridObjectRegistration.d.ts +17 -0
  105. package/lib/syntax/kotlin/KotlinHybridObjectRegistration.js +26 -0
  106. package/lib/syntax/kotlin/KotlinStruct.d.ts +3 -0
  107. package/lib/syntax/kotlin/KotlinStruct.js +172 -0
  108. package/lib/syntax/kotlin/KotlinVariant.d.ts +3 -0
  109. package/lib/syntax/kotlin/KotlinVariant.js +191 -0
  110. package/lib/syntax/swift/SwiftCxxBridgedType.d.ts +21 -0
  111. package/lib/syntax/swift/SwiftCxxBridgedType.js +819 -0
  112. package/lib/syntax/swift/SwiftCxxTypeHelper.d.ts +17 -0
  113. package/lib/syntax/swift/SwiftCxxTypeHelper.js +613 -0
  114. package/lib/syntax/swift/SwiftEnum.d.ts +3 -0
  115. package/lib/syntax/swift/SwiftEnum.js +52 -0
  116. package/lib/syntax/swift/SwiftFunction.d.ts +3 -0
  117. package/lib/syntax/swift/SwiftFunction.js +83 -0
  118. package/lib/syntax/swift/SwiftHybridObject.d.ts +3 -0
  119. package/lib/syntax/swift/SwiftHybridObject.js +103 -0
  120. package/lib/syntax/swift/SwiftHybridObjectBridge.d.ts +11 -0
  121. package/lib/syntax/swift/SwiftHybridObjectBridge.js +451 -0
  122. package/lib/syntax/swift/SwiftHybridObjectRegistration.d.ts +19 -0
  123. package/lib/syntax/swift/SwiftHybridObjectRegistration.js +42 -0
  124. package/lib/syntax/swift/SwiftStruct.d.ts +3 -0
  125. package/lib/syntax/swift/SwiftStruct.js +75 -0
  126. package/lib/syntax/swift/SwiftVariant.d.ts +3 -0
  127. package/lib/syntax/swift/SwiftVariant.js +58 -0
  128. package/lib/syntax/types/ArrayBufferType.d.ts +10 -0
  129. package/lib/syntax/types/ArrayBufferType.js +37 -0
  130. package/lib/syntax/types/ArrayType.d.ts +12 -0
  131. package/lib/syntax/types/ArrayType.js +52 -0
  132. package/lib/syntax/types/BigIntType.d.ts +10 -0
  133. package/lib/syntax/types/BigIntType.js +27 -0
  134. package/lib/syntax/types/BooleanType.d.ts +10 -0
  135. package/lib/syntax/types/BooleanType.js +27 -0
  136. package/lib/syntax/types/CustomType.d.ts +14 -0
  137. package/lib/syntax/types/CustomType.js +36 -0
  138. package/lib/syntax/types/DateType.d.ts +10 -0
  139. package/lib/syntax/types/DateType.js +35 -0
  140. package/lib/syntax/types/EnumType.d.ts +23 -0
  141. package/lib/syntax/types/EnumType.js +101 -0
  142. package/lib/syntax/types/ErrorType.d.ts +11 -0
  143. package/lib/syntax/types/ErrorType.js +37 -0
  144. package/lib/syntax/types/FunctionType.d.ts +29 -0
  145. package/lib/syntax/types/FunctionType.js +147 -0
  146. package/lib/syntax/types/HybridObjectBaseType.d.ts +11 -0
  147. package/lib/syntax/types/HybridObjectBaseType.js +38 -0
  148. package/lib/syntax/types/HybridObjectType.d.ts +23 -0
  149. package/lib/syntax/types/HybridObjectType.js +131 -0
  150. package/lib/syntax/types/MapType.d.ts +10 -0
  151. package/lib/syntax/types/MapType.js +37 -0
  152. package/lib/syntax/types/NamedWrappingType.d.ts +14 -0
  153. package/lib/syntax/types/NamedWrappingType.js +27 -0
  154. package/lib/syntax/types/NullType.d.ts +10 -0
  155. package/lib/syntax/types/NullType.js +23 -0
  156. package/lib/syntax/types/NumberType.d.ts +10 -0
  157. package/lib/syntax/types/NumberType.js +27 -0
  158. package/lib/syntax/types/OptionalType.d.ts +13 -0
  159. package/lib/syntax/types/OptionalType.js +59 -0
  160. package/lib/syntax/types/PromiseType.d.ts +16 -0
  161. package/lib/syntax/types/PromiseType.js +62 -0
  162. package/lib/syntax/types/RecordType.d.ts +13 -0
  163. package/lib/syntax/types/RecordType.js +47 -0
  164. package/lib/syntax/types/ResultWrappingType.d.ts +13 -0
  165. package/lib/syntax/types/ResultWrappingType.js +44 -0
  166. package/lib/syntax/types/StringType.d.ts +10 -0
  167. package/lib/syntax/types/StringType.js +35 -0
  168. package/lib/syntax/types/StructType.d.ts +14 -0
  169. package/lib/syntax/types/StructType.js +61 -0
  170. package/lib/syntax/types/TupleType.d.ts +12 -0
  171. package/lib/syntax/types/TupleType.js +39 -0
  172. package/lib/syntax/types/Type.d.ts +55 -0
  173. package/lib/syntax/types/Type.js +1 -0
  174. package/lib/syntax/types/VariantType.d.ts +19 -0
  175. package/lib/syntax/types/VariantType.js +75 -0
  176. package/lib/syntax/types/VoidType.d.ts +10 -0
  177. package/lib/syntax/types/VoidType.js +27 -0
  178. package/lib/syntax/types/getTypeAs.d.ts +2 -0
  179. package/lib/syntax/types/getTypeAs.js +12 -0
  180. package/lib/utils.d.ts +22 -0
  181. package/lib/utils.js +126 -0
  182. package/lib/views/CppHybridViewComponent.d.ts +14 -0
  183. package/lib/views/CppHybridViewComponent.js +254 -0
  184. package/lib/views/createHostComponentJs.d.ts +3 -0
  185. package/lib/views/createHostComponentJs.js +27 -0
  186. package/lib/views/kotlin/KotlinHybridViewManager.d.ts +3 -0
  187. package/lib/views/kotlin/KotlinHybridViewManager.js +229 -0
  188. package/lib/views/swift/SwiftHybridViewManager.d.ts +3 -0
  189. package/lib/views/swift/SwiftHybridViewManager.js +131 -0
  190. package/lib/writeFile.d.ts +5 -0
  191. package/lib/writeFile.js +19 -0
  192. package/package.json +58 -29
  193. package/src/Logger.ts +63 -0
  194. package/src/autolinking/Autolinking.ts +9 -0
  195. package/src/autolinking/android/createCMakeExtension.ts +123 -0
  196. package/src/autolinking/android/createGradleExtension.ts +43 -0
  197. package/src/autolinking/android/createHybridObjectInitializer.ts +174 -0
  198. package/src/autolinking/createAndroidAutolinking.ts +28 -0
  199. package/src/autolinking/createIOSAutolinking.ts +24 -0
  200. package/src/autolinking/ios/createHybridObjectInitializer.ts +112 -0
  201. package/src/autolinking/ios/createPodspecRubyExtension.ts +76 -0
  202. package/src/autolinking/ios/createSwiftCxxBridge.ts +137 -0
  203. package/src/autolinking/ios/createSwiftUmbrellaHeader.ts +90 -0
  204. package/src/config/NitroConfig.ts +139 -0
  205. package/src/config/NitroUserConfig.ts +105 -0
  206. package/src/config/getConfig.ts +91 -0
  207. package/src/createGitAttributes.ts +15 -0
  208. package/src/createPlatformSpec.ts +176 -0
  209. package/src/getFiles.ts +31 -0
  210. package/src/getPlatformSpecs.ts +202 -0
  211. package/src/index.ts +146 -0
  212. package/src/init.ts +186 -0
  213. package/src/nitrogen.ts +246 -0
  214. package/src/prettifyDirectory.ts +32 -0
  215. package/src/syntax/BridgedType.ts +59 -0
  216. package/src/syntax/CodeNode.ts +24 -0
  217. package/src/syntax/HybridObjectSpec.ts +14 -0
  218. package/src/syntax/Method.ts +154 -0
  219. package/src/syntax/Parameter.ts +81 -0
  220. package/src/syntax/Property.ts +203 -0
  221. package/src/syntax/SourceFile.ts +80 -0
  222. package/src/syntax/c++/CppEnum.ts +128 -0
  223. package/src/syntax/c++/CppHybridObject.ts +165 -0
  224. package/src/syntax/c++/CppHybridObjectRegistration.ts +39 -0
  225. package/src/syntax/c++/CppStruct.ts +129 -0
  226. package/src/syntax/c++/CppUnion.ts +105 -0
  227. package/src/syntax/c++/getForwardDeclaration.ts +19 -0
  228. package/src/syntax/c++/includeNitroHeader.ts +40 -0
  229. package/src/syntax/createType.ts +365 -0
  230. package/src/syntax/getAllTypes.ts +18 -0
  231. package/src/syntax/getCustomTypeConfig.ts +71 -0
  232. package/src/syntax/getHybridObjectName.ts +48 -0
  233. package/src/syntax/getInterfaceProperties.ts +21 -0
  234. package/src/syntax/getReferencedTypes.ts +57 -0
  235. package/src/syntax/helpers.ts +79 -0
  236. package/src/syntax/isCoreType.ts +60 -0
  237. package/src/syntax/kotlin/FbjniHybridObject.ts +313 -0
  238. package/src/syntax/kotlin/JNINativeRegistrations.ts +19 -0
  239. package/src/syntax/kotlin/KotlinBoxedPrimitive.ts +19 -0
  240. package/src/syntax/kotlin/KotlinCxxBridgedType.ts +942 -0
  241. package/src/syntax/kotlin/KotlinEnum.ts +130 -0
  242. package/src/syntax/kotlin/KotlinFunction.ts +277 -0
  243. package/src/syntax/kotlin/KotlinHybridObject.ts +205 -0
  244. package/src/syntax/kotlin/KotlinHybridObjectRegistration.ts +51 -0
  245. package/src/syntax/kotlin/KotlinStruct.ts +198 -0
  246. package/src/syntax/kotlin/KotlinVariant.ts +212 -0
  247. package/src/syntax/swift/SwiftCxxBridgedType.ts +874 -0
  248. package/src/syntax/swift/SwiftCxxTypeHelper.ts +674 -0
  249. package/src/syntax/swift/SwiftEnum.ts +65 -0
  250. package/src/syntax/swift/SwiftFunction.ts +91 -0
  251. package/src/syntax/swift/SwiftHybridObject.ts +121 -0
  252. package/src/syntax/swift/SwiftHybridObjectBridge.ts +522 -0
  253. package/src/syntax/swift/SwiftHybridObjectRegistration.ts +75 -0
  254. package/src/syntax/swift/SwiftStruct.ts +85 -0
  255. package/src/syntax/swift/SwiftVariant.ts +67 -0
  256. package/src/syntax/types/ArrayBufferType.ts +49 -0
  257. package/src/syntax/types/ArrayType.ts +62 -0
  258. package/src/syntax/types/BigIntType.ts +35 -0
  259. package/src/syntax/types/BooleanType.ts +35 -0
  260. package/src/syntax/types/CustomType.ts +47 -0
  261. package/src/syntax/types/DateType.ts +43 -0
  262. package/src/syntax/types/EnumType.ts +130 -0
  263. package/src/syntax/types/ErrorType.ts +44 -0
  264. package/src/syntax/types/FunctionType.ts +167 -0
  265. package/src/syntax/types/HybridObjectBaseType.ts +54 -0
  266. package/src/syntax/types/HybridObjectType.ts +198 -0
  267. package/src/syntax/types/MapType.ts +49 -0
  268. package/src/syntax/types/NamedWrappingType.ts +33 -0
  269. package/src/syntax/types/NullType.ts +30 -0
  270. package/src/syntax/types/NumberType.ts +34 -0
  271. package/src/syntax/types/OptionalType.ts +66 -0
  272. package/src/syntax/types/PromiseType.ts +72 -0
  273. package/src/syntax/types/RecordType.ts +56 -0
  274. package/src/syntax/types/ResultWrappingType.ts +53 -0
  275. package/src/syntax/types/StringType.ts +44 -0
  276. package/src/syntax/types/StructType.ts +83 -0
  277. package/src/syntax/types/TupleType.ts +53 -0
  278. package/src/syntax/types/Type.ts +82 -0
  279. package/src/syntax/types/VariantType.ts +92 -0
  280. package/src/syntax/types/VoidType.ts +34 -0
  281. package/src/syntax/types/getTypeAs.ts +15 -0
  282. package/src/utils.ts +162 -0
  283. package/src/views/CppHybridViewComponent.ts +301 -0
  284. package/src/views/createHostComponentJs.ts +34 -0
  285. package/src/views/kotlin/KotlinHybridViewManager.ts +258 -0
  286. package/src/views/swift/SwiftHybridViewManager.ts +153 -0
  287. package/src/writeFile.ts +27 -0
  288. package/.jshintignore +0 -6
  289. package/.jshintrc +0 -3
  290. package/.npmignore +0 -3
  291. package/.travis.yml +0 -13
  292. package/LICENSE +0 -13
  293. package/browser/nitrogen-min.js +0 -3
  294. package/browser/nitrogen.js +0 -6369
  295. package/lib/apiKey.js +0 -67
  296. package/lib/blob.js +0 -57
  297. package/lib/commandManager.js +0 -350
  298. package/lib/device.js +0 -19
  299. package/lib/memoryStore.js +0 -24
  300. package/lib/message.js +0 -298
  301. package/lib/permission.js +0 -121
  302. package/lib/principal.js +0 -330
  303. package/lib/service.js +0 -349
  304. package/lib/session.js +0 -494
  305. package/lib/user.js +0 -20
  306. package/publish +0 -2
  307. package/scripts/build-documentation +0 -4
  308. package/scripts/build-module +0 -27
  309. package/scripts/module.js +0 -12
  310. package/scripts/postamble.js +0 -1
  311. package/scripts/preamble.js +0 -2
  312. package/scripts/run-test-server +0 -9
  313. package/test/config.js +0 -12
  314. package/test/fixtures/images/image.jpg +0 -0
  315. package/test/fixtures/images/motion0.jpg +0 -0
  316. package/test/fixtures/images/motion1.jpg +0 -0
  317. package/test/fixtures/images/motion2.jpg +0 -0
  318. package/test/fixtures/index.js +0 -76
  319. package/test/main.js +0 -5
  320. package/test/memoryStore.js +0 -22
  321. package/test/mocha.opts +0 -3
  322. package/test/units/apiKey.js +0 -46
  323. package/test/units/blob.js +0 -35
  324. package/test/units/commandManager.js +0 -67
  325. package/test/units/device.js +0 -26
  326. package/test/units/heartbeat.js +0 -28
  327. package/test/units/message.js +0 -79
  328. package/test/units/permissions.js +0 -43
  329. package/test/units/principal.js +0 -116
  330. package/test/units/service.js +0 -92
  331. package/test/units/session.js +0 -97
  332. package/test/units/user.js +0 -48
  333. package/yuidoc.json +0 -8
@@ -0,0 +1,153 @@
1
+ import type { SourceFile } from '../../syntax/SourceFile.js'
2
+ import type { HybridObjectSpec } from '../../syntax/HybridObjectSpec.js'
3
+ import {
4
+ createViewComponentShadowNodeFiles,
5
+ getViewComponentNames,
6
+ } from '../CppHybridViewComponent.js'
7
+ import {
8
+ createFileMetadataString,
9
+ escapeCppName,
10
+ } from '../../syntax/helpers.js'
11
+ import { getUmbrellaHeaderName } from '../../autolinking/ios/createSwiftUmbrellaHeader.js'
12
+ import { getHybridObjectName } from '../../syntax/getHybridObjectName.js'
13
+ import { getHybridObjectConstructorCall } from '../../syntax/swift/SwiftHybridObjectRegistration.js'
14
+ import { indent } from '../../utils.js'
15
+ import { SwiftCxxBridgedType } from '../../syntax/swift/SwiftCxxBridgedType.js'
16
+
17
+ export function createSwiftHybridViewManager(
18
+ spec: HybridObjectSpec
19
+ ): SourceFile[] {
20
+ const cppFiles = createViewComponentShadowNodeFiles(spec)
21
+ const namespace = spec.config.getCxxNamespace('c++')
22
+ const swiftNamespace = spec.config.getIosModuleName()
23
+ const { HybridTSpec, HybridTSpecSwift, HybridTSpecCxx } = getHybridObjectName(
24
+ spec.name
25
+ )
26
+ const { component, descriptorClassName, propsClassName } =
27
+ getViewComponentNames(spec)
28
+ const autolinking = spec.config.getAutolinkedHybridObjects()
29
+ const viewImplementation = autolinking[spec.name]?.swift
30
+ if (viewImplementation == null) {
31
+ throw new Error(
32
+ `Cannot create Swift HybridView ViewManager for ${spec.name} - it is not autolinked in nitro.json!`
33
+ )
34
+ }
35
+
36
+ const propAssignments = spec.properties.map((p) => {
37
+ const name = escapeCppName(p.name)
38
+ const setter = p.getSetterName('swift')
39
+ const bridge = new SwiftCxxBridgedType(p.type, false)
40
+ const parse = bridge.parseFromCppToSwift(
41
+ `newViewProps.${name}.value`,
42
+ 'c++'
43
+ )
44
+ return `
45
+ // ${p.jsSignature}
46
+ if (newViewProps.${name}.isDirty) {
47
+ swiftPart.${setter}(${indent(parse, ' ')});
48
+ newViewProps.${name}.isDirty = false;
49
+ }
50
+ `.trim()
51
+ })
52
+
53
+ const mmFile = `
54
+ ${createFileMetadataString(`${component}.mm`)}
55
+
56
+ #import "${component}.hpp"
57
+ #import <memory>
58
+ #import <react/renderer/componentregistry/ComponentDescriptorProvider.h>
59
+ #import <React/RCTViewComponentView.h>
60
+ #import <React/RCTComponentViewFactory.h>
61
+ #import <React/UIView+ComponentViewProtocol.h>
62
+ #import <NitroModules/NitroDefines.hpp>
63
+ #import <UIKit/UIKit.h>
64
+
65
+ #import "${HybridTSpecSwift}.hpp"
66
+ #import "${getUmbrellaHeaderName()}"
67
+
68
+ using namespace facebook;
69
+ using namespace ${namespace};
70
+ using namespace ${namespace}::views;
71
+
72
+ /**
73
+ * Represents the React Native View holder for the Nitro "${spec.name}" HybridView.
74
+ */
75
+ @interface ${component}: RCTViewComponentView
76
+ @end
77
+
78
+ @implementation ${component} {
79
+ std::shared_ptr<${HybridTSpecSwift}> _hybridView;
80
+ }
81
+
82
+ + (void) load {
83
+ [super load];
84
+ [RCTComponentViewFactory.currentComponentViewFactory registerComponentViewClass:[${component} class]];
85
+ }
86
+
87
+ + (react::ComponentDescriptorProvider) componentDescriptorProvider {
88
+ return react::concreteComponentDescriptorProvider<${descriptorClassName}>();
89
+ }
90
+
91
+ - (instancetype) init {
92
+ if (self = [super init]) {
93
+ std::shared_ptr<${HybridTSpec}> hybridView = ${getHybridObjectConstructorCall(spec.name)}
94
+ _hybridView = std::dynamic_pointer_cast<${HybridTSpecSwift}>(hybridView);
95
+ [self updateView];
96
+ }
97
+ return self;
98
+ }
99
+
100
+ - (void) updateView {
101
+ // 1. Get Swift part
102
+ ${swiftNamespace}::${HybridTSpecCxx}& swiftPart = _hybridView->getSwiftPart();
103
+
104
+ // 2. Get UIView*
105
+ void* viewUnsafe = swiftPart.getView();
106
+ UIView* view = (__bridge_transfer UIView*) viewUnsafe;
107
+
108
+ // 3. Update RCTViewComponentView's [contentView]
109
+ [self setContentView:view];
110
+ }
111
+
112
+ - (void) updateProps:(const std::shared_ptr<const react::Props>&)props
113
+ oldProps:(const std::shared_ptr<const react::Props>&)oldProps {
114
+ // 1. Downcast props
115
+ const auto& newViewPropsConst = *std::static_pointer_cast<${propsClassName} const>(props);
116
+ auto& newViewProps = const_cast<${propsClassName}&>(newViewPropsConst);
117
+ ${swiftNamespace}::${HybridTSpecCxx}& swiftPart = _hybridView->getSwiftPart();
118
+
119
+ // 2. Update each prop individually
120
+ swiftPart.beforeUpdate();
121
+
122
+ ${indent(propAssignments.join('\n'), ' ')}
123
+
124
+ swiftPart.afterUpdate();
125
+
126
+ // 3. Update hybridRef if it changed
127
+ if (newViewProps.hybridRef.isDirty) {
128
+ // hybridRef changed - call it with new this
129
+ const auto& maybeFunc = newViewProps.hybridRef.value;
130
+ if (maybeFunc.has_value()) {
131
+ maybeFunc.value()(_hybridView);
132
+ }
133
+ newViewProps.hybridRef.isDirty = false;
134
+ }
135
+
136
+ // 4. Continue in base class
137
+ [super updateProps:props oldProps:oldProps];
138
+ }
139
+
140
+ @end
141
+ `
142
+
143
+ return [
144
+ ...cppFiles,
145
+ {
146
+ content: mmFile,
147
+ language: 'c++',
148
+ name: `${component}.mm`,
149
+ platform: 'ios',
150
+ subdirectory: ['views'],
151
+ },
152
+ ]
153
+ }
@@ -0,0 +1,27 @@
1
+ import path from 'path'
2
+ import { promises as fs } from 'fs'
3
+ import { capitalizeName } from './utils.js'
4
+ import type { SourceFile } from './syntax/SourceFile.js'
5
+ import chalk from 'chalk'
6
+ import { Logger } from './Logger.js'
7
+
8
+ /**
9
+ * Writes the given file to disk and returns it's actual path.
10
+ */
11
+ export async function writeFile(
12
+ basePath: string,
13
+ file: SourceFile
14
+ ): Promise<string> {
15
+ const filepath = path.join(basePath, ...file.subdirectory, file.name)
16
+ const language = capitalizeName(file.language)
17
+ Logger.debug(` ${chalk.dim(language)}: Creating ${file.name}...`)
18
+
19
+ const dir = path.dirname(filepath)
20
+ // Create directory if it doesn't exist yet
21
+ await fs.mkdir(dir, { recursive: true })
22
+
23
+ // Write file
24
+ await fs.writeFile(filepath, file.content.trim() + '\n', 'utf8')
25
+
26
+ return filepath
27
+ }
package/.jshintignore DELETED
@@ -1,6 +0,0 @@
1
- docs
2
- browser
3
- node_modules
4
- scripts
5
- LICENSE
6
- README.md
package/.jshintrc DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "laxcomma": true
3
- }
package/.npmignore DELETED
@@ -1,3 +0,0 @@
1
- localhost_3030.store
2
- node_modules
3
- .DS_Store
package/.travis.yml DELETED
@@ -1,13 +0,0 @@
1
- language: node_js
2
- node_js:
3
- - 0.10
4
-
5
- before_script:
6
- - scripts/run-test-server
7
-
8
- after_script:
9
- - kill -9 $(lsof -i:3050 -t)
10
-
11
- services:
12
- - mongodb
13
- - redis
package/LICENSE DELETED
@@ -1,13 +0,0 @@
1
- Nitrogen
2
-
3
- Copyright (c) Microsoft Corporation
4
-
5
- All rights reserved.
6
-
7
- MIT License
8
-
9
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,3 +0,0 @@
1
- var XHR=XMLHttpRequest;if(!XHR)throw new Error("missing XMLHttpRequest");request.log={trace:noop,debug:noop,info:noop,warn:noop,error:noop};var DEFAULT_TIMEOUT=3*60*1e3;function request(options,callback){if(typeof callback!=="function")throw new Error("Bad callback given: "+callback);if(!options)throw new Error("No options given");var options_onResponse=options.onResponse;if(typeof options==="string")options={uri:options};else options=JSON.parse(JSON.stringify(options));options.onResponse=options_onResponse;if(options.verbose)request.log=getLogger();if(options.url){options.uri=options.url;delete options.url}if(!options.uri&&options.uri!=="")throw new Error("options.uri is a required argument");if(typeof options.uri!="string")throw new Error("options.uri must be a string");var unsupported_options=["proxy","_redirectsFollowed","maxRedirects","followRedirect"];for(var i=0;i<unsupported_options.length;i++)if(options[unsupported_options[i]])throw new Error("options."+unsupported_options[i]+" is not supported");options.callback=callback;options.method=options.method||"GET";options.headers=options.headers||{};options.body=options.body||null;options.timeout=options.timeout||request.DEFAULT_TIMEOUT;if(options.headers.host)throw new Error("Options.headers.host is not supported");if(options.json){options.headers.accept=options.headers.accept||"application/json";if(options.method!=="GET")options.headers["content-type"]="application/json";if(typeof options.json!=="boolean")options.body=JSON.stringify(options.json);else if(typeof options.body!=="string")options.body=JSON.stringify(options.body)}options.onResponse=options.onResponse||noop;if(options.onResponse===true){options.onResponse=callback;options.callback=noop}if(!options.headers.authorization&&options.auth)options.headers.authorization="Basic "+b64_enc(options.auth.username+":"+options.auth.password);return run_xhr(options)}var req_seq=0;function run_xhr(options){var xhr=new XHR,timed_out=false,is_cors=is_crossDomain(options.uri),supports_cors="withCredentials"in xhr;req_seq+=1;xhr.seq_id=req_seq;xhr.id=req_seq+": "+options.method+" "+options.uri;xhr._id=xhr.id;if(is_cors&&!supports_cors){var cors_err=new Error("Browser does not support cross-origin request: "+options.uri);cors_err.cors="unsupported";return options.callback(cors_err,xhr)}xhr.timeoutTimer=setTimeout(too_late,options.timeout);function too_late(){timed_out=true;var er=new Error("ETIMEDOUT");er.code="ETIMEDOUT";er.duration=options.timeout;request.log.error("Timeout",{id:xhr._id,milliseconds:options.timeout});return options.callback(er,xhr)}var did={response:false,loading:false,end:false};xhr.onreadystatechange=on_state_change;xhr.open(options.method,options.uri,true);if(is_cors)xhr.withCredentials=!!options.withCredentials;xhr.send(options.body);return xhr;function on_state_change(event){if(timed_out)return request.log.debug("Ignoring timed out state change",{state:xhr.readyState,id:xhr.id});request.log.debug("State change",{state:xhr.readyState,id:xhr.id,timed_out:timed_out});if(xhr.readyState===XHR.OPENED){request.log.debug("Request started",{id:xhr.id});try{for(var key in options.headers)xhr.setRequestHeader(key,options.headers[key])}catch(anException){}}else if(xhr.readyState===XHR.HEADERS_RECEIVED)on_response();else if(xhr.readyState===XHR.LOADING){on_response();on_loading()}else if(xhr.readyState===XHR.DONE){on_response();on_loading();on_end()}}function on_response(){if(did.response)return;did.response=true;request.log.debug("Got response",{id:xhr.id,status:xhr.status});clearTimeout(xhr.timeoutTimer);xhr.statusCode=xhr.status;if(is_cors&&xhr.statusCode==0){var cors_err=new Error("CORS request rejected: "+options.uri);cors_err.cors="rejected";did.loading=true;did.end=true;return options.callback(cors_err,xhr)}options.onResponse(null,xhr)}function on_loading(){if(did.loading)return;did.loading=true;request.log.debug("Response body loading",{id:xhr.id})}function on_end(){if(did.end)return;did.end=true;request.log.debug("Request done",{id:xhr.id});xhr.body=xhr.responseText;if(options.json){try{xhr.body=JSON.parse(xhr.responseText)}catch(er){return options.callback(er,xhr)}}options.callback(null,xhr,xhr.body)}}request.withCredentials=false;request.DEFAULT_TIMEOUT=DEFAULT_TIMEOUT;request.defaults=function(options,requester){var def=function(method){var d=function(params,callback){if(typeof params==="string")params={uri:params};else{params=JSON.parse(JSON.stringify(params))}for(var i in options){if(params[i]===undefined)params[i]=options[i]}return method(params,callback)};return d};var de=def(request);de.get=def(request.get);de.post=def(request.post);de.put=def(request.put);de.head=def(request.head);return de};var shortcuts=["get","put","post","head","del"];var shortcutToMethod={del:"DELETE"};shortcuts.forEach(function(shortcut){var method=shortcutToMethod[shortcut]||shortcut.toUpperCase();var func=shortcut.toLowerCase();request[func]=function(opts){if(typeof opts==="string")opts={method:method,uri:opts};else{opts=JSON.parse(JSON.stringify(opts));opts.method=method}var args=[opts].concat(Array.prototype.slice.apply(arguments,[1]));return request.apply(this,args)}});function noop(){}function getLogger(){var logger={},levels=["trace","debug","info","warn","error"],level,i;for(i=0;i<levels.length;i++){level=levels[i];logger[level]=noop;if(typeof console!=="undefined"&&console&&console[level])logger[level]=formatted(console,level)}return logger}function formatted(obj,method){return formatted_logger;function formatted_logger(str,context){if(typeof context==="object")str+=" "+JSON.stringify(context);return obj[method].call(obj,str)}}function is_crossDomain(url){var rurl=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/;var ajaxLocation;try{ajaxLocation=location.href}catch(e){ajaxLocation=document.createElement("a");ajaxLocation.href="";ajaxLocation=ajaxLocation.href}var ajaxLocParts=rurl.exec(ajaxLocation.toLowerCase())||[],parts=rurl.exec(url.toLowerCase());var result=!!(parts&&(parts[1]!=ajaxLocParts[1]||parts[2]!=ajaxLocParts[2]||(parts[3]||(parts[1]==="http:"?80:443))!=(ajaxLocParts[3]||(ajaxLocParts[1]==="http:"?80:443))));return result}function b64_enc(data){var b64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var o1,o2,o3,h1,h2,h3,h4,bits,i=0,ac=0,enc="",tmp_arr=[];if(!data){return data}do{o1=data.charCodeAt(i++);o2=data.charCodeAt(i++);o3=data.charCodeAt(i++);bits=o1<<16|o2<<8|o3;h1=bits>>18&63;h2=bits>>12&63;h3=bits>>6&63;h4=bits&63;tmp_arr[ac++]=b64.charAt(h1)+b64.charAt(h2)+b64.charAt(h3)+b64.charAt(h4)}while(i<data.length);enc=tmp_arr.join("");switch(data.length%3){case 1:enc=enc.slice(0,-2)+"==";break;case 2:enc=enc.slice(0,-1)+"=";break}return enc}var io="undefined"===typeof module?{}:module.exports;(function(){(function(exports,global){var io=exports;io.version="0.9.17";io.protocol=1;io.transports=[];io.j=[];io.sockets={};io.connect=function(host,details){var uri=io.util.parseUri(host),uuri,socket;if(global&&global.location){uri.protocol=uri.protocol||global.location.protocol.slice(0,-1);uri.host=uri.host||(global.document?global.document.domain:global.location.hostname);uri.port=uri.port||global.location.port}uuri=io.util.uniqueUri(uri);var options={host:uri.host,secure:"https"==uri.protocol,port:uri.port||("https"==uri.protocol?443:80),query:uri.query||""};io.util.merge(options,details);if(options["force new connection"]||!io.sockets[uuri]){socket=new io.Socket(options)}if(!options["force new connection"]&&socket){io.sockets[uuri]=socket}socket=socket||io.sockets[uuri];return socket.of(uri.path.length>1?uri.path:"")}})("object"===typeof module?module.exports:this.io={},this);(function(exports,global){var util=exports.util={};var re=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;var parts=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];util.parseUri=function(str){var m=re.exec(str||""),uri={},i=14;while(i--){uri[parts[i]]=m[i]||""}return uri};util.uniqueUri=function(uri){var protocol=uri.protocol,host=uri.host,port=uri.port;if("document"in global){host=host||document.domain;port=port||(protocol=="https"&&document.location.protocol!=="https:"?443:document.location.port)}else{host=host||"localhost";if(!port&&protocol=="https"){port=443}}return(protocol||"http")+"://"+host+":"+(port||80)};util.query=function(base,addition){var query=util.chunkQuery(base||""),components=[];util.merge(query,util.chunkQuery(addition||""));for(var part in query){if(query.hasOwnProperty(part)){components.push(part+"="+query[part])}}return components.length?"?"+components.join("&"):""};util.chunkQuery=function(qs){var query={},params=qs.split("&"),i=0,l=params.length,kv;for(;i<l;++i){kv=params[i].split("=");if(kv[0]){query[kv[0]]=kv[1]}}return query};var pageLoaded=false;util.load=function(fn){if("document"in global&&document.readyState==="complete"||pageLoaded){return fn()}util.on(global,"load",fn,false)};util.on=function(element,event,fn,capture){if(element.attachEvent){element.attachEvent("on"+event,fn)}else if(element.addEventListener){element.addEventListener(event,fn,capture)}};util.request=function(xdomain){if(xdomain&&"undefined"!=typeof XDomainRequest&&!util.ua.hasCORS){return new XDomainRequest}if("undefined"!=typeof XMLHttpRequest&&(!xdomain||util.ua.hasCORS)){return new XMLHttpRequest}if(!xdomain){try{return new(window[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(e){}}return null};if("undefined"!=typeof window){util.load(function(){pageLoaded=true})}util.defer=function(fn){if(!util.ua.webkit||"undefined"!=typeof importScripts){return fn()}util.load(function(){setTimeout(fn,100)})};util.merge=function merge(target,additional,deep,lastseen){var seen=lastseen||[],depth=typeof deep=="undefined"?2:deep,prop;for(prop in additional){if(additional.hasOwnProperty(prop)&&util.indexOf(seen,prop)<0){if(typeof target[prop]!=="object"||!depth){target[prop]=additional[prop];seen.push(additional[prop])}else{util.merge(target[prop],additional[prop],depth-1,seen)}}}return target};util.mixin=function(ctor,ctor2){util.merge(ctor.prototype,ctor2.prototype)};util.inherit=function(ctor,ctor2){function f(){}f.prototype=ctor2.prototype;ctor.prototype=new f};util.isArray=Array.isArray||function(obj){return Object.prototype.toString.call(obj)==="[object Array]"};util.intersect=function(arr,arr2){var ret=[],longest=arr.length>arr2.length?arr:arr2,shortest=arr.length>arr2.length?arr2:arr;for(var i=0,l=shortest.length;i<l;i++){if(~util.indexOf(longest,shortest[i]))ret.push(shortest[i])}return ret};util.indexOf=function(arr,o,i){for(var j=arr.length,i=i<0?i+j<0?0:i+j:i||0;i<j&&arr[i]!==o;i++){}return j<=i?-1:i};util.toArray=function(enu){var arr=[];for(var i=0,l=enu.length;i<l;i++)arr.push(enu[i]);return arr};util.ua={};util.ua.hasCORS="undefined"!=typeof XMLHttpRequest&&function(){try{var a=new XMLHttpRequest}catch(e){return false}return a.withCredentials!=undefined}();util.ua.webkit="undefined"!=typeof navigator&&/webkit/i.test(navigator.userAgent);util.ua.iDevice="undefined"!=typeof navigator&&/iPad|iPhone|iPod/i.test(navigator.userAgent)})("undefined"!=typeof io?io:module.exports,this);(function(exports,io){exports.EventEmitter=EventEmitter;function EventEmitter(){}EventEmitter.prototype.on=function(name,fn){if(!this.$events){this.$events={}}if(!this.$events[name]){this.$events[name]=fn}else if(io.util.isArray(this.$events[name])){this.$events[name].push(fn)}else{this.$events[name]=[this.$events[name],fn]}return this};EventEmitter.prototype.addListener=EventEmitter.prototype.on;EventEmitter.prototype.once=function(name,fn){var self=this;function on(){self.removeListener(name,on);fn.apply(this,arguments)}on.listener=fn;this.on(name,on);return this};EventEmitter.prototype.removeListener=function(name,fn){if(this.$events&&this.$events[name]){var list=this.$events[name];if(io.util.isArray(list)){var pos=-1;for(var i=0,l=list.length;i<l;i++){if(list[i]===fn||list[i].listener&&list[i].listener===fn){pos=i;break}}if(pos<0){return this}list.splice(pos,1);if(!list.length){delete this.$events[name]}}else if(list===fn||list.listener&&list.listener===fn){delete this.$events[name]}}return this};EventEmitter.prototype.removeAllListeners=function(name){if(name===undefined){this.$events={};return this}if(this.$events&&this.$events[name]){this.$events[name]=null}return this};EventEmitter.prototype.listeners=function(name){if(!this.$events){this.$events={}}if(!this.$events[name]){this.$events[name]=[]}if(!io.util.isArray(this.$events[name])){this.$events[name]=[this.$events[name]]}return this.$events[name]};EventEmitter.prototype.emit=function(name){if(!this.$events){return false}var handler=this.$events[name];if(!handler){return false}var args=Array.prototype.slice.call(arguments,1);if("function"==typeof handler){handler.apply(this,args)}else if(io.util.isArray(handler)){var listeners=handler.slice();for(var i=0,l=listeners.length;i<l;i++){listeners[i].apply(this,args)}}else{return false}return true}})("undefined"!=typeof io?io:module.exports,"undefined"!=typeof io?io:module.parent.exports);(function(exports,nativeJSON){"use strict";if(nativeJSON&&nativeJSON.parse){return exports.JSON={parse:nativeJSON.parse,stringify:nativeJSON.stringify}}var JSON=exports.JSON={};function f(n){return n<10?"0"+n:n}function date(d,key){return isFinite(d.valueOf())?d.getUTCFullYear()+"-"+f(d.getUTCMonth()+1)+"-"+f(d.getUTCDate())+"T"+f(d.getUTCHours())+":"+f(d.getUTCMinutes())+":"+f(d.getUTCSeconds())+"Z":null}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value instanceof Date){value=date(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==="string"){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else if(typeof space==="string"){indent=space}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})};JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}})("undefined"!=typeof io?io:module.exports,typeof JSON!=="undefined"?JSON:undefined);(function(exports,io){var parser=exports.parser={};var packets=parser.packets=["disconnect","connect","heartbeat","message","json","event","ack","error","noop"];var reasons=parser.reasons=["transport not supported","client not handshaken","unauthorized"];var advice=parser.advice=["reconnect"];var JSON=io.JSON,indexOf=io.util.indexOf;parser.encodePacket=function(packet){var type=indexOf(packets,packet.type),id=packet.id||"",endpoint=packet.endpoint||"",ack=packet.ack,data=null;switch(packet.type){case"error":var reason=packet.reason?indexOf(reasons,packet.reason):"",adv=packet.advice?indexOf(advice,packet.advice):"";if(reason!==""||adv!=="")data=reason+(adv!==""?"+"+adv:"");break;case"message":if(packet.data!=="")data=packet.data;break;case"event":var ev={name:packet.name};if(packet.args&&packet.args.length){ev.args=packet.args}data=JSON.stringify(ev);break;case"json":data=JSON.stringify(packet.data);break;case"connect":if(packet.qs)data=packet.qs;break;case"ack":data=packet.ackId+(packet.args&&packet.args.length?"+"+JSON.stringify(packet.args):"");break}var encoded=[type,id+(ack=="data"?"+":""),endpoint];if(data!==null&&data!==undefined)encoded.push(data);return encoded.join(":")};parser.encodePayload=function(packets){var decoded="";if(packets.length==1)return packets[0];for(var i=0,l=packets.length;i<l;i++){var packet=packets[i];decoded+="�"+packet.length+"�"+packets[i]}return decoded};var regexp=/([^:]+):([0-9]+)?(\+)?:([^:]+)?:?([\s\S]*)?/;parser.decodePacket=function(data){var pieces=data.match(regexp);if(!pieces)return{};var id=pieces[2]||"",data=pieces[5]||"",packet={type:packets[pieces[1]],endpoint:pieces[4]||""};if(id){packet.id=id;if(pieces[3])packet.ack="data";else packet.ack=true}switch(packet.type){case"error":var pieces=data.split("+");packet.reason=reasons[pieces[0]]||"";packet.advice=advice[pieces[1]]||"";break;case"message":packet.data=data||"";break;case"event":try{var opts=JSON.parse(data);packet.name=opts.name;packet.args=opts.args}catch(e){}packet.args=packet.args||[];break;case"json":try{packet.data=JSON.parse(data)}catch(e){}break;case"connect":packet.qs=data||"";break;case"ack":var pieces=data.match(/^([0-9]+)(\+)?(.*)/);if(pieces){packet.ackId=pieces[1];packet.args=[];if(pieces[3]){try{packet.args=pieces[3]?JSON.parse(pieces[3]):[]}catch(e){}}}break;case"disconnect":case"heartbeat":break}return packet};parser.decodePayload=function(data){if(data.charAt(0)=="�"){var ret=[];for(var i=1,length="";i<data.length;i++){if(data.charAt(i)=="�"){ret.push(parser.decodePacket(data.substr(i+1).substr(0,length)));i+=Number(length)+1;length=""}else{length+=data.charAt(i)}}return ret}else{return[parser.decodePacket(data)]}}})("undefined"!=typeof io?io:module.exports,"undefined"!=typeof io?io:module.parent.exports);(function(exports,io){exports.Transport=Transport;function Transport(socket,sessid){this.socket=socket;this.sessid=sessid}io.util.mixin(Transport,io.EventEmitter);Transport.prototype.heartbeats=function(){return true};Transport.prototype.onData=function(data){this.clearCloseTimeout();if(this.socket.connected||this.socket.connecting||this.socket.reconnecting){this.setCloseTimeout()}if(data!==""){var msgs=io.parser.decodePayload(data);if(msgs&&msgs.length){for(var i=0,l=msgs.length;i<l;i++){this.onPacket(msgs[i])}}}return this};Transport.prototype.onPacket=function(packet){this.socket.setHeartbeatTimeout();if(packet.type=="heartbeat"){return this.onHeartbeat()}if(packet.type=="connect"&&packet.endpoint==""){this.onConnect()}if(packet.type=="error"&&packet.advice=="reconnect"){this.isOpen=false}this.socket.onPacket(packet);return this};Transport.prototype.setCloseTimeout=function(){if(!this.closeTimeout){var self=this;this.closeTimeout=setTimeout(function(){self.onDisconnect()},this.socket.closeTimeout)}};Transport.prototype.onDisconnect=function(){if(this.isOpen)this.close();this.clearTimeouts();this.socket.onDisconnect();return this};Transport.prototype.onConnect=function(){this.socket.onConnect();return this};Transport.prototype.clearCloseTimeout=function(){if(this.closeTimeout){clearTimeout(this.closeTimeout);this.closeTimeout=null}};Transport.prototype.clearTimeouts=function(){this.clearCloseTimeout();if(this.reopenTimeout){clearTimeout(this.reopenTimeout)}};Transport.prototype.packet=function(packet){this.send(io.parser.encodePacket(packet))};Transport.prototype.onHeartbeat=function(heartbeat){this.packet({type:"heartbeat"})};Transport.prototype.onOpen=function(){this.isOpen=true;this.clearCloseTimeout();this.socket.onOpen()};Transport.prototype.onClose=function(){var self=this;this.isOpen=false;this.socket.onClose();this.onDisconnect()};Transport.prototype.prepareUrl=function(){var options=this.socket.options;return this.scheme()+"://"+options.host+":"+options.port+"/"+options.resource+"/"+io.protocol+"/"+this.name+"/"+this.sessid};Transport.prototype.ready=function(socket,fn){fn.call(this)}})("undefined"!=typeof io?io:module.exports,"undefined"!=typeof io?io:module.parent.exports);(function(exports,io,global){exports.Socket=Socket;function Socket(options){this.options={port:80,secure:false,document:"document"in global?document:false,resource:"socket.io",transports:io.transports,"connect timeout":1e4,"try multiple transports":true,reconnect:true,"reconnection delay":500,"reconnection limit":Infinity,"reopen delay":3e3,"max reconnection attempts":10,"sync disconnect on unload":false,"auto connect":true,"flash policy port":10843,manualFlush:false};io.util.merge(this.options,options);this.connected=false;this.open=false;this.connecting=false;this.reconnecting=false;this.namespaces={};this.buffer=[];this.doBuffer=false;if(this.options["sync disconnect on unload"]&&(!this.isXDomain()||io.util.ua.hasCORS)){var self=this;io.util.on(global,"beforeunload",function(){self.disconnectSync()},false)}if(this.options["auto connect"]){this.connect()}}io.util.mixin(Socket,io.EventEmitter);Socket.prototype.of=function(name){if(!this.namespaces[name]){this.namespaces[name]=new io.SocketNamespace(this,name);if(name!==""){this.namespaces[name].packet({type:"connect"})}}return this.namespaces[name]};Socket.prototype.publish=function(){this.emit.apply(this,arguments);var nsp;for(var i in this.namespaces){if(this.namespaces.hasOwnProperty(i)){nsp=this.of(i);nsp.$emit.apply(nsp,arguments)}}};function empty(){}Socket.prototype.handshake=function(fn){var self=this,options=this.options;function complete(data){if(data instanceof Error){self.connecting=false;self.onError(data.message)}else{fn.apply(null,data.split(":"))}}var url=["http"+(options.secure?"s":"")+":/",options.host+":"+options.port,options.resource,io.protocol,io.util.query(this.options.query,"t="+ +new Date)].join("/");if(this.isXDomain()&&!io.util.ua.hasCORS){var insertAt=document.getElementsByTagName("script")[0],script=document.createElement("script");script.src=url+"&jsonp="+io.j.length;insertAt.parentNode.insertBefore(script,insertAt);io.j.push(function(data){complete(data);script.parentNode.removeChild(script)})}else{var xhr=io.util.request();xhr.open("GET",url,true);if(this.isXDomain()){xhr.withCredentials=true}xhr.onreadystatechange=function(){if(xhr.readyState==4){xhr.onreadystatechange=empty;if(xhr.status==200){complete(xhr.responseText)}else if(xhr.status==403){self.onError(xhr.responseText)}else{self.connecting=false;!self.reconnecting&&self.onError(xhr.responseText)}}};xhr.send(null)}};Socket.prototype.getTransport=function(override){var transports=override||this.transports,match;for(var i=0,transport;transport=transports[i];i++){if(io.Transport[transport]&&io.Transport[transport].check(this)&&(!this.isXDomain()||io.Transport[transport].xdomainCheck(this))){return new io.Transport[transport](this,this.sessionid)}}return null};Socket.prototype.connect=function(fn){if(this.connecting){return this}var self=this;self.connecting=true;this.handshake(function(sid,heartbeat,close,transports){self.sessionid=sid;self.closeTimeout=close*1e3;self.heartbeatTimeout=heartbeat*1e3;if(!self.transports)self.transports=self.origTransports=transports?io.util.intersect(transports.split(","),self.options.transports):self.options.transports;self.setHeartbeatTimeout();function connect(transports){if(self.transport)self.transport.clearTimeouts();self.transport=self.getTransport(transports);if(!self.transport)return self.publish("connect_failed");self.transport.ready(self,function(){self.connecting=true;self.publish("connecting",self.transport.name);self.transport.open();if(self.options["connect timeout"]){self.connectTimeoutTimer=setTimeout(function(){if(!self.connected){self.connecting=false;if(self.options["try multiple transports"]){var remaining=self.transports;while(remaining.length>0&&remaining.splice(0,1)[0]!=self.transport.name){}if(remaining.length){connect(remaining)}else{self.publish("connect_failed")}}}},self.options["connect timeout"])}})}connect(self.transports);self.once("connect",function(){clearTimeout(self.connectTimeoutTimer);fn&&typeof fn=="function"&&fn()})});return this};Socket.prototype.setHeartbeatTimeout=function(){clearTimeout(this.heartbeatTimeoutTimer);if(this.transport&&!this.transport.heartbeats())return;var self=this;this.heartbeatTimeoutTimer=setTimeout(function(){self.transport.onClose()},this.heartbeatTimeout)};Socket.prototype.packet=function(data){if(this.connected&&!this.doBuffer){this.transport.packet(data)}else{this.buffer.push(data)}return this};Socket.prototype.setBuffer=function(v){this.doBuffer=v;if(!v&&this.connected&&this.buffer.length){if(!this.options["manualFlush"]){this.flushBuffer()}}};Socket.prototype.flushBuffer=function(){this.transport.payload(this.buffer);this.buffer=[]};Socket.prototype.disconnect=function(){if(this.connected||this.connecting){if(this.open){this.of("").packet({type:"disconnect"})}this.onDisconnect("booted")}return this};Socket.prototype.disconnectSync=function(){var xhr=io.util.request();var uri=["http"+(this.options.secure?"s":"")+":/",this.options.host+":"+this.options.port,this.options.resource,io.protocol,"",this.sessionid].join("/")+"/?disconnect=1";xhr.open("GET",uri,false);xhr.send(null);this.onDisconnect("booted")};Socket.prototype.isXDomain=function(){var port=global.location.port||("https:"==global.location.protocol?443:80);return this.options.host!==global.location.hostname||this.options.port!=port};Socket.prototype.onConnect=function(){if(!this.connected){this.connected=true;this.connecting=false;if(!this.doBuffer){this.setBuffer(false)}this.emit("connect")}};Socket.prototype.onOpen=function(){this.open=true};Socket.prototype.onClose=function(){this.open=false;clearTimeout(this.heartbeatTimeoutTimer)};Socket.prototype.onPacket=function(packet){this.of(packet.endpoint).onPacket(packet)};Socket.prototype.onError=function(err){if(err&&err.advice){if(err.advice==="reconnect"&&(this.connected||this.connecting)){this.disconnect();if(this.options.reconnect){this.reconnect()}}}this.publish("error",err&&err.reason?err.reason:err)};Socket.prototype.onDisconnect=function(reason){var wasConnected=this.connected,wasConnecting=this.connecting;this.connected=false;this.connecting=false;this.open=false;if(wasConnected||wasConnecting){this.transport.close();this.transport.clearTimeouts();if(wasConnected){this.publish("disconnect",reason);if("booted"!=reason&&this.options.reconnect&&!this.reconnecting){this.reconnect()}}}};Socket.prototype.reconnect=function(){this.reconnecting=true;this.reconnectionAttempts=0;this.reconnectionDelay=this.options["reconnection delay"];var self=this,maxAttempts=this.options["max reconnection attempts"],tryMultiple=this.options["try multiple transports"],limit=this.options["reconnection limit"];function reset(){if(self.connected){for(var i in self.namespaces){if(self.namespaces.hasOwnProperty(i)&&""!==i){self.namespaces[i].packet({type:"connect"})}}self.publish("reconnect",self.transport.name,self.reconnectionAttempts)}clearTimeout(self.reconnectionTimer);self.removeListener("connect_failed",maybeReconnect);self.removeListener("connect",maybeReconnect);self.reconnecting=false;delete self.reconnectionAttempts;delete self.reconnectionDelay;delete self.reconnectionTimer;delete self.redoTransports;self.options["try multiple transports"]=tryMultiple}function maybeReconnect(){if(!self.reconnecting){return}if(self.connected){return reset()}if(self.connecting&&self.reconnecting){return self.reconnectionTimer=setTimeout(maybeReconnect,1e3)}if(self.reconnectionAttempts++>=maxAttempts){if(!self.redoTransports){self.on("connect_failed",maybeReconnect);self.options["try multiple transports"]=true;self.transports=self.origTransports;self.transport=self.getTransport();self.redoTransports=true;self.connect()}else{self.publish("reconnect_failed");reset()}}else{if(self.reconnectionDelay<limit){self.reconnectionDelay*=2}self.connect();self.publish("reconnecting",self.reconnectionDelay,self.reconnectionAttempts);self.reconnectionTimer=setTimeout(maybeReconnect,self.reconnectionDelay)}}this.options["try multiple transports"]=false;this.reconnectionTimer=setTimeout(maybeReconnect,this.reconnectionDelay);this.on("connect",maybeReconnect)}})("undefined"!=typeof io?io:module.exports,"undefined"!=typeof io?io:module.parent.exports,this);(function(exports,io){exports.SocketNamespace=SocketNamespace;function SocketNamespace(socket,name){this.socket=socket;this.name=name||"";this.flags={};this.json=new Flag(this,"json");this.ackPackets=0;this.acks={}}io.util.mixin(SocketNamespace,io.EventEmitter);SocketNamespace.prototype.$emit=io.EventEmitter.prototype.emit;SocketNamespace.prototype.of=function(){return this.socket.of.apply(this.socket,arguments)};SocketNamespace.prototype.packet=function(packet){packet.endpoint=this.name;this.socket.packet(packet);this.flags={};return this};SocketNamespace.prototype.send=function(data,fn){var packet={type:this.flags.json?"json":"message",data:data};if("function"==typeof fn){packet.id=++this.ackPackets;packet.ack=true;this.acks[packet.id]=fn}return this.packet(packet)};SocketNamespace.prototype.emit=function(name){var args=Array.prototype.slice.call(arguments,1),lastArg=args[args.length-1],packet={type:"event",name:name};if("function"==typeof lastArg){packet.id=++this.ackPackets;packet.ack="data";this.acks[packet.id]=lastArg;args=args.slice(0,args.length-1)}packet.args=args;return this.packet(packet)};SocketNamespace.prototype.disconnect=function(){if(this.name===""){this.socket.disconnect()}else{this.packet({type:"disconnect"});this.$emit("disconnect")}return this};SocketNamespace.prototype.onPacket=function(packet){var self=this;function ack(){self.packet({type:"ack",args:io.util.toArray(arguments),ackId:packet.id})}switch(packet.type){case"connect":this.$emit("connect");break;case"disconnect":if(this.name===""){this.socket.onDisconnect(packet.reason||"booted")}else{this.$emit("disconnect",packet.reason)}break;case"message":case"json":var params=["message",packet.data];if(packet.ack=="data"){params.push(ack)}else if(packet.ack){this.packet({type:"ack",ackId:packet.id})}this.$emit.apply(this,params);break;case"event":var params=[packet.name].concat(packet.args);if(packet.ack=="data")params.push(ack);this.$emit.apply(this,params);break;case"ack":if(this.acks[packet.ackId]){this.acks[packet.ackId].apply(this,packet.args);delete this.acks[packet.ackId]}break;case"error":if(packet.advice){this.socket.onError(packet)}else{if(packet.reason=="unauthorized"){this.$emit("connect_failed",packet.reason)}else{this.$emit("error",packet.reason)
2
- }}break}};function Flag(nsp,name){this.namespace=nsp;this.name=name}Flag.prototype.send=function(){this.namespace.flags[this.name]=true;this.namespace.send.apply(this.namespace,arguments)};Flag.prototype.emit=function(){this.namespace.flags[this.name]=true;this.namespace.emit.apply(this.namespace,arguments)}})("undefined"!=typeof io?io:module.exports,"undefined"!=typeof io?io:module.parent.exports);(function(exports,io,global){exports.websocket=WS;function WS(socket){io.Transport.apply(this,arguments)}io.util.inherit(WS,io.Transport);WS.prototype.name="websocket";WS.prototype.open=function(){var query=io.util.query(this.socket.options.query),self=this,Socket;if(!Socket){Socket=global.MozWebSocket||global.WebSocket}this.websocket=new Socket(this.prepareUrl()+query);this.websocket.onopen=function(){self.onOpen();self.socket.setBuffer(false)};this.websocket.onmessage=function(ev){self.onData(ev.data)};this.websocket.onclose=function(){self.onClose();self.socket.setBuffer(true)};this.websocket.onerror=function(e){self.onError(e)};return this};if(io.util.ua.iDevice){WS.prototype.send=function(data){var self=this;setTimeout(function(){self.websocket.send(data)},0);return this}}else{WS.prototype.send=function(data){this.websocket.send(data);return this}}WS.prototype.payload=function(arr){for(var i=0,l=arr.length;i<l;i++){this.packet(arr[i])}return this};WS.prototype.close=function(){this.websocket.close();return this};WS.prototype.onError=function(e){this.socket.onError(e)};WS.prototype.scheme=function(){return this.socket.options.secure?"wss":"ws"};WS.check=function(){return"WebSocket"in global&&!("__addTask"in WebSocket)||"MozWebSocket"in global};WS.xdomainCheck=function(){return true};io.transports.push("websocket")})("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports,this);(function(exports,io){exports.flashsocket=Flashsocket;function Flashsocket(){io.Transport.websocket.apply(this,arguments)}io.util.inherit(Flashsocket,io.Transport.websocket);Flashsocket.prototype.name="flashsocket";Flashsocket.prototype.open=function(){var self=this,args=arguments;WebSocket.__addTask(function(){io.Transport.websocket.prototype.open.apply(self,args)});return this};Flashsocket.prototype.send=function(){var self=this,args=arguments;WebSocket.__addTask(function(){io.Transport.websocket.prototype.send.apply(self,args)});return this};Flashsocket.prototype.close=function(){WebSocket.__tasks.length=0;io.Transport.websocket.prototype.close.call(this);return this};Flashsocket.prototype.ready=function(socket,fn){function init(){var options=socket.options,port=options["flash policy port"],path=["http"+(options.secure?"s":"")+":/",options.host+":"+options.port,options.resource,"static/flashsocket","WebSocketMain"+(socket.isXDomain()?"Insecure":"")+".swf"];if(!Flashsocket.loaded){if(typeof WEB_SOCKET_SWF_LOCATION==="undefined"){WEB_SOCKET_SWF_LOCATION=path.join("/")}if(port!==843){WebSocket.loadFlashPolicyFile("xmlsocket://"+options.host+":"+port)}WebSocket.__initialize();Flashsocket.loaded=true}fn.call(self)}var self=this;if(document.body)return init();io.util.load(init)};Flashsocket.check=function(){if(typeof WebSocket=="undefined"||!("__initialize"in WebSocket)||!swfobject)return false;return swfobject.getFlashPlayerVersion().major>=10};Flashsocket.xdomainCheck=function(){return true};if(typeof window!="undefined"){WEB_SOCKET_DISABLE_AUTO_INITIALIZATION=true}io.transports.push("flashsocket")})("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports);if("undefined"!=typeof window){var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+" 1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O[["Active"].concat("Object").join("X")]!=D){try{var ad=new(window[["Active"].concat("Object").join("X")])(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if(typeof j.readyState!=D&&j.readyState=="complete"||typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body)){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return!a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||!/%$/.test(aa.width)&&parseInt(aa.width,10)<310){aa.width="310"}if(typeof aa.height==D||!/%$/.test(aa.height)&&parseInt(aa.height,10)<137){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?["Active"].concat("").join("X"):"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return Y[0]>X[0]||Y[0]==X[0]&&Y[1]>X[1]||Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=ad&&typeof ad=="string"?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring(Y[X].indexOf("=")+1))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}()}(function(){if("undefined"==typeof window||window.WebSocket)return;var console=window.console;if(!console||!console.log||!console.error){console={log:function(){},error:function(){}}}if(!swfobject.hasFlashPlayerVersion("10.0.0")){console.error("Flash Player >= 10.0.0 is required.");return}if(location.protocol=="file:"){console.error("WARNING: web-socket-js doesn't work in file:///... URL "+"unless you set Flash Security Settings properly. "+"Open the page via Web server i.e. http://...")}WebSocket=function(url,protocols,proxyHost,proxyPort,headers){var self=this;self.__id=WebSocket.__nextId++;WebSocket.__instances[self.__id]=self;self.readyState=WebSocket.CONNECTING;self.bufferedAmount=0;self.__events={};if(!protocols){protocols=[]}else if(typeof protocols=="string"){protocols=[protocols]}setTimeout(function(){WebSocket.__addTask(function(){WebSocket.__flash.create(self.__id,url,protocols,proxyHost||null,proxyPort||0,headers||null)})},0)};WebSocket.prototype.send=function(data){if(this.readyState==WebSocket.CONNECTING){throw"INVALID_STATE_ERR: Web Socket connection has not been established"}var result=WebSocket.__flash.send(this.__id,encodeURIComponent(data));if(result<0){return true}else{this.bufferedAmount+=result;return false}};WebSocket.prototype.close=function(){if(this.readyState==WebSocket.CLOSED||this.readyState==WebSocket.CLOSING){return}this.readyState=WebSocket.CLOSING;WebSocket.__flash.close(this.__id)};WebSocket.prototype.addEventListener=function(type,listener,useCapture){if(!(type in this.__events)){this.__events[type]=[]}this.__events[type].push(listener)};WebSocket.prototype.removeEventListener=function(type,listener,useCapture){if(!(type in this.__events))return;var events=this.__events[type];for(var i=events.length-1;i>=0;--i){if(events[i]===listener){events.splice(i,1);break}}};WebSocket.prototype.dispatchEvent=function(event){var events=this.__events[event.type]||[];for(var i=0;i<events.length;++i){events[i](event)}var handler=this["on"+event.type];if(handler)handler(event)};WebSocket.prototype.__handleEvent=function(flashEvent){if("readyState"in flashEvent){this.readyState=flashEvent.readyState}if("protocol"in flashEvent){this.protocol=flashEvent.protocol}var jsEvent;if(flashEvent.type=="open"||flashEvent.type=="error"){jsEvent=this.__createSimpleEvent(flashEvent.type)}else if(flashEvent.type=="close"){jsEvent=this.__createSimpleEvent("close")}else if(flashEvent.type=="message"){var data=decodeURIComponent(flashEvent.message);jsEvent=this.__createMessageEvent("message",data)}else{throw"unknown event type: "+flashEvent.type}this.dispatchEvent(jsEvent)};WebSocket.prototype.__createSimpleEvent=function(type){if(document.createEvent&&window.Event){var event=document.createEvent("Event");event.initEvent(type,false,false);return event}else{return{type:type,bubbles:false,cancelable:false}}};WebSocket.prototype.__createMessageEvent=function(type,data){if(document.createEvent&&window.MessageEvent&&!window.opera){var event=document.createEvent("MessageEvent");event.initMessageEvent("message",false,false,data,null,null,window,null);return event}else{return{type:type,data:data,bubbles:false,cancelable:false}}};WebSocket.CONNECTING=0;WebSocket.OPEN=1;WebSocket.CLOSING=2;WebSocket.CLOSED=3;WebSocket.__flash=null;WebSocket.__instances={};WebSocket.__tasks=[];WebSocket.__nextId=0;WebSocket.loadFlashPolicyFile=function(url){WebSocket.__addTask(function(){WebSocket.__flash.loadManualPolicyFile(url)})};WebSocket.__initialize=function(){if(WebSocket.__flash)return;if(WebSocket.__swfLocation){window.WEB_SOCKET_SWF_LOCATION=WebSocket.__swfLocation}if(!window.WEB_SOCKET_SWF_LOCATION){console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");return}var container=document.createElement("div");container.id="webSocketContainer";container.style.position="absolute";if(WebSocket.__isFlashLite()){container.style.left="0px";container.style.top="0px"}else{container.style.left="-100px";container.style.top="-100px"}var holder=document.createElement("div");holder.id="webSocketFlash";container.appendChild(holder);document.body.appendChild(container);swfobject.embedSWF(WEB_SOCKET_SWF_LOCATION,"webSocketFlash","1","1","10.0.0",null,null,{hasPriority:true,swliveconnect:true,allowScriptAccess:"always"},null,function(e){if(!e.success){console.error("[WebSocket] swfobject.embedSWF failed")}})};WebSocket.__onFlashInitialized=function(){setTimeout(function(){WebSocket.__flash=document.getElementById("webSocketFlash");WebSocket.__flash.setCallerUrl(location.href);WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);for(var i=0;i<WebSocket.__tasks.length;++i){WebSocket.__tasks[i]()}WebSocket.__tasks=[]},0)};WebSocket.__onFlashEvent=function(){setTimeout(function(){try{var events=WebSocket.__flash.receiveEvents();for(var i=0;i<events.length;++i){WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i])}}catch(e){console.error(e)}},0);return true};WebSocket.__log=function(message){console.log(decodeURIComponent(message))};WebSocket.__error=function(message){console.error(decodeURIComponent(message))};WebSocket.__addTask=function(task){if(WebSocket.__flash){task()}else{WebSocket.__tasks.push(task)}};WebSocket.__isFlashLite=function(){if(!window.navigator||!window.navigator.mimeTypes){return false}var mimeType=window.navigator.mimeTypes["application/x-shockwave-flash"];if(!mimeType||!mimeType.enabledPlugin||!mimeType.enabledPlugin.filename){return false}return mimeType.enabledPlugin.filename.match(/flashlite/i)?true:false};if(!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION){if(window.addEventListener){window.addEventListener("load",function(){WebSocket.__initialize()},false)}else{window.attachEvent("onload",function(){WebSocket.__initialize()})}}})();(function(exports,io,global){exports.XHR=XHR;function XHR(socket){if(!socket)return;io.Transport.apply(this,arguments);this.sendBuffer=[]}io.util.inherit(XHR,io.Transport);XHR.prototype.open=function(){this.socket.setBuffer(false);this.onOpen();this.get();this.setCloseTimeout();return this};XHR.prototype.payload=function(payload){var msgs=[];for(var i=0,l=payload.length;i<l;i++){msgs.push(io.parser.encodePacket(payload[i]))}this.send(io.parser.encodePayload(msgs))};XHR.prototype.send=function(data){this.post(data);return this};function empty(){}XHR.prototype.post=function(data){var self=this;this.socket.setBuffer(true);function stateChange(){if(this.readyState==4){this.onreadystatechange=empty;self.posting=false;if(this.status==200){self.socket.setBuffer(false)}else{self.onClose()}}}function onload(){this.onload=empty;self.socket.setBuffer(false)}this.sendXHR=this.request("POST");if(global.XDomainRequest&&this.sendXHR instanceof XDomainRequest){this.sendXHR.onload=this.sendXHR.onerror=onload}else{this.sendXHR.onreadystatechange=stateChange}this.sendXHR.send(data)};XHR.prototype.close=function(){this.onClose();return this};XHR.prototype.request=function(method){var req=io.util.request(this.socket.isXDomain()),query=io.util.query(this.socket.options.query,"t="+ +new Date);req.open(method||"GET",this.prepareUrl()+query,true);if(method=="POST"){try{if(req.setRequestHeader){req.setRequestHeader("Content-type","text/plain;charset=UTF-8")}else{req.contentType="text/plain"}}catch(e){}}return req};XHR.prototype.scheme=function(){return this.socket.options.secure?"https":"http"};XHR.check=function(socket,xdomain){try{var request=io.util.request(xdomain),usesXDomReq=global.XDomainRequest&&request instanceof XDomainRequest,socketProtocol=socket&&socket.options&&socket.options.secure?"https:":"http:",isXProtocol=global.location&&socketProtocol!=global.location.protocol;if(request&&!(usesXDomReq&&isXProtocol)){return true}}catch(e){}return false};XHR.xdomainCheck=function(socket){return XHR.check(socket,true)}})("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports,this);(function(exports,io){exports.htmlfile=HTMLFile;function HTMLFile(socket){io.Transport.XHR.apply(this,arguments)}io.util.inherit(HTMLFile,io.Transport.XHR);HTMLFile.prototype.name="htmlfile";HTMLFile.prototype.get=function(){this.doc=new(window[["Active"].concat("Object").join("X")])("htmlfile");this.doc.open();this.doc.write("<html></html>");this.doc.close();this.doc.parentWindow.s=this;var iframeC=this.doc.createElement("div");iframeC.className="socketio";this.doc.body.appendChild(iframeC);this.iframe=this.doc.createElement("iframe");iframeC.appendChild(this.iframe);var self=this,query=io.util.query(this.socket.options.query,"t="+ +new Date);this.iframe.src=this.prepareUrl()+query;io.util.on(window,"unload",function(){self.destroy()})};HTMLFile.prototype._=function(data,doc){data=data.replace(/\\\//g,"/");this.onData(data);try{var script=doc.getElementsByTagName("script")[0];script.parentNode.removeChild(script)}catch(e){}};HTMLFile.prototype.destroy=function(){if(this.iframe){try{this.iframe.src="about:blank"}catch(e){}this.doc=null;this.iframe.parentNode.removeChild(this.iframe);this.iframe=null;CollectGarbage()}};HTMLFile.prototype.close=function(){this.destroy();return io.Transport.XHR.prototype.close.call(this)};HTMLFile.check=function(socket){if(typeof window!="undefined"&&["Active"].concat("Object").join("X")in window){try{var a=new(window[["Active"].concat("Object").join("X")])("htmlfile");return a&&io.Transport.XHR.check(socket)}catch(e){}}return false};HTMLFile.xdomainCheck=function(){return false};io.transports.push("htmlfile")})("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports);(function(exports,io,global){exports["xhr-polling"]=XHRPolling;function XHRPolling(){io.Transport.XHR.apply(this,arguments)}io.util.inherit(XHRPolling,io.Transport.XHR);io.util.merge(XHRPolling,io.Transport.XHR);XHRPolling.prototype.name="xhr-polling";XHRPolling.prototype.heartbeats=function(){return false};XHRPolling.prototype.open=function(){var self=this;io.Transport.XHR.prototype.open.call(self);return false};function empty(){}XHRPolling.prototype.get=function(){if(!this.isOpen)return;var self=this;function stateChange(){if(this.readyState==4){this.onreadystatechange=empty;if(this.status==200){self.onData(this.responseText);self.get()}else{self.onClose()}}}function onload(){this.onload=empty;this.onerror=empty;self.retryCounter=1;self.onData(this.responseText);self.get()}function onerror(){self.retryCounter++;if(!self.retryCounter||self.retryCounter>3){self.onClose()}else{self.get()}}this.xhr=this.request();if(global.XDomainRequest&&this.xhr instanceof XDomainRequest){this.xhr.onload=onload;this.xhr.onerror=onerror}else{this.xhr.onreadystatechange=stateChange}this.xhr.send(null)};XHRPolling.prototype.onClose=function(){io.Transport.XHR.prototype.onClose.call(this);if(this.xhr){this.xhr.onreadystatechange=this.xhr.onload=this.xhr.onerror=empty;try{this.xhr.abort()}catch(e){}this.xhr=null}};XHRPolling.prototype.ready=function(socket,fn){var self=this;io.util.defer(function(){fn.call(self)})};io.transports.push("xhr-polling")})("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports,this);(function(exports,io,global){var indicator=global.document&&"MozAppearance"in global.document.documentElement.style;exports["jsonp-polling"]=JSONPPolling;function JSONPPolling(socket){io.Transport["xhr-polling"].apply(this,arguments);this.index=io.j.length;var self=this;io.j.push(function(msg){self._(msg)})}io.util.inherit(JSONPPolling,io.Transport["xhr-polling"]);JSONPPolling.prototype.name="jsonp-polling";JSONPPolling.prototype.post=function(data){var self=this,query=io.util.query(this.socket.options.query,"t="+ +new Date+"&i="+this.index);if(!this.form){var form=document.createElement("form"),area=document.createElement("textarea"),id=this.iframeId="socketio_iframe_"+this.index,iframe;form.className="socketio";form.style.position="absolute";form.style.top="0px";form.style.left="0px";form.style.display="none";form.target=id;form.method="POST";form.setAttribute("accept-charset","utf-8");area.name="d";form.appendChild(area);document.body.appendChild(form);this.form=form;this.area=area}this.form.action=this.prepareUrl()+query;function complete(){initIframe();self.socket.setBuffer(false)}function initIframe(){if(self.iframe){self.form.removeChild(self.iframe)}try{iframe=document.createElement('<iframe name="'+self.iframeId+'">')}catch(e){iframe=document.createElement("iframe");iframe.name=self.iframeId}iframe.id=self.iframeId;self.form.appendChild(iframe);self.iframe=iframe}initIframe();this.area.value=io.JSON.stringify(data);try{this.form.submit()}catch(e){}if(this.iframe.attachEvent){iframe.onreadystatechange=function(){if(self.iframe.readyState=="complete"){complete()}}}else{this.iframe.onload=complete}this.socket.setBuffer(true)};JSONPPolling.prototype.get=function(){var self=this,script=document.createElement("script"),query=io.util.query(this.socket.options.query,"t="+ +new Date+"&i="+this.index);if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}script.async=true;script.src=this.prepareUrl()+query;script.onerror=function(){self.onClose()};var insertAt=document.getElementsByTagName("script")[0];insertAt.parentNode.insertBefore(script,insertAt);this.script=script;if(indicator){setTimeout(function(){var iframe=document.createElement("iframe");document.body.appendChild(iframe);document.body.removeChild(iframe)},100)}};JSONPPolling.prototype._=function(msg){this.onData(msg);if(this.isOpen){this.get()}return this};JSONPPolling.prototype.ready=function(socket,fn){var self=this;if(!indicator)return fn.call(this);io.util.load(function(){fn.call(self)})};JSONPPolling.check=function(){return"document"in global};JSONPPolling.xdomainCheck=function(){return true};io.transports.push("jsonp-polling")})("undefined"!=typeof io?io.Transport:module.exports,"undefined"!=typeof io?io:module.parent.exports,this);if(typeof define==="function"&&define.amd){define([],function(){return io})}})();(function(){"use strict";function CommandManager(device){this.device=device;this.executing=false;this.messageQueue=[]}CommandManager.prototype.activeCommands=function(){var filtered=[];this.messageQueue.forEach(function(message){if(message.millisToTimestamp()<=0){filtered.push(message)}});return filtered};CommandManager.prototype.commandFilter=function(){return{tags:CommandManager.commandTag(this.device.id)}};CommandManager.commandTag=function(principalId){return"command:"+principalId};CommandManager.prototype.collapse=function(){var collapsedMessages=[];var upstreamMessage;var self=this;this.sortQueue();var relevantMessages=[];this.messageQueue.forEach(function(message){if(self.isRelevant(message)){relevantMessages.push(message)}});while(upstreamMessage=relevantMessages.shift()){if(self.isCommand(upstreamMessage)){var idx;var obsoleted=false;for(idx=0;idx<relevantMessages.length&&!obsoleted;idx++){var downstreamMessage=relevantMessages[idx];obsoleted=this.obsoletes(downstreamMessage,upstreamMessage)}if(!obsoleted){collapsedMessages.push(upstreamMessage)}else{}}else{}}this.messageQueue=collapsedMessages};CommandManager.prototype.execute=function(){var self=this;if(this.device.id!==this.session.principal.id)return self.session.log.debug("CommandManager::execute: not in session of device, skipping execution.");if(this.executing)return;if(!this.messageQueue||this.messageQueue.length===0)return self.session.log.debug("CommandManager::execute: empty command queue.");var msToExecute=this.messageQueue[0].millisToTimestamp();if(msToExecute>0){self.session.log.debug("CommandManager::execute: top message occurs in the future, setting timeout for "+msToExecute+"ms.");return setTimeout(function(){self.execute()},msToExecute)}this.executing=true;this.executeQueue(function(err){self.executing=false;if(err)self.session.log.error("CommandManager::execute: execution error: "+err);setTimeout(function(){self.execute()},0)})};CommandManager.prototype.lastActiveCommand=function(){var activeCommands=this.activeCommands();return activeCommands.length>0?activeCommands[activeCommands.length-1]:null};CommandManager.obsoletes=function(downstreamMsg,upstreamMsg){if(downstreamMsg.ts<upstreamMsg.ts)return false;if(downstreamMsg.expired())return false;if(upstreamMsg.expired())return true;return false};CommandManager.prototype.process=function(message){if(!this.isRelevant(message))return;this.messageQueue.push(message);this.collapse();var self=this;if(message.expires){var nextExpiration=Math.max(message.millisToExpiration(),0);setTimeout(function(){self.collapse()},nextExpiration)}};CommandManager.prototype.sortQueue=function(){this.messageQueue.sort(function(a,b){return a.ts-b.ts})};CommandManager.prototype.start=function(session,filter,callback){this.session=session;if(!filter){filter=this.commandFilter()}var self=this;Message.find(session,filter,{sort:{ts:-1},limit:1e3},function(err,reversedMessages){if(err)return callback(err);var messages=reversedMessages.reverse();messages.forEach(function(message){self.process(message)});self.execute();session.onMessage(filter,function(message){self.process(message);callback(null,message);if(!self.executing){self.execute()}});session.log.info("commandManager: started.");callback()})};function ApiKey(json){for(var key in json){if(json.hasOwnProperty(key)){this[key]=json[key]}}}ApiKey.find=function(session,query,options,callback){if(!session)return callback(new Error("Session required for ApiKey.index."));if(!callback||typeof callback!=="function")return callback(new Error("Callback required for ApiKey.index."));session.get({url:session.service.config.endpoints.api_keys,json:true},function(err,resp,body){if(err)return callback(err);var apiKeys=body.api_keys.map(function(apiKey){return new ApiKey(apiKey)});callback(null,apiKeys)})};ApiKey.prototype.create=function(session,callback){var self=this;session.post({url:session.service.config.endpoints.api_keys,json:this},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(body.error||resp.statusCode);return callback(null,new ApiKey(body.api_key))})};function Permission(json){for(var key in json){if(json.hasOwnProperty(key)){this[key]=json[key]}}}Permission.prototype.create=function(session,callback){session.post({url:session.service.config.endpoints.permissions,json:this},function(err,resp,body){if(err)return callback(err);
3
- if(resp.statusCode!=200)return callback(body);if(callback)callback(null,new Permission(body.permission))})};Permission.find=function(session,query,options,callback){if(!session)return callback(new Error("session required for find"));if(!callback||typeof callback!=="function")return callback(new Error("callback required for find."));session.get({url:session.service.config.endpoints.permissions,query:query,queryOptions:options,json:true},function(err,resp,body){if(err)return callback(err);var permissions=body.permissions.map(function(permission){return new Permission(permission)});callback(null,permissions)})};Permission.prototype.remove=function(session,callback){var self=this;session.remove({url:session.service.config.endpoints.permissions+"/"+this.id},function(err){return callback(err)})};Permission.prototype.save=function(session,callback){if(!this.id)return callback("Permission must have id to be saved.");session.put({url:session.service.config.endpoints.permissions+"/"+this.id,json:this},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(body,null);if(callback)callback(null,new Permission(body.permission))})};Permission.NORMAL_PRIORITY=1e7;function Principal(json){this.updateAttributes(json);if(!this.nickname)this.nickname="default"}Principal.DEVICE_SECRET_BYTES=128;Principal.prototype.authenticate=function(config,callback){var self=this;var authBody={type:this.type,id:this.id};var headers={};if(this.is("user")){authBody.email=this.email;authBody.password=this.password}else{authBody.secret=this.secret}var path;if(this.is("user")){path="/user/auth"}else{path="/secret/auth"}request.post({url:config.endpoints.principals+path,headers:headers,json:authBody},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!==200){return callback(JSON.stringify(body.error)||resp.statusCode)}self.updateAttributes(body.principal);return callback(null,self,body.accessToken)})};Principal.accessTokenFor=function(session,principalId,options,callback){if(!session)return callback("no session passed to Principal.accessTokenFor");if(!callback||typeof callback!=="function")return callback("no callback passed to to Principal.accessTokenFor.");var accessTokenUrl=session.service.config.endpoints.principals+"/accesstoken";options.principal_id=principalId;session.post({url:accessTokenUrl,json:options},function(err,resp,body){if(err)return callback(err);callback(null,body.accessToken)})};Principal.prototype.create=function(config,callback){var self=this;crypto.randomBytes(Principal.DEVICE_SECRET_BYTES,function(err,secretBuf){if(err)return callback(err);var secretBase64=secretBuf.toString("base64");if(self.is("user")&&(!self.email||!self.password||!self.name)){return callback(new Error("Please provide your full name, email, and password to create an account."))}else if(!self.is("user")){if(!self.api_key&&config.api_key)self.api_key=config.api_key;if(!self.api_key)return callback(new Error("Parameter api_key required for principal.create"));self.secret=secretBase64}var principalObject=JSON.parse(JSON.stringify(self));request.post({url:config.endpoints.principals,json:principalObject},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!==200)return callback(body.error||resp.statusCode);body.principal.secret=secretBase64;self.updateAttributes(body.principal);return callback(null,self,body.accessToken)})})};Principal.find=function(session,query,options,callback){if(!session)return callback(new Error("Principal.findById requires active session."));var principalsUrl=session.service.config.endpoints.principals;session.get({url:principalsUrl,query:query,queryOptions:options,json:true},function(err,resp,body){if(err)return callback(err);var principals=body.principals.map(function(principal){return new Principal(principal)});callback(null,principals)})};Principal.findById=function(session,principalId,callback){if(!session)return callback(new Error("Principal.findById requires active session."));var principalsUrl=session.service.config.endpoints.principals+"/"+principalId;session.get({url:principalsUrl,json:true},function(err,resp,body){if(err)return callback(err);callback(null,new Principal(body.principal))})};Principal.impersonate=function(session,principalId,callback){var self=this;var impersonateUrl=session.service.config.endpoints.principals+"/impersonate";session.post({url:impersonateUrl,json:{id:principalId}},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(body.error||resp.statusCode);var receivedPrincipal=new Principal(body.principal);receivedPrincipal.nickname=self.nickname;return callback(null,receivedPrincipal,body.accessToken)})};Principal.prototype.remove=function(session,callback){var self=this;session.remove({url:session.service.config.endpoints.principals+"/"+this.id},function(err){if(err)return callback(err);session.service.clearCredentials(self);return callback()})};Principal.prototype.resume=function(config,callback){return callback(null,this,this.accessToken)};Principal.prototype.save=function(session,callback){if(!this.id)return callback("Principal must have id to be saved.");var self=this;Principal.update(session,this.id,this,function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(resp.statusCode,null);self.updateAttributes(body.principal);if(callback)callback(null,self)})};Principal.prototype.status=function(callback){callback(null,{})};Principal.prototype.toStoreId=function(){if(!this.nickname)console.log("WARNING: nickname is not defined for device.");return"principal."+this.nickname};Principal.prototype.toStoreObject=function(){return{id:this.id,api_key:this.api_key,email:this.email,type:this.type,public_key:this.public_key,private_key:this.private_key,secret:this.secret}};Principal.update=function(session,id,updates,callback){session.put({url:session.service.config.endpoints.principals+"/"+id,json:updates},callback)};Principal.prototype.updateAttributes=function(attributes){for(var key in attributes){this[key]=attributes[key]}};Principal.prototype.is=function(type){return this.type===type};function Message(json){this.ts=new Date;this.body={};for(var key in json){if(json.hasOwnProperty(key)){if(key==="ts"||key==="expires"||key==="index_until")this[key]=new Date(Date.parse(json[key]));else this[key]=json[key]}}}Message.find=function(session,query,options,callback){if(!session)return callback("no session passed to Message.find");if(!callback||typeof callback!=="function")return callback("no callback passed to Message.find.");if(!query)query={};if(!options)options={};var messageUrl=session.service.config.endpoints.messages;session.get({url:messageUrl,query:query,queryOptions:options,json:true},function(err,resp,body){if(err)return callback(err);var messages=body.messages.map(function(message){return new Message(message)});callback(null,messages)})};Message.prototype.is=function(type){return this.type===type};Message.prototype.isFrom=function(principal){return this.from===principal.id};Message.prototype.isResponseTo=function(otherMessage){return otherMessage.id&&this.response_to&&this.response_to.indexOf(otherMessage.id)!==-1};Message.prototype.isTo=function(principal){return this.to===principal.id};Message.remove=function(session,query,callback){session.remove({url:session.service.config.endpoints.messages,query:query,json:true},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(resp.statusCode);callback(null,body.removed)})};Message.prototype.remove=function(session,callback){Message.remove(session,{_id:this.id},callback||function(){})};Message.prototype.send=function(session,callback){Message.sendMany(session,[this],callback||function(){})};Message.sendMany=function(session,messages,callback){if(!session)return callback("session required for Message.sendMany");var self=this;Message.queuedMessages.push({session:session,messages:messages,callback:callback});Message.setupSendTimeout()};Message.backoffMillis=1;Message.sendQueue=function(){Message.sendTimeout=null;var context=Message.queuedMessages[0];Message.queuedMessages=Message.queuedMessages.slice(1);context.session.post({url:context.session.service.config.endpoints.messages,json:context.messages},function(err,resp,body){if(resp&&resp.statusCode!==200){err=err||body.message||resp.statusCode;if(resp.statusCode!==400)Message.queuedMessages.unshift(context)}if(err){Message.backoffMillis*=4;Message.backoffMillis=Math.min((64+Math.random())*1e3,Message.backoffMillis)}else{Message.backoffMillis=1}if(Message.queuedMessages.length){Message.setupSendTimeout()}if(err){context.session.log.error("sending message failed with error: "+JSON.stringify(err));if(context.callback)context.callback(err);return}var sentMessages=[];body.messages.forEach(function(messageJson){sentMessages.push(new Message(messageJson))});if(context.callback)context.callback(null,sentMessages)})};Message.setupSendTimeout=function(){var self=this;if(!Message.sendTimeout){Message.sendTimeout=setTimeout(function(){self.sendQueue()},Message.backoffMillis)}};Message.queuedMessages=[];Message.sendTimeout=null;Message.prototype.expired=function(){return this.millisToExpiration()<0};Message.prototype.millisToExpiration=function(){return this.expires-(new Date).getTime()};Message.prototype.millisToTimestamp=function(){return this.ts-(new Date).getTime()};Message.NEVER_EXPIRE=new Date(Date.UTC(2500,0,1));Message.INDEX_FOREVER=new Date(Date.UTC(2500,0,1));function Blob(json){for(var key in json){this[key]=json[key]}}Blob.prototype.save=function(session,stream,callback){if(!session.service.config.endpoints.blobs)return callback("blob endpoint not available on this service");var self=this;stream.pipe(session.post({url:session.service.config.endpoints.blobs,headers:{"Content-Type":self.content_type}},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(resp.statusCode);var bodyJson=JSON.parse(body);return callback(null,new Blob(bodyJson.blob))}))};Blob.get=function(session,url,callback){session.get({url:url,encoding:null},callback)};function Session(service,principal,accessToken){var self=this;this.service=service;this.principal=principal;this.accessToken=accessToken;this.subscriptionCount=0;this.sessionId=Math.floor(Math.random()*1e8);this.heartbeatTimeout=false;this.heartbeatReceived=true;this.consecutiveHeartbeatFailures=0;this.subscriptions={};this.failureCallback=function(){};Session.prototype.log={};Session.prototype.log.debug=function(message){Session.log(self,"debug",message)};Session.prototype.log.info=function(message){Session.log(self,"info",message)};Session.prototype.log.warn=function(message){Session.log(self,"warn",message)};Session.prototype.log.error=function(message){Session.log(self,"error",message)};this.log.debug("session: created.")}Session.HEARTBEAT_DEFAULT_INTERVAL=5*60*1e3;Session.MAX_SUBSCRIPTION_RESTARTS=3;Session.HEARTBEAT_TIMEOUT=15*1e3;Session.queryStringFromObject=function(obj){var str=[];for(var p in obj)str.push(encodeURIComponent(p)+"="+encodeURIComponent(obj[p]));return str.join("&")};Session.startSession=function(service,principal,accessToken){if(!Session.sessions)Session.sessions={};if(!Session.sessions[principal.id]){Session.sessions[principal.id]=new Session(service,principal,accessToken)}return Session.sessions[principal.id]};Session.stopSession=function(session){delete Session.sessions[session.principal.id]};Session.prototype.stop=function(){Session.stopSession(this);this.failureCallback=null;var self=this;for(var key in this.subscriptions){this.disconnectSubscription(this.subscriptions[key].id)}if(this.socket)this.socket.disconnect();this.socket=null;if(this.heartbeat)this.heartbeat.stop();this.heartbeat=null};Session.prototype.beforeRequest=function(options){if(!options.headers)options.headers={};options.headers.Authorization="Bearer "+this.accessToken.token;var prefix="?";if(options.query){var queryString=JSON.stringify(options.query);options.url+=prefix+"q="+encodeURIComponent(queryString);delete options.query;prefix="&"}if(options.queryOptions){var optionsString=JSON.stringify(options.queryOptions);options.url+=prefix+"options="+encodeURIComponent(optionsString);delete options.queryOptions}};Session.prototype.afterRequest=function(err,resp,body,callback){if(resp&&resp.statusCode!==200){if(body&&body.error)err=body.error;else err=resp.statusCode}if(resp&&resp.statusCode===401)this.signalFailure();if(resp&&resp.headers&&resp.headers["x-n2-set-access-token"]){this.accessToken=JSON.parse(resp.headers["x-n2-set-access-token"])}callback(err,resp,body)};Session.prototype.makeRequest=function(options,requestFunc,callback){var self=this;this.beforeRequest(options);return requestFunc(options,function(err,resp,body){self.afterRequest(err,resp,body,callback)})};Session.prototype.get=function(options,callback){return this.makeRequest(options,request.get,callback)};Session.prototype.post=function(options,callback){return this.makeRequest(options,request.post,callback)};Session.prototype.put=function(options,callback){return this.makeRequest(options,request.put,callback)};Session.prototype.remove=function(options,callback){return this.makeRequest(options,request.del,callback)};Session.prototype.clearCredentials=function(){this.service.clearCredentials(this.principal)};Session.prototype.connectSocket=function(){var self=this;if(!this.principal||!this.principal.id||!this.accessToken)throw new Error("need both principal and accessToken to connectSocket");if(!this.socket){this.socket=io.connect(this.service.config.endpoints.subscriptions,{query:Session.queryStringFromObject({auth:this.accessToken.token}),"force new connection":true});this.setupSocketEvents();self.startHeartbeat()}return this.socket};Session.prototype.setupSocketEvents=function(){var self=this;this.socket.on("connect",function(){self.log.debug("session: socket.io connected")});this.socket.on("disconnect",function(){self.log.debug("session: socket.io connection disconnected")});this.socket.on("reconnect",function(){if(self.socket){self.log.warn("session: socket.io connection reconnected. restarting subscriptions: "+JSON.stringify(self.subscriptions));self.restartSubscriptions()}})};Session.prototype.disconnectSubscription=function(subscriptionId){if(!this.subscriptions[subscriptionId])return;this.socket.emit("stop",this.subscriptions[subscriptionId]);delete this.subscriptions[subscriptionId]};Session.prototype.connectSubscription=function(options){this.subscriptions[options.id]=options;this.socket.emit("start",options)};Session.prototype.restartSubscriptions=function(){for(var key in this.subscriptions){var subscription=this.subscriptions[key];this.log.info("restarting subscription: "+key+": "+JSON.stringify(subscription));if(this.socket)this.socket.emit("stop",this.subscriptions[subscription.id]);this.connectSubscription(this.subscriptions[key])}};Session.prototype.impersonate=function(principal,callback){this.service.impersonate(this,principal,callback)};Session.prototype.onAuthFailure=function(callback){this.failureCallback=callback};Session.prototype.onFailure=function(callback){this.failureCallback=callback};Session.prototype.signalFailure=function(){var failureCallback=this.failureCallback;this.stop();if(failureCallback)failureCallback()};Session.prototype.on=function(options,callback){if(!options)return callback("Options hash required for subscription");if(["message","principal"].indexOf(options.type)===-1)return callback("Unknown subscription 'type'");this.connectSocket();this.subscriptionCount+=1;options.id=this.principal.id+"_"+this.sessionId+"_"+this.subscriptionCount;this.socket.on(options.id,function(obj){if(options.type==="message")return callback(new Message(obj));if(options.type==="principal")return callback(new Principal(obj))});this.connectSubscription(options);return options.id};Session.prototype.onMessage=function(filter,callback){if(typeof filter==="function"){callback=filter}var options={};options.filter=filter||{};options.type="message";return this.on(options,callback)};Session.prototype.onPrincipal=function(filter,callback){if(typeof filter==="function"){callback=filter}var options={};options.filter=filter||{};options.type="principal";return this.on(options,callback)};Session.log=function(session,severity,message){if(session.service.config.log_levels&&session.service.config.log_levels.indexOf(severity)===-1)return;var logLifetime=session.service.config.log_lifetime||24*60*6e4;var logMessage=new Message({type:"log",ts:new Date,from:session.principal.id,body:{severity:severity,message:message},index_until:new Date((new Date).getTime()+logLifetime)});var principalNameOrId=session.principal.name||session.principal.id;var dateFormat=[logMessage.ts.getMonth()+1,logMessage.ts.getDate(),logMessage.ts.getFullYear()];var date=dateFormat.join("/");console.log(date+" "+logMessage.ts.toLocaleTimeString()+": "+principalNameOrId+": "+severity+": "+message);logMessage.send(session)};Session.prototype.heartbeatReceivedCheck=function(){if(!this.heartbeatReceived){this.consecutiveHeartbeatFailures+=1;this.log.error("heartbeat: not received within timeout: restarting subscriptions ("+this.consecutiveHeartbeatFailures+" consecutive).");if(this.session&&this.consecutiveHeartbeatFailures<Heartbeat.MAX_SUBSCRIPTION_RESTARTS){this.stopHeartbeat();this.restartSubscriptions();this.startHeartbeatInterval()}else{this.log.error("heartbeat: too many consecutive failures. signalling session failure.");this.signalFailure()}}};Session.prototype.startHeartbeat=function(){if(this.heartbeatTimeout)return;var self=this;this.onMessage({type:"heartbeat"},function(message){self.log.debug("received heartbeat");self.heartbeatReceived=true;self.consecutiveHeartbeatFailures=0});this.startHeartbeatInterval()};Session.prototype.startHeartbeatInterval=function(){var self=this;this.stopHeartbeat();this.log.debug("starting heartbeat interval");this.heartbeatTimeout=setInterval(function(){self.sendHeartbeat()},Session.HEARTBEAT_DEFAULT_INTERVAL)};Session.prototype.sendHeartbeat=function(callback){var self=this;this.principal.status(function(err,status){if(err){status=status||{};status.error=err}var heartbeatIndexUntil=self.service.config.heartbeat_lifetime||30*60*1e3;var message=new Message({type:"heartbeat","public":false,body:{error:!!err,status:status},index_until:new Date((new Date).getTime()+heartbeatIndexUntil)});setTimeout(function(){self.heartbeatReceivedCheck()},Session.HEARTBEAT_TIMEOUT);self.heartbeatReceived=false;self.log.debug("sending heartbeat");message.send(self,function(err,message){if(err){self.log.error("failed to send heartbeat: "+err);self.heartbeatReceived=true;if(self)self.signalFailure()}if(callback)return callback(err)})})};Session.prototype.stopHeartbeat=function(){if(!this.heartbeatTimeout)return;this.log.debug("clearing heartbeat interval");clearInterval(this.heartbeatTimeout);this.heartbeatTimeout=false};function Service(config){this.config=config||{};if(!this.config.store)this.config.store=new MemoryStore;this.config.host=this.config.host||"api.nitrogen.io";this.config.protocol=this.config.protocol||"https";this.config.http_port=this.config.http_port||443;this.config.max_session_lifetime=Service.MAX_SESSION_LIFETIME_DEFAULT;this.config.base_url=this.config.protocol+"://"+this.config.host+":"+this.config.http_port+"/api/v1";if(!this.config.endpoints)this.config.endpoints={};for(var key in config.endpoints){this.config.endpoints[key]=config.endpoints[key]}if(!this.config.endpoints.headwaiter){this.config.endpoints.headwaiter=this.config.base_url+"/headwaiter"}if(!this.config.endpoints.principals){this.config.endpoints.principals=this.config.base_url+"/principals"}this.store=config.store}Service.BACKOFF_RATE_MILLIS=500;Service.MAXIMUM_BACKOFF_STEPS=7;Service.MAX_SESSION_LIFETIME_DEFAULT=24*60*60*1e3;Service.prototype.authenticate=function(principal,callback){this.authenticateSession(principal,principal.authenticate,callback)};Service.prototype.create=function(principal,callback){this.authenticateSession(principal,principal.create,callback)};Service.prototype.resume=function(principal,callback){if(!this.store)return callback(new Error("No store configured with service."));this.authenticateSession(principal,principal.resume,function(err,session,principal){if(err)return callback(err);Principal.findById(session,principal.id,function(err,loadedPrincipal){if(err)return callback(err);loadedPrincipal.nickname=principal.nickname;return callback(err,session,loadedPrincipal)})})};Service.prototype.connect=function(principal,callback){var self=this;this.store.get(principal.toStoreId(),function(err,storedPrincipal){if(storedPrincipal){principal.updateAttributes(storedPrincipal);self.restartOnFailureAuthWrapper(principal,principal.authenticate,callback)}else{self.restartOnFailureAuthWrapper(principal,principal.create,callback)}})};function asyncWhilst(test,iterator,callback){if(test()){iterator(function(err){if(err){return callback(err)}asyncWhilst(test,iterator,callback)})}else{callback()}}Service.prototype.restartOnFailureAuthWrapper=function(principal,initialOp,sessionCallback){var self=this;var authOp=initialOp;asyncWhilst(function(){return true},function(restartCallback){self.authOpWithRetry(principal,authOp,function(err,session,principal){if(err)return sessionCallback(err);session.onFailure(function(){session.log.error("session failure: restarting");session.stop();authOp=principal.authenticate;return restartCallback()});return sessionCallback(err,session,principal)})},function(err){})};Service.prototype.authOpWithRetry=function(principal,authOperation,callback){var self=this;var failures=0;var successful=false;var backoffMillis=0;var err;var session;asyncWhilst(function(){return!successful},function(retryCallback){if(backoffMillis>0)console.log("service: retrying auth request after backoff of "+backoffMillis+" ms.");setTimeout(function(){self.authenticateSession(principal,authOperation,function(e,s,p){successful=!e;err=e;if(!successful){console.log("service: authentication failed: "+JSON.stringify(err));failures+=1;console.log("service: "+failures+" consecutive auth failures.");var backoffAmount=Math.min(failures,Service.MAXIMUM_BACKOFF_STEPS);backoffMillis=Math.pow(2,backoffAmount)*Service.BACKOFF_RATE_MILLIS*(1+Math.random());backoffMillis=Math.floor(backoffMillis)}else{session=s;principal=p}return retryCallback()})},backoffMillis)},function(e){return callback(err,session,principal)})};Service.prototype.authenticateSession=function(principal,authOperation,callback){var self=this;this.configure(principal,function(err,config){if(err)return callback(err);self.config=config;if(self.config.log_levels&&self.config.log_levels.indexOf("debug"))console.log("service: configured.");authOperation.bind(principal)(self.config,function(err,principal,accessToken){if(err)return callback(err);if(!principal)return callback(new Error("authentication failed: no principal returned"));if(!accessToken)return callback(new Error("authentication failed: no accessToken returned"));if(self.config.log_levels&&self.config.log_levels.indexOf("debug")!==-1)console.log("principal: authenticated.");if(principal.claim_code){console.log("This principal ("+principal.id+") can be claimed using code: "+principal.claim_code)}self.store.set(principal.toStoreId(),principal.toStoreObject(),function(err){if(err)return callback(err);var session=Session.startSession(self,principal,accessToken);if(self.config.max_session_lifetime)setInterval(function(){session.onFailure()},config.max_session_lifetime);callback(null,session,principal)})})})};Service.prototype.impersonate=function(session,principalId,callback){var self=this;Principal.impersonate(session,principalId,function(err,impersonatedPrincipal,accessToken){if(err)return callback(err);impersonatedPrincipal.accessToken=accessToken;var impersonatedSession=Session.startSession(self,impersonatedPrincipal,accessToken);self.configure(impersonatedPrincipal,function(err,config){if(err)return callback(err);impersonatedSession.service.config=config;callback(null,impersonatedSession,impersonatedPrincipal)})})};Service.prototype.configure=function(principal,callback){var self=this;var headwaiter_url=this.config.endpoints.headwaiter;if(principal){if(principal.is("user")&&principal.email){headwaiter_url+="?email="+principal.email}else if(principal.id){headwaiter_url+="?principal_id="+principal.id}}request.get({url:headwaiter_url,json:true},function(err,resp,body){if(err)return callback(err);if(resp.statusCode!=200)return callback(JSON.stringify(body.error)||resp.statusCode);for(var key in body.endpoints){self.config.endpoints[key]=body.endpoints[key]}self.config.nonce=body.nonce;callback(null,self.config)})};Service.prototype.clearCredentials=function(principal){if(!this.store)return;this.store.delete(principal.toStoreId())};function Device(){Principal.apply(this,arguments);this.type="device"}Device.prototype=Object.create(Principal.prototype);Device.prototype.constructor=Device;function User(){Principal.apply(this,arguments);this.type="user"}User.prototype=Object.create(Principal.prototype);User.prototype.constructor=User;function MemoryStore(){this.clear()}MemoryStore.prototype.clear=function(callback){this.store={};if(callback)return callback()};MemoryStore.prototype.get=function(key,callback){return callback(null,this.store[key])};MemoryStore.prototype.set=function(key,value,callback){this.store[key]=value;if(callback)return callback()};MemoryStore.prototype.delete=function(key,callback){delete this.store[key];if(callback)return callback()};window.nitrogen={ApiKey:ApiKey,Blob:Blob,CommandManager:CommandManager,Device:Device,Message:Message,Permission:Permission,Principal:Principal,Service:Service,Session:Session,User:User}})();