Compare commits
	
		
			49 Commits
		
	
	
		
			v1.2.0
			...
			60c50f078d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 60c50f078d | ||
|   | 54f5074483 | ||
|   | 772eeb0465 | ||
|   | 456f889b9c | ||
|   | c3a4ca5925 | ||
|   | 06dc507590 | ||
|   | 5eaf027dba | ||
|   | 04c3728fcd | ||
|   | d34050e9af | ||
|   | 2c8381deac | ||
|   | 4aacbc9dbc | ||
|   | 8a4e677ebf | ||
|   | 84e85f3240 | ||
|   | e34a85ac39 | ||
|   | c306088ea3 | ||
|   | 308c37720d | ||
|   | 90af315222 | ||
|   | bd5e4f07ae | ||
|   | ae4757fb9d | ||
|   | 5dd586f9af | ||
|   | b69e838a8a | ||
|   | 8a2710339a | ||
|   | dd773e3b16 | ||
|   | 72c94f280d | ||
|   | 809914274a | ||
|   | 6f16f1cb85 | ||
|   | cad5b2dd95 | ||
|   | 74a6a65434 | ||
|   | b0a6c701ae | ||
|   | 1bd47fcb21 | ||
|   | 20bd96918c | ||
|   | 60805b7187 | ||
|   | 12b1df764c | ||
|   | 43b8982b88 | ||
|   | 7be868648b | ||
|   | 1702d8dfb5 | ||
|   | 8ac2901e23 | ||
|   | e47c8593da | ||
|   | 060f557752 | ||
|   | 224e4d8a29 | ||
|   | 4c8c8ecb05 | ||
|   | 1199ae2d14 | ||
|   | 784ab07442 | ||
|   | 0e53380420 | ||
|   | c2ebd5dfe4 | ||
|   | c320411a40 | ||
|   | 3c3d418aa2 | ||
|   | f00ab975dc | ||
|   | eb2d5f07be | 
| @@ -1,86 +0,0 @@ | |||||||
| version: 2.1 |  | ||||||
| jobs: |  | ||||||
|   build: |  | ||||||
|     working_directory: ~/code |  | ||||||
|     docker: |  | ||||||
|       - image: circleci/android:api-29 |  | ||||||
|     environment: |  | ||||||
|       JVM_OPTS: -Xmx3200m |  | ||||||
|     steps: |  | ||||||
|       - checkout |  | ||||||
|       - restore_cache: |  | ||||||
|           key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }} |  | ||||||
|       - run: |  | ||||||
|           name: Download Dependencies |  | ||||||
|           command: ./gradlew androidDependencies |  | ||||||
|       - save_cache: |  | ||||||
|           paths: |  | ||||||
|             - ~/.gradle |  | ||||||
|           key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }} |  | ||||||
|  |  | ||||||
|   tests: |  | ||||||
|     working_directory: ~/code |  | ||||||
|     docker: |  | ||||||
|       - image: circleci/android:api-29 |  | ||||||
|     environment: |  | ||||||
|       JVM_OPTS: -Xmx3200m |  | ||||||
|     steps: |  | ||||||
|       - checkout |  | ||||||
|       - restore_cache: |  | ||||||
|           key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }} |  | ||||||
|       - store_artifacts: |  | ||||||
|           path: app/build/reports |  | ||||||
|           destination: reports |  | ||||||
|       - run: |  | ||||||
|           name: Run Lint Test |  | ||||||
|           command: ./gradlew lint |  | ||||||
|       - run: |  | ||||||
|           name: Run Tests |  | ||||||
|           command: ./gradlew lint test |  | ||||||
|       - store_artifacts: |  | ||||||
|           path: app/build/reports |  | ||||||
|           destination: reports |  | ||||||
|       - store_test_results: |  | ||||||
|           path: app/build/test-results |  | ||||||
|  |  | ||||||
|   deploy: |  | ||||||
|     working_directory: ~/code |  | ||||||
|     docker: |  | ||||||
|       - image: circleci/android:api-29 |  | ||||||
|     environment: |  | ||||||
|       JVM_OPTS: -Xmx3200m |  | ||||||
|     steps: |  | ||||||
|       - checkout |  | ||||||
|       - restore_cache: |  | ||||||
|           key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }} |  | ||||||
|       - run: |  | ||||||
|           name: Build Library |  | ||||||
|           command: ./gradlew :treedatastructure:assembleRelease |  | ||||||
|       - run: |  | ||||||
|           name: Export key |  | ||||||
|           command: | |  | ||||||
|             mkdir treedatastructure/maven |  | ||||||
|             echo ${GPG_KEY_CONTENTS} | base64 -d --ignore-garbage > treedatastructure/maven/secret.gpg |  | ||||||
|       - run: |  | ||||||
|           name: Staging |  | ||||||
|           command: ./gradlew :treedatastructure:publishReleasePublicationToSonatypeRepository |  | ||||||
|       - run: |  | ||||||
|           name: Release Library |  | ||||||
|           command: ./gradlew closeAndReleaseRepository |  | ||||||
|  |  | ||||||
| workflows: |  | ||||||
|   version: 2.1 |  | ||||||
|   build-and-deploy: |  | ||||||
|     jobs: |  | ||||||
|       - build: |  | ||||||
|           filters:  # required since `deploy` has tag filters AND requires `build` |  | ||||||
|             tags: |  | ||||||
|               only: /.*/ |  | ||||||
|       - deploy: |  | ||||||
|           requires: |  | ||||||
|             - build |  | ||||||
|           filters: |  | ||||||
|             tags: |  | ||||||
|               only: /v[0-9]{1,3}\.[0-9]{1,3}\.?[0-9]{0,3}/ |  | ||||||
|             branches: |  | ||||||
|               ignore: /.*/ |  | ||||||
							
								
								
									
										11
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,11 @@ | |||||||
|  | # To get started with Dependabot version updates, you'll need to specify which | ||||||
|  | # package ecosystems to update and where the package manifests are located. | ||||||
|  | # Please see the documentation for all configuration options: | ||||||
|  | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file | ||||||
|  |  | ||||||
|  | version: 2 | ||||||
|  | updates: | ||||||
|  |   - package-ecosystem: "" # See documentation for possible values | ||||||
|  |     directory: "/" # Location of package manifests | ||||||
|  |     schedule: | ||||||
|  |       interval: "weekly" | ||||||
							
								
								
									
										36
									
								
								.github/workflows/publishRelease.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,36 @@ | |||||||
|  | name: Publish | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   release: | ||||||
|  |     # We'll run this workflow when a new GitHub release is created | ||||||
|  |     types: [released] | ||||||
|  |  | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   test: | ||||||
|  |     uses: ./.github/workflows/test.yml | ||||||
|  |     secrets: inherit | ||||||
|  |  | ||||||
|  |   publish: | ||||||
|  |     needs: test | ||||||
|  |     name: Publish Production | ||||||
|  |     environment: production | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Check out code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Set up JDK 21 | ||||||
|  |         uses: actions/setup-java@v4 | ||||||
|  |         with: | ||||||
|  |           distribution: temurin | ||||||
|  |           java-version: '21' | ||||||
|  |  | ||||||
|  |         # Runs upload, and then closes & releases the repository | ||||||
|  |       - name: Publish to MavenCentral | ||||||
|  |         run: ./gradlew publishToMavenCentral | ||||||
|  |         env: | ||||||
|  |           ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} | ||||||
|  |           ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} | ||||||
|  |           ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} | ||||||
|  |           ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} | ||||||
|  |           SNAPSHOT: false | ||||||
							
								
								
									
										23
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,23 @@ | |||||||
|  | name: Test | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches-ignore: [master] | ||||||
|  |   workflow_call: | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     name: Run unit tests | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Check out code | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |       - name: Set up JDK 21 | ||||||
|  |         uses: actions/setup-java@v4 | ||||||
|  |         with: | ||||||
|  |           distribution: temurin | ||||||
|  |           java-version: '21' | ||||||
|  |  | ||||||
|  |         # Builds the release artifacts of the library | ||||||
|  |       - name: Test | ||||||
|  |         run: ./gradlew cleanJvmTest jvmTest | ||||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -12,3 +12,7 @@ | |||||||
| /captures | /captures | ||||||
| .externalNativeBuild | .externalNativeBuild | ||||||
| .cxx | .cxx | ||||||
|  | /.idea/.name | ||||||
|  | /.idea/compiler.xml | ||||||
|  | /.idea/jarRepositories.xml | ||||||
|  | /.idea/deploymentTargetDropDown.xml | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,4 @@ | |||||||
|  | # Default ignored files | ||||||
|  | /shelf/ | ||||||
|  | /workspace.xml | ||||||
|  | artifacts | ||||||
							
								
								
									
										6
									
								
								.idea/AndroidProjectSystem.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,6 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="AndroidProjectSystem"> | ||||||
|  |     <option name="providerId" value="com.android.tools.idea.GradleProjectSystem" /> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										150
									
								
								.idea/codeStyles/Project.xml
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -1,123 +1,43 @@ | |||||||
| <component name="ProjectCodeStyleConfiguration"> | <component name="ProjectCodeStyleConfiguration"> | ||||||
|   <code_scheme name="Project" version="173"> |   <code_scheme name="Project" version="173"> | ||||||
|  |     <JavaCodeStyleSettings> | ||||||
|  |       <option name="IMPORT_LAYOUT_TABLE"> | ||||||
|  |         <value> | ||||||
|  |           <package name="" withSubpackages="true" static="false" module="true" /> | ||||||
|  |           <package name="android" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="androidx" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="com" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="junit" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="net" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="org" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="java" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="javax" withSubpackages="true" static="true" /> | ||||||
|  |           <package name="" withSubpackages="true" static="true" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="android" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="androidx" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="com" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="junit" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="net" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="org" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="java" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="javax" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |           <package name="" withSubpackages="true" static="false" /> | ||||||
|  |           <emptyLine /> | ||||||
|  |         </value> | ||||||
|  |       </option> | ||||||
|  |     </JavaCodeStyleSettings> | ||||||
|     <JetCodeStyleSettings> |     <JetCodeStyleSettings> | ||||||
|       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> |       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||||||
|     </JetCodeStyleSettings> |     </JetCodeStyleSettings> | ||||||
|     <MarkdownNavigatorCodeStyleSettings> |  | ||||||
|       <option name="RIGHT_MARGIN" value="72" /> |  | ||||||
|     </MarkdownNavigatorCodeStyleSettings> |  | ||||||
|     <codeStyleSettings language="XML"> |  | ||||||
|       <indentOptions> |  | ||||||
|         <option name="CONTINUATION_INDENT_SIZE" value="4" /> |  | ||||||
|       </indentOptions> |  | ||||||
|       <arrangement> |  | ||||||
|         <rules> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>xmlns:android</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>xmlns:.*</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|               <order>BY_NAME</order> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>.*:id</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>.*:name</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>name</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>style</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>.*</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>^$</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|               <order>BY_NAME</order> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>.*</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|               <order>ANDROID_ATTRIBUTE_ORDER</order> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|           <section> |  | ||||||
|             <rule> |  | ||||||
|               <match> |  | ||||||
|                 <AND> |  | ||||||
|                   <NAME>.*</NAME> |  | ||||||
|                   <XML_ATTRIBUTE /> |  | ||||||
|                   <XML_NAMESPACE>.*</XML_NAMESPACE> |  | ||||||
|                 </AND> |  | ||||||
|               </match> |  | ||||||
|               <order>BY_NAME</order> |  | ||||||
|             </rule> |  | ||||||
|           </section> |  | ||||||
|         </rules> |  | ||||||
|       </arrangement> |  | ||||||
|     </codeStyleSettings> |  | ||||||
|     <codeStyleSettings language="kotlin"> |     <codeStyleSettings language="kotlin"> | ||||||
|       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> |       <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> | ||||||
|     </codeStyleSettings> |     </codeStyleSettings> | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -1,19 +1,17 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project version="4"> | <project version="4"> | ||||||
|  |   <component name="GradleMigrationSettings" migrationVersion="1" /> | ||||||
|   <component name="GradleSettings"> |   <component name="GradleSettings"> | ||||||
|     <option name="linkedExternalProjectsSettings"> |     <option name="linkedExternalProjectsSettings"> | ||||||
|       <GradleProjectSettings> |       <GradleProjectSettings> | ||||||
|         <option name="distributionType" value="DEFAULT_WRAPPED" /> |         <option name="testRunner" value="CHOOSE_PER_TEST" /> | ||||||
|         <option name="externalProjectPath" value="$PROJECT_DIR$" /> |         <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||||||
|  |         <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> | ||||||
|         <option name="modules"> |         <option name="modules"> | ||||||
|           <set> |           <set> | ||||||
|             <option value="$PROJECT_DIR$" /> |             <option value="$PROJECT_DIR$" /> | ||||||
|             <option value="$PROJECT_DIR$/app" /> |  | ||||||
|             <option value="$PROJECT_DIR$/treedatastructure" /> |  | ||||||
|           </set> |           </set> | ||||||
|         </option> |         </option> | ||||||
|         <option name="resolveModulePerSourceSet" value="false" /> |  | ||||||
|         <option name="testRunner" value="PLATFORM" /> |  | ||||||
|       </GradleProjectSettings> |       </GradleProjectSettings> | ||||||
|     </option> |     </option> | ||||||
|   </component> |   </component> | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.idea/inspectionProfiles/Project_Default.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,6 @@ | |||||||
|  | <component name="InspectionProjectProfileManager"> | ||||||
|  |   <profile version="1.0"> | ||||||
|  |     <option name="myName" value="Project Default" /> | ||||||
|  |     <inspection_tool class="ReplaceUntilWithRangeUntil" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> | ||||||
|  |   </profile> | ||||||
|  | </component> | ||||||
							
								
								
									
										8
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -1,9 +1,7 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||||
| <project version="4"> | <project version="4"> | ||||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> |   <component name="ExternalStorageConfigurationManager" enabled="true" /> | ||||||
|     <output url="file://$PROJECT_DIR$/build/classes" /> |   <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> | ||||||
|   </component> |     <output url="file://$PROJECT_DIR$/out" /> | ||||||
|   <component name="ProjectType"> |  | ||||||
|     <option name="id" value="Android" /> |  | ||||||
|   </component> |   </component> | ||||||
| </project> | </project> | ||||||
							
								
								
									
										11
									
								
								.idea/runConfigurations.xml
									
									
									
										generated
									
									
									
								
							
							
						
						| @@ -3,9 +3,14 @@ | |||||||
|   <component name="RunConfigurationProducerService"> |   <component name="RunConfigurationProducerService"> | ||||||
|     <option name="ignoredProducers"> |     <option name="ignoredProducers"> | ||||||
|       <set> |       <set> | ||||||
|         <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" /> |         <option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" /> | ||||||
|         <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" /> |         <option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" /> | ||||||
|         <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" /> |         <option value="com.intellij.execution.junit.PatternConfigurationProducer" /> | ||||||
|  |         <option value="com.intellij.execution.junit.TestInClassConfigurationProducer" /> | ||||||
|  |         <option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" /> | ||||||
|  |         <option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" /> | ||||||
|  |         <option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" /> | ||||||
|  |         <option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" /> | ||||||
|       </set> |       </set> | ||||||
|     </option> |     </option> | ||||||
|   </component> |   </component> | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.idea/studiobot.xml
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,6 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <project version="4"> | ||||||
|  |   <component name="StudioBotProjectSettings"> | ||||||
|  |     <option name="shareContext" value="OptedIn" /> | ||||||
|  |   </component> | ||||||
|  | </project> | ||||||
							
								
								
									
										116
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -1,9 +1,40 @@ | |||||||
| # Tree (Data Structure) | # Tree (Data Structure) | ||||||
| [](https://mvnrepository.com/artifact/com.github.adriankuta/tree-structure) | [](https://mvnrepository.com/artifact/com.github.adriankuta/tree-structure) | ||||||
| [](https://github.com/AdrianKuta/Design-Patterns-Kotlin/blob/master/LICENSE) | [](https://github.com/AdrianKuta/Tree-Data-Structure/blob/master/LICENSE) | ||||||
| [](https://circleci.com/gh/AdrianKuta/Tree-Data-Structure) | [](https://github.com/AdrianKuta/Tree-Data-Structure/actions/workflows/publishRelease.yml) | ||||||
|  |  | ||||||
| Simple implementation to store object in tree structure. Method `toString()` is overrided to provide nice tree view in logs. | Lightweight Kotlin Multiplatform tree data structure for Kotlin and Java. Includes a small DSL, multiple traversal iterators, and pretty-print support. | ||||||
|  |  | ||||||
|  | - Kotlin Multiplatform (JVM, JS, iOS, and Native host) | ||||||
|  | - Pre-order, Post-order, and Level-order iteration | ||||||
|  | - Simple DSL: tree { child(...) } | ||||||
|  | - Utilities: nodeCount(), height(), depth(), path(), prettyString(), clear(), removeChild() | ||||||
|  |  | ||||||
|  | ## Installation | ||||||
|  |  | ||||||
|  | Gradle (Kotlin DSL): | ||||||
|  | ```kotlin | ||||||
|  | // commonMain for KMP projects, or any sourceSet/module where you need it | ||||||
|  | dependencies { | ||||||
|  |     implementation("com.github.adriankuta:tree-structure:3.1.1") // see badge above for the latest version | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Gradle (Groovy): | ||||||
|  | ```groovy | ||||||
|  | dependencies { | ||||||
|  |     implementation "com.github.adriankuta:tree-structure:3.1.1" // see badge above for the latest | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Maven: | ||||||
|  | ```xml | ||||||
|  | <dependency> | ||||||
|  |   <groupId>com.github.adriankuta</groupId> | ||||||
|  |   <artifactId>tree-structure</artifactId> | ||||||
|  |   <version>3.1.1</version> | ||||||
|  | </dependency> | ||||||
|  | ``` | ||||||
|  |  | ||||||
| ## Usage | ## Usage | ||||||
|  |  | ||||||
| @@ -22,22 +53,18 @@ val poland = TreeNode("Poland") | |||||||
| val france = TreeNode("France") | val france = TreeNode("France") | ||||||
| europe.addChild(poland) | europe.addChild(poland) | ||||||
| europe.addChild(france) | europe.addChild(france) | ||||||
| println(root) | println(root.prettyString()) | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| **Pretty Kotlin** | **Pretty Kotlin (DSL)** | ||||||
|  |  | ||||||
| ```kotlin | ```kotlin | ||||||
| val root = | val root = tree("World") { | ||||||
|     tree("World") { |     child("North America") { child("USA") } | ||||||
|         child("North America") { |     child("Europe") { | ||||||
|             child("USA") |         child("Poland") | ||||||
|         } |         child("Germany") | ||||||
|         child("Europe") { |  | ||||||
|             child("Poland") |  | ||||||
|             child("Germany") |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  | } | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| **Java** | **Java** | ||||||
| @@ -55,11 +82,10 @@ TreeNode<String> poland = new TreeNode<>("Poland"); | |||||||
| TreeNode<String> france = new TreeNode<>("France"); | TreeNode<String> france = new TreeNode<>("France"); | ||||||
| europe.addChild(poland); | europe.addChild(poland); | ||||||
| europe.addChild(france); | europe.addChild(france); | ||||||
| System.out.println(root); | System.out.println(root.prettyString()); | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| *Output:* | Output: | ||||||
|  |  | ||||||
| ``` | ``` | ||||||
| World | World | ||||||
| ├── North America | ├── North America | ||||||
| @@ -69,10 +95,58 @@ World | |||||||
|     └── France |     └── France | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | ### Traversal and utilities | ||||||
|  | ```kotlin | ||||||
|  | val root = TreeNode("root") | ||||||
|  | // ... build your tree | ||||||
|  |  | ||||||
| ## Download | // Choose iteration order (default is PreOrder) | ||||||
|  | root.treeIterator = TreeNodeIterators.PostOrder | ||||||
|  | for (node in root) println(node.value) | ||||||
|  |  | ||||||
|     implementation "com.github.adriankuta:tree-structure:$latest_versions" | // Utilities | ||||||
|  | root.nodeCount()   // number of descendants | ||||||
|  | root.height()      // longest path to a leaf (in edges) | ||||||
|  | root.depth()       // distance from current node to the root | ||||||
|  | val path = root.path(root.children.first()) // nodes from descendant up to root | ||||||
|  |  | ||||||
|  | // Mutations | ||||||
|  | val child = root.children.first() | ||||||
|  | root.removeChild(child) | ||||||
|  | root.clear()       // remove entire subtree | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Publishing to Maven Central (central.sonatype.com) | ||||||
|  |  | ||||||
|  | This project is configured to publish artifacts to Maven Central via the Sonatype Central Portal. | ||||||
|  |  | ||||||
|  | There are two supported ways to publish: | ||||||
|  |  | ||||||
|  | 1) Via GitHub Actions (recommended) | ||||||
|  | - Create a GitHub Release (tag) in this repository. When a release is published, the workflow .github/workflows/publishRelease.yml runs automatically. | ||||||
|  | - The workflow uses the Gradle task publishToMavenCentral to upload artifacts through the Central Portal. | ||||||
|  | - Make sure these repository secrets are configured in GitHub: | ||||||
|  |   - MAVEN_CENTRAL_USERNAME — Your Sonatype Central username (not email). | ||||||
|  |   - MAVEN_CENTRAL_PASSWORD — Your Sonatype Central password or a token from central.sonatype.com. | ||||||
|  |   - SIGNING_KEY — ASCII‑armored GPG private key (exported, single line; for in‑memory signing). | ||||||
|  |   - SIGNING_PASSWORD — Passphrase for the key above. | ||||||
|  | - The workflow uses JDK 21 and publishes the version defined in build.gradle.kts. | ||||||
|  |  | ||||||
|  | 2) Locally via Gradle | ||||||
|  | - Ensure you have a Sonatype Central account and that the groupId com.github.adriankuta is verified in central.sonatype.com (Namespace Rules → Verify). | ||||||
|  | - Export the same credentials/signing values as environment variables or pass them as Gradle properties: | ||||||
|  |   - ORG_GRADLE_PROJECT_mavenCentralUsername | ||||||
|  |   - ORG_GRADLE_PROJECT_mavenCentralPassword | ||||||
|  |   - ORG_GRADLE_PROJECT_signingInMemoryKey | ||||||
|  |   - ORG_GRADLE_PROJECT_signingInMemoryKeyPassword | ||||||
|  | - Then run: | ||||||
|  |   - ./gradlew publishToMavenCentral | ||||||
|  | - For snapshot publishing, set -Psnapshot=true (the version is derived from PUBLISH_VERSION with -SNAPSHOT). | ||||||
|  |  | ||||||
|  | Notes | ||||||
|  | - Publishing is powered by the com.vanniktech.maven.publish Gradle plugin and Sonatype Central Portal (no legacy Nexus staging URLs needed). | ||||||
|  | - The plugin is configured to sign all publications. Coordinates and POM metadata are defined in build.gradle.kts. | ||||||
|  | - If using the combined task is preferred, you can also run publishAndReleaseToMavenCentral when automatic release is enabled; this repository currently uploads with publishToMavenCentral from CI. | ||||||
|  |  | ||||||
| ## License | ## License | ||||||
|  |  | ||||||
| @@ -97,3 +171,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 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 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
| SOFTWARE. | SOFTWARE. | ||||||
|  |  | ||||||
|  | --- | ||||||
|   | |||||||
| @@ -1,3 +0,0 @@ | |||||||
| theme: jekyll-theme-minimal |  | ||||||
| title: Tree Data Structure |  | ||||||
| logo: images/console_output.png |  | ||||||
							
								
								
									
										1
									
								
								app/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1 +0,0 @@ | |||||||
| /build |  | ||||||
| @@ -1,35 +0,0 @@ | |||||||
| apply plugin: 'com.android.application' |  | ||||||
|  |  | ||||||
| apply plugin: 'kotlin-android' |  | ||||||
|  |  | ||||||
| apply plugin: 'kotlin-android-extensions' |  | ||||||
|  |  | ||||||
| android { |  | ||||||
|     compileSdkVersion 29 |  | ||||||
|     buildToolsVersion "29.0.2" |  | ||||||
|     defaultConfig { |  | ||||||
|         applicationId "com.github.adriankuta.treedatastructure" |  | ||||||
|         minSdkVersion 15 |  | ||||||
|         targetSdkVersion 29 |  | ||||||
|         versionCode 1 |  | ||||||
|         versionName "1.0" |  | ||||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |  | ||||||
|     } |  | ||||||
|     buildTypes { |  | ||||||
|         release { |  | ||||||
|             minifyEnabled false |  | ||||||
|             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| dependencies { |  | ||||||
|     implementation fileTree(dir: 'libs', include: ['*.jar']) |  | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" |  | ||||||
|     implementation 'androidx.appcompat:appcompat:1.1.0' |  | ||||||
|     implementation 'androidx.core:core-ktx:1.1.0' |  | ||||||
|     implementation 'androidx.constraintlayout:constraintlayout:1.1.3' |  | ||||||
|     testImplementation 'junit:junit:4.12' |  | ||||||
|     androidTestImplementation 'androidx.test.ext:junit:1.1.1' |  | ||||||
|     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' |  | ||||||
| } |  | ||||||
							
								
								
									
										21
									
								
								app/proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,21 +0,0 @@ | |||||||
| # Add project specific ProGuard rules here. |  | ||||||
| # You can control the set of applied configuration files using the |  | ||||||
| # proguardFiles setting in build.gradle. |  | ||||||
| # |  | ||||||
| # For more details, see |  | ||||||
| #   http://developer.android.com/guide/developing/tools/proguard.html |  | ||||||
|  |  | ||||||
| # If your project uses WebView with JS, uncomment the following |  | ||||||
| # and specify the fully qualified class name to the JavaScript interface |  | ||||||
| # class: |  | ||||||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { |  | ||||||
| #   public *; |  | ||||||
| #} |  | ||||||
|  |  | ||||||
| # Uncomment this to preserve the line number information for |  | ||||||
| # debugging stack traces. |  | ||||||
| #-keepattributes SourceFile,LineNumberTable |  | ||||||
|  |  | ||||||
| # If you keep the line number information, uncomment this to |  | ||||||
| # hide the original source file name. |  | ||||||
| #-renamesourcefileattribute SourceFile |  | ||||||
| @@ -1,24 +0,0 @@ | |||||||
| package com.github.adriankuta.treedatastructure |  | ||||||
|  |  | ||||||
| import androidx.test.platform.app.InstrumentationRegistry |  | ||||||
| import androidx.test.ext.junit.runners.AndroidJUnit4 |  | ||||||
|  |  | ||||||
| import org.junit.Test |  | ||||||
| import org.junit.runner.RunWith |  | ||||||
|  |  | ||||||
| import org.junit.Assert.* |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Instrumented test, which will execute on an Android device. |  | ||||||
|  * |  | ||||||
|  * See [testing documentation](http://d.android.com/tools/testing). |  | ||||||
|  */ |  | ||||||
| @RunWith(AndroidJUnit4::class) |  | ||||||
| class ExampleInstrumentedTest { |  | ||||||
|     @Test |  | ||||||
|     fun useAppContext() { |  | ||||||
|         // Context of the app under test. |  | ||||||
|         val appContext = InstrumentationRegistry.getInstrumentation().targetContext |  | ||||||
|         assertEquals("com.github.adriankuta.treedatastructure", appContext.packageName) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     package="com.github.adriankuta.treedatastructure"> |  | ||||||
|  |  | ||||||
|     <application |  | ||||||
|         android:allowBackup="true" |  | ||||||
|         android:icon="@mipmap/ic_launcher" |  | ||||||
|         android:label="@string/app_name" |  | ||||||
|         android:roundIcon="@mipmap/ic_launcher_round" |  | ||||||
|         android:supportsRtl="true" |  | ||||||
|         android:theme="@style/AppTheme"> |  | ||||||
|         <activity android:name=".MainActivity"> |  | ||||||
|             <intent-filter> |  | ||||||
|                 <action android:name="android.intent.action.MAIN" /> |  | ||||||
|  |  | ||||||
|                 <category android:name="android.intent.category.LAUNCHER" /> |  | ||||||
|             </intent-filter> |  | ||||||
|         </activity> |  | ||||||
|     </application> |  | ||||||
|  |  | ||||||
| </manifest> |  | ||||||
| @@ -1,12 +0,0 @@ | |||||||
| package com.github.adriankuta.treedatastructure |  | ||||||
|  |  | ||||||
| import androidx.appcompat.app.AppCompatActivity |  | ||||||
| import android.os.Bundle |  | ||||||
|  |  | ||||||
| class MainActivity : AppCompatActivity() { |  | ||||||
|  |  | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |  | ||||||
|         super.onCreate(savedInstanceState) |  | ||||||
|         setContentView(R.layout.activity_main) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,34 +0,0 @@ | |||||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     xmlns:aapt="http://schemas.android.com/aapt" |  | ||||||
|     android:width="108dp" |  | ||||||
|     android:height="108dp" |  | ||||||
|     android:viewportWidth="108" |  | ||||||
|     android:viewportHeight="108"> |  | ||||||
|     <path |  | ||||||
|         android:fillType="evenOdd" |  | ||||||
|         android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z" |  | ||||||
|         android:strokeWidth="1" |  | ||||||
|         android:strokeColor="#00000000"> |  | ||||||
|         <aapt:attr name="android:fillColor"> |  | ||||||
|             <gradient |  | ||||||
|                 android:endX="78.5885" |  | ||||||
|                 android:endY="90.9159" |  | ||||||
|                 android:startX="48.7653" |  | ||||||
|                 android:startY="61.0927" |  | ||||||
|                 android:type="linear"> |  | ||||||
|                 <item |  | ||||||
|                     android:color="#44000000" |  | ||||||
|                     android:offset="0.0" /> |  | ||||||
|                 <item |  | ||||||
|                     android:color="#00000000" |  | ||||||
|                     android:offset="1.0" /> |  | ||||||
|             </gradient> |  | ||||||
|         </aapt:attr> |  | ||||||
|     </path> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#FFFFFF" |  | ||||||
|         android:fillType="nonZero" |  | ||||||
|         android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" |  | ||||||
|         android:strokeWidth="1" |  | ||||||
|         android:strokeColor="#00000000" /> |  | ||||||
| </vector> |  | ||||||
| @@ -1,170 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     android:width="108dp" |  | ||||||
|     android:height="108dp" |  | ||||||
|     android:viewportWidth="108" |  | ||||||
|     android:viewportHeight="108"> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#008577" |  | ||||||
|         android:pathData="M0,0h108v108h-108z" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M9,0L9,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,0L19,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M29,0L29,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M39,0L39,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M49,0L49,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M59,0L59,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M69,0L69,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M79,0L79,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M89,0L89,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M99,0L99,108" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,9L108,9" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,19L108,19" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,29L108,29" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,39L108,39" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,49L108,49" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,59L108,59" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,69L108,69" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,79L108,79" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,89L108,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M0,99L108,99" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,29L89,29" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,39L89,39" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,49L89,49" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,59L89,59" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,69L89,69" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M19,79L89,79" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M29,19L29,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M39,19L39,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M49,19L49,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M59,19L59,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M69,19L69,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
|     <path |  | ||||||
|         android:fillColor="#00000000" |  | ||||||
|         android:pathData="M79,19L79,89" |  | ||||||
|         android:strokeWidth="0.8" |  | ||||||
|         android:strokeColor="#33FFFFFF" /> |  | ||||||
| </vector> |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |  | ||||||
|     xmlns:tools="http://schemas.android.com/tools" |  | ||||||
|     android:layout_width="match_parent" |  | ||||||
|     android:layout_height="match_parent" |  | ||||||
|     tools:context=".MainActivity"> |  | ||||||
|  |  | ||||||
|     <TextView |  | ||||||
|         android:layout_width="wrap_content" |  | ||||||
|         android:layout_height="wrap_content" |  | ||||||
|         android:text="Hello World!" |  | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |  | ||||||
|         app:layout_constraintLeft_toLeftOf="parent" |  | ||||||
|         app:layout_constraintRight_toRightOf="parent" |  | ||||||
|         app:layout_constraintTop_toTopOf="parent" /> |  | ||||||
|  |  | ||||||
| </androidx.constraintlayout.widget.ConstraintLayout> |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |  | ||||||
|     <background android:drawable="@drawable/ic_launcher_background" /> |  | ||||||
|     <foreground android:drawable="@drawable/ic_launcher_foreground" /> |  | ||||||
| </adaptive-icon> |  | ||||||
| @@ -1,5 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> |  | ||||||
|     <background android:drawable="@drawable/ic_launcher_background" /> |  | ||||||
|     <foreground android:drawable="@drawable/ic_launcher_foreground" /> |  | ||||||
| </adaptive-icon> |  | ||||||
| Before Width: | Height: | Size: 2.9 KiB | 
| Before Width: | Height: | Size: 4.8 KiB | 
| Before Width: | Height: | Size: 2.0 KiB | 
| Before Width: | Height: | Size: 2.7 KiB | 
| Before Width: | Height: | Size: 4.4 KiB | 
| Before Width: | Height: | Size: 6.7 KiB | 
| Before Width: | Height: | Size: 6.2 KiB | 
| Before Width: | Height: | Size: 10 KiB | 
| Before Width: | Height: | Size: 8.9 KiB | 
| Before Width: | Height: | Size: 15 KiB | 
| @@ -1,6 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <resources> |  | ||||||
|     <color name="colorPrimary">#008577</color> |  | ||||||
|     <color name="colorPrimaryDark">#00574B</color> |  | ||||||
|     <color name="colorAccent">#D81B60</color> |  | ||||||
| </resources> |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| <resources> |  | ||||||
|     <string name="app_name">Tree Data Structure</string> |  | ||||||
| </resources> |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| <resources> |  | ||||||
|  |  | ||||||
|     <!-- Base application theme. --> |  | ||||||
|     <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> |  | ||||||
|         <!-- Customize your theme here. --> |  | ||||||
|         <item name="colorPrimary">@color/colorPrimary</item> |  | ||||||
|         <item name="colorPrimaryDark">@color/colorPrimaryDark</item> |  | ||||||
|         <item name="colorAccent">@color/colorAccent</item> |  | ||||||
|     </style> |  | ||||||
|  |  | ||||||
| </resources> |  | ||||||
| @@ -1,17 +0,0 @@ | |||||||
| package com.github.adriankuta.treedatastructure |  | ||||||
|  |  | ||||||
| import org.junit.Test |  | ||||||
|  |  | ||||||
| import org.junit.Assert.* |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Example local unit test, which will execute on the development machine (host). |  | ||||||
|  * |  | ||||||
|  * See [testing documentation](http://d.android.com/tools/testing). |  | ||||||
|  */ |  | ||||||
| class ExampleUnitTest { |  | ||||||
|     @Test |  | ||||||
|     fun addition_isCorrect() { |  | ||||||
|         assertEquals(4, 2 + 2) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										31
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						| @@ -1,31 +0,0 @@ | |||||||
| // Top-level build file where you can add configuration options common to all sub-projects/modules. |  | ||||||
|  |  | ||||||
| buildscript { |  | ||||||
|     ext.kotlin_version = '1.3.61' |  | ||||||
|     repositories { |  | ||||||
|         google() |  | ||||||
|         jcenter() |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|     dependencies { |  | ||||||
|         classpath 'com.android.tools.build:gradle:3.5.3' |  | ||||||
|         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |  | ||||||
|         classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.2" |  | ||||||
|         // NOTE: Do not place your application dependencies here; they belong |  | ||||||
|         // in the individual module build.gradle files |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| allprojects { |  | ||||||
|     repositories { |  | ||||||
|         google() |  | ||||||
|         jcenter() |  | ||||||
|  |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| task clean(type: Delete) { |  | ||||||
|     delete rootProject.buildDir |  | ||||||
| } |  | ||||||
|  |  | ||||||
| apply plugin: 'io.codearte.nexus-staging' |  | ||||||
							
								
								
									
										115
									
								
								build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,115 @@ | |||||||
|  | import org.jetbrains.kotlin.konan.properties.Properties | ||||||
|  |  | ||||||
|  | plugins { | ||||||
|  |     kotlin("multiplatform") version "1.9.20" | ||||||
|  |     id("org.jetbrains.dokka") version "1.9.20" | ||||||
|  |     id("com.vanniktech.maven.publish") version "0.34.0" | ||||||
|  |     signing | ||||||
|  | } | ||||||
|  |  | ||||||
|  | val PUBLISH_GROUP_ID = "com.github.adriankuta" | ||||||
|  | val PUBLISH_ARTIFACT_ID = "tree-structure"    // base artifact; KMP will add -jvm, -ios*, etc. | ||||||
|  | val PUBLISH_VERSION = "3.1.2" | ||||||
|  |  | ||||||
|  | val snapshot: String? by project | ||||||
|  |  | ||||||
|  | group = PUBLISH_GROUP_ID | ||||||
|  | version = if (snapshot.toBoolean()) "$PUBLISH_VERSION-SNAPSHOT" else PUBLISH_VERSION | ||||||
|  |  | ||||||
|  | mavenPublishing { | ||||||
|  |     // Central Portal + auto release when we call publishAndReleaseToMavenCentral | ||||||
|  |     publishToMavenCentral(automaticRelease = false) | ||||||
|  |     signAllPublications() | ||||||
|  |  | ||||||
|  |     coordinates(PUBLISH_GROUP_ID, PUBLISH_ARTIFACT_ID, version.toString()) | ||||||
|  |  | ||||||
|  |     pom { | ||||||
|  |         name.set("Tree Data Structure") | ||||||
|  |         description.set("Simple implementation to store object in tree structure.") | ||||||
|  |         url.set("https://github.com/AdrianKuta/Tree-Data-Structure") | ||||||
|  |  | ||||||
|  |         licenses { | ||||||
|  |             license { | ||||||
|  |                 name.set("MIT License") | ||||||
|  |                 url.set("https://opensource.org/licenses/MIT") | ||||||
|  |                 distribution.set("repo") | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         developers { | ||||||
|  |             developer { | ||||||
|  |                 id.set("AdrianKuta") | ||||||
|  |                 name.set("Adrian Kuta") | ||||||
|  |                 email.set("adrian.kuta93@gmail.com") | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         scm { | ||||||
|  |             url.set("https://github.com/AdrianKuta/Tree-Data-Structure") | ||||||
|  |             connection.set("scm:git:https://github.com/AdrianKuta/Tree-Data-Structure.git") | ||||||
|  |             developerConnection.set("scm:git:ssh://git@github.com/AdrianKuta/Tree-Data-Structure.git") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // No legacy publishing {} block or s01 repos — Central Portal handles it. | ||||||
|  |  | ||||||
|  | repositories { | ||||||
|  |     mavenCentral() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | java { | ||||||
|  |     toolchain { | ||||||
|  |         languageVersion.set(JavaLanguageVersion.of(21)) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | kotlin { | ||||||
|  |     jvmToolchain(21); | ||||||
|  |     jvm { | ||||||
|  |         compilations.all { | ||||||
|  |             kotlinOptions { | ||||||
|  |                 jvmTarget = "21"   // <- was "1.8" | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // JS targets (IR) for publishing | ||||||
|  |     js(IR) { | ||||||
|  |         browser() | ||||||
|  |         nodejs() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // iOS targets | ||||||
|  |     iosX64() | ||||||
|  |     iosArm64() | ||||||
|  |     iosSimulatorArm64() | ||||||
|  |  | ||||||
|  |     // Native host target | ||||||
|  |     val hostOs = System.getProperty("os.name") | ||||||
|  |     val isMingwX64 = hostOs.startsWith("Windows") | ||||||
|  |     val nativeTarget = when { | ||||||
|  |         hostOs == "Mac OS X" -> macosX64("native") | ||||||
|  |         hostOs == "Linux" -> linuxX64("native") | ||||||
|  |         isMingwX64 -> mingwX64("native") | ||||||
|  |         else -> throw GradleException("Host OS is not supported in Kotlin/Native.") | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     sourceSets { | ||||||
|  |         val commonMain by getting | ||||||
|  |         val commonTest by getting { dependencies { implementation(kotlin("test")) } } | ||||||
|  |         val jvmMain by getting { dependencies { implementation(kotlin("script-runtime")) } } | ||||||
|  |         val jvmTest by getting | ||||||
|  |         val jsMain by getting | ||||||
|  |         val jsTest by getting | ||||||
|  |         val nativeMain by getting | ||||||
|  |         val nativeTest by getting | ||||||
|  |  | ||||||
|  |         // Shared iOS source sets | ||||||
|  |         val iosMain by creating { dependsOn(commonMain) } | ||||||
|  |         val iosTest by creating { dependsOn(commonTest) } | ||||||
|  |         val iosX64Main by getting { dependsOn(iosMain) } | ||||||
|  |         val iosArm64Main by getting { dependsOn(iosMain) } | ||||||
|  |         val iosSimulatorArm64Main by getting { dependsOn(iosMain) } | ||||||
|  |         val iosX64Test by getting { dependsOn(iosTest) } | ||||||
|  |         val iosArm64Test by getting { dependsOn(iosTest) } | ||||||
|  |         val iosSimulatorArm64Test by getting { dependsOn(iosTest) } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,21 +1,2 @@ | |||||||
| # Project-wide Gradle settings. |  | ||||||
| # IDE (e.g. Android Studio) users: |  | ||||||
| # Gradle settings configured through the IDE *will override* |  | ||||||
| # any settings specified in this file. |  | ||||||
| # For more details on how to configure your build environment visit |  | ||||||
| # http://www.gradle.org/docs/current/userguide/build_environment.html |  | ||||||
| # Specifies the JVM arguments used for the daemon process. |  | ||||||
| # The setting is particularly useful for tweaking memory settings. |  | ||||||
| org.gradle.jvmargs=-Xmx1536m |  | ||||||
| # When configured, Gradle will run in incubating parallel mode. |  | ||||||
| # This option should only be used with decoupled projects. More details, visit |  | ||||||
| # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects |  | ||||||
| # org.gradle.parallel=true |  | ||||||
| # AndroidX package structure to make it clearer which packages are bundled with the |  | ||||||
| # Android operating system, and which are packaged with your app's APK |  | ||||||
| # https://developer.android.com/topic/libraries/support-library/androidx-rn |  | ||||||
| android.useAndroidX=true |  | ||||||
| # Automatically convert third-party libraries to use AndroidX |  | ||||||
| android.enableJetifier=true |  | ||||||
| # Kotlin code style for this project: "official" or "obsolete": |  | ||||||
| kotlin.code.style=official | kotlin.code.style=official | ||||||
|  | kotlin.js.compiler=ir | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
							
						
						
							
								
								
									
										5
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,6 +1,7 @@ | |||||||
| #Wed Jan 08 12:28:15 CET 2020 |  | ||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
|  | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip | ||||||
|  | networkTimeout=10000 | ||||||
|  | validateDistributionUrl=true | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip |  | ||||||
|   | |||||||
							
								
								
									
										309
									
								
								gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,78 +1,127 @@ | |||||||
| #!/usr/bin/env sh | #!/bin/sh | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # Copyright © 2015-2021 the original authors. | ||||||
|  | # | ||||||
|  | # Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | # you may not use this file except in compliance with the License. | ||||||
|  | # You may obtain a copy of the License at | ||||||
|  | # | ||||||
|  | #      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | # | ||||||
|  | # Unless required by applicable law or agreed to in writing, software | ||||||
|  | # distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | # See the License for the specific language governing permissions and | ||||||
|  | # limitations under the License. | ||||||
|  | # | ||||||
|  |  | ||||||
| ############################################################################## | ############################################################################## | ||||||
| ## | # | ||||||
| ##  Gradle start up script for UN*X | #   Gradle start up script for POSIX generated by Gradle. | ||||||
| ## | # | ||||||
|  | #   Important for running: | ||||||
|  | # | ||||||
|  | #   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is | ||||||
|  | #       noncompliant, but you have some other compliant shell such as ksh or | ||||||
|  | #       bash, then to run this script, type that shell name before the whole | ||||||
|  | #       command line, like: | ||||||
|  | # | ||||||
|  | #           ksh Gradle | ||||||
|  | # | ||||||
|  | #       Busybox and similar reduced shells will NOT work, because this script | ||||||
|  | #       requires all of these POSIX shell features: | ||||||
|  | #         * functions; | ||||||
|  | #         * expansions «$var», «${var}», «${var:-default}», «${var+SET}», | ||||||
|  | #           «${var#prefix}», «${var%suffix}», and «$( cmd )»; | ||||||
|  | #         * compound commands having a testable exit status, especially «case»; | ||||||
|  | #         * various built-in commands including «command», «set», and «ulimit». | ||||||
|  | # | ||||||
|  | #   Important for patching: | ||||||
|  | # | ||||||
|  | #   (2) This script targets any POSIX shell, so it avoids extensions provided | ||||||
|  | #       by Bash, Ksh, etc; in particular arrays are avoided. | ||||||
|  | # | ||||||
|  | #       The "traditional" practice of packing multiple parameters into a | ||||||
|  | #       space-separated string is a well documented source of bugs and security | ||||||
|  | #       problems, so this is (mostly) avoided, by progressively accumulating | ||||||
|  | #       options in "$@", and eventually passing that to Java. | ||||||
|  | # | ||||||
|  | #       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, | ||||||
|  | #       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; | ||||||
|  | #       see the in-line comments for details. | ||||||
|  | # | ||||||
|  | #       There are tweaks for specific operating systems such as AIX, CygWin, | ||||||
|  | #       Darwin, MinGW, and NonStop. | ||||||
|  | # | ||||||
|  | #   (3) This script is generated from the Groovy template | ||||||
|  | #       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt | ||||||
|  | #       within the Gradle project. | ||||||
|  | # | ||||||
|  | #       You can find Gradle at https://github.com/gradle/gradle/. | ||||||
|  | # | ||||||
| ############################################################################## | ############################################################################## | ||||||
|  |  | ||||||
| # Attempt to set APP_HOME | # Attempt to set APP_HOME | ||||||
|  |  | ||||||
| # Resolve links: $0 may be a link | # Resolve links: $0 may be a link | ||||||
| PRG="$0" | app_path=$0 | ||||||
| # Need this for relative symlinks. |  | ||||||
| while [ -h "$PRG" ] ; do | # Need this for daisy-chained symlinks. | ||||||
|     ls=`ls -ld "$PRG"` | while | ||||||
|     link=`expr "$ls" : '.*-> \(.*\)$'` |     APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path | ||||||
|     if expr "$link" : '/.*' > /dev/null; then |     [ -h "$app_path" ] | ||||||
|         PRG="$link" | do | ||||||
|     else |     ls=$( ls -ld "$app_path" ) | ||||||
|         PRG=`dirname "$PRG"`"/$link" |     link=${ls#*' -> '} | ||||||
|     fi |     case $link in             #( | ||||||
|  |       /*)   app_path=$link ;; #( | ||||||
|  |       *)    app_path=$APP_HOME$link ;; | ||||||
|  |     esac | ||||||
| done | done | ||||||
| SAVED="`pwd`" |  | ||||||
| cd "`dirname \"$PRG\"`/" >/dev/null |  | ||||||
| APP_HOME="`pwd -P`" |  | ||||||
| cd "$SAVED" >/dev/null |  | ||||||
|  |  | ||||||
| APP_NAME="Gradle" | # This is normally unused | ||||||
| APP_BASE_NAME=`basename "$0"` | # shellcheck disable=SC2034 | ||||||
|  | APP_BASE_NAME=${0##*/} | ||||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | ||||||
| DEFAULT_JVM_OPTS="" | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | ||||||
|  |  | ||||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
| MAX_FD="maximum" | MAX_FD=maximum | ||||||
|  |  | ||||||
| warn () { | warn () { | ||||||
|     echo "$*" |     echo "$*" | ||||||
| } | } >&2 | ||||||
|  |  | ||||||
| die () { | die () { | ||||||
|     echo |     echo | ||||||
|     echo "$*" |     echo "$*" | ||||||
|     echo |     echo | ||||||
|     exit 1 |     exit 1 | ||||||
| } | } >&2 | ||||||
|  |  | ||||||
| # OS specific support (must be 'true' or 'false'). | # OS specific support (must be 'true' or 'false'). | ||||||
| cygwin=false | cygwin=false | ||||||
| msys=false | msys=false | ||||||
| darwin=false | darwin=false | ||||||
| nonstop=false | nonstop=false | ||||||
| case "`uname`" in | case "$( uname )" in                #( | ||||||
|   CYGWIN* ) |   CYGWIN* )         cygwin=true  ;; #( | ||||||
|     cygwin=true |   Darwin* )         darwin=true  ;; #( | ||||||
|     ;; |   MSYS* | MINGW* )  msys=true    ;; #( | ||||||
|   Darwin* ) |   NONSTOP* )        nonstop=true ;; | ||||||
|     darwin=true |  | ||||||
|     ;; |  | ||||||
|   MINGW* ) |  | ||||||
|     msys=true |  | ||||||
|     ;; |  | ||||||
|   NONSTOP* ) |  | ||||||
|     nonstop=true |  | ||||||
|     ;; |  | ||||||
| esac | esac | ||||||
|  |  | ||||||
| CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||||||
|  |  | ||||||
|  |  | ||||||
| # Determine the Java command to use to start the JVM. | # Determine the Java command to use to start the JVM. | ||||||
| if [ -n "$JAVA_HOME" ] ; then | if [ -n "$JAVA_HOME" ] ; then | ||||||
|     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then |     if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||||||
|         # IBM's JDK on AIX uses strange locations for the executables |         # IBM's JDK on AIX uses strange locations for the executables | ||||||
|         JAVACMD="$JAVA_HOME/jre/sh/java" |         JAVACMD=$JAVA_HOME/jre/sh/java | ||||||
|     else |     else | ||||||
|         JAVACMD="$JAVA_HOME/bin/java" |         JAVACMD=$JAVA_HOME/bin/java | ||||||
|     fi |     fi | ||||||
|     if [ ! -x "$JAVACMD" ] ; then |     if [ ! -x "$JAVACMD" ] ; then | ||||||
|         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME |         die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||||||
| @@ -81,92 +130,120 @@ Please set the JAVA_HOME variable in your environment to match the | |||||||
| location of your Java installation." | location of your Java installation." | ||||||
|     fi |     fi | ||||||
| else | else | ||||||
|     JAVACMD="java" |     JAVACMD=java | ||||||
|     which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. |     if ! command -v java >/dev/null 2>&1 | ||||||
|  |     then | ||||||
|  |         die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
|  |  | ||||||
| Please set the JAVA_HOME variable in your environment to match the | Please set the JAVA_HOME variable in your environment to match the | ||||||
| location of your Java installation." | location of your Java installation." | ||||||
|  |     fi | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # Increase the maximum file descriptors if we can. | # Increase the maximum file descriptors if we can. | ||||||
| if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | ||||||
|     MAX_FD_LIMIT=`ulimit -H -n` |     case $MAX_FD in #( | ||||||
|     if [ $? -eq 0 ] ; then |       max*) | ||||||
|         if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then |         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. | ||||||
|             MAX_FD="$MAX_FD_LIMIT" |         # shellcheck disable=SC2039,SC3045 | ||||||
|         fi |         MAX_FD=$( ulimit -H -n ) || | ||||||
|         ulimit -n $MAX_FD |             warn "Could not query maximum file descriptor limit" | ||||||
|         if [ $? -ne 0 ] ; then |     esac | ||||||
|             warn "Could not set maximum file descriptor limit: $MAX_FD" |     case $MAX_FD in  #( | ||||||
|         fi |       '' | soft) :;; #( | ||||||
|     else |       *) | ||||||
|         warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" |         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. | ||||||
|     fi |         # shellcheck disable=SC2039,SC3045 | ||||||
| fi |         ulimit -n "$MAX_FD" || | ||||||
|  |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
| # For Darwin, add options to specify how the application appears in the dock |  | ||||||
| if $darwin; then |  | ||||||
|     GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| # For Cygwin, switch paths to Windows format before running java |  | ||||||
| if $cygwin ; then |  | ||||||
|     APP_HOME=`cygpath --path --mixed "$APP_HOME"` |  | ||||||
|     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` |  | ||||||
|     JAVACMD=`cygpath --unix "$JAVACMD"` |  | ||||||
|  |  | ||||||
|     # We build the pattern for arguments to be converted via cygpath |  | ||||||
|     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` |  | ||||||
|     SEP="" |  | ||||||
|     for dir in $ROOTDIRSRAW ; do |  | ||||||
|         ROOTDIRS="$ROOTDIRS$SEP$dir" |  | ||||||
|         SEP="|" |  | ||||||
|     done |  | ||||||
|     OURCYGPATTERN="(^($ROOTDIRS))" |  | ||||||
|     # Add a user-defined pattern to the cygpath arguments |  | ||||||
|     if [ "$GRADLE_CYGPATTERN" != "" ] ; then |  | ||||||
|         OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" |  | ||||||
|     fi |  | ||||||
|     # Now convert the arguments - kludge to limit ourselves to /bin/sh |  | ||||||
|     i=0 |  | ||||||
|     for arg in "$@" ; do |  | ||||||
|         CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` |  | ||||||
|         CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option |  | ||||||
|  |  | ||||||
|         if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition |  | ||||||
|             eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` |  | ||||||
|         else |  | ||||||
|             eval `echo args$i`="\"$arg\"" |  | ||||||
|         fi |  | ||||||
|         i=$((i+1)) |  | ||||||
|     done |  | ||||||
|     case $i in |  | ||||||
|         (0) set -- ;; |  | ||||||
|         (1) set -- "$args0" ;; |  | ||||||
|         (2) set -- "$args0" "$args1" ;; |  | ||||||
|         (3) set -- "$args0" "$args1" "$args2" ;; |  | ||||||
|         (4) set -- "$args0" "$args1" "$args2" "$args3" ;; |  | ||||||
|         (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; |  | ||||||
|         (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; |  | ||||||
|         (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; |  | ||||||
|         (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; |  | ||||||
|         (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; |  | ||||||
|     esac |     esac | ||||||
| fi | fi | ||||||
|  |  | ||||||
| # Escape application args | # Collect all arguments for the java command, stacking in reverse order: | ||||||
| save () { | #   * args from the command line | ||||||
|     for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | #   * the main class name | ||||||
|     echo " " | #   * -classpath | ||||||
| } | #   * -D...appname settings | ||||||
| APP_ARGS=$(save "$@") | #   * --module-path (only if needed) | ||||||
|  | #   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. | ||||||
|  |  | ||||||
| # Collect all arguments for the java command, following the shell quoting and substitution rules | # For Cygwin or MSYS, switch paths to Windows format before running java | ||||||
| eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | if "$cygwin" || "$msys" ; then | ||||||
|  |     APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) | ||||||
|  |     CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) | ||||||
|  |  | ||||||
| # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong |     JAVACMD=$( cygpath --unix "$JAVACMD" ) | ||||||
| if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then |  | ||||||
|   cd "$(dirname "$0")" |     # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||||||
|  |     for arg do | ||||||
|  |         if | ||||||
|  |             case $arg in                                #( | ||||||
|  |               -*)   false ;;                            # don't mess with options #( | ||||||
|  |               /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath | ||||||
|  |                     [ -e "$t" ] ;;                      #( | ||||||
|  |               *)    false ;; | ||||||
|  |             esac | ||||||
|  |         then | ||||||
|  |             arg=$( cygpath --path --ignore --mixed "$arg" ) | ||||||
|  |         fi | ||||||
|  |         # Roll the args list around exactly as many times as the number of | ||||||
|  |         # args, so each arg winds up back in the position where it started, but | ||||||
|  |         # possibly modified. | ||||||
|  |         # | ||||||
|  |         # NB: a `for` loop captures its iteration list before it begins, so | ||||||
|  |         # changing the positional parameters here affects neither the number of | ||||||
|  |         # iterations, nor the values presented in `arg`. | ||||||
|  |         shift                   # remove old arg | ||||||
|  |         set -- "$@" "$arg"      # push replacement arg | ||||||
|  |     done | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  |  | ||||||
|  | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
|  | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
|  |  | ||||||
|  | # Collect all arguments for the java command: | ||||||
|  | #   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, | ||||||
|  | #     and any embedded shellness will be escaped. | ||||||
|  | #   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be | ||||||
|  | #     treated as '${Hostname}' itself on the command line. | ||||||
|  |  | ||||||
|  | set -- \ | ||||||
|  |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|  |         -classpath "$CLASSPATH" \ | ||||||
|  |         org.gradle.wrapper.GradleWrapperMain \ | ||||||
|  |         "$@" | ||||||
|  |  | ||||||
|  | # Stop when "xargs" is not available. | ||||||
|  | if ! command -v xargs >/dev/null 2>&1 | ||||||
|  | then | ||||||
|  |     die "xargs is not available" | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Use "xargs" to parse quoted args. | ||||||
|  | # | ||||||
|  | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. | ||||||
|  | # | ||||||
|  | # In Bash we could simply go: | ||||||
|  | # | ||||||
|  | #   readarray ARGS < <( xargs -n1 <<<"$var" ) && | ||||||
|  | #   set -- "${ARGS[@]}" "$@" | ||||||
|  | # | ||||||
|  | # but POSIX shell has neither arrays nor command substitution, so instead we | ||||||
|  | # post-process each arg (as a line of input to sed) to backslash-escape any | ||||||
|  | # character that might be a shell metacharacter, then use eval to reverse | ||||||
|  | # that process (while maintaining the separation between arguments), and wrap | ||||||
|  | # the whole thing up as a single "set" statement. | ||||||
|  | # | ||||||
|  | # This will of course break if any of these variables contains a newline or | ||||||
|  | # an unmatched quote. | ||||||
|  | # | ||||||
|  |  | ||||||
|  | eval "set -- $( | ||||||
|  |         printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | | ||||||
|  |         xargs -n1 | | ||||||
|  |         sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | | ||||||
|  |         tr '\n' ' ' | ||||||
|  |     )" '"$@"' | ||||||
|  |  | ||||||
| exec "$JAVACMD" "$@" | exec "$JAVACMD" "$@" | ||||||
|   | |||||||
							
								
								
									
										56
									
								
								gradlew.bat
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,4 +1,20 @@ | |||||||
| @if "%DEBUG%" == "" @echo off | @rem | ||||||
|  | @rem Copyright 2015 the original author or authors. | ||||||
|  | @rem | ||||||
|  | @rem Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | @rem you may not use this file except in compliance with the License. | ||||||
|  | @rem You may obtain a copy of the License at | ||||||
|  | @rem | ||||||
|  | @rem      https://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | @rem | ||||||
|  | @rem Unless required by applicable law or agreed to in writing, software | ||||||
|  | @rem distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | @rem See the License for the specific language governing permissions and | ||||||
|  | @rem limitations under the License. | ||||||
|  | @rem | ||||||
|  |  | ||||||
|  | @if "%DEBUG%"=="" @echo off | ||||||
| @rem ########################################################################## | @rem ########################################################################## | ||||||
| @rem | @rem | ||||||
| @rem  Gradle startup script for Windows | @rem  Gradle startup script for Windows | ||||||
| @@ -9,19 +25,23 @@ | |||||||
| if "%OS%"=="Windows_NT" setlocal | if "%OS%"=="Windows_NT" setlocal | ||||||
|  |  | ||||||
| set DIRNAME=%~dp0 | set DIRNAME=%~dp0 | ||||||
| if "%DIRNAME%" == "" set DIRNAME=. | if "%DIRNAME%"=="" set DIRNAME=. | ||||||
|  | @rem This is normally unused | ||||||
| set APP_BASE_NAME=%~n0 | set APP_BASE_NAME=%~n0 | ||||||
| set APP_HOME=%DIRNAME% | set APP_HOME=%DIRNAME% | ||||||
|  |  | ||||||
|  | @rem Resolve any "." and ".." in APP_HOME to make it shorter. | ||||||
|  | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | ||||||
|  |  | ||||||
| @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
| set DEFAULT_JVM_OPTS= | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | ||||||
|  |  | ||||||
| @rem Find java.exe | @rem Find java.exe | ||||||
| if defined JAVA_HOME goto findJavaFromJavaHome | if defined JAVA_HOME goto findJavaFromJavaHome | ||||||
|  |  | ||||||
| set JAVA_EXE=java.exe | set JAVA_EXE=java.exe | ||||||
| %JAVA_EXE% -version >NUL 2>&1 | %JAVA_EXE% -version >NUL 2>&1 | ||||||
| if "%ERRORLEVEL%" == "0" goto init | if %ERRORLEVEL% equ 0 goto execute | ||||||
|  |  | ||||||
| echo. | echo. | ||||||
| echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||||||
| @@ -35,7 +55,7 @@ goto fail | |||||||
| set JAVA_HOME=%JAVA_HOME:"=% | set JAVA_HOME=%JAVA_HOME:"=% | ||||||
| set JAVA_EXE=%JAVA_HOME%/bin/java.exe | set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||||||
|  |  | ||||||
| if exist "%JAVA_EXE%" goto init | if exist "%JAVA_EXE%" goto execute | ||||||
|  |  | ||||||
| echo. | echo. | ||||||
| echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||||||
| @@ -45,38 +65,26 @@ echo location of your Java installation. | |||||||
|  |  | ||||||
| goto fail | goto fail | ||||||
|  |  | ||||||
| :init |  | ||||||
| @rem Get command-line arguments, handling Windows variants |  | ||||||
|  |  | ||||||
| if not "%OS%" == "Windows_NT" goto win9xME_args |  | ||||||
|  |  | ||||||
| :win9xME_args |  | ||||||
| @rem Slurp the command line arguments. |  | ||||||
| set CMD_LINE_ARGS= |  | ||||||
| set _SKIP=2 |  | ||||||
|  |  | ||||||
| :win9xME_args_slurp |  | ||||||
| if "x%~1" == "x" goto execute |  | ||||||
|  |  | ||||||
| set CMD_LINE_ARGS=%* |  | ||||||
|  |  | ||||||
| :execute | :execute | ||||||
| @rem Setup the command line | @rem Setup the command line | ||||||
|  |  | ||||||
| set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||||||
|  |  | ||||||
|  |  | ||||||
| @rem Execute Gradle | @rem Execute Gradle | ||||||
| "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* | ||||||
|  |  | ||||||
| :end | :end | ||||||
| @rem End local scope for the variables with windows NT shell | @rem End local scope for the variables with windows NT shell | ||||||
| if "%ERRORLEVEL%"=="0" goto mainEnd | if %ERRORLEVEL% equ 0 goto mainEnd | ||||||
|  |  | ||||||
| :fail | :fail | ||||||
| rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||||||
| rem the _cmd.exe /c_ return code! | rem the _cmd.exe /c_ return code! | ||||||
| if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | set EXIT_CODE=%ERRORLEVEL% | ||||||
| exit /b 1 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 | ||||||
|  | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% | ||||||
|  | exit /b %EXIT_CODE% | ||||||
|  |  | ||||||
| :mainEnd | :mainEnd | ||||||
| if "%OS%"=="Windows_NT" endlocal | if "%OS%"=="Windows_NT" endlocal | ||||||
|   | |||||||
| Before Width: | Height: | Size: 71 KiB | 
							
								
								
									
										2020
									
								
								kotlin-js-store/yarn.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -1,122 +0,0 @@ | |||||||
| task androidSourcesJar(type: Jar) { |  | ||||||
|     archiveClassifier.set("sources") |  | ||||||
|     from android.sourceSets.main.java.source |  | ||||||
| } |  | ||||||
|  |  | ||||||
| artifacts { |  | ||||||
|     archives androidSourcesJar |  | ||||||
| } |  | ||||||
|  |  | ||||||
| apply plugin: 'maven-publish' |  | ||||||
| apply plugin: 'signing' |  | ||||||
|  |  | ||||||
| group = PUBLISH_GROUP_ID |  | ||||||
| version = PUBLISH_VERSION |  | ||||||
|  |  | ||||||
| ext["signing.keyId"] = '' |  | ||||||
| ext["signing.password"] = '' |  | ||||||
| ext["signing.secretKeyRingFile"] = '' |  | ||||||
| ext["ossrhUsername"] = '' |  | ||||||
| ext["ossrhPassword"] = '' |  | ||||||
|  |  | ||||||
| File secretPropsFile = project.rootProject.file('local.properties') |  | ||||||
| if (secretPropsFile.exists()) { |  | ||||||
|     println "Found secret props file, loading props" |  | ||||||
|     Properties p = new Properties() |  | ||||||
|     p.load(new FileInputStream(secretPropsFile)) |  | ||||||
|     p.each { name, value -> |  | ||||||
|         ext[name] = value |  | ||||||
|     } |  | ||||||
| } else { |  | ||||||
|     println "No props file, loading env vars" |  | ||||||
|     ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') |  | ||||||
|     ext["signing.password"] = System.getenv('SIGNING_PASSWORD') |  | ||||||
|     ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE') |  | ||||||
|     ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') |  | ||||||
|     ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') |  | ||||||
| } |  | ||||||
|  |  | ||||||
| nexusStaging { |  | ||||||
|     packageGroup = PUBLISH_GROUP_ID |  | ||||||
|     stagingProfileId = '2097bad464f778' |  | ||||||
|     username = ossrhUsername |  | ||||||
|     password = ossrhPassword |  | ||||||
| } |  | ||||||
|  |  | ||||||
| publishing { |  | ||||||
|     publications { |  | ||||||
|         release(MavenPublication) { |  | ||||||
|             // The coordinates of the library, being set from variables that |  | ||||||
|             // we'll set up in a moment |  | ||||||
|             groupId PUBLISH_GROUP_ID |  | ||||||
|             artifactId PUBLISH_ARTIFACT_ID |  | ||||||
|             version PUBLISH_VERSION |  | ||||||
|  |  | ||||||
|             // Two artifacts, the `aar` and the sources |  | ||||||
|             artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") |  | ||||||
|             artifact androidSourcesJar |  | ||||||
|  |  | ||||||
|             // Self-explanatory metadata for the most part |  | ||||||
|             pom { |  | ||||||
|                 name = PUBLISH_ARTIFACT_ID |  | ||||||
|                 description = 'Simple implementation to store object in tree structure.' |  | ||||||
|                 // If your project has a dedicated site, use its URL here |  | ||||||
|                 url = 'https://github.com/AdrianKuta/Tree-Data-Structure' |  | ||||||
|                 licenses { |  | ||||||
|                     license { |  | ||||||
|                         name = 'MIT License' |  | ||||||
|                         url = 'https://www.mit.edu/~amini/LICENSE.md' |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 developers { |  | ||||||
|                     developer { |  | ||||||
|                         name = 'Adrian Kuta' |  | ||||||
|                         email = 'adrian.kuta93@gmail.com' |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 // Version control info, if you're using GitHub, follow the format as seen here |  | ||||||
|                 scm { |  | ||||||
|                     connection = 'scm:git:github.com/AdrianKuta/Tree-Data-Structure.git' |  | ||||||
|                     developerConnection = 'scm:git:ssh://github.com/AdrianKuta/Tree-Data-Structure.git' |  | ||||||
|                     url = 'https://github.com/AdrianKuta/Tree-Data-Structure/tree/master' |  | ||||||
|                 } |  | ||||||
|                 // A slightly hacky fix so that your POM will include any transitive dependencies |  | ||||||
|                 // that your library builds upon |  | ||||||
|                 withXml { |  | ||||||
|                     def dependenciesNode = asNode().appendNode('dependencies') |  | ||||||
|  |  | ||||||
|                     project.configurations.implementation.allDependencies.each { |  | ||||||
|                         def dependencyNode = dependenciesNode.appendNode('dependency') |  | ||||||
|                         dependencyNode.appendNode('groupId', it.group) |  | ||||||
|                         dependencyNode.appendNode('artifactId', it.name) |  | ||||||
|                         dependencyNode.appendNode('version', it.version) |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     repositories { |  | ||||||
|         // The repository to publish to, Sonatype/MavenCentral |  | ||||||
|         maven { |  | ||||||
|             // This is an arbitrary name, you may also use "mavencentral" or |  | ||||||
|             // any other name that's descriptive for you |  | ||||||
|             name = "sonatype" |  | ||||||
|  |  | ||||||
|             def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" |  | ||||||
|             def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" |  | ||||||
|             // You only need this if you want to publish snapshots, otherwise just set the URL |  | ||||||
|             // to the release repo directly |  | ||||||
|             url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl |  | ||||||
|  |  | ||||||
|             // The username and password we've fetched earlier |  | ||||||
|             credentials { |  | ||||||
|                 username ossrhUsername |  | ||||||
|                 password ossrhPassword |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| signing { |  | ||||||
|     sign publishing.publications |  | ||||||
| } |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| include ':app', ':treedatastructure' |  | ||||||
| rootProject.name='Tree Data Structure' |  | ||||||
							
								
								
									
										3
									
								
								settings.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,3 @@ | |||||||
|  |  | ||||||
|  | rootProject.name = "tree-structure" | ||||||
|  |  | ||||||
| @@ -1,5 +1,7 @@ | |||||||
| package com.github.adriankuta.datastructure.tree | package com.github.adriankuta.datastructure.tree | ||||||
| 
 | 
 | ||||||
|  | import kotlin.jvm.JvmSynthetic | ||||||
|  | 
 | ||||||
| interface ChildDeclarationInterface<T> { | interface ChildDeclarationInterface<T> { | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @@ -15,7 +17,8 @@ interface ChildDeclarationInterface<T> { | |||||||
|      *     } |      *     } | ||||||
|      * } |      * } | ||||||
|      * ``` |      * ``` | ||||||
|  |      * @return New created TreeNode. | ||||||
|      */ |      */ | ||||||
|     @JvmSynthetic |     @JvmSynthetic | ||||||
|     fun child(value: T, childDeclaration: ChildDeclaration<T>? = null) |     fun child(value: T, childDeclaration: ChildDeclaration<T>? = null): TreeNode<T> | ||||||
| } | } | ||||||
| @@ -1,8 +1,20 @@ | |||||||
| package com.github.adriankuta.datastructure.tree | package com.github.adriankuta.datastructure.tree | ||||||
| 
 | 
 | ||||||
| open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationInterface<T> { | import com.github.adriankuta.datastructure.tree.exceptions.TreeNodeException | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.LevelOrderTreeIterator | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.PostOrderTreeIterator | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.PreOrderTreeIterator | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.TreeNodeIterators | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.TreeNodeIterators.* | ||||||
|  | import kotlin.jvm.JvmSynthetic | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * @param treeIterator Choose one of available iterators from [TreeNodeIterators] | ||||||
|  |  */ | ||||||
|  | open class TreeNode<T>(val value: T, var treeIterator: TreeNodeIterators = PreOrder) : Iterable<TreeNode<T>>, ChildDeclarationInterface<T> { | ||||||
| 
 | 
 | ||||||
|     private var _parent: TreeNode<T>? = null |     private var _parent: TreeNode<T>? = null | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * The converse notion of a child, an immediate ancestor. |      * The converse notion of a child, an immediate ancestor. | ||||||
|      */ |      */ | ||||||
| @@ -10,12 +22,20 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|         get() = _parent |         get() = _parent | ||||||
| 
 | 
 | ||||||
|     private val _children = mutableListOf<TreeNode<T>>() |     private val _children = mutableListOf<TreeNode<T>>() | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * A group of nodes with the same parent. |      * A group of nodes with the same parent. | ||||||
|      */ |      */ | ||||||
|     val children: List<TreeNode<T>> |     val children: List<TreeNode<T>> | ||||||
|         get() = _children |         get() = _children | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Checks whether the current tree node is the root of the tree | ||||||
|  |      * @return `true` if the current tree node is root of the tree, `false` otherwise. | ||||||
|  |      */ | ||||||
|  |     val isRoot: Boolean | ||||||
|  |         get() = _parent == null | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Add new child to current node or root. |      * Add new child to current node or root. | ||||||
|      * |      * | ||||||
| @@ -27,11 +47,13 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @JvmSynthetic |     @JvmSynthetic | ||||||
|     override fun child(child: T, childDeclaration: ChildDeclaration<T>?) { |     override fun child(value: T, childDeclaration: ChildDeclaration<T>?): TreeNode<T> { | ||||||
|         val newChild = TreeNode(value) |         val newChild = TreeNode(value) | ||||||
|         if(childDeclaration != null) |         newChild._parent = this | ||||||
|  |         if (childDeclaration != null) | ||||||
|             newChild.childDeclaration() |             newChild.childDeclaration() | ||||||
|         _children.add(newChild) |         _children.add(newChild) | ||||||
|  |         return newChild | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @@ -40,6 +62,7 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|      * @return `true` if the node has been successfully removed; `false` if it was not present in the tree. |      * @return `true` if the node has been successfully removed; `false` if it was not present in the tree. | ||||||
|      */ |      */ | ||||||
|     fun removeChild(child: TreeNode<T>): Boolean { |     fun removeChild(child: TreeNode<T>): Boolean { | ||||||
|  |         println(child.value) | ||||||
|         val removed = child._parent?._children?.remove(child) |         val removed = child._parent?._children?.remove(child) | ||||||
|         child._parent = null |         child._parent = null | ||||||
|         return removed ?: false |         return removed ?: false | ||||||
| @@ -53,7 +76,7 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|         if (_children.isEmpty()) |         if (_children.isEmpty()) | ||||||
|             return 0 |             return 0 | ||||||
|         return _children.size + |         return _children.size + | ||||||
|                 _children.sumBy { it.nodeCount() } |                 _children.sumOf { it.nodeCount() } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @@ -61,7 +84,7 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|      */ |      */ | ||||||
|     fun height(): Int { |     fun height(): Int { | ||||||
|         val childrenMaxDepth = _children.map { it.height() } |         val childrenMaxDepth = _children.map { it.height() } | ||||||
|             .max() |             .maxOrNull() | ||||||
|             ?: -1 // -1 because this method counts nodes, and edges are always one less then nodes. |             ?: -1 // -1 because this method counts nodes, and edges are always one less then nodes. | ||||||
|         return childrenMaxDepth + 1 |         return childrenMaxDepth + 1 | ||||||
|     } |     } | ||||||
| @@ -71,14 +94,39 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|      * @return The distance between current node and the root. |      * @return The distance between current node and the root. | ||||||
|      */ |      */ | ||||||
|     fun depth(): Int { |     fun depth(): Int { | ||||||
|         var _depth = 0 |         var depth = 0 | ||||||
|         var tempParent = parent |         var tempParent = parent | ||||||
| 
 | 
 | ||||||
|         while (tempParent != null) { |         while (tempParent != null) { | ||||||
|             _depth++ |             depth++ | ||||||
|             tempParent = tempParent.parent |             tempParent = tempParent.parent | ||||||
|         } |         } | ||||||
|         return _depth |         return depth | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns the collection of nodes, which connect the current node | ||||||
|  |      * with its descendants | ||||||
|  |      * | ||||||
|  |      * @param descendant the bottom child node for which the path is calculated | ||||||
|  |      * @return collection of nodes, which connect the current node with its descendants | ||||||
|  |      * @throws TreeNodeException exception that may be thrown in case if the | ||||||
|  |      *                           current node does not have such descendant or if the | ||||||
|  |      *                           specified tree node is root | ||||||
|  |      */ | ||||||
|  |     @Throws(TreeNodeException::class) | ||||||
|  |     fun path(descendant: TreeNode<T>): List<TreeNode<T>> { | ||||||
|  | 
 | ||||||
|  |         val path = mutableListOf<TreeNode<T>>() | ||||||
|  |         var node = descendant | ||||||
|  |         path.add(node) | ||||||
|  |         while (!node.isRoot) { | ||||||
|  |             node = node.parent!! | ||||||
|  |             path.add(node) | ||||||
|  |             if (node == this) | ||||||
|  |                 return path | ||||||
|  |         } | ||||||
|  |         throw TreeNodeException("The specified tree node $descendant is not the descendant of tree node $this") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @@ -91,6 +139,10 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override fun toString(): String { |     override fun toString(): String { | ||||||
|  |         return value.toString() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fun prettyString(): String { | ||||||
|         val stringBuilder = StringBuilder() |         val stringBuilder = StringBuilder() | ||||||
|         print(stringBuilder, "", "") |         print(stringBuilder, "", "") | ||||||
|         return stringBuilder.toString() |         return stringBuilder.toString() | ||||||
| @@ -112,24 +164,11 @@ open class TreeNode<T>(val value: T) : Iterable<TreeNode<T>>, ChildDeclarationIn | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Tree is iterated by using `Pre-order Traversal Algorithm" |      * You can change default iterator by changing [treeIterator] property. | ||||||
|      *  1. Check if the current node is empty or null. |  | ||||||
|      *  2. Display the data part of the root (or current node). |  | ||||||
|      *  3. Traverse the left subtree by recursively calling the pre-order function. |  | ||||||
|      *  4. Traverse the right subtree by recursively calling the pre-order function. |  | ||||||
|      * ``` |  | ||||||
|      * E.g. |  | ||||||
|      *                    1 |  | ||||||
|      *                  / | \ |  | ||||||
|      *                 /  |   \ |  | ||||||
|      *               2    3     4 |  | ||||||
|      *              / \       / | \ |  | ||||||
|      *             5    6    7  8  9 |  | ||||||
|      *            /   / | \ |  | ||||||
|      *           10  11 12 13 |  | ||||||
|      * |  | ||||||
|      * Output: 1 2 5 10 6 11 12 13 3 4 7 8 9 |  | ||||||
|      * ``` |  | ||||||
|      */ |      */ | ||||||
|     override fun iterator(): Iterator<TreeNode<T>> = TreeNodeIterator(this) |     override fun iterator(): Iterator<TreeNode<T>> = when (treeIterator) { | ||||||
|  |         PreOrder -> PreOrderTreeIterator(this) | ||||||
|  |         PostOrder -> PostOrderTreeIterator(this) | ||||||
|  |         LevelOrder -> LevelOrderTreeIterator(this) | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -1,5 +1,8 @@ | |||||||
| package com.github.adriankuta.datastructure.tree | package com.github.adriankuta.datastructure.tree | ||||||
| 
 | 
 | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.TreeNodeIterators | ||||||
|  | import kotlin.jvm.JvmSynthetic | ||||||
|  | 
 | ||||||
| typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit | typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @@ -11,8 +14,12 @@ typealias ChildDeclaration<T> = ChildDeclarationInterface<T>.() -> Unit | |||||||
|  * @see [ChildDeclarationInterface.child] |  * @see [ChildDeclarationInterface.child] | ||||||
|  */ |  */ | ||||||
| @JvmSynthetic | @JvmSynthetic | ||||||
| inline fun<reified T> tree(root: T, childDeclaration: ChildDeclaration<T>): TreeNode<T> { | inline fun <reified T> tree( | ||||||
|     val treeNode = TreeNode(root) |     root: T, | ||||||
|  |     defaultIterator: TreeNodeIterators = TreeNodeIterators.PreOrder, | ||||||
|  |     childDeclaration: ChildDeclaration<T> | ||||||
|  | ): TreeNode<T> { | ||||||
|  |     val treeNode = TreeNode(root, defaultIterator) | ||||||
|     treeNode.childDeclaration() |     treeNode.childDeclaration() | ||||||
|     return treeNode |     return treeNode | ||||||
| } | } | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | package com.github.adriankuta.datastructure.tree.exceptions | ||||||
|  |  | ||||||
|  | import kotlin.jvm.JvmOverloads | ||||||
|  |  | ||||||
|  | class TreeNodeException @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : | ||||||
|  |     RuntimeException(message, cause) | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | package com.github.adriankuta.datastructure.tree.iterators | ||||||
|  |  | ||||||
|  | import com.github.adriankuta.datastructure.tree.TreeNode | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Tree is iterated by using `Level-order Traversal Algorithm" | ||||||
|  |  * In level-order traversal we iterating nodes level by level, | ||||||
|  |  * starting from root, and going deeper and deeper in tree. | ||||||
|  |  * ``` | ||||||
|  |  * E.g. | ||||||
|  |  *                    1 | ||||||
|  |  *                  / | \ | ||||||
|  |  *                 /  |   \ | ||||||
|  |  *               2    3     4 | ||||||
|  |  *              / \       / | \ | ||||||
|  |  *             5    6    7  8  9 | ||||||
|  |  *            /   / | \ | ||||||
|  |  *           10  11 12 13 | ||||||
|  |  * | ||||||
|  |  * Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 | ||||||
|  |  * ``` | ||||||
|  |  */ | ||||||
|  | class LevelOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> { | ||||||
|  |  | ||||||
|  |     private val stack = ArrayDeque<TreeNode<T>>() | ||||||
|  |  | ||||||
|  |     init { | ||||||
|  |         stack.addLast(root) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun hasNext(): Boolean = stack.isNotEmpty() | ||||||
|  |  | ||||||
|  |     override fun next(): TreeNode<T> { | ||||||
|  |         val node =  stack.removeFirst() | ||||||
|  |         node.children | ||||||
|  |             .forEach { stack.addLast(it) } | ||||||
|  |         return node | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,48 @@ | |||||||
|  | package com.github.adriankuta.datastructure.tree.iterators | ||||||
|  |  | ||||||
|  | import com.github.adriankuta.datastructure.tree.TreeNode | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Tree is iterated by using `Post-order Traversal Algorithm" | ||||||
|  |  * In post-order traversal, we starting from most left child. | ||||||
|  |  * First visit all children of parent, then parent. | ||||||
|  |  * ``` | ||||||
|  |  * E.g. | ||||||
|  |  *                    1 | ||||||
|  |  *                  / | \ | ||||||
|  |  *                 /  |   \ | ||||||
|  |  *               2    3     4 | ||||||
|  |  *              / \       / | \ | ||||||
|  |  *             5    6    7  8  9 | ||||||
|  |  *            /   / | \ | ||||||
|  |  *           10  11 12 13 | ||||||
|  |  * | ||||||
|  |  * Output: 10 5 11 12 13 6 2 3 7 8 9 4 1 | ||||||
|  |  * ``` | ||||||
|  |  */ | ||||||
|  | class PostOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> { | ||||||
|  |  | ||||||
|  |     private val stack = ArrayDeque<TreeNode<T>>() | ||||||
|  |  | ||||||
|  |     init { | ||||||
|  |         stack.addAll(getChildrenStack(root)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun hasNext(): Boolean = stack.isNotEmpty() | ||||||
|  |  | ||||||
|  |     override fun next(): TreeNode<T> { | ||||||
|  |         return stack.removeFirst() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private fun getChildrenStack(node: TreeNode<T>): ArrayDeque<TreeNode<T>> { | ||||||
|  |         val stack = ArrayDeque<TreeNode<T>>() | ||||||
|  |         if(node.children.isEmpty()) { | ||||||
|  |             return ArrayDeque(listOf(node)) | ||||||
|  |         } | ||||||
|  |         node.children.forEach { | ||||||
|  |             stack.addAll(getChildrenStack(it)) | ||||||
|  |         } | ||||||
|  |         stack.addLast(node) | ||||||
|  |         return stack | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | package com.github.adriankuta.datastructure.tree.iterators | ||||||
|  |  | ||||||
|  | import com.github.adriankuta.datastructure.tree.TreeNode | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Tree is iterated by using `Pre-order Traversal Algorithm" | ||||||
|  |  * The pre-order traversal is a topologically sorted one, | ||||||
|  |  * because a parent node is processed before any of its child nodes is done. | ||||||
|  |  * ``` | ||||||
|  |  * E.g. | ||||||
|  |  *                    1 | ||||||
|  |  *                  / | \ | ||||||
|  |  *                 /  |   \ | ||||||
|  |  *               2    3     4 | ||||||
|  |  *              / \       / | \ | ||||||
|  |  *             5    6    7  8  9 | ||||||
|  |  *            /   / | \ | ||||||
|  |  *           10  11 12 13 | ||||||
|  |  * | ||||||
|  |  * Output: 1 2 5 10 6 11 12 13 3 4 7 8 9 | ||||||
|  |  * ``` | ||||||
|  |  */ | ||||||
|  | class PreOrderTreeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> { | ||||||
|  |  | ||||||
|  |     private val stack = ArrayDeque<TreeNode<T>>() | ||||||
|  |  | ||||||
|  |     init { | ||||||
|  |         stack.addLast(root) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     override fun hasNext(): Boolean = stack.isNotEmpty() | ||||||
|  |  | ||||||
|  |     override fun next(): TreeNode<T> { | ||||||
|  |         val node = stack.removeLast() | ||||||
|  |         node.children | ||||||
|  |             .asReversed() | ||||||
|  |             .forEach { stack.addLast(it) } | ||||||
|  |         return node | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,68 @@ | |||||||
|  | package com.github.adriankuta.datastructure.tree.iterators | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @see PreOrder | ||||||
|  |  * @see PostOrder | ||||||
|  |  * @see LevelOrder | ||||||
|  |  */ | ||||||
|  | enum class TreeNodeIterators { | ||||||
|  |     /** | ||||||
|  |      * Tree is iterated by using `Pre-order Traversal Algorithm" | ||||||
|  |      * The pre-order traversal is a topologically sorted one, | ||||||
|  |      * because a parent node is processed before any of its child nodes is done. | ||||||
|  |      * ``` | ||||||
|  |      * E.g. | ||||||
|  |      *                    1 | ||||||
|  |      *                  / | \ | ||||||
|  |      *                 /  |   \ | ||||||
|  |      *               2    3     4 | ||||||
|  |      *              / \       / | \ | ||||||
|  |      *             5    6    7  8  9 | ||||||
|  |      *            /   / | \ | ||||||
|  |      *           10  11 12 13 | ||||||
|  |      * | ||||||
|  |      * Output: 1 2 5 10 6 11 12 13 3 4 7 8 9 | ||||||
|  |      * ``` | ||||||
|  |      */ | ||||||
|  |     PreOrder, | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Tree is iterated by using `Post-order Traversal Algorithm" | ||||||
|  |      * In post-order traversal, we starting from most left child. | ||||||
|  |      * First visit all children of parent, then parent. | ||||||
|  |      * ``` | ||||||
|  |      * E.g. | ||||||
|  |      *                    1 | ||||||
|  |      *                  / | \ | ||||||
|  |      *                 /  |   \ | ||||||
|  |      *               2    3     4 | ||||||
|  |      *              / \       / | \ | ||||||
|  |      *             5    6    7  8  9 | ||||||
|  |      *            /   / | \ | ||||||
|  |      *           10  11 12 13 | ||||||
|  |      * | ||||||
|  |      * Output: 10 5 11 12 13 6 2 3 7 8 9 4 1 | ||||||
|  |      * ``` | ||||||
|  |      */ | ||||||
|  |     PostOrder, | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Tree is iterated by using `Level-order Traversal Algorithm" | ||||||
|  |      * In level-order traversal we iterating nodes level by level, | ||||||
|  |      * starting from root, and going deeper and deeper in tree. | ||||||
|  |      * ``` | ||||||
|  |      * E.g. | ||||||
|  |      *                    1 | ||||||
|  |      *                  / | \ | ||||||
|  |      *                 /  |   \ | ||||||
|  |      *               2    3     4 | ||||||
|  |      *              / \       / | \ | ||||||
|  |      *             5    6    7  8  9 | ||||||
|  |      *            /   / | \ | ||||||
|  |      *           10  11 12 13 | ||||||
|  |      * | ||||||
|  |      * Output: 1 2 3 4 5 6 7 8 9 10 11 12 13 | ||||||
|  |      * ``` | ||||||
|  |      */ | ||||||
|  |     LevelOrder | ||||||
|  | } | ||||||
| @@ -1,8 +1,7 @@ | |||||||
| package com.github.adriankuta.datastructure.tree | package com.github.adriankuta.datastructure.tree | ||||||
| 
 | 
 | ||||||
| import org.junit.Test | import kotlin.test.Test | ||||||
| 
 | import kotlin.test.assertEquals | ||||||
| import org.junit.Assert.* |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Example local unit test, which will execute on the development machine (host). |  * Example local unit test, which will execute on the development machine (host). | ||||||
| @@ -0,0 +1,228 @@ | |||||||
|  | package com.github.adriankuta.datastructure.tree | ||||||
|  |  | ||||||
|  | import com.github.adriankuta.datastructure.tree.iterators.TreeNodeIterators | ||||||
|  | import kotlin.test.Test | ||||||
|  | import kotlin.test.assertContentEquals | ||||||
|  | import kotlin.test.assertEquals | ||||||
|  | import kotlin.test.assertNull | ||||||
|  |  | ||||||
|  | class TreeNodeTest { | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     fun removeNodeTest() { | ||||||
|  |         val root = TreeNode("Root") | ||||||
|  |         val beveragesNode = TreeNode("Beverages") | ||||||
|  |         val curdNode = TreeNode("Curd") | ||||||
|  |         root.addChild(beveragesNode) | ||||||
|  |         root.addChild(curdNode) | ||||||
|  |  | ||||||
|  |         val teaNode = TreeNode("tea") | ||||||
|  |         val coffeeNode = TreeNode("coffee") | ||||||
|  |         val milkShakeNode = TreeNode("Milk Shake") | ||||||
|  |         beveragesNode.addChild(teaNode) | ||||||
|  |         beveragesNode.addChild(coffeeNode) | ||||||
|  |         beveragesNode.addChild(milkShakeNode) | ||||||
|  |  | ||||||
|  |         val gingerTeaNode = TreeNode("ginger tea") | ||||||
|  |         val normalTeaNode = TreeNode("normal tea") | ||||||
|  |         teaNode.addChild(gingerTeaNode) | ||||||
|  |         teaNode.addChild(normalTeaNode) | ||||||
|  |  | ||||||
|  |         val yogurtNode = TreeNode("yogurt") | ||||||
|  |         val lassiNode = TreeNode("lassi") | ||||||
|  |         curdNode.addChild(yogurtNode) | ||||||
|  |         curdNode.addChild(lassiNode) | ||||||
|  |  | ||||||
|  |         assertEquals( | ||||||
|  |             "Root\n" + | ||||||
|  |                     "├── Beverages\n" + | ||||||
|  |                     "│   ├── tea\n" + | ||||||
|  |                     "│   │   ├── ginger tea\n" + | ||||||
|  |                     "│   │   └── normal tea\n" + | ||||||
|  |                     "│   ├── coffee\n" + | ||||||
|  |                     "│   └── Milk Shake\n" + | ||||||
|  |                     "└── Curd\n" + | ||||||
|  |                     "    ├── yogurt\n" + | ||||||
|  |                     "    └── lassi\n", | ||||||
|  |             root.prettyString(), | ||||||
|  |             "Pretty print test" | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         root.removeChild(curdNode) | ||||||
|  |         root.removeChild(gingerTeaNode) | ||||||
|  |         assertEquals( | ||||||
|  |             "Root\n" + | ||||||
|  |                     "└── Beverages\n" + | ||||||
|  |                     "    ├── tea\n" + | ||||||
|  |                     "    │   └── normal tea\n" + | ||||||
|  |                     "    ├── coffee\n" + | ||||||
|  |                     "    └── Milk Shake\n", | ||||||
|  |             root.prettyString(), | ||||||
|  |             "Remove node test" | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     fun clearTest() { | ||||||
|  |         val root = TreeNode("Root") | ||||||
|  |         val beveragesNode = TreeNode("Beverages") | ||||||
|  |         val curdNode = TreeNode("Curd") | ||||||
|  |         root.addChild(beveragesNode) | ||||||
|  |         root.addChild(curdNode) | ||||||
|  |  | ||||||
|  |         val teaNode = TreeNode("tea") | ||||||
|  |         val coffeeNode = TreeNode("coffee") | ||||||
|  |         val milkShakeNode = TreeNode("Milk Shake") | ||||||
|  |         beveragesNode.addChild(teaNode) | ||||||
|  |         beveragesNode.addChild(coffeeNode) | ||||||
|  |         beveragesNode.addChild(milkShakeNode) | ||||||
|  |  | ||||||
|  |         val gingerTeaNode = TreeNode("ginger tea") | ||||||
|  |         val normalTeaNode = TreeNode("normal tea") | ||||||
|  |         teaNode.addChild(gingerTeaNode) | ||||||
|  |         teaNode.addChild(normalTeaNode) | ||||||
|  |  | ||||||
|  |         val yogurtNode = TreeNode("yogurt") | ||||||
|  |         val lassiNode = TreeNode("lassi") | ||||||
|  |         curdNode.addChild(yogurtNode) | ||||||
|  |         curdNode.addChild(lassiNode) | ||||||
|  |  | ||||||
|  |         root.clear() | ||||||
|  |         assertEquals(root.children, emptyList()) | ||||||
|  |         assertEquals(beveragesNode.children, emptyList()) | ||||||
|  |         assertEquals(curdNode.children, emptyList()) | ||||||
|  |         assertEquals(teaNode.children, emptyList()) | ||||||
|  |         assertEquals(coffeeNode.children, emptyList()) | ||||||
|  |         assertEquals(milkShakeNode.children, emptyList()) | ||||||
|  |         assertEquals(gingerTeaNode.children, emptyList()) | ||||||
|  |         assertEquals(normalTeaNode.children, emptyList()) | ||||||
|  |         assertEquals(yogurtNode.children, emptyList()) | ||||||
|  |         assertEquals(lassiNode.children, emptyList()) | ||||||
|  |  | ||||||
|  |         assertNull(root.parent) | ||||||
|  |         assertNull(beveragesNode.parent) | ||||||
|  |         assertNull(curdNode.parent) | ||||||
|  |         assertNull(teaNode.parent) | ||||||
|  |         assertNull(coffeeNode.parent) | ||||||
|  |         assertNull(milkShakeNode.parent) | ||||||
|  |         assertNull(gingerTeaNode.parent) | ||||||
|  |         assertNull(normalTeaNode.parent) | ||||||
|  |         assertNull(yogurtNode.parent) | ||||||
|  |         assertNull(lassiNode.parent) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     fun kotlinExtTest() { | ||||||
|  |         val root = TreeNode("World") | ||||||
|  |         val northA = TreeNode("North America") | ||||||
|  |         val europe = TreeNode("Europe") | ||||||
|  |         root.addChild(northA) | ||||||
|  |         root.addChild(europe) | ||||||
|  |  | ||||||
|  |         val usa = TreeNode("USA") | ||||||
|  |         northA.addChild(usa) | ||||||
|  |  | ||||||
|  |         val poland = TreeNode("Poland") | ||||||
|  |         val france = TreeNode("France") | ||||||
|  |         europe.addChild(poland) | ||||||
|  |         europe.addChild(france) | ||||||
|  |  | ||||||
|  |         val rootExt = tree("World") { | ||||||
|  |             child("North America") { | ||||||
|  |                 child("USA") | ||||||
|  |             } | ||||||
|  |             child("Europe") { | ||||||
|  |                 child("Poland") | ||||||
|  |                 child("France") | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         assertEquals(root.prettyString(), rootExt.prettyString()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     fun preOrderIteratorTest() { | ||||||
|  |         val tree = tree("F") { | ||||||
|  |             child("B") { | ||||||
|  |                 child("A") | ||||||
|  |                 child("D") { | ||||||
|  |                     child("C") | ||||||
|  |                     child("E") | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             child("G") { | ||||||
|  |                 child("I") { | ||||||
|  |                     child("H") | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         val expectedPreOrder = listOf("F", "B", "A", "D", "C", "E", "G", "I", "H") | ||||||
|  |         assertContentEquals(expectedPreOrder, tree.toList().map { it.toString() }) | ||||||
|  |     } | ||||||
|  |     @Test | ||||||
|  |     fun postOrderIteratorTest() { | ||||||
|  |         val tree = tree("A", TreeNodeIterators.PostOrder) { | ||||||
|  |             child("B") { | ||||||
|  |                 child("E") | ||||||
|  |             } | ||||||
|  |             child("C") | ||||||
|  |             child("D") { | ||||||
|  |                 child("F") | ||||||
|  |                 child("G") | ||||||
|  |                 child("H") | ||||||
|  |                 child("I") | ||||||
|  |                 child("J") | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val expectedPreOrder = listOf("E", "B", "C", "F", "G", "H", "I", "J", "D", "A") | ||||||
|  |         assertContentEquals(expectedPreOrder, tree.toList().map { it.toString() }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     fun secondPostOrderIteratorTest() { | ||||||
|  |         val tree = tree(1, TreeNodeIterators.PostOrder) { | ||||||
|  |             child(2) { | ||||||
|  |                 child(5) { | ||||||
|  |                     child(10) | ||||||
|  |                 } | ||||||
|  |                 child(6) { | ||||||
|  |                     child(11) | ||||||
|  |                     child(12) | ||||||
|  |                     child(13) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             child(3) | ||||||
|  |             child(4) { | ||||||
|  |                 child(7) | ||||||
|  |                 child(8) | ||||||
|  |                 child(9) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         val expectedOrder = listOf(10, 5, 11, 12, 13, 6, 2, 3, 7, 8, 9, 4, 1) | ||||||
|  |         assertContentEquals(expectedOrder, tree.toList().map { it.value }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     fun levelOrderIteratorTest() { | ||||||
|  |         val tree = tree(1, TreeNodeIterators.LevelOrder) { | ||||||
|  |             child(2) { | ||||||
|  |                 child(5) { | ||||||
|  |                     child(10) | ||||||
|  |                 } | ||||||
|  |                 child(6) { | ||||||
|  |                     child(11) | ||||||
|  |                     child(12) | ||||||
|  |                     child(13) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             child(3) | ||||||
|  |             child(4) { | ||||||
|  |                 child(7) | ||||||
|  |                 child(8) | ||||||
|  |                 child(9) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         val expectedOrder = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) | ||||||
|  |         assertContentEquals(expectedOrder, tree.toList().map { it.value }) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								src/jvmMain/kotlin/Example.ws.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,14 @@ | |||||||
|  | import com.github.adriankuta.datastructure.tree.tree | ||||||
|  |  | ||||||
|  | val root = | ||||||
|  |     tree("World") { | ||||||
|  |         child("North America") { | ||||||
|  |             child("USA") | ||||||
|  |         } | ||||||
|  |         child("Europe") { | ||||||
|  |             child("Poland") | ||||||
|  |             child("Germany") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | print(root.prettyString()) | ||||||
							
								
								
									
										1
									
								
								treedatastructure/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1 +0,0 @@ | |||||||
| /build |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| apply plugin: 'com.android.library' |  | ||||||
| apply plugin: 'kotlin-android' |  | ||||||
| apply plugin: 'kotlin-android-extensions' |  | ||||||
|  |  | ||||||
| afterEvaluate { |  | ||||||
|     generateReleaseBuildConfig.enabled = false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| android { |  | ||||||
|     compileSdkVersion 29 |  | ||||||
|     buildToolsVersion "29.0.2" |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     defaultConfig { |  | ||||||
|         minSdkVersion 15 |  | ||||||
|         targetSdkVersion 29 |  | ||||||
|         versionCode 1 |  | ||||||
|         versionName "1.2.0" |  | ||||||
|  |  | ||||||
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" |  | ||||||
|         consumerProguardFiles 'consumer-rules.pro' |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     buildTypes { |  | ||||||
|         release { |  | ||||||
|             minifyEnabled false |  | ||||||
|             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| dependencies { |  | ||||||
|     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" |  | ||||||
|     implementation 'androidx.appcompat:appcompat:1.1.0' |  | ||||||
|     implementation 'androidx.core:core-ktx:1.1.0' |  | ||||||
|     testImplementation 'junit:junit:4.12' |  | ||||||
|     androidTestImplementation 'androidx.test.ext:junit:1.1.1' |  | ||||||
|     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' |  | ||||||
| } |  | ||||||
|  |  | ||||||
| ext { |  | ||||||
|     PUBLISH_GROUP_ID = 'com.github.adriankuta' |  | ||||||
|     PUBLISH_ARTIFACT_ID = 'tree-structure' |  | ||||||
|     PUBLISH_VERSION = android.defaultConfig.versionName |  | ||||||
| } |  | ||||||
|  |  | ||||||
| apply from: "${rootProject.projectDir}/scripts/publish-mavencentral.gradle" |  | ||||||
							
								
								
									
										21
									
								
								treedatastructure/proguard-rules.pro
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,21 +0,0 @@ | |||||||
| # Add project specific ProGuard rules here. |  | ||||||
| # You can control the set of applied configuration files using the |  | ||||||
| # proguardFiles setting in build.gradle. |  | ||||||
| # |  | ||||||
| # For more details, see |  | ||||||
| #   http://developer.android.com/guide/developing/tools/proguard.html |  | ||||||
|  |  | ||||||
| # If your project uses WebView with JS, uncomment the following |  | ||||||
| # and specify the fully qualified class name to the JavaScript interface |  | ||||||
| # class: |  | ||||||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { |  | ||||||
| #   public *; |  | ||||||
| #} |  | ||||||
|  |  | ||||||
| # Uncomment this to preserve the line number information for |  | ||||||
| # debugging stack traces. |  | ||||||
| #-keepattributes SourceFile,LineNumberTable |  | ||||||
|  |  | ||||||
| # If you keep the line number information, uncomment this to |  | ||||||
| # hide the original source file name. |  | ||||||
| #-renamesourcefileattribute SourceFile |  | ||||||
| @@ -1,24 +0,0 @@ | |||||||
| package com.github.adriankuta.datastructure.tree |  | ||||||
|  |  | ||||||
| import androidx.test.platform.app.InstrumentationRegistry |  | ||||||
| import androidx.test.ext.junit.runners.AndroidJUnit4 |  | ||||||
|  |  | ||||||
| import org.junit.Test |  | ||||||
| import org.junit.runner.RunWith |  | ||||||
|  |  | ||||||
| import org.junit.Assert.* |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Instrumented test, which will execute on an Android device. |  | ||||||
|  * |  | ||||||
|  * See [testing documentation](http://d.android.com/tools/testing). |  | ||||||
|  */ |  | ||||||
| @RunWith(AndroidJUnit4::class) |  | ||||||
| class ExampleInstrumentedTest { |  | ||||||
|     @Test |  | ||||||
|     fun useAppContext() { |  | ||||||
|         // Context of the app under test. |  | ||||||
|         val appContext = InstrumentationRegistry.getInstrumentation().targetContext |  | ||||||
|         assertEquals("com.github.adriankuta.datastructure.tree.test", appContext.packageName) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,2 +0,0 @@ | |||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     package="com.github.adriankuta.datastructure.tree" /> |  | ||||||
| @@ -1,22 +0,0 @@ | |||||||
| package com.github.adriankuta.datastructure.tree |  | ||||||
|  |  | ||||||
| import java.util.* |  | ||||||
|  |  | ||||||
| class TreeNodeIterator<T>(root: TreeNode<T>) : Iterator<TreeNode<T>> { |  | ||||||
|  |  | ||||||
|     private val stack = Stack<TreeNode<T>>() |  | ||||||
|  |  | ||||||
|     init { |  | ||||||
|         stack.push(root) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     override fun hasNext(): Boolean = !stack.empty() |  | ||||||
|  |  | ||||||
|     override fun next(): TreeNode<T> { |  | ||||||
|         val node = stack.pop() |  | ||||||
|         node.children |  | ||||||
|             .asReversed() |  | ||||||
|             .forEach { stack.push(it) } |  | ||||||
|         return node |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,3 +0,0 @@ | |||||||
| <resources> |  | ||||||
|     <string name="app_name">Tree Data Structure</string> |  | ||||||
| </resources> |  | ||||||
| @@ -1,145 +0,0 @@ | |||||||
| package com.github.adriankuta.datastructure.tree |  | ||||||
|  |  | ||||||
| import org.hamcrest.CoreMatchers.`is` |  | ||||||
| import org.hamcrest.CoreMatchers.nullValue |  | ||||||
| import org.junit.Assert.assertEquals |  | ||||||
| import org.junit.Assert.assertThat |  | ||||||
| import org.junit.Test |  | ||||||
|  |  | ||||||
| class TreeNodeTest { |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     fun removeNodeTest() { |  | ||||||
|         val root = TreeNode<String>("Root") |  | ||||||
|         val beveragesNode = TreeNode<String>("Beverages") |  | ||||||
|         val curdNode = TreeNode<String>("Curd") |  | ||||||
|         root.addChild(beveragesNode) |  | ||||||
|         root.addChild(curdNode) |  | ||||||
|  |  | ||||||
|         val teaNode = TreeNode<String>("tea") |  | ||||||
|         val coffeeNode = TreeNode<String>("coffee") |  | ||||||
|         val milkShakeNode = TreeNode<String>("Milk Shake") |  | ||||||
|         beveragesNode.addChild(teaNode) |  | ||||||
|         beveragesNode.addChild(coffeeNode) |  | ||||||
|         beveragesNode.addChild(milkShakeNode) |  | ||||||
|  |  | ||||||
|         val gingerTeaNode = TreeNode<String>("ginger tea") |  | ||||||
|         val normalTeaNode = TreeNode<String>("normal tea") |  | ||||||
|         teaNode.addChild(gingerTeaNode) |  | ||||||
|         teaNode.addChild(normalTeaNode) |  | ||||||
|  |  | ||||||
|         val yogurtNode = TreeNode<String>("yogurt") |  | ||||||
|         val lassiNode = TreeNode<String>("lassi") |  | ||||||
|         curdNode.addChild(yogurtNode) |  | ||||||
|         curdNode.addChild(lassiNode) |  | ||||||
|  |  | ||||||
|         assertEquals( |  | ||||||
|             "Root\n" + |  | ||||||
|                     "├── Beverages\n" + |  | ||||||
|                     "│   ├── tea\n" + |  | ||||||
|                     "│   │   ├── ginger tea\n" + |  | ||||||
|                     "│   │   └── normal tea\n" + |  | ||||||
|                     "│   ├── coffee\n" + |  | ||||||
|                     "│   └── Milk Shake\n" + |  | ||||||
|                     "└── Curd\n" + |  | ||||||
|                     "    ├── yogurt\n" + |  | ||||||
|                     "    └── lassi\n", root.toString() |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         System.out.println("Remove: ${curdNode.value}") |  | ||||||
|         root.removeChild(curdNode) |  | ||||||
|         System.out.println("Remove: ${gingerTeaNode.value}") |  | ||||||
|         root.removeChild(gingerTeaNode) |  | ||||||
|         assertEquals( |  | ||||||
|             "Root\n" + |  | ||||||
|                     "└── Beverages\n" + |  | ||||||
|                     "    ├── tea\n" + |  | ||||||
|                     "    │   └── normal tea\n" + |  | ||||||
|                     "    ├── coffee\n" + |  | ||||||
|                     "    └── Milk Shake\n", root.toString() |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     fun clearTest() { |  | ||||||
|         val root = TreeNode<String>("Root") |  | ||||||
|         val beveragesNode = TreeNode<String>("Beverages") |  | ||||||
|         val curdNode = TreeNode<String>("Curd") |  | ||||||
|         root.addChild(beveragesNode) |  | ||||||
|         root.addChild(curdNode) |  | ||||||
|  |  | ||||||
|         val teaNode = TreeNode<String>("tea") |  | ||||||
|         val coffeeNode = TreeNode<String>("coffee") |  | ||||||
|         val milkShakeNode = TreeNode<String>("Milk Shake") |  | ||||||
|         beveragesNode.addChild(teaNode) |  | ||||||
|         beveragesNode.addChild(coffeeNode) |  | ||||||
|         beveragesNode.addChild(milkShakeNode) |  | ||||||
|  |  | ||||||
|         val gingerTeaNode = TreeNode<String>("ginger tea") |  | ||||||
|         val normalTeaNode = TreeNode<String>("normal tea") |  | ||||||
|         teaNode.addChild(gingerTeaNode) |  | ||||||
|         teaNode.addChild(normalTeaNode) |  | ||||||
|  |  | ||||||
|         val yogurtNode = TreeNode<String>("yogurt") |  | ||||||
|         val lassiNode = TreeNode<String>("lassi") |  | ||||||
|         curdNode.addChild(yogurtNode) |  | ||||||
|         curdNode.addChild(lassiNode) |  | ||||||
|  |  | ||||||
|         println(root.toString()) |  | ||||||
|         println(curdNode.height()) |  | ||||||
|  |  | ||||||
|         root.clear() |  | ||||||
|         assertThat(root.children, `is`(emptyList())) |  | ||||||
|         assertThat(beveragesNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(curdNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(teaNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(coffeeNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(milkShakeNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(gingerTeaNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(normalTeaNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(yogurtNode.children, `is`(emptyList())) |  | ||||||
|         assertThat(lassiNode.children, `is`(emptyList())) |  | ||||||
|  |  | ||||||
|         assertThat(root.parent, `is`(nullValue())) |  | ||||||
|         assertThat(beveragesNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(curdNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(teaNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(coffeeNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(milkShakeNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(gingerTeaNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(normalTeaNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(yogurtNode.parent, `is`(nullValue())) |  | ||||||
|         assertThat(lassiNode.parent, `is`(nullValue())) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Test |  | ||||||
|     fun kotlinExtTest() { |  | ||||||
|         val root = TreeNode("World") |  | ||||||
|         val northA = TreeNode("North America") |  | ||||||
|         val europe = TreeNode("Europe") |  | ||||||
|         root.addChild(northA) |  | ||||||
|         root.addChild(europe) |  | ||||||
|  |  | ||||||
|         val usa = TreeNode("USA") |  | ||||||
|         northA.addChild(usa) |  | ||||||
|  |  | ||||||
|         val poland = TreeNode("Poland") |  | ||||||
|         val france = TreeNode("France") |  | ||||||
|         europe.addChild(poland) |  | ||||||
|         europe.addChild(france) |  | ||||||
|  |  | ||||||
|         val rootExt = treeNode("World") { |  | ||||||
|             treeNode("North America") { |  | ||||||
|                 treeNode("USA") |  | ||||||
|             } |  | ||||||
|             treeNode("Europe") { |  | ||||||
|                 treeNode("Poland") |  | ||||||
|                 treeNode("France") |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         println(root) |  | ||||||
|         assertEquals(root.toString(), rootExt.toString()) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  |  | ||||||
| } |  | ||||||