├── .github └── workflows │ └── VRC-Asset-Release-And-Upload.yml ├── .gitignore ├── Instancer.meta ├── Instancer ├── Local-Mirror-Detection Instancer.asmdef ├── Local-Mirror-Detection Instancer.asmdef.meta ├── Local-Mirror-Detection Instancer.cs └── Local-Mirror-Detection Instancer.cs.meta ├── LICENSE ├── LICENSE.meta ├── Media.meta ├── Media ├── Preview.png ├── Web │ ├── Preview.webp │ └── Preview.webp.meta └── setup.mp4 ├── Mirror Detection FX.controller ├── Mirror Detection FX.controller.meta ├── README.md ├── README.md.meta ├── Resources.meta ├── Resources ├── Animations.meta └── Animations │ ├── Mirror Detection Buffer.anim │ ├── Mirror Detection Buffer.anim.meta │ ├── Mirror Detection False.anim │ ├── Mirror Detection False.anim.meta │ ├── Mirror Detection True.anim │ └── Mirror Detection True.anim.meta ├── package.json └── package.json.meta /.github/workflows/VRC-Asset-Release-And-Upload.yml: -------------------------------------------------------------------------------- 1 | name: Create Tag and Release 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | TAG: 6 | required: true 7 | type: string 8 | description: Tag to be applied, for example 1.0.0 9 | CHANGELOG: 10 | required: true 11 | type: string 12 | description: Enter as a list using '- ' and '\n' (e.g. "- First item\n- Second item".). Don't use ". 13 | CHECKOUT_REF: 14 | type: string 15 | description: full commit hash, if none supplied, latest main is taken 16 | 17 | jobs: 18 | deploy: 19 | uses: VRLabs/Workflows-collection/.github/workflows/VRC-Asset-Release-And-Upload.yml@main 20 | with: 21 | ASSETS_PATH: . 22 | TAG: ${{ inputs.TAG }} 23 | CHANGELOG: ${{ inputs.CHANGELOG }} 24 | REPOSITORY: ${{ github.repository }} 25 | CHECKOUT_REF: ${{ inputs.CHECKOUT_REF }} 26 | secrets: inherit -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .github/.DS_Store 2 | .DS_Store 3 | /Media/*.meta 4 | -------------------------------------------------------------------------------- /Instancer.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f78e8bd7aabb79d468d691527da5852f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Instancer/Local-Mirror-Detection Instancer.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "VRLabs Local-Mirror-Detection Instancer", 3 | "rootNamespace": "", 4 | "references": [], 5 | "includePlatforms": [ 6 | "Editor" 7 | ], 8 | "excludePlatforms": [], 9 | "allowUnsafeCode": false, 10 | "overrideReferences": false, 11 | "precompiledReferences": [], 12 | "autoReferenced": true, 13 | "defineConstraints": [], 14 | "versionDefines": [ 15 | { 16 | "name": "dev.vrlabs.instancer", 17 | "expression": "", 18 | "define": "VRLABS_INSTANCER_FOUND" 19 | } 20 | ], 21 | "noEngineReferences": false 22 | } -------------------------------------------------------------------------------- /Instancer/Local-Mirror-Detection Instancer.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6585e7d475f9a08409880a558b8852d4 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Instancer/Local-Mirror-Detection Instancer.cs: -------------------------------------------------------------------------------- 1 | #if VRLABS_INSTANCER_FOUND 2 | using System; 3 | using System.Linq; 4 | using System.Reflection; 5 | using UnityEditor; 6 | using UnityEngine; 7 | 8 | namespace VRLabs.LocalMirrorDetection 9 | { 10 | public class LocalMirrorDetection : ScriptableObject 11 | { 12 | public const string packageName = "Local-Mirror-Detection"; 13 | 14 | public static string[] excludeRegexs = 15 | { 16 | ".*\\.cs", 17 | ".*\\.asmdef", 18 | "package.json" 19 | }; 20 | 21 | [MenuItem("VRLabs/Create Instance/Local Mirror Detection")] 22 | public static void FancyPackage() 23 | { 24 | Type instancerType = AppDomain.CurrentDomain.GetAssemblies() 25 | .Where(x => x.GetType("VRLabs.Instancer.Instancer") != null) 26 | .Select(x => x.GetType("VRLabs.Instancer.Instancer")).FirstOrDefault(); 27 | 28 | if (instancerType == null) 29 | { 30 | Debug.LogError("Instancer not found. To use this functionality, install the VRLabs Instancer from https://github.com/VRLabs/Instancer"); 31 | return; 32 | } 33 | 34 | MethodInfo instanceMethod = instancerType.GetMethod("Instance", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); 35 | 36 | if (instanceMethod == null) 37 | { 38 | Debug.LogError("Instance method not found"); 39 | return; 40 | } 41 | 42 | var assetPath = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName() 43 | .Replace(System.IO.Path.GetDirectoryName(Application.dataPath), "") 44 | .Replace("\\", "/".Replace("./", "")); 45 | 46 | instanceMethod.Invoke(null, new object[] { packageName, assetPath, excludeRegexs }); 47 | } 48 | } 49 | } 50 | #endif -------------------------------------------------------------------------------- /Instancer/Local-Mirror-Detection Instancer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2fe2022bf42df3b458969b96a7ed799d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 VRLabs LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f72f042519152482e830f39df9c6f7d8 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Media.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee1e67a3158d39746942f4e272e2fa37 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Media/Preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VRLabs/Local-Mirror-Detection/093068df74a45c0d3c01245a2f578a271c8dc491/Media/Preview.png -------------------------------------------------------------------------------- /Media/Web/Preview.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VRLabs/Local-Mirror-Detection/093068df74a45c0d3c01245a2f578a271c8dc491/Media/Web/Preview.webp -------------------------------------------------------------------------------- /Media/Web/Preview.webp.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ad6ecf80a4933204096cd16fc83c954f 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Media/setup.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VRLabs/Local-Mirror-Detection/093068df74a45c0d3c01245a2f578a271c8dc491/Media/setup.mp4 -------------------------------------------------------------------------------- /Mirror Detection FX.controller: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1102 &-9049777313585539016 4 | AnimatorState: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 1 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Fork 11 | m_Speed: 1 12 | m_CycleOffset: 0 13 | m_Transitions: 14 | - {fileID: -7715550311558748690} 15 | - {fileID: 3107862120337283806} 16 | m_StateMachineBehaviours: [] 17 | m_Position: {x: 50, y: 50, z: 0} 18 | m_IKOnFeet: 0 19 | m_WriteDefaultValues: 0 20 | m_Mirror: 0 21 | m_SpeedParameterActive: 0 22 | m_MirrorParameterActive: 0 23 | m_CycleOffsetParameterActive: 0 24 | m_TimeParameterActive: 0 25 | m_Motion: {fileID: 7400000, guid: 26ee6725878c84a4ca5ba99b28042ac4, type: 2} 26 | m_Tag: 27 | m_SpeedParameter: 28 | m_MirrorParameter: 29 | m_CycleOffsetParameter: 30 | m_TimeParameter: 31 | --- !u!114 &-7719676013391324315 32 | MonoBehaviour: 33 | m_ObjectHideFlags: 1 34 | m_CorrespondingSourceObject: {fileID: 0} 35 | m_PrefabInstance: {fileID: 0} 36 | m_PrefabAsset: {fileID: 0} 37 | m_GameObject: {fileID: 0} 38 | m_Enabled: 1 39 | m_EditorHideFlags: 0 40 | m_Script: {fileID: -706344726, guid: 67cc4cb7839cd3741b63733d5adf0442, type: 3} 41 | m_Name: 42 | m_EditorClassIdentifier: 43 | parameters: 44 | - type: 0 45 | name: MirrorDetection/DetectMirror 46 | source: 47 | value: 1 48 | valueMin: 0 49 | valueMax: 0 50 | chance: 0 51 | convertRange: 0 52 | sourceMin: 0 53 | sourceMax: 0 54 | destMin: 0 55 | destMax: 0 56 | localOnly: 1 57 | debugString: 58 | --- !u!1101 &-7715550311558748690 59 | AnimatorStateTransition: 60 | m_ObjectHideFlags: 1 61 | m_CorrespondingSourceObject: {fileID: 0} 62 | m_PrefabInstance: {fileID: 0} 63 | m_PrefabAsset: {fileID: 0} 64 | m_Name: 65 | m_Conditions: 66 | - m_ConditionMode: 2 67 | m_ConditionEvent: MirrorDetection/DetectMirror 68 | m_EventTreshold: 0 69 | m_DstStateMachine: {fileID: 0} 70 | m_DstState: {fileID: -2948385516909857121} 71 | m_Solo: 0 72 | m_Mute: 0 73 | m_IsExit: 0 74 | serializedVersion: 3 75 | m_TransitionDuration: 0 76 | m_TransitionOffset: 0 77 | m_ExitTime: 1 78 | m_HasExitTime: 0 79 | m_HasFixedDuration: 0 80 | m_InterruptionSource: 0 81 | m_OrderedInterruption: 1 82 | m_CanTransitionToSelf: 1 83 | --- !u!1102 &-2948385516909857121 84 | AnimatorState: 85 | serializedVersion: 6 86 | m_ObjectHideFlags: 1 87 | m_CorrespondingSourceObject: {fileID: 0} 88 | m_PrefabInstance: {fileID: 0} 89 | m_PrefabAsset: {fileID: 0} 90 | m_Name: Not Mirror 91 | m_Speed: 1 92 | m_CycleOffset: 0 93 | m_Transitions: [] 94 | m_StateMachineBehaviours: 95 | - {fileID: -7719676013391324315} 96 | m_Position: {x: 50, y: 50, z: 0} 97 | m_IKOnFeet: 0 98 | m_WriteDefaultValues: 0 99 | m_Mirror: 0 100 | m_SpeedParameterActive: 0 101 | m_MirrorParameterActive: 0 102 | m_CycleOffsetParameterActive: 0 103 | m_TimeParameterActive: 0 104 | m_Motion: {fileID: 7400000, guid: 3e2ba1567477a42b3b2686183f7ce451, type: 2} 105 | m_Tag: 106 | m_SpeedParameter: 107 | m_MirrorParameter: 108 | m_CycleOffsetParameter: 109 | m_TimeParameter: 110 | --- !u!91 &9100000 111 | AnimatorController: 112 | m_ObjectHideFlags: 0 113 | m_CorrespondingSourceObject: {fileID: 0} 114 | m_PrefabInstance: {fileID: 0} 115 | m_PrefabAsset: {fileID: 0} 116 | m_Name: Mirror Detection FX 117 | serializedVersion: 5 118 | m_AnimatorParameters: 119 | - m_Name: IsLocal 120 | m_Type: 4 121 | m_DefaultFloat: 0 122 | m_DefaultInt: 0 123 | m_DefaultBool: 0 124 | m_Controller: {fileID: 0} 125 | - m_Name: MirrorDetection/DetectMirror 126 | m_Type: 4 127 | m_DefaultFloat: 0 128 | m_DefaultInt: 0 129 | m_DefaultBool: 0 130 | m_Controller: {fileID: 0} 131 | - m_Name: MirrorDetection/IsMirror 132 | m_Type: 1 133 | m_DefaultFloat: 0 134 | m_DefaultInt: 0 135 | m_DefaultBool: 0 136 | m_Controller: {fileID: 0} 137 | m_AnimatorLayers: 138 | - serializedVersion: 5 139 | m_Name: Local Mirror Detection 140 | m_StateMachine: {fileID: 5094055962389404326} 141 | m_Mask: {fileID: 0} 142 | m_Motions: [] 143 | m_Behaviours: [] 144 | m_BlendingMode: 0 145 | m_SyncedLayerIndex: -1 146 | m_DefaultWeight: 1 147 | m_IKPass: 0 148 | m_SyncedLayerAffectsTiming: 0 149 | m_Controller: {fileID: 9100000} 150 | --- !u!1102 &297040634560182215 151 | AnimatorState: 152 | serializedVersion: 6 153 | m_ObjectHideFlags: 1 154 | m_CorrespondingSourceObject: {fileID: 0} 155 | m_PrefabInstance: {fileID: 0} 156 | m_PrefabAsset: {fileID: 0} 157 | m_Name: Mirror 158 | m_Speed: 1 159 | m_CycleOffset: 0 160 | m_Transitions: [] 161 | m_StateMachineBehaviours: [] 162 | m_Position: {x: 50, y: 50, z: 0} 163 | m_IKOnFeet: 0 164 | m_WriteDefaultValues: 0 165 | m_Mirror: 0 166 | m_SpeedParameterActive: 0 167 | m_MirrorParameterActive: 0 168 | m_CycleOffsetParameterActive: 0 169 | m_TimeParameterActive: 0 170 | m_Motion: {fileID: 7400000, guid: 87293e88fb37f4cc6912d2aa42ccc08e, type: 2} 171 | m_Tag: 172 | m_SpeedParameter: 173 | m_MirrorParameter: 174 | m_CycleOffsetParameter: 175 | m_TimeParameter: 176 | --- !u!1101 &1603005695119593288 177 | AnimatorStateTransition: 178 | m_ObjectHideFlags: 1 179 | m_CorrespondingSourceObject: {fileID: 0} 180 | m_PrefabInstance: {fileID: 0} 181 | m_PrefabAsset: {fileID: 0} 182 | m_Name: 183 | m_Conditions: 184 | - m_ConditionMode: 2 185 | m_ConditionEvent: IsLocal 186 | m_EventTreshold: 0 187 | m_DstStateMachine: {fileID: 0} 188 | m_DstState: {fileID: 7396059198905066274} 189 | m_Solo: 0 190 | m_Mute: 0 191 | m_IsExit: 0 192 | serializedVersion: 3 193 | m_TransitionDuration: 0 194 | m_TransitionOffset: 0 195 | m_ExitTime: 1 196 | m_HasExitTime: 0 197 | m_HasFixedDuration: 0 198 | m_InterruptionSource: 0 199 | m_OrderedInterruption: 1 200 | m_CanTransitionToSelf: 1 201 | --- !u!1101 &3107862120337283806 202 | AnimatorStateTransition: 203 | m_ObjectHideFlags: 1 204 | m_CorrespondingSourceObject: {fileID: 0} 205 | m_PrefabInstance: {fileID: 0} 206 | m_PrefabAsset: {fileID: 0} 207 | m_Name: 208 | m_Conditions: 209 | - m_ConditionMode: 1 210 | m_ConditionEvent: MirrorDetection/DetectMirror 211 | m_EventTreshold: 0 212 | m_DstStateMachine: {fileID: 0} 213 | m_DstState: {fileID: 297040634560182215} 214 | m_Solo: 0 215 | m_Mute: 0 216 | m_IsExit: 0 217 | serializedVersion: 3 218 | m_TransitionDuration: 0 219 | m_TransitionOffset: 0 220 | m_ExitTime: 1 221 | m_HasExitTime: 0 222 | m_HasFixedDuration: 0 223 | m_InterruptionSource: 0 224 | m_OrderedInterruption: 1 225 | m_CanTransitionToSelf: 1 226 | --- !u!1107 &5094055962389404326 227 | AnimatorStateMachine: 228 | serializedVersion: 6 229 | m_ObjectHideFlags: 1 230 | m_CorrespondingSourceObject: {fileID: 0} 231 | m_PrefabInstance: {fileID: 0} 232 | m_PrefabAsset: {fileID: 0} 233 | m_Name: Local Mirror Detection 234 | m_ChildStates: 235 | - serializedVersion: 1 236 | m_State: {fileID: 5701009222351216330} 237 | m_Position: {x: 30, y: 180, z: 0} 238 | - serializedVersion: 1 239 | m_State: {fileID: -9049777313585539016} 240 | m_Position: {x: 30, y: 250, z: 0} 241 | - serializedVersion: 1 242 | m_State: {fileID: 297040634560182215} 243 | m_Position: {x: -90, y: 320, z: 0} 244 | - serializedVersion: 1 245 | m_State: {fileID: -2948385516909857121} 246 | m_Position: {x: 150, y: 320, z: 0} 247 | - serializedVersion: 1 248 | m_State: {fileID: 7396059198905066274} 249 | m_Position: {x: 270, y: 180, z: 0} 250 | m_ChildStateMachines: [] 251 | m_AnyStateTransitions: [] 252 | m_EntryTransitions: [] 253 | m_StateMachineTransitions: {} 254 | m_StateMachineBehaviours: [] 255 | m_AnyStatePosition: {x: 50, y: 40, z: 0} 256 | m_EntryPosition: {x: 50, y: 120, z: 0} 257 | m_ExitPosition: {x: 50, y: 80, z: 0} 258 | m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} 259 | m_DefaultState: {fileID: 5701009222351216330} 260 | --- !u!1101 &5469010140199689570 261 | AnimatorStateTransition: 262 | m_ObjectHideFlags: 1 263 | m_CorrespondingSourceObject: {fileID: 0} 264 | m_PrefabInstance: {fileID: 0} 265 | m_PrefabAsset: {fileID: 0} 266 | m_Name: 267 | m_Conditions: 268 | - m_ConditionMode: 1 269 | m_ConditionEvent: IsLocal 270 | m_EventTreshold: 0 271 | m_DstStateMachine: {fileID: 0} 272 | m_DstState: {fileID: -9049777313585539016} 273 | m_Solo: 0 274 | m_Mute: 0 275 | m_IsExit: 0 276 | serializedVersion: 3 277 | m_TransitionDuration: 0 278 | m_TransitionOffset: 0 279 | m_ExitTime: 1 280 | m_HasExitTime: 0 281 | m_HasFixedDuration: 0 282 | m_InterruptionSource: 0 283 | m_OrderedInterruption: 1 284 | m_CanTransitionToSelf: 1 285 | --- !u!1102 &5701009222351216330 286 | AnimatorState: 287 | serializedVersion: 6 288 | m_ObjectHideFlags: 1 289 | m_CorrespondingSourceObject: {fileID: 0} 290 | m_PrefabInstance: {fileID: 0} 291 | m_PrefabAsset: {fileID: 0} 292 | m_Name: Init 293 | m_Speed: 1 294 | m_CycleOffset: 0 295 | m_Transitions: 296 | - {fileID: 5469010140199689570} 297 | - {fileID: 1603005695119593288} 298 | m_StateMachineBehaviours: [] 299 | m_Position: {x: 50, y: 50, z: 0} 300 | m_IKOnFeet: 0 301 | m_WriteDefaultValues: 0 302 | m_Mirror: 0 303 | m_SpeedParameterActive: 0 304 | m_MirrorParameterActive: 0 305 | m_CycleOffsetParameterActive: 0 306 | m_TimeParameterActive: 0 307 | m_Motion: {fileID: 7400000, guid: 26ee6725878c84a4ca5ba99b28042ac4, type: 2} 308 | m_Tag: 309 | m_SpeedParameter: 310 | m_MirrorParameter: 311 | m_CycleOffsetParameter: 312 | m_TimeParameter: 313 | --- !u!1102 &7396059198905066274 314 | AnimatorState: 315 | serializedVersion: 6 316 | m_ObjectHideFlags: 1 317 | m_CorrespondingSourceObject: {fileID: 0} 318 | m_PrefabInstance: {fileID: 0} 319 | m_PrefabAsset: {fileID: 0} 320 | m_Name: Remote 321 | m_Speed: 1 322 | m_CycleOffset: 0 323 | m_Transitions: [] 324 | m_StateMachineBehaviours: [] 325 | m_Position: {x: 50, y: 50, z: 0} 326 | m_IKOnFeet: 0 327 | m_WriteDefaultValues: 0 328 | m_Mirror: 0 329 | m_SpeedParameterActive: 0 330 | m_MirrorParameterActive: 0 331 | m_CycleOffsetParameterActive: 0 332 | m_TimeParameterActive: 0 333 | m_Motion: {fileID: 7400000, guid: 3e2ba1567477a42b3b2686183f7ce451, type: 2} 334 | m_Tag: 335 | m_SpeedParameter: 336 | m_MirrorParameter: 337 | m_CycleOffsetParameter: 338 | m_TimeParameter: 339 | -------------------------------------------------------------------------------- /Mirror Detection FX.controller.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 980b44fa3d7e748ae9d644959c0f1653 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |