1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
{
"uid": "D98F90F2K8EF9A42FDS925AE12EEBFB09029",
"isLoaded": true,
"lastModificationTime": 1426885735019,
"items": {
"name": "ResourceManager",
"type": "game_script",
"order": 4,
"content": "# ===================================================================\n#\n# Script: ResourceManager\n#\n# $$COPYRIGHT$$\n#\n# ===================================================================\nclass ResourceManagerContext\n ###*\n * If associated to a gs.ResourceManager, a resource context registers all loaded resources\n * resources. If gs.ResourceManager needs to dispose resources, it will only dispose\n * resource associated if the current context.\n *\n * By default, each game scene creates it's own resource context to only dispose resources\n * created by itself.\n *\n * @module gs\n * @class ResourceManager\n * @memberof gs\n * @constructor\n ###\n constructor: -> \n ###*\n * All resources associated with this context.\n * @property resources\n * @type Object[]\n * @readOnly\n ###\n @resources = []\n \n \n ###*\n * Converts the resource context into a data-bundle for serialization. The data-bundle will only contain\n * the names of the resources associated with this context but not the resource-data itself.\n * @method toDataBundle\n * @return {string[]} An array of resource names associated with this context.\n ### \n toDataBundle: -> @resources.select (r) -> r.name\n \n ###*\n * Initializes the resource context from a data-bundle. Any already existing resource associations\n * with this context will be deleted.\n * @method fromDataBundle\n ###\n fromDataBundle: (data, resourcesByPath) -> @resources = data.select (n) -> name: n, data: resourcesByPath[n]\n \n ###*\n * Adds the specified resource to the context.\n * @method add\n * @param {string} name - A unique name for the resource like the file-path for example.\n * @param {gs.Bitmap|gs.AudioBuffer|gs.Video|gs.Live2DModel} data - The resource data like a gs.Bitmap object for example.\n ### \n add: (name, resource) -> @resources.push({ name: name, data: resource })\n \n ###*\n * Removes the resource with the specified name from the context.\n * @method remove\n * @param {string} name - The name of the resource to remove. For Example: The file name.\n ### \n remove: (name) -> @resources.remove(@resources.first((r) -> r.name == name))\n \ngs.ResourceManagerContext = ResourceManagerContext\n\nclass ResourceManager\n ###*\n * Manages the resources of the game like graphics, audio, fonts, etc. It\n * offers a lot of methods to easily access game resources and automatically\n * caches them. So if an image is requested a second time it will be taken\n * from the cache instead of loading it again.\n *\n * @module gs\n * @class ResourceManager\n * @memberof gs\n * @constructor\n ###\n constructor: ->\n ###*\n * Current resource context. All loaded resources will be associated with it. If current context\n * is set to <b>null</b>, the <b>systemContext</b> is used instead.\n * @property context\n * @type gs.ResourceManagerContext\n * @protected\n ###\n @context_ = null\n \n ###*\n * System resource context. All loaded system resources are associated with this context. Resources\n * which are associated with the system context are not disposed until the game ends.\n * @property context\n * @type gs.ResourceManagerContext\n ### \n @systemContext = @createContext()\n \n ###*\n * Holds in-memory created bitmaps.\n * @property customBitmapsByKey\n * @type Object\n * @protected\n ###\n @customBitmapsByKey = {}\n \n ###*\n * Caches resources by file path.\n * @property resourcesByPath\n * @type Object\n * @protected\n ###\n @resourcesByPath = {}\n \n ###*\n * Caches resources by file path and HUE.\n * @property resourcesByPath\n * @type Object\n * @protected\n ###\n @resourcesByPathHue = {}\n \n ###*\n * Stores all loaded resources.\n * @property resources\n * @type Object[]\n ###\n @resources = []\n \n ###*\n * Indicates if all requested resources are loaded.\n * @property resourcesLoaded\n * @type boolean\n ###\n @resourcesLoaded = true\n \n ###*\n * @property events\n * @type gs.EventEmitter\n ###\n @events = new gs.EventEmitter()\n \n ###*\n * Current resource context. All loaded resources will be associated with it. If current context\n * is set to <b>null</b>, the <b>systemContext</b> is used instead.\n * @property context\n * @type gs.ResourceManagerContext\n ###\n @accessors \"context\", \n set: (v) -> @context_ = v\n get: -> @context_ ? @systemContext\n \n ###*\n * Creates a new resource context. Use <b>context</b> to set the new created context\n * as current context.\n *\n * @method createContext\n ###\n createContext: -> new gs.ResourceManagerContext()\n \n ###*\n * Disposes all bitmap resources associated with the current context.\n *\n * @method disposeBitmaps\n ###\n disposeBitmaps: ->\n for resource in @context.resources\n if resource.data instanceof gs.Bitmap\n resource.data.dispose()\n @resources.remove(resource.data)\n if resource.name\n @resourcesByPath[resource.name] = null\n delete @resourcesByPath[resource.name]\n ###*\n * Disposes all video resources associated with the current context.\n *\n * @method disposeVideos\n ###\n disposeVideos: -> \n for resource in @context.resources\n if resource.data instanceof gs.Video\n resource.data.dispose()\n @resources.remove(resource.data)\n @resourcesByPath[resource.name] = null\n delete @resourcesByPath[resource.name]\n \n ###*\n * Disposes all audio resources associated with the current context.\n *\n * @method disposeAudio\n ### \n disposeAudio: ->\n AudioManager.dispose(@context)\n \n for resource in @context.resources\n if resource.data instanceof GS.AudioBuffer or resource instanceof GS.AudioBufferStream\n resource.data.dispose()\n @resources.remove(resource.data)\n @resourcesByPath[resource.name] = null\n delete @resourcesByPath[resource.name]\n \n ###*\n * Disposes all Live2D resources associated with the current context.\n *\n * @method disposeLive2D\n ###\n disposeLive2D: -> \n for resource in @context.resources\n if resource.data instanceof gs.Live2DModel\n resource.data.dispose()\n @resources.remove(resource.data)\n @resourcesByPath[resource.name] = null\n delete @resourcesByPath[resource.name]\n \n ###*\n * Disposes all resources.\n *\n * @method dispose\n ### \n dispose: -> \n @disposeBitmaps()\n @disposeVideos()\n @disposeAudio()\n @disposeLive2D()\n \n @context = @systemContext\n \n ###*\n * Loads all custom fonts in Graphics/Fonts folder.\n *\n * @method loadFonts\n ### \n loadFonts: ->\n resource = { loaded: no }\n @resources.push(resource)\n @resourcesByPath[\"Graphics/Fonts\"] = resource\n \n gs.Font.loadCustomFonts((error) =>\n @resourcesByPath[\"Graphics/Fonts\"].loaded = yes\n if error\n @resourcesByPath[\"Graphics/Fonts\"].error = yes\n )\n ###*\n * Gets a custom created bitmap by key.\n *\n * @method getCustomBitmap\n * @param {String} key - The key for the bitmap to get.\n * @return {gs.Bitmap} The bitmap or <b>null</b> if no bitmap exists for the specified key.\n ### \n getCustomBitmap: (key) ->\n return @customBitmapsByKey[key]\n \n ###*\n * Sets a custom created bitmap for a specified key.\n *\n * @method setCustomBitmap\n * @param {String} key - The key for the bitmap to set.\n * @param {gs.Bitmap} bitmap - The bitmap to set.\n ### \n setCustomBitmap: (key, bitmap) ->\n @customBitmapsByKey[key] = bitmap\n if not bitmap.loaded?\n @resources.push(bitmap)\n @resourcesLoaded = false\n \n ###*\n * Adds a custom created bitmap to the resource manager.\n *\n * @method addCustomBitmap\n * @param {gs.Bitmap} bitmap - The bitmap to add.\n ### \n addCustomBitmap: (bitmap) ->\n @context.resources.push(name: \"\", data: bitmap)\n\n ###*\n * Gets a Live2D model.\n *\n * @method getLive2DModel\n * @param {String} filePath - Path to the Live2D model file.\n * @return {gs.Live2DModel} The Live2D model or <b>null</b> if no model exists at the specified file path.\n ### \n getLive2DModel: (filePath) ->\n result = @resourcesByPath[filePath]\n \n if not result? or result.disposed\n profile = LanguageManager.profile\n result = new gs.Live2DModel(filePath, (if profile? and profile.items? then profile.items.code else null))\n @resourcesByPath[filePath] = result\n @resources.push(result)\n @resourcesLoaded = false\n @context.resources.push(name: filePath, data: result)\n \n return result\n \n ###*\n * Gets a font.\n *\n * @method getFont\n * @param {String} name - The name of the font to get.\n * @param {number} size - The size of the font to get.\n * @return {gs.Font} The font or <b>null</b> if no font with the specified name exists.\n ### \n getFont: (name, size) ->\n result = new Font(name, size)\n \n @resources.push(result)\n @resourcesLoaded = false\n \n return result\n \n ###*\n * Gets a video.\n *\n * @method getVideo\n * @param {String} filePath - Path to the video file.\n * @return {gs.Video} The video or <b>null</b> if no video exists at the specified file path.\n ### \n getVideo: (filePath) ->\n if filePath.endsWith(\"/\") then return null\n \n result = @resourcesByPath[filePath]\n \n if not result? or result.disposed\n profile = LanguageManager.profile\n result = new gs.Video(filePath, (if profile? and profile.items? then profile.items.code else null))\n @resourcesByPath[filePath] = result\n @resources.push(result)\n @resourcesLoaded = false\n @context.resources.push(name: filePath, data: result)\n \n return result\n \n ###*\n * Gets a bitmap.\n *\n * @method getBitmap\n * @param {String} filePath - Path to the bitmap file.\n * @param {number} hue - The bitmap's hue. The bitmap will be loaded and then recolored.\n * @return {gs.Bitmap} The bitmap or <b>null</b> if no bitmap exists at the specified file path.\n ### \n getBitmap: (filePath, hue) ->\n if filePath.endsWith(\"/\") then return null\n \n \n hue = hue || 0\n result = @resourcesByPath[filePath] || @customBitmapsByKey[filePath]\n \n if not result?\n profile = LanguageManager.profile\n result = new Bitmap(filePath, (if profile? and profile.items? then profile.items.code else null), no)\n result.hue = hue\n result.filePath = filePath\n @resourcesByPath[filePath] = result\n @resources.push(result)\n @resourcesLoaded = false\n @context.resources.push(name: filePath, data: result)\n else if not result.loaded and result.hue != hue\n profile = LanguageManager.profile\n result = new Bitmap(filePath, (if profile? and profile.items? then profile.items.code else null))\n result.hue = hue\n result.filePath = filePath\n @resources.push(result)\n @resourcesLoaded = false \n else if hue > 0\n hueBitmap = @resourcesByPathHue[filePath+\"@\"+hue]\n if not hueBitmap? and result.loaded\n hueBitmap = new Bitmap(result.image)\n hueBitmap.changeHue(hue)\n @resourcesByPathHue[filePath+\"@\"+hue] = hueBitmap\n if hueBitmap? then result = hueBitmap\n \n return result\n\n ###*\n * Gets an HTML image.\n *\n * @method getImage\n * @param {String} filePath - Path to the image file.\n * @return {HTMLImageElement} The image or <b>null</b> if no image exists at the specified file path.\n ### \n getImage: (filePath) ->\n result = @resourcesByPath[filePath]\n \n if not result?\n result = new Bitmap(\"resources/#{filePath}.png\");\n \n @resourcesByPath[filePath] = result\n @resources.push(result)\n @resourcesLoaded = false\n \n return result\n\n ###*\n * Gets an audio stream.\n *\n * @method getAudioStream\n * @param {String} filePath - Path to the audio file.\n * @return {gs.AudioBuffer} The audio buffer or <b>null</b> if no audio file exists at the specified file path.\n ### \n getAudioStream: (filePath) ->\n result = @resourcesByPath[filePath]\n profile = LanguageManager.profile\n languageCode = if profile? and profile.items? then profile.items.code else null\n \n if not result?\n result = new GS.AudioBuffer(filePath)\n \n @resourcesByPath[filePath] = result\n @resources.push(result)\n @resourcesLoaded = false\n \n @context.resources.push(name: filePath, data: result)\n \n \n \n return result\n \n ###*\n * Gets an audio buffer. The audio data is fully loaded and decoded in memory. It is recommeneded\n * for sound effects but for a long background music, <b>getAudioStream</b> should be used instead. That is especially\n * the case on mobile devices.\n *\n * @method getAudioBuffer\n * @param {String} filePath - Path to the audio file.\n * @return {gs.AudioBuffer} The audio buffer or <b>null</b> if no audio file exists at the specified file path.\n ### \n getAudioBuffer: (filePath) ->\n result = @resourcesByPath[filePath]\n profile = LanguageManager.profile\n languageCode = if profile? and profile.items? then profile.items.code else null\n \n if not result?\n result = new GS.AudioBuffer(filePath)\n \n @resourcesByPath[filePath] = result\n @resources.push(result)\n @resourcesLoaded = false\n \n @context.resources.push(name: filePath, data: result)\n \n return result\n\n ###*\n * Updates the loading process. Needs to be called once per frame to keep \n * the ResourceManager up to date.\n *\n * @method update\n ### \n update: ->\n if not @events? then @events = new gs.EventEmitter()\n if not @resourcesLoaded\n @resourcesLoaded = true\n for i in [0...@resources.length]\n if not @resources[i].loaded\n @resourcesLoaded = false\n break\n else if @resources[i].hue? and @resources[i].hue > 0\n bitmap = new Bitmap(@resources[i].image)\n \n @resourcesByPath[@resources[i].filePath] = bitmap\n @resources[i].changeHue(@resources[i].hue)\n @resourcesByPathHue[@resources[i].filePath+\"@\"+@resources[i].hue] = @resources[i]\n delete @resources[i].filePath\n delete @resources[i].hue\n if @resourcesLoaded\n @events.emit(\"loaded\", this)\n \n return null\n\nwindow.ResourceManager = ResourceManager\ngs.ResourceManager = ResourceManager",
"compiledContent": "var ResourceManager, ResourceManagerContext;\n\nResourceManagerContext = (function() {\n\n /**\n * If associated to a gs.ResourceManager, a resource context registers all loaded resources\n * resources. If gs.ResourceManager needs to dispose resources, it will only dispose\n * resource associated if the current context.\n *\n * By default, each game scene creates it's own resource context to only dispose resources\n * created by itself.\n *\n * @module gs\n * @class ResourceManager\n * @memberof gs\n * @constructor\n */\n function ResourceManagerContext() {\n\n /**\n * All resources associated with this context.\n * @property resources\n * @type Object[]\n * @readOnly\n */\n this.resources = [];\n }\n\n\n /**\n * Converts the resource context into a data-bundle for serialization. The data-bundle will only contain\n * the names of the resources associated with this context but not the resource-data itself.\n * @method toDataBundle\n * @return {string[]} An array of resource names associated with this context.\n */\n\n ResourceManagerContext.prototype.toDataBundle = function() {\n return this.resources.select(function(r) {\n return r.name;\n });\n };\n\n\n /**\n * Initializes the resource context from a data-bundle. Any already existing resource associations\n * with this context will be deleted.\n * @method fromDataBundle\n */\n\n ResourceManagerContext.prototype.fromDataBundle = function(data, resourcesByPath) {\n return this.resources = data.select(function(n) {\n return {\n name: n,\n data: resourcesByPath[n]\n };\n });\n };\n\n\n /**\n * Adds the specified resource to the context.\n * @method add\n * @param {string} name - A unique name for the resource like the file-path for example.\n * @param {gs.Bitmap|gs.AudioBuffer|gs.Video|gs.Live2DModel} data - The resource data like a gs.Bitmap object for example.\n */\n\n ResourceManagerContext.prototype.add = function(name, resource) {\n return this.resources.push({\n name: name,\n data: resource\n });\n };\n\n\n /**\n * Removes the resource with the specified name from the context.\n * @method remove\n * @param {string} name - The name of the resource to remove. For Example: The file name.\n */\n\n ResourceManagerContext.prototype.remove = function(name) {\n return this.resources.remove(this.resources.first(function(r) {\n return r.name === name;\n }));\n };\n\n return ResourceManagerContext;\n\n})();\n\ngs.ResourceManagerContext = ResourceManagerContext;\n\nResourceManager = (function() {\n\n /**\n * Manages the resources of the game like graphics, audio, fonts, etc. It\n * offers a lot of methods to easily access game resources and automatically\n * caches them. So if an image is requested a second time it will be taken\n * from the cache instead of loading it again.\n *\n * @module gs\n * @class ResourceManager\n * @memberof gs\n * @constructor\n */\n function ResourceManager() {\n\n /**\n * Current resource context. All loaded resources will be associated with it. If current context\n * is set to <b>null</b>, the <b>systemContext</b> is used instead.\n * @property context\n * @type gs.ResourceManagerContext\n * @protected\n */\n this.context_ = null;\n\n /**\n * System resource context. All loaded system resources are associated with this context. Resources\n * which are associated with the system context are not disposed until the game ends.\n * @property context\n * @type gs.ResourceManagerContext\n */\n this.systemContext = this.createContext();\n\n /**\n * Holds in-memory created bitmaps.\n * @property customBitmapsByKey\n * @type Object\n * @protected\n */\n this.customBitmapsByKey = {};\n\n /**\n * Caches resources by file path.\n * @property resourcesByPath\n * @type Object\n * @protected\n */\n this.resourcesByPath = {};\n\n /**\n * Caches resources by file path and HUE.\n * @property resourcesByPath\n * @type Object\n * @protected\n */\n this.resourcesByPathHue = {};\n\n /**\n * Stores all loaded resources.\n * @property resources\n * @type Object[]\n */\n this.resources = [];\n\n /**\n * Indicates if all requested resources are loaded.\n * @property resourcesLoaded\n * @type boolean\n */\n this.resourcesLoaded = true;\n\n /**\n * @property events\n * @type gs.EventEmitter\n */\n this.events = new gs.EventEmitter();\n }\n\n\n /**\n * Current resource context. All loaded resources will be associated with it. If current context\n * is set to <b>null</b>, the <b>systemContext</b> is used instead.\n * @property context\n * @type gs.ResourceManagerContext\n */\n\n ResourceManager.accessors(\"context\", {\n set: function(v) {\n return this.context_ = v;\n },\n get: function() {\n var ref;\n return (ref = this.context_) != null ? ref : this.systemContext;\n }\n });\n\n\n /**\n * Creates a new resource context. Use <b>context</b> to set the new created context\n * as current context.\n *\n * @method createContext\n */\n\n ResourceManager.prototype.createContext = function() {\n return new gs.ResourceManagerContext();\n };\n\n\n /**\n * Disposes all bitmap resources associated with the current context.\n *\n * @method disposeBitmaps\n */\n\n ResourceManager.prototype.disposeBitmaps = function() {\n var j, len, ref, resource, results;\n ref = this.context.resources;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n resource = ref[j];\n if (resource.data instanceof gs.Bitmap) {\n resource.data.dispose();\n this.resources.remove(resource.data);\n if (resource.name) {\n this.resourcesByPath[resource.name] = null;\n results.push(delete this.resourcesByPath[resource.name]);\n } else {\n results.push(void 0);\n }\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Disposes all video resources associated with the current context.\n *\n * @method disposeVideos\n */\n\n ResourceManager.prototype.disposeVideos = function() {\n var j, len, ref, resource, results;\n ref = this.context.resources;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n resource = ref[j];\n if (resource.data instanceof gs.Video) {\n resource.data.dispose();\n this.resources.remove(resource.data);\n this.resourcesByPath[resource.name] = null;\n results.push(delete this.resourcesByPath[resource.name]);\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Disposes all audio resources associated with the current context.\n *\n * @method disposeAudio\n */\n\n ResourceManager.prototype.disposeAudio = function() {\n var j, len, ref, resource, results;\n AudioManager.dispose(this.context);\n ref = this.context.resources;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n resource = ref[j];\n if (resource.data instanceof GS.AudioBuffer || resource instanceof GS.AudioBufferStream) {\n resource.data.dispose();\n this.resources.remove(resource.data);\n this.resourcesByPath[resource.name] = null;\n results.push(delete this.resourcesByPath[resource.name]);\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Disposes all Live2D resources associated with the current context.\n *\n * @method disposeLive2D\n */\n\n ResourceManager.prototype.disposeLive2D = function() {\n var j, len, ref, resource, results;\n ref = this.context.resources;\n results = [];\n for (j = 0, len = ref.length; j < len; j++) {\n resource = ref[j];\n if (resource.data instanceof gs.Live2DModel) {\n resource.data.dispose();\n this.resources.remove(resource.data);\n this.resourcesByPath[resource.name] = null;\n results.push(delete this.resourcesByPath[resource.name]);\n } else {\n results.push(void 0);\n }\n }\n return results;\n };\n\n\n /**\n * Disposes all resources.\n *\n * @method dispose\n */\n\n ResourceManager.prototype.dispose = function() {\n this.disposeBitmaps();\n this.disposeVideos();\n this.disposeAudio();\n this.disposeLive2D();\n return this.context = this.systemContext;\n };\n\n\n /**\n * Loads all custom fonts in Graphics/Fonts folder.\n *\n * @method loadFonts\n */\n\n ResourceManager.prototype.loadFonts = function() {\n var resource;\n resource = {\n loaded: false\n };\n this.resources.push(resource);\n this.resourcesByPath[\"Graphics/Fonts\"] = resource;\n return gs.Font.loadCustomFonts((function(_this) {\n return function(error) {\n _this.resourcesByPath[\"Graphics/Fonts\"].loaded = true;\n if (error) {\n return _this.resourcesByPath[\"Graphics/Fonts\"].error = true;\n }\n };\n })(this));\n };\n\n\n /**\n * Gets a custom created bitmap by key.\n *\n * @method getCustomBitmap\n * @param {String} key - The key for the bitmap to get.\n * @return {gs.Bitmap} The bitmap or <b>null</b> if no bitmap exists for the specified key.\n */\n\n ResourceManager.prototype.getCustomBitmap = function(key) {\n return this.customBitmapsByKey[key];\n };\n\n\n /**\n * Sets a custom created bitmap for a specified key.\n *\n * @method setCustomBitmap\n * @param {String} key - The key for the bitmap to set.\n * @param {gs.Bitmap} bitmap - The bitmap to set.\n */\n\n ResourceManager.prototype.setCustomBitmap = function(key, bitmap) {\n this.customBitmapsByKey[key] = bitmap;\n if (bitmap.loaded == null) {\n this.resources.push(bitmap);\n return this.resourcesLoaded = false;\n }\n };\n\n\n /**\n * Adds a custom created bitmap to the resource manager.\n *\n * @method addCustomBitmap\n * @param {gs.Bitmap} bitmap - The bitmap to add.\n */\n\n ResourceManager.prototype.addCustomBitmap = function(bitmap) {\n return this.context.resources.push({\n name: \"\",\n data: bitmap\n });\n };\n\n\n /**\n * Gets a Live2D model.\n *\n * @method getLive2DModel\n * @param {String} filePath - Path to the Live2D model file.\n * @return {gs.Live2DModel} The Live2D model or <b>null</b> if no model exists at the specified file path.\n */\n\n ResourceManager.prototype.getLive2DModel = function(filePath) {\n var profile, result;\n result = this.resourcesByPath[filePath];\n if ((result == null) || result.disposed) {\n profile = LanguageManager.profile;\n result = new gs.Live2DModel(filePath, ((profile != null) && (profile.items != null) ? profile.items.code : null));\n this.resourcesByPath[filePath] = result;\n this.resources.push(result);\n this.resourcesLoaded = false;\n this.context.resources.push({\n name: filePath,\n data: result\n });\n }\n return result;\n };\n\n\n /**\n * Gets a font.\n *\n * @method getFont\n * @param {String} name - The name of the font to get.\n * @param {number} size - The size of the font to get.\n * @return {gs.Font} The font or <b>null</b> if no font with the specified name exists.\n */\n\n ResourceManager.prototype.getFont = function(name, size) {\n var result;\n result = new Font(name, size);\n this.resources.push(result);\n this.resourcesLoaded = false;\n return result;\n };\n\n\n /**\n * Gets a video.\n *\n * @method getVideo\n * @param {String} filePath - Path to the video file.\n * @return {gs.Video} The video or <b>null</b> if no video exists at the specified file path.\n */\n\n ResourceManager.prototype.getVideo = function(filePath) {\n var profile, result;\n if (filePath.endsWith(\"/\")) {\n return null;\n }\n result = this.resourcesByPath[filePath];\n if ((result == null) || result.disposed) {\n profile = LanguageManager.profile;\n result = new gs.Video(filePath, ((profile != null) && (profile.items != null) ? profile.items.code : null));\n this.resourcesByPath[filePath] = result;\n this.resources.push(result);\n this.resourcesLoaded = false;\n this.context.resources.push({\n name: filePath,\n data: result\n });\n }\n return result;\n };\n\n\n /**\n * Gets a bitmap.\n *\n * @method getBitmap\n * @param {String} filePath - Path to the bitmap file.\n * @param {number} hue - The bitmap's hue. The bitmap will be loaded and then recolored.\n * @return {gs.Bitmap} The bitmap or <b>null</b> if no bitmap exists at the specified file path.\n */\n\n ResourceManager.prototype.getBitmap = function(filePath, hue) {\n var hueBitmap, profile, result;\n if (filePath.endsWith(\"/\")) {\n return null;\n }\n hue = hue || 0;\n result = this.resourcesByPath[filePath] || this.customBitmapsByKey[filePath];\n if (result == null) {\n profile = LanguageManager.profile;\n result = new Bitmap(filePath, ((profile != null) && (profile.items != null) ? profile.items.code : null), false);\n result.hue = hue;\n result.filePath = filePath;\n this.resourcesByPath[filePath] = result;\n this.resources.push(result);\n this.resourcesLoaded = false;\n this.context.resources.push({\n name: filePath,\n data: result\n });\n } else if (!result.loaded && result.hue !== hue) {\n profile = LanguageManager.profile;\n result = new Bitmap(filePath, ((profile != null) && (profile.items != null) ? profile.items.code : null));\n result.hue = hue;\n result.filePath = filePath;\n this.resources.push(result);\n this.resourcesLoaded = false;\n } else if (hue > 0) {\n hueBitmap = this.resourcesByPathHue[filePath + \"@\" + hue];\n if ((hueBitmap == null) && result.loaded) {\n hueBitmap = new Bitmap(result.image);\n hueBitmap.changeHue(hue);\n this.resourcesByPathHue[filePath + \"@\" + hue] = hueBitmap;\n }\n if (hueBitmap != null) {\n result = hueBitmap;\n }\n }\n return result;\n };\n\n\n /**\n * Gets an HTML image.\n *\n * @method getImage\n * @param {String} filePath - Path to the image file.\n * @return {HTMLImageElement} The image or <b>null</b> if no image exists at the specified file path.\n */\n\n ResourceManager.prototype.getImage = function(filePath) {\n var result;\n result = this.resourcesByPath[filePath];\n if (result == null) {\n result = new Bitmap(\"resources/\" + filePath + \".png\");\n this.resourcesByPath[filePath] = result;\n this.resources.push(result);\n this.resourcesLoaded = false;\n }\n return result;\n };\n\n\n /**\n * Gets an audio stream.\n *\n * @method getAudioStream\n * @param {String} filePath - Path to the audio file.\n * @return {gs.AudioBuffer} The audio buffer or <b>null</b> if no audio file exists at the specified file path.\n */\n\n ResourceManager.prototype.getAudioStream = function(filePath) {\n var languageCode, profile, result;\n result = this.resourcesByPath[filePath];\n profile = LanguageManager.profile;\n languageCode = (profile != null) && (profile.items != null) ? profile.items.code : null;\n if (result == null) {\n result = new GS.AudioBuffer(filePath);\n this.resourcesByPath[filePath] = result;\n this.resources.push(result);\n this.resourcesLoaded = false;\n this.context.resources.push({\n name: filePath,\n data: result\n });\n }\n return result;\n };\n\n\n /**\n * Gets an audio buffer. The audio data is fully loaded and decoded in memory. It is recommeneded\n * for sound effects but for a long background music, <b>getAudioStream</b> should be used instead. That is especially\n * the case on mobile devices.\n *\n * @method getAudioBuffer\n * @param {String} filePath - Path to the audio file.\n * @return {gs.AudioBuffer} The audio buffer or <b>null</b> if no audio file exists at the specified file path.\n */\n\n ResourceManager.prototype.getAudioBuffer = function(filePath) {\n var languageCode, profile, result;\n result = this.resourcesByPath[filePath];\n profile = LanguageManager.profile;\n languageCode = (profile != null) && (profile.items != null) ? profile.items.code : null;\n if (result == null) {\n result = new GS.AudioBuffer(filePath);\n this.resourcesByPath[filePath] = result;\n this.resources.push(result);\n this.resourcesLoaded = false;\n this.context.resources.push({\n name: filePath,\n data: result\n });\n }\n return result;\n };\n\n\n /**\n * Updates the loading process. Needs to be called once per frame to keep \n * the ResourceManager up to date.\n *\n * @method update\n */\n\n ResourceManager.prototype.update = function() {\n var bitmap, i, j, ref;\n if (this.events == null) {\n this.events = new gs.EventEmitter();\n }\n if (!this.resourcesLoaded) {\n this.resourcesLoaded = true;\n for (i = j = 0, ref = this.resources.length; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {\n if (!this.resources[i].loaded) {\n this.resourcesLoaded = false;\n break;\n } else if ((this.resources[i].hue != null) && this.resources[i].hue > 0) {\n bitmap = new Bitmap(this.resources[i].image);\n this.resourcesByPath[this.resources[i].filePath] = bitmap;\n this.resources[i].changeHue(this.resources[i].hue);\n this.resourcesByPathHue[this.resources[i].filePath + \"@\" + this.resources[i].hue] = this.resources[i];\n delete this.resources[i].filePath;\n delete this.resources[i].hue;\n }\n }\n if (this.resourcesLoaded) {\n this.events.emit(\"loaded\", this);\n }\n }\n return null;\n };\n\n return ResourceManager;\n\n})();\n\nwindow.ResourceManager = ResourceManager;\n\ngs.ResourceManager = ResourceManager;\n\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUE7O0FBQU07O0FBQ0Y7Ozs7Ozs7Ozs7Ozs7RUFhYSxnQ0FBQTs7QUFDVDs7Ozs7O0lBTUEsSUFBQyxDQUFBLFNBQUQsR0FBYTtFQVBKOzs7QUFVYjs7Ozs7OzttQ0FNQSxZQUFBLEdBQWMsU0FBQTtXQUFHLElBQUMsQ0FBQSxTQUFTLENBQUMsTUFBWCxDQUFrQixTQUFDLENBQUQ7YUFBTyxDQUFDLENBQUM7SUFBVCxDQUFsQjtFQUFIOzs7QUFFZDs7Ozs7O21DQUtBLGNBQUEsR0FBZ0IsU0FBQyxJQUFELEVBQU8sZUFBUDtXQUEyQixJQUFDLENBQUEsU0FBRCxHQUFhLElBQUksQ0FBQyxNQUFMLENBQVksU0FBQyxDQUFEO2FBQU87UUFBQSxJQUFBLEVBQU0sQ0FBTjtRQUFTLElBQUEsRUFBTSxlQUFnQixDQUFBLENBQUEsQ0FBL0I7O0lBQVAsQ0FBWjtFQUF4Qzs7O0FBRWhCOzs7Ozs7O21DQU1BLEdBQUEsR0FBSyxTQUFDLElBQUQsRUFBTyxRQUFQO1dBQW9CLElBQUMsQ0FBQSxTQUFTLENBQUMsSUFBWCxDQUFnQjtNQUFFLElBQUEsRUFBTSxJQUFSO01BQWMsSUFBQSxFQUFNLFFBQXBCO0tBQWhCO0VBQXBCOzs7QUFFTDs7Ozs7O21DQUtBLE1BQUEsR0FBUSxTQUFDLElBQUQ7V0FBVSxJQUFDLENBQUEsU0FBUyxDQUFDLE1BQVgsQ0FBa0IsSUFBQyxDQUFBLFNBQVMsQ0FBQyxLQUFYLENBQWlCLFNBQUMsQ0FBRDthQUFPLENBQUMsQ0FBQyxJQUFGLEtBQVU7SUFBakIsQ0FBakIsQ0FBbEI7RUFBVjs7Ozs7O0FBRVosRUFBRSxDQUFDLHNCQUFILEdBQTRCOztBQUV0Qjs7QUFDRjs7Ozs7Ozs7Ozs7RUFXYSx5QkFBQTs7QUFDVDs7Ozs7OztJQU9BLElBQUMsQ0FBQSxRQUFELEdBQVk7O0FBRVo7Ozs7OztJQU1BLElBQUMsQ0FBQSxhQUFELEdBQWlC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b0IsQ0FBOUM7VUFDRCxNQUFBLEdBQWEsSUFBQSxNQUFBLENBQU8sSUFBQyxDQUFBLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxLQUFyQjtVQUViLElBQUMsQ0FBQSxlQUFnQixDQUFBLElBQUMsQ0FBQSxTQUFVLENBQUEsQ0FBQSxDQUFFLENBQUMsUUFBZCxDQUFqQixHQUEyQztVQUMzQyxJQUFDLENBQUEsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLFNBQWQsQ0FBd0IsSUFBQyxDQUFBLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxHQUF0QztVQUNBLElBQUMsQ0FBQSxrQkFBbUIsQ0FBQSxJQUFDLENBQUEsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDLFFBQWQsR0FBdUIsR0FBdkIsR0FBMkIsSUFBQyxDQUFBLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxHQUF6QyxDQUFwQixHQUFvRSxJQUFDLENBQUEsU0FBVSxDQUFBLENBQUE7VUFDL0UsT0FBTyxJQUFDLENBQUEsU0FBVSxDQUFBLENBQUEsQ0FBRSxDQUFDO1VBQ3JCLE9BQU8sSUFBQyxDQUFBLFNBQVUsQ0FBQSxDQUFBLENBQUUsQ0FBQyxJQVBwQjs7QUFKVDtNQVlBLElBQUcsSUFBQyxDQUFBLGVBQUo7UUFDSSxJQUFDLENBQUEsTUFBTSxDQUFDLElBQVIsQ0FBYSxRQUFiLEVBQXVCLElBQXZCLEVBREo7T0FkSjs7QUFpQkEsV0FBTztFQW5CSDs7Ozs7O0FBcUJaLE1BQU0sQ0FBQyxlQUFQLEdBQXlCOztBQUN6QixFQUFFLENBQUMsZUFBSCxHQUFxQiIsInNvdXJjZXNDb250ZW50IjpbIiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuI1xuIyAgIFNjcmlwdDogUmVzb3VyY2VNYW5hZ2VyXG4jXG4jICAgJCRDT1BZUklHSFQkJFxuI1xuIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5jbGFzcyBSZXNvdXJjZU1hbmFnZXJDb250ZXh0XG4gICAgIyMjKlxuICAgICogSWYgYXNzb2NpYXRlZCB0byBhIGdzLlJlc291cmNlTWFuYWdlciwgYSByZXNvdXJjZSBjb250ZXh0IHJlZ2lzdGVycyBhbGwgbG9hZGVkIHJlc291cmNlc1xuICAgICogcmVzb3VyY2VzLiBJZiBncy5SZXNvdXJjZU1hbmFnZXIgbmVlZHMgdG8gZGlzcG9zZSByZXNvdXJjZXMsIGl0IHdpbGwgb25seSBkaXNwb3NlXG4gICAgKiByZXNvdXJjZSBhc3NvY2lhdGVkIGlmIHRoZSBjdXJyZW50IGNvbnRleHQuXG4gICAgKlxuICAgICogQnkgZGVmYXVsdCwgZWFjaCBnYW1lIHNjZW5lIGNyZWF0ZXMgaXQncyBvd24gcmVzb3VyY2UgY29udGV4dCB0byBvbmx5IGRpc3Bvc2UgcmVzb3VyY2VzXG4gICAgKiBjcmVhdGVkIGJ5IGl0c2VsZi5cbiAgICAqXG4gICAgKiBAbW9kdWxlIGdzXG4gICAgKiBAY2xhc3MgUmVzb3VyY2VNYW5hZ2VyXG4gICAgKiBAbWVtYmVyb2YgZ3NcbiAgICAqIEBjb25zdHJ1Y3RvclxuICAgICMjI1xuICAgIGNvbnN0cnVjdG9yOiAtPiBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEFsbCByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dC5cbiAgICAgICAgKiBAcHJvcGVydHkgcmVzb3VyY2VzXG4gICAgICAgICogQHR5cGUgT2JqZWN0W11cbiAgICAgICAgKiBAcmVhZE9ubHlcbiAgICAgICAgIyMjXG4gICAgICAgIEByZXNvdXJjZXMgPSBbXVxuICAgIFxuICAgIFxuICAgICMjIypcbiAgICAqIENvbnZlcnRzIHRoZSByZXNvdXJjZSBjb250ZXh0IGludG8gYSBkYXRhLWJ1bmRsZSBmb3Igc2VyaWFsaXphdGlvbi4gVGhlIGRhdGEtYnVuZGxlIHdpbGwgb25seSBjb250YWluXG4gICAgKiB0aGUgbmFtZXMgb2YgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb250ZXh0IGJ1dCBub3QgdGhlIHJlc291cmNlLWRhdGEgaXRzZWxmLlxuICAgICogQG1ldGhvZCB0b0RhdGFCdW5kbGVcbiAgICAqIEByZXR1cm4ge3N0cmluZ1tdfSBBbiBhcnJheSBvZiByZXNvdXJjZSBuYW1lcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBjb250ZXh0LlxuICAgICMjIyAgXG4gICAgdG9EYXRhQnVuZGxlOiAtPiBAcmVzb3VyY2VzLnNlbGVjdCAocikgLT4gci5uYW1lXG4gICAgXG4gICAgIyMjKlxuICAgICogSW5pdGlhbGl6ZXMgdGhlIHJlc291cmNlIGNvbnRleHQgZnJvbSBhIGRhdGEtYnVuZGxlLiBBbnkgYWxyZWFkeSBleGlzdGluZyByZXNvdXJjZSBhc3NvY2lhdGlvbnNcbiAgICAqIHdpdGggdGhpcyBjb250ZXh0IHdpbGwgYmUgZGVsZXRlZC5cbiAgICAqIEBtZXRob2QgZnJvbURhdGFCdW5kbGVcbiAgICAjIyNcbiAgICBmcm9tRGF0YUJ1bmRsZTogKGRhdGEsIHJlc291cmNlc0J5UGF0aCkgLT4gQHJlc291cmNlcyA9IGRhdGEuc2VsZWN0IChuKSAtPiBuYW1lOiBuLCBkYXRhOiByZXNvdXJjZXNCeVBhdGhbbl1cbiAgICBcbiAgICAjIyMqXG4gICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgcmVzb3VyY2UgdG8gdGhlIGNvbnRleHQuXG4gICAgKiBAbWV0aG9kIGFkZFxuICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBBIHVuaXF1ZSBuYW1lIGZvciB0aGUgcmVzb3VyY2UgbGlrZSB0aGUgZmlsZS1wYXRoIGZvciBleGFtcGxlLlxuICAgICogQHBhcmFtIHtncy5CaXRtYXB8Z3MuQXVkaW9CdWZmZXJ8Z3MuVmlkZW98Z3MuTGl2ZTJETW9kZWx9IGRhdGEgLSBUaGUgcmVzb3VyY2UgZGF0YSBsaWtlIGEgZ3MuQml0bWFwIG9iamVjdCBmb3IgZXhhbXBsZS5cbiAgICAjIyMgICBcbiAgICBhZGQ6IChuYW1lLCByZXNvdXJjZSkgLT4gQHJlc291cmNlcy5wdXNoKHsgbmFtZTogbmFtZSwgZGF0YTogcmVzb3VyY2UgfSlcbiAgICBcbiAgICAjIyMqXG4gICAgKiBSZW1vdmVzIHRoZSByZXNvdXJjZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBmcm9tIHRoZSBjb250ZXh0LlxuICAgICogQG1ldGhvZCByZW1vdmVcbiAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHJlc291cmNlIHRvIHJlbW92ZS4gRm9yIEV4YW1wbGU6IFRoZSBmaWxlIG5hbWUuXG4gICAgIyMjICBcbiAgICByZW1vdmU6IChuYW1lKSAtPiBAcmVzb3VyY2VzLnJlbW92ZShAcmVzb3VyY2VzLmZpcnN0KChyKSAtPiByLm5hbWUgPT0gbmFtZSkpXG4gICAgXG5ncy5SZXNvdXJjZU1hbmFnZXJDb250ZXh0ID0gUmVzb3VyY2VNYW5hZ2VyQ29udGV4dFxuXG5jbGFzcyBSZXNvdXJjZU1hbmFnZXJcbiAgICAjIyMqXG4gICAgKiBNYW5hZ2VzIHRoZSByZXNvdXJjZXMgb2YgdGhlIGdhbWUgbGlrZSBncmFwaGljcywgYXVkaW8sIGZvbnRzLCBldGMuIEl0XG4gICAgKiBvZmZlcnMgYSBsb3Qgb2YgbWV0aG9kcyB0byBlYXNpbHkgYWNjZXNzIGdhbWUgcmVzb3VyY2VzIGFuZCBhdXRvbWF0aWNhbGx5XG4gICAgKiBjYWNoZXMgdGhlbS4gU28gaWYgYW4gaW1hZ2UgaXMgcmVxdWVzdGVkIGEgc2Vjb25kIHRpbWUgaXQgd2lsbCBiZSB0YWtlblxuICAgICogZnJvbSB0aGUgY2FjaGUgaW5zdGVhZCBvZiBsb2FkaW5nIGl0IGFnYWluLlxuICAgICpcbiAgICAqIEBtb2R1bGUgZ3NcbiAgICAqIEBjbGFzcyBSZXNvdXJjZU1hbmFnZXJcbiAgICAqIEBtZW1iZXJvZiBnc1xuICAgICogQGNvbnN0cnVjdG9yXG4gICAgIyMjXG4gICAgY29uc3RydWN0b3I6IC0+XG4gICAgICAgICMjIypcbiAgICAgICAgKiBDdXJyZW50IHJlc291cmNlIGNvbnRleHQuIEFsbCBsb2FkZWQgcmVzb3VyY2VzIHdpbGwgYmUgYXNzb2NpYXRlZCB3aXRoIGl0LiBJZiBjdXJyZW50IGNvbnRleHRcbiAgICAgICAgKiBpcyBzZXQgdG8gPGI+bnVsbDwvYj4sIHRoZSA8Yj5zeXN0ZW1Db250ZXh0PC9iPiBpcyB1c2VkIGluc3RlYWQuXG4gICAgICAgICogQHByb3BlcnR5IGNvbnRleHRcbiAgICAgICAgKiBAdHlwZSBncy5SZXNvdXJjZU1hbmFnZXJDb250ZXh0XG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyNcbiAgICAgICAgQGNvbnRleHRfID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN5c3RlbSByZXNvdXJjZSBjb250ZXh0LiBBbGwgbG9hZGVkIHN5c3RlbSByZXNvdXJjZXMgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNvbnRleHQuIFJlc291cmNlc1xuICAgICAgICAqIHdoaWNoIGFyZSBhc3NvY2lhdGVkIHdpdGggdGhlIHN5c3RlbSBjb250ZXh0IGFyZSBub3QgZGlzcG9zZWQgdW50aWwgdGhlIGdhbWUgZW5kcy5cbiAgICAgICAgKiBAcHJvcGVydHkgY29udGV4dFxuICAgICAgICAqIEB0eXBlIGdzLlJlc291cmNlTWFuYWdlckNvbnRleHRcbiAgICAgICAgIyMjICAgIFxuICAgICAgICBAc3lzdGVtQ29udGV4dCA9IEBjcmVhdGVDb250ZXh0KClcbiAgICAgICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogSG9sZHMgaW4tbWVtb3J5IGNyZWF0ZWQgYml0bWFwcy5cbiAgICAgICAgKiBAcHJvcGVydHkgY3VzdG9tQml0bWFwc0J5S2V5XG4gICAgICAgICogQHR5cGUgT2JqZWN0XG4gICAgICAgICogQHByb3RlY3RlZFxuICAgICAgICAjIyNcbiAgICAgICAgQGN1c3RvbUJpdG1hcHNCeUtleSA9IHt9XG4gICAgICAgIFxuICAgICAgICAjIyMqXG4gICAgICAgICogQ2FjaGVzIHJlc291cmNlcyBieSBmaWxlIHBhdGguXG4gICAgICAgICogQHByb3BlcnR5IHJlc291cmNlc0J5UGF0aFxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjXG4gICAgICAgIEByZXNvdXJjZXNCeVBhdGggPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIENhY2hlcyByZXNvdXJjZXMgYnkgZmlsZSBwYXRoIGFuZCBIVUUuXG4gICAgICAgICogQHByb3BlcnR5IHJlc291cmNlc0J5UGF0aFxuICAgICAgICAqIEB0eXBlIE9iamVjdFxuICAgICAgICAqIEBwcm90ZWN0ZWRcbiAgICAgICAgIyMjXG4gICAgICAgIEByZXNvdXJjZXNCeVBhdGhIdWUgPSB7fVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIFN0b3JlcyBhbGwgbG9hZGVkIHJlc291cmNlcy5cbiAgICAgICAgKiBAcHJvcGVydHkgcmVzb3VyY2VzXG4gICAgICAgICogQHR5cGUgT2JqZWN0W11cbiAgICAgICAgIyMjXG4gICAgICAgIEByZXNvdXJjZXMgPSBbXVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEluZGljYXRlcyBpZiBhbGwgcmVxdWVzdGVkIHJlc291cmNlcyBhcmUgbG9hZGVkLlxuICAgICAgICAqIEBwcm9wZXJ0eSByZXNvdXJjZXNMb2FkZWRcbiAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICMjI1xuICAgICAgICBAcmVzb3VyY2VzTG9hZGVkID0gdHJ1ZVxuICAgICAgICBcbiAgICAgICAgIyMjKlxuICAgICAgICAqIEBwcm9wZXJ0eSBldmVudHNcbiAgICAgICAgKiBAdHlwZSBncy5FdmVudEVtaXR0ZXJcbiAgICAgICAgIyMjXG4gICAgICAgIEBldmVudHMgPSBuZXcgZ3MuRXZlbnRFbWl0dGVyKClcbiAgICBcbiAgICAjIyMqXG4gICAgKiBDdXJyZW50IHJlc291cmNlIGNvbnRleHQuIEFsbCBsb2FkZWQgcmVzb3VyY2VzIHdpbGwgYmUgYXNzb2NpYXRlZCB3aXRoIGl0LiBJZiBjdXJyZW50IGNvbnRleHRcbiAgICAqIGlzIHNldCB0byA8Yj5udWxsPC9iPiwgdGhlIDxiPnN5c3RlbUNvbnRleHQ8L2I+IGlzIHVzZWQgaW5zdGVhZC5cbiAgICAqIEBwcm9wZXJ0eSBjb250ZXh0XG4gICAgKiBAdHlwZSBncy5SZXNvdXJjZU1hbmFnZXJDb250ZXh0XG4gICAgIyMjXG4gICAgQGFjY2Vzc29ycyBcImNvbnRleHRcIiwgXG4gICAgICAgIHNldDogKHYpIC0+IEBjb250ZXh0XyA9IHZcbiAgICAgICAgZ2V0OiAtPiBAY29udGV4dF8gPyBAc3lzdGVtQ29udGV4dFxuICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBDcmVhdGVzIGEgbmV3IHJlc291cmNlIGNvbnRleHQuIFVzZSA8Yj5jb250ZXh0PC9iPiB0byBzZXQgdGhlIG5ldyBjcmVhdGVkIGNvbnRleHRcbiAgICAqIGFzIGN1cnJlbnQgY29udGV4dC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGNyZWF0ZUNvbnRleHRcbiAgICAjIyNcbiAgICBjcmVhdGVDb250ZXh0OiAtPiBuZXcgZ3MuUmVzb3VyY2VNYW5hZ2VyQ29udGV4dCgpXG4gICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgYWxsIGJpdG1hcCByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQuXG4gICAgKlxuICAgICogQG1ldGhvZCBkaXNwb3NlQml0bWFwc1xuICAgICMjI1xuICAgIGRpc3Bvc2VCaXRtYXBzOiAtPlxuICAgICAgICBmb3IgcmVzb3VyY2UgaW4gQGNvbnRleHQucmVzb3VyY2VzXG4gICAgICAgICAgICBpZiByZXNvdXJjZS5kYXRhIGluc3RhbmNlb2YgZ3MuQml0bWFwXG4gICAgICAgICAgICAgICAgcmVzb3VyY2UuZGF0YS5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICBAcmVzb3VyY2VzLnJlbW92ZShyZXNvdXJjZS5kYXRhKVxuICAgICAgICAgICAgICAgIGlmIHJlc291cmNlLm5hbWVcbiAgICAgICAgICAgICAgICAgICAgQHJlc291cmNlc0J5UGF0aFtyZXNvdXJjZS5uYW1lXSA9IG51bGxcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIEByZXNvdXJjZXNCeVBhdGhbcmVzb3VyY2UubmFtZV1cbiAgICAjIyMqXG4gICAgKiBEaXNwb3NlcyBhbGwgdmlkZW8gcmVzb3VyY2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3VycmVudCBjb250ZXh0LlxuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZVZpZGVvc1xuICAgICMjI1xuICAgIGRpc3Bvc2VWaWRlb3M6IC0+ICAgICAgICAgICAgXG4gICAgICAgIGZvciByZXNvdXJjZSBpbiBAY29udGV4dC5yZXNvdXJjZXNcbiAgICAgICAgICAgIGlmIHJlc291cmNlLmRhdGEgaW5zdGFuY2VvZiBncy5WaWRlb1xuICAgICAgICAgICAgICAgIHJlc291cmNlLmRhdGEuZGlzcG9zZSgpXG4gICAgICAgICAgICAgICAgQHJlc291cmNlcy5yZW1vdmUocmVzb3VyY2UuZGF0YSlcbiAgICAgICAgICAgICAgICBAcmVzb3VyY2VzQnlQYXRoW3Jlc291cmNlLm5hbWVdID0gbnVsbFxuICAgICAgICAgICAgICAgIGRlbGV0ZSBAcmVzb3VyY2VzQnlQYXRoW3Jlc291cmNlLm5hbWVdXG4gICAgIFxuICAgICMjIypcbiAgICAqIERpc3Bvc2VzIGFsbCBhdWRpbyByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQuXG4gICAgKlxuICAgICogQG1ldGhvZCBkaXNwb3NlQXVkaW9cbiAgICAjIyMgICAgICAgICAgIFxuICAgIGRpc3Bvc2VBdWRpbzogLT5cbiAgICAgICAgQXVkaW9NYW5hZ2VyLmRpc3Bvc2UoQGNvbnRleHQpXG4gICAgICAgIFxuICAgICAgICBmb3IgcmVzb3VyY2UgaW4gQGNvbnRleHQucmVzb3VyY2VzXG4gICAgICAgICAgICBpZiByZXNvdXJjZS5kYXRhIGluc3RhbmNlb2YgR1MuQXVkaW9CdWZmZXIgb3IgcmVzb3VyY2UgaW5zdGFuY2VvZiBHUy5BdWRpb0J1ZmZlclN0cmVhbVxuICAgICAgICAgICAgICAgIHJlc291cmNlLmRhdGEuZGlzcG9zZSgpXG4gICAgICAgICAgICAgICAgQHJlc291cmNlcy5yZW1vdmUocmVzb3VyY2UuZGF0YSlcbiAgICAgICAgICAgICAgICBAcmVzb3VyY2VzQnlQYXRoW3Jlc291cmNlLm5hbWVdID0gbnVsbFxuICAgICAgICAgICAgICAgIGRlbGV0ZSBAcmVzb3VyY2VzQnlQYXRoW3Jlc291cmNlLm5hbWVdXG4gICAgICAgICAgICAgICAgXG4gICAgIyMjKlxuICAgICogRGlzcG9zZXMgYWxsIExpdmUyRCByZXNvdXJjZXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQuXG4gICAgKlxuICAgICogQG1ldGhvZCBkaXNwb3NlTGl2ZTJEXG4gICAgIyMjXG4gICAgZGlzcG9zZUxpdmUyRDogLT4gICAgICAgICAgICBcbiAgICAgICAgZm9yIHJlc291cmNlIGluIEBjb250ZXh0LnJlc291cmNlc1xuICAgICAgICAgICAgaWYgcmVzb3VyY2UuZGF0YSBpbnN0YW5jZW9mIGdzLkxpdmUyRE1vZGVsXG4gICAgICAgICAgICAgICAgcmVzb3VyY2UuZGF0YS5kaXNwb3NlKClcbiAgICAgICAgICAgICAgICBAcmVzb3VyY2VzLnJlbW92ZShyZXNvdXJjZS5kYXRhKVxuICAgICAgICAgICAgICAgIEByZXNvdXJjZXNCeVBhdGhbcmVzb3VyY2UubmFtZV0gPSBudWxsXG4gICAgICAgICAgICAgICAgZGVsZXRlIEByZXNvdXJjZXNCeVBhdGhbcmVzb3VyY2UubmFtZV1cbiAgICAgICAgICAgICAgICBcbiAgICAjIyMqXG4gICAgKiBEaXNwb3NlcyBhbGwgcmVzb3VyY2VzLlxuICAgICpcbiAgICAqIEBtZXRob2QgZGlzcG9zZVxuICAgICMjIyAgICAgICAgXG4gICAgZGlzcG9zZTogLT4gXG4gICAgICAgIEBkaXNwb3NlQml0bWFwcygpXG4gICAgICAgIEBkaXNwb3NlVmlkZW9zKClcbiAgICAgICAgQGRpc3Bvc2VBdWRpbygpXG4gICAgICAgIEBkaXNwb3NlTGl2ZTJEKClcbiAgICAgICAgXG4gICAgICAgIEBjb250ZXh0ID0gQHN5c3RlbUNvbnRleHRcbiAgICAgXG4gICAgIyMjKlxuICAgICogTG9hZHMgYWxsIGN1c3RvbSBmb250cyBpbiBHcmFwaGljcy9Gb250cyBmb2xkZXIuXG4gICAgKlxuICAgICogQG1ldGhvZCBsb2FkRm9udHNcbiAgICAjIyMgICAgICAgXG4gICAgbG9hZEZvbnRzOiAtPlxuICAgICAgICByZXNvdXJjZSA9IHsgbG9hZGVkOiBubyB9XG4gICAgICAgIEByZXNvdXJjZXMucHVzaChyZXNvdXJjZSlcbiAgICAgICAgQHJlc291cmNlc0J5UGF0aFtcIkdyYXBoaWNzL0ZvbnRzXCJdID0gcmVzb3VyY2VcbiAgICAgICAgXG4gICAgICAgIGdzLkZvbnQubG9hZEN1c3RvbUZvbnRzKChlcnJvcikgPT5cbiAgICAgICAgICAgIEByZXNvdXJjZXNCeVBhdGhbXCJHcmFwaGljcy9Gb250c1wiXS5sb2FkZWQgPSB5ZXNcbiAgICAgICAgICAgIGlmIGVycm9yXG4gICAgICAgICAgICAgICAgQHJlc291cmNlc0J5UGF0aFtcIkdyYXBoaWNzL0ZvbnRzXCJdLmVycm9yID0geWVzXG4gICAgICAgIClcbiAgICAjIyMqXG4gICAgKiBHZXRzIGEgY3VzdG9tIGNyZWF0ZWQgYml0bWFwIGJ5IGtleS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGdldEN1c3RvbUJpdG1hcFxuICAgICogQHBhcmFtIHtTdHJpbmd9IGtleSAtIFRoZSBrZXkgZm9yIHRoZSBiaXRtYXAgdG8gZ2V0LlxuICAgICogQHJldHVybiB7Z3MuQml0bWFwfSBUaGUgYml0bWFwIG9yIDxiPm51bGw8L2I+IGlmIG5vIGJpdG1hcCBleGlzdHMgZm9yIHRoZSBzcGVjaWZpZWQga2V5LlxuICAgICMjIyAgICAgXG4gICAgZ2V0Q3VzdG9tQml0bWFwOiAoa2V5KSAtPlxuICAgICAgICByZXR1cm4gQGN1c3RvbUJpdG1hcHNCeUtleVtrZXldXG4gICAgXG4gICAgIyMjKlxuICAgICogU2V0cyBhIGN1c3RvbSBjcmVhdGVkIGJpdG1hcCBmb3IgYSBzcGVjaWZpZWQga2V5LlxuICAgICpcbiAgICAqIEBtZXRob2Qgc2V0Q3VzdG9tQml0bWFwXG4gICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IC0gVGhlIGtleSBmb3IgdGhlIGJpdG1hcCB0byBzZXQuXG4gICAgKiBAcGFyYW0ge2dzLkJpdG1hcH0gYml0bWFwIC0gVGhlIGJpdG1hcCB0byBzZXQuXG4gICAgIyMjIFxuICAgIHNldEN1c3RvbUJpdG1hcDogKGtleSwgYml0bWFwKSAtPlxuICAgICAgICBAY3VzdG9tQml0bWFwc0J5S2V5W2tleV0gPSBiaXRtYXBcbiAgICAgICAgaWYgbm90IGJpdG1hcC5sb2FkZWQ/XG4gICAgICAgICAgICBAcmVzb3VyY2VzLnB1c2goYml0bWFwKVxuICAgICAgICAgICAgQHJlc291cmNlc0xvYWRlZCA9IGZhbHNlXG4gICAgXG4gICAgIyMjKlxuICAgICogQWRkcyBhIGN1c3RvbSBjcmVhdGVkIGJpdG1hcCB0byB0aGUgcmVzb3VyY2UgbWFuYWdlci5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGFkZEN1c3RvbUJpdG1hcFxuICAgICogQHBhcmFtIHtncy5CaXRtYXB9IGJpdG1hcCAtIFRoZSBiaXRtYXAgdG8gYWRkLlxuICAgICMjIyAgICAgICAgIFxuICAgIGFkZEN1c3RvbUJpdG1hcDogKGJpdG1hcCkgLT5cbiAgICAgICAgQGNvbnRleHQucmVzb3VyY2VzLnB1c2gobmFtZTogXCJcIiwgZGF0YTogYml0bWFwKVxuXG4gICAgIyMjKlxuICAgICogR2V0cyBhIExpdmUyRCBtb2RlbC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGdldExpdmUyRE1vZGVsXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZVBhdGggLSBQYXRoIHRvIHRoZSBMaXZlMkQgbW9kZWwgZmlsZS5cbiAgICAqIEByZXR1cm4ge2dzLkxpdmUyRE1vZGVsfSBUaGUgTGl2ZTJEIG1vZGVsIG9yIDxiPm51bGw8L2I+IGlmIG5vIG1vZGVsIGV4aXN0cyBhdCB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aC5cbiAgICAjIyMgIFxuICAgIGdldExpdmUyRE1vZGVsOiAoZmlsZVBhdGgpIC0+XG4gICAgICAgIHJlc3VsdCA9IEByZXNvdXJjZXNCeVBhdGhbZmlsZVBhdGhdXG4gICAgICAgIFxuICAgICAgICBpZiBub3QgcmVzdWx0PyBvciByZXN1bHQuZGlzcG9zZWRcbiAgICAgICAgICAgIHByb2ZpbGUgPSBMYW5ndWFnZU1hbmFnZXIucHJvZmlsZVxuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IGdzLkxpdmUyRE1vZGVsKGZpbGVQYXRoLCAoaWYgcHJvZmlsZT8gYW5kIHByb2ZpbGUuaXRlbXM/IHRoZW4gcHJvZmlsZS5pdGVtcy5jb2RlIGVsc2UgbnVsbCkpXG4gICAgICAgICAgICBAcmVzb3VyY2VzQnlQYXRoW2ZpbGVQYXRoXSA9IHJlc3VsdFxuICAgICAgICAgICAgQHJlc291cmNlcy5wdXNoKHJlc3VsdClcbiAgICAgICAgICAgIEByZXNvdXJjZXNMb2FkZWQgPSBmYWxzZVxuICAgICAgICAgICAgQGNvbnRleHQucmVzb3VyY2VzLnB1c2gobmFtZTogZmlsZVBhdGgsIGRhdGE6IHJlc3VsdClcbiAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIFxuICAgICMjIypcbiAgICAqIEdldHMgYSBmb250LlxuICAgICpcbiAgICAqIEBtZXRob2QgZ2V0Rm9udFxuICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZm9udCB0byBnZXQuXG4gICAgKiBAcGFyYW0ge251bWJlcn0gc2l6ZSAtIFRoZSBzaXplIG9mIHRoZSBmb250IHRvIGdldC5cbiAgICAqIEByZXR1cm4ge2dzLkZvbnR9IFRoZSBmb250IG9yIDxiPm51bGw8L2I+IGlmIG5vIGZvbnQgd2l0aCB0aGUgc3BlY2lmaWVkIG5hbWUgZXhpc3RzLlxuICAgICMjIyAgXG4gICAgZ2V0Rm9udDogKG5hbWUsIHNpemUpIC0+XG4gICAgICAgIHJlc3VsdCA9IG5ldyBGb250KG5hbWUsIHNpemUpXG4gICAgICAgIFxuICAgICAgICBAcmVzb3VyY2VzLnB1c2gocmVzdWx0KVxuICAgICAgICBAcmVzb3VyY2VzTG9hZGVkID0gZmFsc2VcbiAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICBcbiAgICAjIyMqXG4gICAgKiBHZXRzIGEgdmlkZW8uXG4gICAgKlxuICAgICogQG1ldGhvZCBnZXRWaWRlb1xuICAgICogQHBhcmFtIHtTdHJpbmd9IGZpbGVQYXRoIC0gUGF0aCB0byB0aGUgdmlkZW8gZmlsZS5cbiAgICAqIEByZXR1cm4ge2dzLlZpZGVvfSBUaGUgdmlkZW8gb3IgPGI+bnVsbDwvYj4gaWYgbm8gdmlkZW8gZXhpc3RzIGF0IHRoZSBzcGVjaWZpZWQgZmlsZSBwYXRoLlxuICAgICMjIyAgIFxuICAgIGdldFZpZGVvOiAoZmlsZVBhdGgpIC0+XG4gICAgICAgIGlmIGZpbGVQYXRoLmVuZHNXaXRoKFwiL1wiKSB0aGVuIHJldHVybiBudWxsXG4gICAgICAgIFxuICAgICAgICByZXN1bHQgPSBAcmVzb3VyY2VzQnlQYXRoW2ZpbGVQYXRoXVxuICAgICAgICBcbiAgICAgICAgaWYgbm90IHJlc3VsdD8gb3IgcmVzdWx0LmRpc3Bvc2VkXG4gICAgICAgICAgICBwcm9maWxlID0gTGFuZ3VhZ2VNYW5hZ2VyLnByb2ZpbGVcbiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBncy5WaWRlbyhmaWxlUGF0aCwgKGlmIHByb2ZpbGU/IGFuZCBwcm9maWxlLml0ZW1zPyB0aGVuIHByb2ZpbGUuaXRlbXMuY29kZSBlbHNlIG51bGwpKVxuICAgICAgICAgICAgQHJlc291cmNlc0J5UGF0aFtmaWxlUGF0aF0gPSByZXN1bHRcbiAgICAgICAgICAgIEByZXNvdXJjZXMucHVzaChyZXN1bHQpXG4gICAgICAgICAgICBAcmVzb3VyY2VzTG9hZGVkID0gZmFsc2VcbiAgICAgICAgICAgIEBjb250ZXh0LnJlc291cmNlcy5wdXNoKG5hbWU6IGZpbGVQYXRoLCBkYXRhOiByZXN1bHQpXG4gICAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICBcbiAgICAjIyMqXG4gICAgKiBHZXRzIGEgYml0bWFwLlxuICAgICpcbiAgICAqIEBtZXRob2QgZ2V0Qml0bWFwXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZVBhdGggLSBQYXRoIHRvIHRoZSBiaXRtYXAgZmlsZS5cbiAgICAqIEBwYXJhbSB7bnVtYmVyfSBodWUgLSBUaGUgYml0bWFwJ3MgaHVlLiBUaGUgYml0bWFwIHdpbGwgYmUgbG9hZGVkIGFuZCB0aGVuIHJlY29sb3JlZC5cbiAgICAqIEByZXR1cm4ge2dzLkJpdG1hcH0gVGhlIGJpdG1hcCBvciA8Yj5udWxsPC9iPiBpZiBubyBiaXRtYXAgZXhpc3RzIGF0IHRoZSBzcGVjaWZpZWQgZmlsZSBwYXRoLlxuICAgICMjIyAgIFxuICAgIGdldEJpdG1hcDogKGZpbGVQYXRoLCBodWUpIC0+XG4gICAgICAgIGlmIGZpbGVQYXRoLmVuZHNXaXRoKFwiL1wiKSB0aGVuIHJldHVybiBudWxsXG4gICAgICAgIFxuICAgICAgICBcbiAgICAgICAgaHVlID0gaHVlIHx8IDBcbiAgICAgICAgcmVzdWx0ID0gQHJlc291cmNlc0J5UGF0aFtmaWxlUGF0aF0gfHwgQGN1c3RvbUJpdG1hcHNCeUtleVtmaWxlUGF0aF1cbiAgICAgICAgXG4gICAgICAgIGlmIG5vdCByZXN1bHQ/XG4gICAgICAgICAgICBwcm9maWxlID0gTGFuZ3VhZ2VNYW5hZ2VyLnByb2ZpbGVcbiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaXRtYXAoZmlsZVBhdGgsIChpZiBwcm9maWxlPyBhbmQgcHJvZmlsZS5pdGVtcz8gdGhlbiBwcm9maWxlLml0ZW1zLmNvZGUgZWxzZSBudWxsKSwgbm8pXG4gICAgICAgICAgICByZXN1bHQuaHVlID0gaHVlXG4gICAgICAgICAgICByZXN1bHQuZmlsZVBhdGggPSBmaWxlUGF0aFxuICAgICAgICAgICAgQHJlc291cmNlc0J5UGF0aFtmaWxlUGF0aF0gPSByZXN1bHRcbiAgICAgICAgICAgIEByZXNvdXJjZXMucHVzaChyZXN1bHQpXG4gICAgICAgICAgICBAcmVzb3VyY2VzTG9hZGVkID0gZmFsc2VcbiAgICAgICAgICAgIEBjb250ZXh0LnJlc291cmNlcy5wdXNoKG5hbWU6IGZpbGVQYXRoLCBkYXRhOiByZXN1bHQpXG4gICAgICAgIGVsc2UgaWYgbm90IHJlc3VsdC5sb2FkZWQgYW5kIHJlc3VsdC5odWUgIT0gaHVlXG4gICAgICAgICAgICBwcm9maWxlID0gTGFuZ3VhZ2VNYW5hZ2VyLnByb2ZpbGVcbiAgICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaXRtYXAoZmlsZVBhdGgsIChpZiBwcm9maWxlPyBhbmQgcHJvZmlsZS5pdGVtcz8gdGhlbiBwcm9maWxlLml0ZW1zLmNvZGUgZWxzZSBudWxsKSlcbiAgICAgICAgICAgIHJlc3VsdC5odWUgPSBodWVcbiAgICAgICAgICAgIHJlc3VsdC5maWxlUGF0aCA9IGZpbGVQYXRoXG4gICAgICAgICAgICBAcmVzb3VyY2VzLnB1c2gocmVzdWx0KVxuICAgICAgICAgICAgQHJlc291cmNlc0xvYWRlZCA9IGZhbHNlICBcbiAgICAgICAgZWxzZSBpZiBodWUgPiAwXG4gICAgICAgICAgICBodWVCaXRtYXAgPSBAcmVzb3VyY2VzQnlQYXRoSHVlW2ZpbGVQYXRoK1wiQFwiK2h1ZV1cbiAgICAgICAgICAgIGlmIG5vdCBodWVCaXRtYXA/IGFuZCByZXN1bHQubG9hZGVkXG4gICAgICAgICAgICAgICAgaHVlQml0bWFwID0gbmV3IEJpdG1hcChyZXN1bHQuaW1hZ2UpXG4gICAgICAgICAgICAgICAgaHVlQml0bWFwLmNoYW5nZUh1ZShodWUpXG4gICAgICAgICAgICAgICAgQHJlc291cmNlc0J5UGF0aEh1ZVtmaWxlUGF0aCtcIkBcIitodWVdID0gaHVlQml0bWFwXG4gICAgICAgICAgICBpZiBodWVCaXRtYXA/IHRoZW4gcmVzdWx0ID0gaHVlQml0bWFwXG4gICAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcblxuICAgICMjIypcbiAgICAqIEdldHMgYW4gSFRNTCBpbWFnZS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGdldEltYWdlXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZVBhdGggLSBQYXRoIHRvIHRoZSBpbWFnZSBmaWxlLlxuICAgICogQHJldHVybiB7SFRNTEltYWdlRWxlbWVudH0gVGhlIGltYWdlIG9yIDxiPm51bGw8L2I+IGlmIG5vIGltYWdlIGV4aXN0cyBhdCB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aC5cbiAgICAjIyMgIFxuICAgIGdldEltYWdlOiAoZmlsZVBhdGgpIC0+XG4gICAgICAgIHJlc3VsdCA9IEByZXNvdXJjZXNCeVBhdGhbZmlsZVBhdGhdXG4gICAgICAgIFxuICAgICAgICBpZiBub3QgcmVzdWx0P1xuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEJpdG1hcChcInJlc291cmNlcy8je2ZpbGVQYXRofS5wbmdcIik7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEByZXNvdXJjZXNCeVBhdGhbZmlsZVBhdGhdID0gcmVzdWx0XG4gICAgICAgICAgICBAcmVzb3VyY2VzLnB1c2gocmVzdWx0KVxuICAgICAgICAgICAgQHJlc291cmNlc0xvYWRlZCA9IGZhbHNlXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gcmVzdWx0XG5cbiAgICAjIyMqXG4gICAgKiBHZXRzIGFuIGF1ZGlvIHN0cmVhbS5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGdldEF1ZGlvU3RyZWFtXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gZmlsZVBhdGggLSBQYXRoIHRvIHRoZSBhdWRpbyBmaWxlLlxuICAgICogQHJldHVybiB7Z3MuQXVkaW9CdWZmZXJ9IFRoZSBhdWRpbyBidWZmZXIgb3IgPGI+bnVsbDwvYj4gaWYgbm8gYXVkaW8gZmlsZSBleGlzdHMgYXQgdGhlIHNwZWNpZmllZCBmaWxlIHBhdGguXG4gICAgIyMjIFxuICAgIGdldEF1ZGlvU3RyZWFtOiAoZmlsZVBhdGgpIC0+XG4gICAgICAgIHJlc3VsdCA9IEByZXNvdXJjZXNCeVBhdGhbZmlsZVBhdGhdXG4gICAgICAgIHByb2ZpbGUgPSBMYW5ndWFnZU1hbmFnZXIucHJvZmlsZVxuICAgICAgICBsYW5ndWFnZUNvZGUgPSBpZiBwcm9maWxlPyBhbmQgcHJvZmlsZS5pdGVtcz8gdGhlbiBwcm9maWxlLml0ZW1zLmNvZGUgZWxzZSBudWxsXG4gICAgICAgIFxuICAgICAgICBpZiBub3QgcmVzdWx0P1xuICAgICAgICAgICAgcmVzdWx0ID0gbmV3IEdTLkF1ZGlvQnVmZmVyKGZpbGVQYXRoKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBAcmVzb3VyY2VzQnlQYXRoW2ZpbGVQYXRoXSA9IHJlc3VsdFxuICAgICAgICAgICAgQHJlc291cmNlcy5wdXNoKHJlc3VsdClcbiAgICAgICAgICAgIEByZXNvdXJjZXNMb2FkZWQgPSBmYWxzZVxuICAgICAgICAgICAgXG4gICAgICAgICAgICBAY29udGV4dC5yZXNvdXJjZXMucHVzaChuYW1lOiBmaWxlUGF0aCwgZGF0YTogcmVzdWx0KVxuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIFxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICAgIFxuICAgICMjIypcbiAgICAqIEdldHMgYW4gYXVkaW8gYnVmZmVyLiBUaGUgYXVkaW8gZGF0YSBpcyBmdWxseSBsb2FkZWQgYW5kIGRlY29kZWQgaW4gbWVtb3J5LiBJdCBpcyByZWNvbW1lbmVkZWRcbiAgICAqIGZvciBzb3VuZCBlZmZlY3RzIGJ1dCBmb3IgYSBsb25nIGJhY2tncm91bmQgbXVzaWMsIDxiPmdldEF1ZGlvU3RyZWFtPC9iPiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkLiBUaGF0IGlzIGVzcGVjaWFsbHlcbiAgICAqIHRoZSBjYXNlIG9uIG1vYmlsZSBkZXZpY2VzLlxuICAgICpcbiAgICAqIEBtZXRob2QgZ2V0QXVkaW9CdWZmZXJcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBmaWxlUGF0aCAtIFBhdGggdG8gdGhlIGF1ZGlvIGZpbGUuXG4gICAgKiBAcmV0dXJuIHtncy5BdWRpb0J1ZmZlcn0gVGhlIGF1ZGlvIGJ1ZmZlciBvciA8Yj5udWxsPC9iPiBpZiBubyBhdWRpbyBmaWxlIGV4aXN0cyBhdCB0aGUgc3BlY2lmaWVkIGZpbGUgcGF0aC5cbiAgICAjIyMgXG4gICAgZ2V0QXVkaW9CdWZmZXI6IChmaWxlUGF0aCkgLT5cbiAgICAgICAgcmVzdWx0ID0gQHJlc291cmNlc0J5UGF0aFtmaWxlUGF0aF1cbiAgICAgICAgcHJvZmlsZSA9IExhbmd1YWdlTWFuYWdlci5wcm9maWxlXG4gICAgICAgIGxhbmd1YWdlQ29kZSA9IGlmIHByb2ZpbGU/IGFuZCBwcm9maWxlLml0ZW1zPyB0aGVuIHByb2ZpbGUuaXRlbXMuY29kZSBlbHNlIG51bGxcbiAgICAgICAgXG4gICAgICAgIGlmIG5vdCByZXN1bHQ/XG4gICAgICAgICAgICByZXN1bHQgPSBuZXcgR1MuQXVkaW9CdWZmZXIoZmlsZVBhdGgpXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIEByZXNvdXJjZXNCeVBhdGhbZmlsZVBhdGhdID0gcmVzdWx0XG4gICAgICAgICAgICBAcmVzb3VyY2VzLnB1c2gocmVzdWx0KVxuICAgICAgICAgICAgQHJlc291cmNlc0xvYWRlZCA9IGZhbHNlXG4gICAgICAgIFxuICAgICAgICAgICAgQGNvbnRleHQucmVzb3VyY2VzLnB1c2gobmFtZTogZmlsZVBhdGgsIGRhdGE6IHJlc3VsdClcbiAgICAgICAgXG4gICAgICAgIHJldHVybiByZXN1bHRcblxuICAgICMjIypcbiAgICAqIFVwZGF0ZXMgdGhlIGxvYWRpbmcgcHJvY2Vzcy4gTmVlZHMgdG8gYmUgY2FsbGVkIG9uY2UgcGVyIGZyYW1lIHRvIGtlZXAgXG4gICAgKiB0aGUgUmVzb3VyY2VNYW5hZ2VyIHVwIHRvIGRhdGUuXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVcbiAgICAjIyMgIFxuICAgIHVwZGF0ZTogLT5cbiAgICAgICAgaWYgbm90IEBldmVudHM/IHRoZW4gQGV2ZW50cyA9IG5ldyBncy5FdmVudEVtaXR0ZXIoKVxuICAgICAgICBpZiBub3QgQHJlc291cmNlc0xvYWRlZFxuICAgICAgICAgICAgQHJlc291cmNlc0xvYWRlZCA9IHRydWVcbiAgICAgICAgICAgIGZvciBpIGluIFswLi4uQHJlc291cmNlcy5sZW5ndGhdXG4gICAgICAgICAgICAgICAgaWYgbm90IEByZXNvdXJjZXNbaV0ubG9hZGVkXG4gICAgICAgICAgICAgICAgICAgIEByZXNvdXJjZXNMb2FkZWQgPSBmYWxzZVxuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgQHJlc291cmNlc1tpXS5odWU/IGFuZCBAcmVzb3VyY2VzW2ldLmh1ZSA+IDBcbiAgICAgICAgICAgICAgICAgICAgYml0bWFwID0gbmV3IEJpdG1hcChAcmVzb3VyY2VzW2ldLmltYWdlKVxuICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIEByZXNvdXJjZXNCeVBhdGhbQHJlc291cmNlc1tpXS5maWxlUGF0aF0gPSBiaXRtYXBcbiAgICAgICAgICAgICAgICAgICAgQHJlc291cmNlc1tpXS5jaGFuZ2VIdWUoQHJlc291cmNlc1tpXS5odWUpXG4gICAgICAgICAgICAgICAgICAgIEByZXNvdXJjZXNCeVBhdGhIdWVbQHJlc291cmNlc1tpXS5maWxlUGF0aCtcIkBcIitAcmVzb3VyY2VzW2ldLmh1ZV0gPSBAcmVzb3VyY2VzW2ldXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBAcmVzb3VyY2VzW2ldLmZpbGVQYXRoXG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBAcmVzb3VyY2VzW2ldLmh1ZVxuICAgICAgICAgICAgaWYgQHJlc291cmNlc0xvYWRlZFxuICAgICAgICAgICAgICAgIEBldmVudHMuZW1pdChcImxvYWRlZFwiLCB0aGlzKVxuICAgICAgICBcbiAgICAgICAgcmV0dXJuIG51bGxcblxud2luZG93LlJlc291cmNlTWFuYWdlciA9IFJlc291cmNlTWFuYWdlclxuZ3MuUmVzb3VyY2VNYW5hZ2VyID0gUmVzb3VyY2VNYW5hZ2VyIl19\n//# sourceURL=ResourceManager_58.js",
"parentId": "C0268943K60B3A42B7SA6F1EDDCF2F642FD7"
},
"summary": [
"name",
"type",
"order"
]
}
|