From 7503402e8b9c885ecaf27a927b66d327aea5bb14 Mon Sep 17 00:00:00 2001
From: IgnatBeresnev
Date: Mon, 9 Oct 2023 16:45:27 +0200
Subject: [PATCH 01/72] Prepare for the next development iteration
---
gradle.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gradle.properties b/gradle.properties
index 8f23dc5df4..e1bbd2bb07 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,7 +3,7 @@
#
# Project Settings
-dokka_version=1.9.10-SNAPSHOT
+dokka_version=1.9.20-SNAPSHOT
org.jetbrains.dokka.javaToolchain.mainCompiler=8
org.jetbrains.dokka.javaToolchain.testLauncher=8
org.jetbrains.dokka.kotlinLanguageLevel=1.4
From 562a5951ca942c0bd26d839f2ebf509b43ca3c59 Mon Sep 17 00:00:00 2001
From: Vadim Mishenev
Date: Tue, 10 Oct 2023 12:36:34 +0300
Subject: [PATCH 02/72] [K2] Display enum entry members (#3180)
---
.../src/test/kotlin/enums/KotlinEnumsTest.kt | 44 +++++++++++++++-
...ntriesDocumentableFilterTransfromerTest.kt | 5 +-
...rgeImplicitExpectActualDeclarationsTest.kt | 15 ++----
.../src/test/kotlin/utils/contentUtils.kt | 25 +++++++--
.../DefaultSymbolToDocumentableTranslator.kt | 52 +++++++++++++------
5 files changed, 103 insertions(+), 38 deletions(-)
diff --git a/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt b/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
index 94a6b932f5..c32a5cc288 100644
--- a/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
+++ b/plugins/base/src/test/kotlin/enums/KotlinEnumsTest.kt
@@ -15,8 +15,7 @@ import org.jetbrains.dokka.pages.ContentGroup
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import signatures.renderedContent
-import utils.TestOutputWriter
-import utils.TestOutputWriterPlugin
+import utils.*
import java.net.URL
import kotlin.test.Test
import kotlin.test.assertEquals
@@ -328,6 +327,47 @@ class KotlinEnumsTest : BaseAbstractTest() {
}
}
+ @Test
+ @OnlyDescriptors("K2 has `compareTo`, that should be suppressed, due to #3196")
+ fun `enum should have functions on page`() {
+ val configuration = dokkaConfiguration {
+ sourceSets {
+ sourceSet {
+ sourceRoots = listOf("src/")
+ }
+ }
+ }
+
+ testInline(
+ """
+ |/src/main/kotlin/basic/TestEnum.kt
+ |package testpackage
+ |
+ |
+ |interface Sample {
+ | fun toBeImplemented(): String
+ |}
+ |
+ |enum class TestEnum: Sample {
+ | E1 {
+ | override fun toBeImplemented(): String = "e1"
+ | }
+ |}
+ """.trimMargin(),
+ configuration
+ ) {
+ pagesTransformationStage = { root ->
+ root.contentPage("E1") {
+ assertHasFunctions("toBeImplemented")
+ }
+
+ root.contentPage("TestEnum") {
+ assertHasFunctions("toBeImplemented", "valueOf", "values")
+ }
+ }
+ }
+ }
+
@Test
fun enumWithAnnotationsOnEntries() {
val configuration = dokkaConfiguration {
diff --git a/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt b/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt
index 831d2680cd..c07dd5b813 100644
--- a/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt
+++ b/plugins/base/src/test/kotlin/transformers/InheritedEntriesDocumentableFilterTransfromerTest.kt
@@ -9,7 +9,6 @@ import org.jetbrains.dokka.model.DEnum
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
-import utils.OnlyDescriptors
class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
val suppressingInheritedConfiguration = dokkaConfiguration {
@@ -138,7 +137,6 @@ class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
}
}
- @OnlyDescriptors("Entry does not have `name` and `ordinal`") // TODO
@Test
fun `should work with enum entries when not suppressing`(){
testInline(
@@ -146,7 +144,8 @@ class InheritedEntriesDocumentableFilterTransformerTest : BaseAbstractTest() {
/src/suppressed/Suppressed.kt
package suppressed
enum class Suppressed {
- ENTRY_SUPPRESSED
+ ENTRY_SUPPRESSED;
+ class A
}
""".trimIndent(),
nonSuppressingInheritedConfiguration
diff --git a/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt b/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
index f7118f335a..18e42e477d 100644
--- a/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
+++ b/plugins/base/src/test/kotlin/transformers/MergeImplicitExpectActualDeclarationsTest.kt
@@ -13,10 +13,10 @@ import org.jetbrains.dokka.model.dfs
import org.jetbrains.dokka.model.firstChildOfType
import org.jetbrains.dokka.pages.*
import utils.assertNotNull
+import utils.findSectionWithName
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
-import utils.OnlyDescriptors
class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
@@ -52,15 +52,6 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
)
}
- private fun ClasslikePageNode.findSectionWithName(name: String) : ContentNode? {
- var sectionHeader: ContentHeader? = null
- return content.dfs { node ->
- node.children.filterIsInstance().any { header ->
- header.children.firstOrNull { it is ContentText && it.text == name }?.also { sectionHeader = header } != null
- }
- }?.children?.dropWhile { child -> child != sectionHeader }?.drop(1)?.firstOrNull()
- }
-
private fun ContentNode.findTabWithType(type: TabbedContentType): ContentNode? = dfs { node ->
node.children.filterIsInstance().any { gr ->
gr.extra[TabbedContentTypeExtra]?.value == type
@@ -274,7 +265,6 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
fun PageNode.childrenRec(): List = listOf(this) + children.flatMap { it.childrenRec() }
- @OnlyDescriptors("Enum entry [SMTH] does not have functions") // TODO
@Test
fun `should merge enum entries`() {
testInline(
@@ -304,7 +294,8 @@ class MergeImplicitExpectActualDeclarationsTest : BaseAbstractTest() {
assertNotNull(classPage, "Tested class not found!")
val functions = classPage.findSectionWithName("Functions").assertNotNull("Functions")
- val method1 = functions.children.singleOrNull().assertNotNull("method1")
+ val method1 = functions.children.single { it.sourceSets.size == 2 && it.dci.dri.singleOrNull()?.callable?.name == "method1" }
+ .assertNotNull("method1")
assertEquals(
2,
diff --git a/plugins/base/src/test/kotlin/utils/contentUtils.kt b/plugins/base/src/test/kotlin/utils/contentUtils.kt
index b83d8697bb..3ca0bd2d6c 100644
--- a/plugins/base/src/test/kotlin/utils/contentUtils.kt
+++ b/plugins/base/src/test/kotlin/utils/contentUtils.kt
@@ -5,10 +5,9 @@
package utils
import matchers.content.*
-import org.jetbrains.dokka.pages.BasicTabbedContentType
-import org.jetbrains.dokka.pages.ContentGroup
-import org.jetbrains.dokka.pages.ContentPage
-import org.jetbrains.dokka.pages.RootPageNode
+import org.jetbrains.dokka.model.dfs
+import org.jetbrains.dokka.pages.*
+import kotlin.test.assertEquals
//TODO: Try to unify those functions after update to 1.4
fun ContentMatcherBuilder<*>.functionSignature(
@@ -327,6 +326,24 @@ fun ContentMatcherBuilder<*>.unwrapAnnotation(elem: Map.Entry PageNode.contentPage(name: String, block: T.() -> Unit) {
+ (dfs { it.name == name } as? T).assertNotNull("The page `$name` is not found").block()
+}
+
+fun ClasslikePageNode.assertHasFunctions(vararg expectedFunctionName: String) {
+ val functions = this.findSectionWithName("Functions").assertNotNull("Functions")
+ val functionsName = functions.children.map { (it.dfs { it is ContentText } as ContentText).text }
+ assertEquals(expectedFunctionName.toList(), functionsName)
+}
+
+fun ClasslikePageNode.findSectionWithName(name: String) : ContentNode? {
+ var sectionHeader: ContentHeader? = null
+ return content.dfs { node ->
+ node.children.filterIsInstance().any { header ->
+ header.children.firstOrNull { it is ContentText && it.text == name }?.also { sectionHeader = header } != null
+ }
+ }?.children?.dropWhile { child -> child != sectionHeader }?.drop(1)?.firstOrNull()
+}
data class ParamAttributes(
val annotations: Map>,
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
index 4e741d09e1..f217c88f9f 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
@@ -343,7 +343,30 @@ internal class DokkaSymbolVisitor(
KtClassKind.ANONYMOUS_OBJECT -> throw NotImplementedError("ANONYMOUS_OBJECT does not support")
KtClassKind.ENUM_CLASS -> {
- val entries = namedClassOrObjectSymbol.getEnumEntries().map { visitEnumEntrySymbol(it) }
+ /**
+ * See https://github.com/Kotlin/dokka/issues/3129
+ *
+ * e.g. the `A` enum entry in the `enum E` is
+ * ```
+ * static val A: E = object : E() {
+ * val x: Int = 5
+ * }
+ * ```
+ * it needs to exclude all static members like `values` and `valueOf` from the enum class's scope
+ */
+ val enumEntryScope = lazy {
+ getDokkaScopeFrom(namedClassOrObjectSymbol, dri, includeStaticScope = false).let {
+ it.copy(
+ functions = it.functions.map { it.withNewExtras( it.extra + InheritedMember(dri.copy(callable = null).toSourceSetDependent())) },
+ properties = it.properties.map { it.withNewExtras( it.extra + InheritedMember(dri.copy(callable = null).toSourceSetDependent())) }
+ )
+ }
+ }
+
+ val entries =
+ namedClassOrObjectSymbol.getEnumEntries().map {
+ visitEnumEntrySymbol(it, enumEntryScope.value)
+ }
DEnum(
dri = dri,
@@ -383,12 +406,17 @@ internal class DokkaSymbolVisitor(
val properties: List,
val classlikes: List
)
+
+ /**
+ * @param includeStaticScope flag to add static members, e.g. `valueOf`, `values` and `entries` members for Enum
+ */
private fun KtAnalysisSession.getDokkaScopeFrom(
namedClassOrObjectSymbol: KtNamedClassOrObjectSymbol,
- dri: DRI
+ dri: DRI,
+ includeStaticScope: Boolean = true
): DokkaScope {
// e.g. getStaticMemberScope contains `valueOf`, `values` and `entries` members for Enum
- val scope = listOf(namedClassOrObjectSymbol.getMemberScope(), namedClassOrObjectSymbol.getStaticMemberScope()).asCompositeScope()
+ val scope = if(includeStaticScope) listOf(namedClassOrObjectSymbol.getMemberScope(), namedClassOrObjectSymbol.getStaticMemberScope()).asCompositeScope() else namedClassOrObjectSymbol.getMemberScope()
val constructors = scope.getConstructors().map { visitConstructorSymbol(it) }.toList()
val callables = scope.getCallableSymbols().toList()
@@ -453,28 +481,18 @@ internal class DokkaSymbolVisitor(
}
private fun KtAnalysisSession.visitEnumEntrySymbol(
- enumEntrySymbol: KtEnumEntrySymbol
+ enumEntrySymbol: KtEnumEntrySymbol, scope: DokkaScope
): DEnumEntry = withExceptionCatcher(enumEntrySymbol) {
val dri = getDRIFromEnumEntry(enumEntrySymbol)
val isExpect = false
- val scope = enumEntrySymbol.getMemberScope()
- val callables = scope.getCallableSymbols().toList()
- val classifiers = scope.getClassifierSymbols().toList()
-
- val functions = callables.filterIsInstance().map { visitFunctionSymbol(it, dri) }
- val properties = callables.filterIsInstance().map { visitPropertySymbol(it, dri) }
- val classlikes =
- classifiers.filterIsInstance()
- .map { visitNamedClassOrObjectSymbol(it, dri) }
-
return DEnumEntry(
dri = dri,
name = enumEntrySymbol.name.asString(),
documentation = getDocumentation(enumEntrySymbol)?.toSourceSetDependent() ?: emptyMap(),
- functions = functions,
- properties = properties,
- classlikes = classlikes,
+ functions = scope.functions,
+ properties = scope.properties,
+ classlikes = emptyList(), // always empty, see https://github.com/Kotlin/dokka/issues/3129
sourceSets = setOf(sourceSet),
expectPresentInSet = sourceSet.takeIf { isExpect },
extra = PropertyContainer.withAll(
From edd51958c657e0aa226a584b6c7b8d0749641b9f Mon Sep 17 00:00:00 2001
From: Vadim Mishenev
Date: Wed, 11 Oct 2023 20:00:09 +0300
Subject: [PATCH 03/72] Avoid calling analyze on built-ins (#3200)
Otherwise, `Caused by: org.jetbrains.kotlin.utils.exceptions.KotlinIllegalArgumentExceptionWithAttachments: Unexpected class org.jetbrains.kotlin.analysis.project.structure.KtBuiltinsModule
at org.jetbrains.kotlin.analysis.low.level.api.fir.util.ExceptionUtilsKt.errorWithFirSpecificEntries(exceptionUtils.kt:50)`
---
.../kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt | 2 +-
.../services/SymbolFullClassHierarchyBuilder.kt | 14 ++++++++++----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt
index 43435a55ca..ef79514567 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/SymbolsAnalysisPlugin.kt
@@ -93,7 +93,7 @@ public class SymbolsAnalysisPlugin : DokkaPlugin() {
plugin().documentableSourceLanguageParser providing { KotlinDocumentableSourceLanguageParser() }
}
internal val symbolFullClassHierarchyBuilder by extending {
- plugin().fullClassHierarchyBuilder providing { SymbolFullClassHierarchyBuilder() }
+ plugin().fullClassHierarchyBuilder providing ::SymbolFullClassHierarchyBuilder
}
internal val symbolSyntheticDocumentableDetector by extending {
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt
index 375aee9065..0e90bec8e8 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/services/SymbolFullClassHierarchyBuilder.kt
@@ -16,12 +16,18 @@ import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.dokka.analysis.kotlin.internal.ClassHierarchy
import org.jetbrains.dokka.analysis.kotlin.internal.FullClassHierarchyBuilder
import org.jetbrains.dokka.analysis.kotlin.internal.Supertypes
+import org.jetbrains.dokka.analysis.kotlin.symbols.plugin.SymbolsAnalysisPlugin
+import org.jetbrains.dokka.plugability.DokkaContext
+import org.jetbrains.dokka.plugability.plugin
+import org.jetbrains.dokka.plugability.querySingle
import org.jetbrains.kotlin.psi.KtClassOrObject
import java.util.concurrent.ConcurrentHashMap
-internal class SymbolFullClassHierarchyBuilder : FullClassHierarchyBuilder {
- override suspend fun build(module: DModule): ClassHierarchy {
+internal class SymbolFullClassHierarchyBuilder(val context: DokkaContext) : FullClassHierarchyBuilder {
+ private val kotlinAnalysis = context.plugin().querySingle { kotlinAnalysis }
+
+ override suspend fun build(module: DModule): ClassHierarchy {
val map = module.sourceSets.associateWith { ConcurrentHashMap>() }
module.packages.forEach { visitDocumentable(it, map) }
return map
@@ -41,7 +47,7 @@ internal class SymbolFullClassHierarchyBuilder : FullClassHierarchyBuilder {
if (supersMap[dri] == null) {
supersMap[dri] = supertypesDriWithKType.map { it.first }
- supertypesDriWithKType.forEach{ collectSupertypesFromKtType(it, supersMap) }
+ supertypesDriWithKType.forEach { collectSupertypesFromKtType(it, supersMap) }
}
}
@@ -73,7 +79,7 @@ internal class SymbolFullClassHierarchyBuilder : FullClassHierarchyBuilder {
documentable.sources.forEach { (sourceSet, source) ->
if (source is KtPsiDocumentableSource) {
(source.psi as? KtClassOrObject)?.let { psi ->
- analyze(psi) {
+ analyze(kotlinAnalysis[sourceSet].mainModule) {
val type = psi.getNamedClassOrObjectSymbol()?.buildSelfClassType() ?: return@analyze
hierarchy[sourceSet]?.let { collectSupertypesFromKtType(documentable.dri to type, it) }
}
From 33210a46c7f92f868af98efa04c31295c7a224bf Mon Sep 17 00:00:00 2001
From: Vadim Mishenev
Date: Wed, 11 Oct 2023 20:01:55 +0300
Subject: [PATCH 04/72] [K2] Migrate to new standalone API (#3201)
* Migrate K2-Based dokka to use the new standalone mode API
see https://youtrack.jetbrains.com/issue/KT-60884
* Do not use copy-n-pasted code from Analysis API in K2-Based Dokka
see https://youtrack.jetbrains.com/issue/KT-60884
* Remove copy-n-pasted API from Analysis API in K2-Based Dokka
as it's now unused
see https://youtrack.jetbrains.com/issue/KT-60884
* Update version Analysis API to 1.9.30-dev-3330
---------
Co-authored-by: Ilya Kirillov
---
gradle/libs.versions.toml | 2 +-
.../analysis-kotlin-symbols/build.gradle.kts | 3 +-
.../kotlin/symbols/plugin/AnalysisContext.kt | 3 +-
.../kotlin/symbols/plugin/KotlinAnalysis.kt | 194 +++---------------
.../DefaultSymbolToDocumentableTranslator.kt | 5 +-
5 files changed, 34 insertions(+), 173 deletions(-)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 6acd2a57a1..83bfe621f7 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -11,7 +11,7 @@ kotlinx-bcv = "0.12.1"
## Analysis
kotlin-compiler = "1.9.10"
-kotlin-compiler-k2 = "1.9.0-release-358"
+kotlin-compiler-k2 = "1.9.30-dev-3330"
# MUST match the version of the intellij platform used in the kotlin compiler,
# otherwise this will lead to different versions of psi API and implementations
diff --git a/subprojects/analysis-kotlin-symbols/build.gradle.kts b/subprojects/analysis-kotlin-symbols/build.gradle.kts
index c1705e9f3a..6733b7788a 100644
--- a/subprojects/analysis-kotlin-symbols/build.gradle.kts
+++ b/subprojects/analysis-kotlin-symbols/build.gradle.kts
@@ -54,7 +54,6 @@ dependencies {
listOf(
libs.kotlin.high.level.api.api,
libs.kotlin.analysis.api.standalone,
- libs.kotlin.high.level.api.impl // for Standalone prototype
).forEach {
implementation(it) {
isTransitive = false // see KTIJ-19820
@@ -67,7 +66,7 @@ dependencies {
libs.kotlin.low.level.api.fir,
libs.kotlin.analysis.project.structure,
libs.kotlin.analysis.api.providers,
- libs.kotlin.symbol.light.classes
+ libs.kotlin.symbol.light.classes,
).forEach {
runtimeOnly(it) {
isTransitive = false // see KTIJ-19820
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt
index 9ccd52b297..cf57e81539 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/AnalysisContext.kt
@@ -125,11 +125,12 @@ internal open class EnvironmentKotlinAnalysis(
internal interface AnalysisContext: Closeable {
val project: Project
val mainModule: KtSourceModule
+ val analysisSession: StandaloneAnalysisAPISession
}
private class AnalysisContextImpl(
override val mainModule: KtSourceModule,
- private val analysisSession: StandaloneAnalysisAPISession,
+ override val analysisSession: StandaloneAnalysisAPISession,
private val applicationDisposable: Disposable,
private val projectDisposable: Disposable
) : AnalysisContext {
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt
index 9419ec651c..a6155fb028 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/plugin/KotlinAnalysis.kt
@@ -4,19 +4,11 @@
package org.jetbrains.dokka.analysis.kotlin.symbols.plugin
-import com.intellij.core.CoreApplicationEnvironment
import com.intellij.openapi.Disposable
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.vfs.StandardFileSystems
-import com.intellij.openapi.vfs.VirtualFileManager
-import com.intellij.psi.PsiFileSystemItem
-import com.intellij.psi.PsiManager
-import com.intellij.psi.search.GlobalSearchScope
-import com.intellij.psi.search.ProjectScope
-import com.intellij.util.io.URLUtil
import org.jetbrains.dokka.Platform
-import org.jetbrains.kotlin.analysis.api.impl.base.util.LibraryUtils
-import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider
+import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
+import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
+import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.StandaloneAnalysisAPISession
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
@@ -24,18 +16,12 @@ import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleBuilder
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSdkModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSourceModule
-import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.config.*
-import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.platform.konan.NativePlatforms
-import org.jetbrains.kotlin.psi.KtFile
import java.io.File
-import java.io.IOException
-import java.nio.file.*
-import java.nio.file.attribute.BasicFileAttributes
internal fun Platform.toTargetPlatform() = when (this) {
Platform.js, Platform.wasm -> JsPlatforms.defaultJsPlatform
@@ -71,6 +57,7 @@ internal fun getLanguageVersionSettings(
}
// it should be changed after https://github.com/Kotlin/dokka/issues/3114
+@OptIn(KtAnalysisApiInternals::class)
internal fun createAnalysisSession(
classpath: List,
sourceRoots: Set,
@@ -87,163 +74,40 @@ internal fun createAnalysisSession(
projectDisposable = projectDisposable,
withPsiDeclarationFromBinaryModuleProvider = false
) {
- val project = project
+ registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
val targetPlatform = analysisPlatform.toTargetPlatform()
- fun KtModuleBuilder.addModuleDependencies(moduleName: String) {
+
+ buildKtModuleProvider {
val libraryRoots = classpath
- addRegularDependency(
- buildKtLibraryModule {
- contentScope = ProjectScope.getLibrariesScope(project)
- this.platform = targetPlatform
- this.project = project
- binaryRoots = libraryRoots.map { it.toPath() }
- libraryName = "Library for $moduleName"
- }
- )
- getJdkHomeFromSystemProperty()?.let { jdkHome ->
- val vfm = VirtualFileManager.getInstance()
- val jdkHomePath = jdkHome.toPath()
- val jdkHomeVirtualFile = vfm.findFileByNioPath(jdkHome.toPath())//vfm.findFileByPath(jdkHomePath)
- val binaryRoots = LibraryUtils.findClassesFromJdkHome(jdkHomePath).map {
- Paths.get(URLUtil.extractPath(it))
- }
+ fun KtModuleBuilder.addModuleDependencies(moduleName: String) {
addRegularDependency(
- buildKtSdkModule {
- contentScope = GlobalSearchScope.fileScope(project, jdkHomeVirtualFile)
+ buildKtLibraryModule {
this.platform = targetPlatform
- this.project = project
- this.binaryRoots = binaryRoots
- sdkName = "JDK for $moduleName"
+ addBinaryRoots(libraryRoots.map { it.toPath() })
+ libraryName = "Library for $moduleName"
}
)
+ getJdkHomeFromSystemProperty()?.let { jdkHome ->
+ addRegularDependency(
+ buildKtSdkModule {
+ this.platform = targetPlatform
+ addBinaryRootsFromJdkHome(jdkHome.toPath(), isJre = true)
+ sdkName = "JDK for $moduleName"
+ }
+ )
+ }
+ }
+ sourceModule = buildKtSourceModule {
+ languageVersionSettings = getLanguageVersionSettings(languageVersion, apiVersion)
+ platform = targetPlatform
+ moduleName = ""
+ // TODO: We should handle (virtual) file changes announced via LSP with the VFS
+ addSourceRoots(sourceRoots.map { it.toPath() })
+ addModuleDependencies(moduleName)
}
- }
- sourceModule = buildKtSourceModule {
- this.languageVersionSettings = getLanguageVersionSettings(languageVersion, apiVersion)
-
- //val fs = StandardFileSystems.local()
- //val psiManager = PsiManager.getInstance(project)
- // TODO: We should handle (virtual) file changes announced via LSP with the VFS
- /*val ktFiles = sources
- .flatMap { Files.walk(it).toList() }
- .mapNotNull { fs.findFileByPath(it.toString()) }
- .mapNotNull { psiManager.findFile(it) }
- .map { it as KtFile }*/
- val sourcePaths = sourceRoots.map { it.absolutePath }
- val (ktFilePath, javaFilePath) = getSourceFilePaths(sourcePaths).partition { it.endsWith(KotlinFileType.EXTENSION) }
- val javaFiles: List = getPsiFilesFromPaths(project, javaFilePath)
- val ktFiles: List = getPsiFilesFromPaths(project, getSourceFilePaths(ktFilePath))
- addSourceRoots(ktFiles + javaFiles)
- contentScope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles)
- platform = targetPlatform
- moduleName = ""
- this.project = project
- addModuleDependencies(moduleName)
- }
-
- buildKtModuleProvider {
platform = targetPlatform
- this.project = project
addModule(sourceModule!!)
}
}
- // TODO remove further
- CoreApplicationEnvironment.registerExtensionPoint(
- analysisSession.project.extensionArea,
- KtResolveExtensionProvider.EP_NAME.name,
- KtResolveExtensionProvider::class.java
- )
return Pair(analysisSession, sourceModule ?: throw IllegalStateException())
-}
-
-// ----------- copy-paste from Analysis API ----------------------------------------------------------------------------
-/**
- * Collect source file path from the given [root] store them in [result].
- *
- * E.g., for `project/app/src` as a [root], this will walk the file tree and
- * collect all `.kt` and `.java` files under that folder.
- *
- * Note that this util gracefully skips [IOException] during file tree traversal.
- */
-internal fun collectSourceFilePaths(
- root: Path,
- result: MutableSet
-) {
- // NB: [Files#walk] throws an exception if there is an issue during IO.
- // With [Files#walkFileTree] with a custom visitor, we can take control of exception handling.
- Files.walkFileTree(
- root,
- object : SimpleFileVisitor() {
- override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
- return if (Files.isReadable(dir))
- FileVisitResult.CONTINUE
- else
- FileVisitResult.SKIP_SUBTREE
- }
-
- override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
- if (!Files.isRegularFile(file) || !Files.isReadable(file))
- return FileVisitResult.CONTINUE
- val ext = file.toFile().extension
- if (ext == KotlinFileType.EXTENSION || ext == "java"/*JavaFileType.DEFAULT_EXTENSION*/) {
- result.add(file.toString())
- }
- return FileVisitResult.CONTINUE
- }
-
- override fun visitFileFailed(file: Path, exc: IOException?): FileVisitResult {
- // TODO: report or log [IOException]?
- // NB: this intentionally swallows the exception, hence fail-safe.
- // Skipping subtree doesn't make any sense, since this is not a directory.
- // Skipping sibling may drop valid file paths afterward, so we just continue.
- return FileVisitResult.CONTINUE
- }
- }
- )
-}
-
-/**
- * Collect source file path as [String] from the given source roots in [sourceRoot].
- *
- * this util collects all `.kt` and `.java` files under source roots.
- */
-internal fun getSourceFilePaths(
- sourceRoot: Collection,
- includeDirectoryRoot: Boolean = false,
-): Set {
- val result = mutableSetOf()
- sourceRoot.forEach { srcRoot ->
- val path = Paths.get(srcRoot)
- if (Files.isDirectory(path)) {
- // E.g., project/app/src
- collectSourceFilePaths(path, result)
- if (includeDirectoryRoot) {
- result.add(srcRoot)
- }
- } else {
- // E.g., project/app/src/some/pkg/main.kt
- result.add(srcRoot)
- }
- }
-
- return result
-}
-
-internal inline fun getPsiFilesFromPaths(
- project: Project,
- paths: Collection,
-): List {
- val fs = StandardFileSystems.local()
- val psiManager = PsiManager.getInstance(project)
- val result = mutableListOf()
- for (path in paths) {
- val vFile = fs.findFileByPath(path) ?: continue
- val psiFileSystemItem =
- if (vFile.isDirectory)
- psiManager.findDirectory(vFile) as? T
- else
- psiManager.findFile(vFile) as? T
- psiFileSystemItem?.let { result.add(it) }
- }
- return result
-}
+}
\ No newline at end of file
diff --git a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
index f217c88f9f..74d312690f 100644
--- a/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
+++ b/subprojects/analysis-kotlin-symbols/src/main/kotlin/org/jetbrains/dokka/analysis/kotlin/symbols/translators/DefaultSymbolToDocumentableTranslator.kt
@@ -118,10 +118,7 @@ internal class DokkaSymbolVisitor(
}
fun visitModule(): DModule {
- val ktFiles: List = getPsiFilesFromPaths(
- analysisContext.project,
- getSourceFilePaths(sourceSet.sourceRoots.map { it.canonicalPath })
- )
+ val ktFiles = analysisContext.analysisSession.modulesWithFiles.entries.single().value.filterIsInstance()
val processedPackages: MutableSet = mutableSetOf()
return analyze(analysisContext.mainModule) {
val packageSymbols: List = ktFiles
From 514cbb11962ba77abf5b35f7698b84f1aef1e813 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Thu, 12 Oct 2023 11:40:43 +1300
Subject: [PATCH 05/72] Fix Maven plugin help task (#3036)
Fixes #3035
---
.../conventions/maven-cli-setup.gradle.kts | 3 -
.../dokka/it/maven/MavenIntegrationTest.kt | 50 +++++++++-
.../jetbrains/dokka/it/TestOutputCopier.kt | 2 +-
runners/maven-plugin/api/maven-plugin.api | 5 +
runners/maven-plugin/build.gradle.kts | 93 +++++++++++--------
runners/maven-plugin/pom.template.xml | 26 ++++++
6 files changed, 133 insertions(+), 46 deletions(-)
diff --git a/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts b/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts
index 8d228bc355..f07ff98d6b 100644
--- a/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts
+++ b/build-logic/src/main/kotlin/org/jetbrains/conventions/maven-cli-setup.gradle.kts
@@ -22,7 +22,6 @@ plugins {
abstract class MavenCliSetupExtension {
abstract val mavenVersion: Property
abstract val mavenPluginToolsVersion: Property
- abstract val mavenBuildDir: DirectoryProperty
/** Directory that will contain the unpacked Apache Maven dependency */
abstract val mavenInstallDir: DirectoryProperty
@@ -43,7 +42,6 @@ val mavenCliSetupExtension =
mavenVersion.convention(libs.versions.apacheMaven.core)
mavenPluginToolsVersion.convention(libs.versions.apacheMaven.pluginTools)
- mavenBuildDir.convention(layout.buildDirectory.dir("maven"))
mavenInstallDir.convention(layout.buildDirectory.dir("apache-maven"))
val isWindowsProvider =
@@ -81,7 +79,6 @@ val mavenBinary by configurations.registering {
}
tasks.clean {
- delete(mavenCliSetupExtension.mavenBuildDir)
delete(mavenCliSetupExtension.mavenInstallDir)
}
diff --git a/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt b/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt
index 92bdc45ecd..7606072c80 100644
--- a/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt
+++ b/integration-tests/maven/src/integrationTest/kotlin/org/jetbrains/dokka/it/maven/MavenIntegrationTest.kt
@@ -4,9 +4,10 @@
package org.jetbrains.dokka.it.maven
+import org.intellij.lang.annotations.Language
import org.jetbrains.dokka.it.AbstractIntegrationTest
-import org.jetbrains.dokka.it.awaitProcessResult
import org.jetbrains.dokka.it.ProcessResult
+import org.jetbrains.dokka.it.awaitProcessResult
import java.io.File
import kotlin.test.*
@@ -26,11 +27,33 @@ class MavenIntegrationTest : AbstractIntegrationTest() {
writeText(readText().replace("\$dokka_version", currentDokkaVersion))
}
val customResourcesDir = File(templateProjectDir, "customResources")
- if(customResourcesDir.exists() && customResourcesDir.isDirectory) {
+ if (customResourcesDir.exists() && customResourcesDir.isDirectory) {
customResourcesDir.copyRecursively(File(projectDir, "customResources"), overwrite = true)
}
}
+ @Test
+ fun `dokka help`() {
+ val result = ProcessBuilder().directory(projectDir)
+ .command(mavenBinaryFile.absolutePath, "dokka:help", "-U", "-e")
+ .start()
+ .awaitProcessResult()
+
+ // format the output to remove blank lines and make newlines system-independent
+ val output = result.output.lines().filter { it.isNotBlank() }.joinToString("\n")
+
+ assertContains(
+ output,
+ """
+ |This plugin has 4 goals:
+ |dokka:dokka
+ |dokka:help
+ |dokka:javadoc
+ |dokka:javadocJar
+ """.trimMargin()
+ )
+ }
+
@Test
fun `dokka dokka`() {
val result = ProcessBuilder().directory(projectDir)
@@ -67,7 +90,12 @@ class MavenIntegrationTest : AbstractIntegrationTest() {
)
assertTrue(stylesDir.resolve("custom-style-to-add.css").isFile)
projectDir.allHtmlFiles().forEach { file ->
- if(file.name != "navigation.html") assertTrue("custom-style-to-add.css" in file.readText(), "custom styles not added to html file ${file.name}")
+ if (file.name != "navigation.html") {
+ assertTrue(
+ "custom-style-to-add.css" in file.readText(),
+ "custom styles not added to html file ${file.name}"
+ )
+ }
}
assertTrue(stylesDir.resolve("custom-style-to-add.css").readText().contains("""/* custom stylesheet */"""))
assertTrue(imagesDir.resolve("custom-resource.svg").isFile)
@@ -172,4 +200,20 @@ class MavenIntegrationTest : AbstractIntegrationTest() {
)
)
}
+
+ companion object {
+ /*
+ * TODO replace with kotlin.test.assertContains after migrating to Kotlin language version 1.5+
+ */
+ fun assertContains(
+ charSequence: CharSequence,
+ @Language("TEXT") other: CharSequence,
+ ignoreCase: Boolean = false
+ ) {
+ asserter.assertTrue(
+ { "Expected the char sequence to contain the substring.\nCharSequence <$charSequence>, substring <$other>, ignoreCase <$ignoreCase>." },
+ charSequence.contains(other, ignoreCase)
+ )
+ }
+ }
}
diff --git a/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/TestOutputCopier.kt b/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/TestOutputCopier.kt
index 681c9d539f..2e2113a910 100644
--- a/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/TestOutputCopier.kt
+++ b/integration-tests/src/main/kotlin/org/jetbrains/dokka/it/TestOutputCopier.kt
@@ -15,6 +15,6 @@ public interface TestOutputCopier {
System.getenv("DOKKA_TEST_OUTPUT_PATH")?.also { location ->
println("Copying to ${File(location).absolutePath}")
projectOutputLocation.copyRecursively(File(location))
- } ?: println("No path via env. varbiable 'DOKKA_TEST_OUTPUT_PATH' provided, skipping copying")
+ } ?: println("No path via env. variable 'DOKKA_TEST_OUTPUT_PATH' provided, skipping copying")
}
}
diff --git a/runners/maven-plugin/api/maven-plugin.api b/runners/maven-plugin/api/maven-plugin.api
index 28d96bd3b6..069e7744ee 100644
--- a/runners/maven-plugin/api/maven-plugin.api
+++ b/runners/maven-plugin/api/maven-plugin.api
@@ -94,6 +94,11 @@ public final class org/jetbrains/dokka/maven/ExternalDocumentationLinkBuilder {
public final fun setUrl (Ljava/net/URL;)V
}
+public class org/jetbrains/dokka/maven/HelpMojo : org/apache/maven/plugin/AbstractMojo {
+ public fun ()V
+ public fun execute ()V
+}
+
public final class org/jetbrains/dokka/maven/MavenDokkaLogger : org/jetbrains/dokka/utilities/DokkaLogger {
public fun (Lorg/apache/maven/plugin/logging/Log;)V
public fun debug (Ljava/lang/String;)V
diff --git a/runners/maven-plugin/build.gradle.kts b/runners/maven-plugin/build.gradle.kts
index 5e27929835..825493ad27 100644
--- a/runners/maven-plugin/build.gradle.kts
+++ b/runners/maven-plugin/build.gradle.kts
@@ -2,7 +2,6 @@
* Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/
-import org.gradle.kotlin.dsl.support.appendReproducibleNewLine
import org.jetbrains.registerDokkaArtifactPublication
plugins {
@@ -47,77 +46,93 @@ val generatePom by tasks.registering(Sync::class) {
into(temporaryDir)
}
-val prepareMavenPluginBuildDir by tasks.registering(Sync::class) {
- description = "Prepares all files for Maven Plugin task execution"
+val prepareHelpMojoDir by tasks.registering(Sync::class) {
+ description = "Prepare files for generating the Maven Plugin HelpMojo"
group = mavenPluginTaskGroup
- from(tasks.compileKotlin.flatMap { it.destinationDirectory }) { into("classes/java/main") }
- from(tasks.compileJava.flatMap { it.destinationDirectory }) { into("classes/java/main") }
-
+ into(layout.buildDirectory.dir("maven-help-mojo"))
from(generatePom)
-
- into(mavenCliSetup.mavenBuildDir)
}
val helpMojo by tasks.registering(Exec::class) {
+ description = "Generate the Maven Plugin HelpMojo"
group = mavenPluginTaskGroup
- dependsOn(tasks.installMavenBinary, prepareMavenPluginBuildDir)
+ dependsOn(tasks.installMavenBinary, prepareHelpMojoDir)
- workingDir(mavenCliSetup.mavenBuildDir)
+ workingDir(prepareHelpMojoDir.map { it.destinationDir })
executable(mavenCliSetup.mvn.get())
args("-e", "-B", "org.apache.maven.plugins:maven-plugin-plugin:helpmojo")
- outputs.dir(mavenCliSetup.mavenBuildDir)
-
- doLast("normalize maven-plugin-help.properties") {
- // The maven-plugin-help.properties file contains a timestamp by default.
- // It should be removed as it is not reproducible and impacts Gradle caching
- val pluginHelpProperties = workingDir.resolve("maven-plugin-help.properties")
- pluginHelpProperties.writeText(
- buildString {
- val lines = pluginHelpProperties.readText().lines().iterator()
- // the first line is a descriptive comment
- appendReproducibleNewLine(lines.next())
- // the second line is the timestamp, which should be ignored
- lines.next()
- // the remaining lines are properties
- lines.forEach { appendReproducibleNewLine(it) }
- }
- )
+ outputs.dir(workingDir)
+}
+
+val helpMojoSources by tasks.registering(Sync::class) {
+ description = "Sync the HelpMojo source files into a SourceSet SrcDir"
+ group = mavenPluginTaskGroup
+ from(helpMojo) {
+ eachFile {
+ // drop 2 leading directories
+ relativePath = RelativePath(true, *relativePath.segments.drop(2).toTypedArray())
+ }
}
+ includeEmptyDirs = false
+ into(temporaryDir)
+ include("**/*.java")
+}
+
+val helpMojoResources by tasks.registering(Sync::class) {
+ description = "Sync the HelpMojo resource files into a SourceSet SrcDir"
+ group = mavenPluginTaskGroup
+ from(helpMojo)
+ into(temporaryDir)
+ include("**/**")
+ exclude("**/*.java")
+}
+
+sourceSets.main {
+ // use the generated HelpMojo as compilation input, so Gradle will automatically generate the mojo
+ java.srcDirs(helpMojoSources)
+ resources.srcDirs(helpMojoResources)
+}
+
+val preparePluginDescriptorDir by tasks.registering(Sync::class) {
+ description = "Prepare files for generating the Maven Plugin descriptor"
+ group = mavenPluginTaskGroup
+
+ into(layout.buildDirectory.dir("maven-plugin-descriptor"))
+
+ from(tasks.compileKotlin) { into("classes/java/main") }
+ from(tasks.compileJava) { into("classes/java/main") }
+ from(helpMojoResources)
}
val pluginDescriptor by tasks.registering(Exec::class) {
+ description = "Generate the Maven Plugin descriptor"
group = mavenPluginTaskGroup
- dependsOn(tasks.installMavenBinary, prepareMavenPluginBuildDir)
+ dependsOn(tasks.installMavenBinary, preparePluginDescriptorDir)
- workingDir(mavenCliSetup.mavenBuildDir)
+ workingDir(preparePluginDescriptorDir.map { it.destinationDir })
executable(mavenCliSetup.mvn.get())
- args(
- "-e",
- "-B",
- "org.apache.maven.plugins:maven-plugin-plugin:descriptor"
- )
+ args("-e", "-B", "org.apache.maven.plugins:maven-plugin-plugin:descriptor")
- outputs.dir(layout.buildDirectory.dir("maven/classes/java/main/META-INF/maven"))
+ outputs.dir("$workingDir/classes/java/main/META-INF/maven")
}
tasks.jar {
- dependsOn(pluginDescriptor, helpMojo)
metaInf {
- from(mavenCliSetup.mavenBuildDir.map { it.dir("classes/java/main/META-INF") })
+ from(pluginDescriptor) {
+ into("maven")
+ }
}
manifest {
attributes("Class-Path" to configurations.runtimeClasspath.map { configuration ->
configuration.resolve().joinToString(" ") { it.name }
})
}
- duplicatesStrategy = DuplicatesStrategy.WARN
}
-
registerDokkaArtifactPublication("dokkaMavenPlugin") {
artifactId = "dokka-maven-plugin"
}
diff --git a/runners/maven-plugin/pom.template.xml b/runners/maven-plugin/pom.template.xml
index 01ad60d268..b47951125d 100644
--- a/runners/maven-plugin/pom.template.xml
+++ b/runners/maven-plugin/pom.template.xml
@@ -12,6 +12,7 @@
maven-plugin
${mavenVersion}
+ UTF-8
@@ -21,10 +22,35 @@
${mavenPluginToolsVersion}
org.jetbrains.dokka.maven
+ true
+
+
+ default-descriptor
+
+ descriptor
+
+ process-classes
+
+
+ help-descriptor
+
+ helpmojo
+
+ process-classes
+
+
./
./classes/java/main
+
+
+ org.apache.maven.plugin-tools
+ maven-plugin-annotations
+ ${mavenPluginToolsVersion}
+ provided
+
+
From 6a55173f0e2c66488aa264d02363db41fb0e1213 Mon Sep 17 00:00:00 2001
From: Ignat Beresnev
Date: Mon, 16 Oct 2023 18:24:35 +0200
Subject: [PATCH 06/72] Bump kotlinx.html to 0.9.1 (#3206)
---
gradle/libs.versions.toml | 2 +-
plugins/base/api/base.api | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 83bfe621f7..75e0e305be 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -23,7 +23,7 @@ intellij-platform = "213.7172.25"
jsoup = "1.15.3"
freemarker = "2.3.31"
soywiz-korte = "2.7.0"
-kotlinx-html = "0.7.5"
+kotlinx-html = "0.9.1"
## Markdown
jetbrains-markdown = "0.3.1"
diff --git a/plugins/base/api/base.api b/plugins/base/api/base.api
index 360073fe10..788444b93c 100644
--- a/plugins/base/api/base.api
+++ b/plugins/base/api/base.api
@@ -549,7 +549,6 @@ public final class org/jetbrains/dokka/base/renderers/html/command/consumers/Imm
public fun onTagContentEntity (Lkotlinx/html/Entities;)V
public fun onTagContentUnsafe (Lkotlin/jvm/functions/Function1;)V
public fun onTagEnd (Lkotlinx/html/Tag;)V
- public fun onTagError (Lkotlinx/html/Tag;Ljava/lang/Throwable;)V
public fun onTagEvent (Lkotlinx/html/Tag;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V
public fun onTagStart (Lkotlinx/html/Tag;)V
public final fun processCommand (Lorg/jetbrains/dokka/base/templating/Command;Lkotlin/jvm/functions/Function1;)V
From 9bbcc21affe7a2b787c5a8cfb64f416cf226a0fd Mon Sep 17 00:00:00 2001
From: Ignat Beresnev
Date: Mon, 16 Oct 2023 18:36:42 +0200
Subject: [PATCH 07/72] Update Dokka's references to 1.9.10 (#3210)
---
CONTRIBUTING.md | 12 ++++-----
README.md | 14 +++++-----
.../src/doc/docs/developer_guide/workflow.md | 4 +--
docs/v.list | 4 +--
.../build.gradle.kts | 6 ++---
.../dokka-gradle-example/build.gradle.kts | 4 +--
.../build.gradle.kts | 10 +++----
.../build.gradle.kts | 4 +--
.../gradle.properties | 4 +--
.../build.gradle.kts | 4 +--
.../build.gradle.kts | 6 ++---
.../parentProject/build.gradle.kts | 2 +-
examples/maven/pom.xml | 4 +--
examples/plugin/hide-internal-api/README.md | 4 +--
.../plugin/hide-internal-api/build.gradle.kts | 4 +--
.../hide-internal-api/gradle.properties | 2 +-
gradle/libs.versions.toml | 2 +-
.../gradle/projects/it-basic/build.gradle.kts | 2 +-
.../it-configuration/build.gradle.kts | 2 +-
.../it/gradle/BasicGradleIntegrationTest.kt | 2 +-
plugins/kotlin-as-java/README.md | 2 +-
plugins/mathjax/README.md | 2 +-
plugins/versioning/README.md | 26 +++++++++----------
23 files changed, 63 insertions(+), 63 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f5b60bc1de..1dba67f59e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -23,9 +23,9 @@ Bug reports, feature requests and questions are welcome. Submit issues [here](ht
## Submitting PRs
-Dokka has extensive [Developer Guides](https://kotlin.github.io/dokka/1.9.0/developer_guide/introduction/) documentation
-which goes over the development [Workflow](https://kotlin.github.io/dokka/1.9.0/developer_guide/workflow/) and
-[Dokka's architecture](https://kotlin.github.io/dokka/1.9.0/developer_guide/architecture/architecture_overview/),
+Dokka has extensive [Developer Guides](https://kotlin.github.io/dokka/1.9.10/developer_guide/introduction/) documentation
+which goes over the development [Workflow](https://kotlin.github.io/dokka/1.9.10/developer_guide/workflow/) and
+[Dokka's architecture](https://kotlin.github.io/dokka/1.9.10/developer_guide/architecture/architecture_overview/),
which can help you understand how to achieve what you want and where to look.
All development (both new features and bugfixes) takes place in the `master` branch, it contains sources for the next
@@ -61,10 +61,10 @@ Unit tests which are run as part of `build` should not take much time, but you c
### Use/test locally built Dokka
Below you will find a bare-bones instruction on how to use and test locally built Dokka. For more details and examples,
-visit [Workflow](https://kotlin.github.io/dokka/1.9.0/developer_guide/workflow/) topic.
+visit [Workflow](https://kotlin.github.io/dokka/1.9.10/developer_guide/workflow/) topic.
1. Change `dokka_version` in `gradle.properties` to something that you will use later on as the dependency version.
- For instance, you can set it to something like `1.9.0-my-fix-SNAPSHOT`.
+ For instance, you can set it to something like `1.9.10-my-fix-SNAPSHOT`.
2. Publish it to Maven Local (`./gradlew publishToMavenLocal`)
3. In the project for which you want to generate documentation add Maven Local as a buildscript/dependency
repository (`mavenLocal()`)
@@ -72,7 +72,7 @@ visit [Workflow](https://kotlin.github.io/dokka/1.9.0/developer_guide/workflow/)
```kotlin
plugins {
- id("org.jetbrains.dokka") version "1.9.0-my-fix-SNAPSHOT"
+ id("org.jetbrains.dokka") version "1.9.10-my-fix-SNAPSHOT"
}
```
diff --git a/README.md b/README.md
index ff16e45d52..cc51bf8115 100644
--- a/README.md
+++ b/README.md
@@ -43,7 +43,7 @@ Apply the Gradle plugin for Dokka in the root build script of your project:
```kotlin
plugins {
- id("org.jetbrains.dokka") version "1.9.0"
+ id("org.jetbrains.dokka") version "1.9.10"
}
```
@@ -65,7 +65,7 @@ Apply Gradle plugin for Dokka in the root project:
```groovy
plugins {
- id 'org.jetbrains.dokka' version '1.9.0'
+ id 'org.jetbrains.dokka' version '1.9.10'
}
```
@@ -99,7 +99,7 @@ Add the Dokka Maven plugin to the `plugins` section of your POM file:
org.jetbrains.dokka
dokka-maven-plugin
- 1.9.0
+ 1.9.10
pre-site
@@ -138,7 +138,7 @@ Android platform:
```kotlin
dependencies {
- dokkaPlugin("org.jetbrains.dokka:android-documentation-plugin:1.9.0")
+ dokkaPlugin("org.jetbrains.dokka:android-documentation-plugin:1.9.10")
}
```
@@ -149,7 +149,7 @@ dependencies {
```groovy
dependencies {
- dokkaPlugin 'org.jetbrains.dokka:android-documentation-plugin:1.9.0'
+ dokkaPlugin 'org.jetbrains.dokka:android-documentation-plugin:1.9.10'
}
```
@@ -168,7 +168,7 @@ dependencies {
org.jetbrains.dokka
android-documentation-plugin
- 1.9.0
+ 1.9.10
@@ -215,7 +215,7 @@ implement plugins for missing or very specific features that are not provided ou
Learn more about Dokka plugins and their configuration in [Dokka plugins](https://kotlinlang.org/docs/dokka-plugins.html).
If you want to learn how to develop Dokka plugins, see
-[Developer guides](https://kotlin.github.io/dokka/1.9.0/developer_guide/introduction/).
+[Developer guides](https://kotlin.github.io/dokka/1.9.10/developer_guide/introduction/).
## Community
diff --git a/docs-developer/src/doc/docs/developer_guide/workflow.md b/docs-developer/src/doc/docs/developer_guide/workflow.md
index 26452281bb..4b08d44fae 100644
--- a/docs-developer/src/doc/docs/developer_guide/workflow.md
+++ b/docs-developer/src/doc/docs/developer_guide/workflow.md
@@ -42,7 +42,7 @@ Having built Dokka locally, you can publish it to `mavenLocal()`. This will allo
project as well as debug code remotely.
1. Change `dokka_version` in `gradle.properties` to something that you will use later on as the dependency version.
- For instance, you can set it to something like `1.9.0-my-fix-SNAPSHOT`. This version will be propagated to plugins
+ For instance, you can set it to something like `1.9.10-my-fix-SNAPSHOT`. This version will be propagated to plugins
that reside inside Dokka's project (such as `mathjax`, `kotlin-as-java`, etc).
2. Publish it to Maven Local (`./gradlew publishToMavenLocal`). Corresponding artifacts should appear in `~/.m2`
3. In the project you want to generate documentation for or debug on, add maven local as a plugin/dependency
@@ -55,7 +55,7 @@ repositories {
4. Update your Dokka dependency to the version you've just published:
```kotlin
plugins {
- id("org.jetbrains.dokka") version "1.9.0-my-fix-SNAPSHOT"
+ id("org.jetbrains.dokka") version "1.9.10-my-fix-SNAPSHOT"
}
```
diff --git a/docs/v.list b/docs/v.list
index c17d5c7fbf..34141810d4 100644
--- a/docs/v.list
+++ b/docs/v.list
@@ -4,9 +4,9 @@
diff --git a/examples/gradle/dokka-customFormat-example/build.gradle.kts b/examples/gradle/dokka-customFormat-example/build.gradle.kts
index 280b8edbd0..eb647a7e20 100644
--- a/examples/gradle/dokka-customFormat-example/build.gradle.kts
+++ b/examples/gradle/dokka-customFormat-example/build.gradle.kts
@@ -7,13 +7,13 @@ import org.jetbrains.dokka.base.DokkaBase
import org.jetbrains.dokka.base.DokkaBaseConfiguration
plugins {
- kotlin("jvm") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0"
+ kotlin("jvm") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10"
}
buildscript {
dependencies {
- classpath("org.jetbrains.dokka:dokka-base:1.9.0")
+ classpath("org.jetbrains.dokka:dokka-base:1.9.10")
}
}
diff --git a/examples/gradle/dokka-gradle-example/build.gradle.kts b/examples/gradle/dokka-gradle-example/build.gradle.kts
index 0d09f96fe8..330e01046f 100644
--- a/examples/gradle/dokka-gradle-example/build.gradle.kts
+++ b/examples/gradle/dokka-gradle-example/build.gradle.kts
@@ -6,8 +6,8 @@ import org.jetbrains.dokka.gradle.DokkaTask
import java.net.URL
plugins {
- kotlin("jvm") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0"
+ kotlin("jvm") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10"
}
repositories {
diff --git a/examples/gradle/dokka-kotlinAsJava-example/build.gradle.kts b/examples/gradle/dokka-kotlinAsJava-example/build.gradle.kts
index f971188355..83673de772 100644
--- a/examples/gradle/dokka-kotlinAsJava-example/build.gradle.kts
+++ b/examples/gradle/dokka-kotlinAsJava-example/build.gradle.kts
@@ -3,8 +3,8 @@
*/
plugins {
- kotlin("jvm") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0"
+ kotlin("jvm") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10"
}
repositories {
@@ -15,11 +15,11 @@ dependencies {
testImplementation(kotlin("test-junit"))
// Will apply the plugin to all Dokka tasks
- dokkaPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.9.0")
+ dokkaPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.9.10")
// Will apply the plugin only to the `:dokkaHtml` task
- //dokkaHtmlPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.9.0")
+ //dokkaHtmlPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.9.10")
// Will apply the plugin only to the `:dokkaGfm` task
- //dokkaGfmPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.9.0")
+ //dokkaGfmPlugin("org.jetbrains.dokka:kotlin-as-java-plugin:1.9.10")
}
diff --git a/examples/gradle/dokka-library-publishing-example/build.gradle.kts b/examples/gradle/dokka-library-publishing-example/build.gradle.kts
index 003aa04f46..ac6678e338 100644
--- a/examples/gradle/dokka-library-publishing-example/build.gradle.kts
+++ b/examples/gradle/dokka-library-publishing-example/build.gradle.kts
@@ -3,8 +3,8 @@
*/
plugins {
- kotlin("jvm") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0"
+ kotlin("jvm") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10"
`java-library`
`maven-publish`
}
diff --git a/examples/gradle/dokka-multimodule-example/gradle.properties b/examples/gradle/dokka-multimodule-example/gradle.properties
index fda31413f2..18c74db645 100644
--- a/examples/gradle/dokka-multimodule-example/gradle.properties
+++ b/examples/gradle/dokka-multimodule-example/gradle.properties
@@ -2,5 +2,5 @@
# Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
#
-kotlinVersion=1.9.0
-dokkaVersion=1.9.0
+kotlinVersion=1.9.10
+dokkaVersion=1.9.10
diff --git a/examples/gradle/dokka-multiplatform-example/build.gradle.kts b/examples/gradle/dokka-multiplatform-example/build.gradle.kts
index 56c03564c4..df4ea0147f 100644
--- a/examples/gradle/dokka-multiplatform-example/build.gradle.kts
+++ b/examples/gradle/dokka-multiplatform-example/build.gradle.kts
@@ -8,8 +8,8 @@ import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.dokka.Platform
plugins {
- kotlin("multiplatform") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0"
+ kotlin("multiplatform") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10"
}
repositories {
diff --git a/examples/gradle/dokka-versioning-multimodule-example/build.gradle.kts b/examples/gradle/dokka-versioning-multimodule-example/build.gradle.kts
index 3984caa598..88a78e376c 100644
--- a/examples/gradle/dokka-versioning-multimodule-example/build.gradle.kts
+++ b/examples/gradle/dokka-versioning-multimodule-example/build.gradle.kts
@@ -3,8 +3,8 @@
*/
plugins {
- kotlin("jvm") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0" apply false
+ kotlin("jvm") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10" apply false
}
// The versioning plugin must be applied in all submodules
@@ -18,6 +18,6 @@ subprojects {
}
val dokkaPlugin by configurations
dependencies {
- dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.9.0")
+ dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.9.10")
}
}
diff --git a/examples/gradle/dokka-versioning-multimodule-example/parentProject/build.gradle.kts b/examples/gradle/dokka-versioning-multimodule-example/parentProject/build.gradle.kts
index 4bcee1609d..9fc84cbaac 100644
--- a/examples/gradle/dokka-versioning-multimodule-example/parentProject/build.gradle.kts
+++ b/examples/gradle/dokka-versioning-multimodule-example/parentProject/build.gradle.kts
@@ -8,7 +8,7 @@ import org.jetbrains.dokka.versioning.VersioningConfiguration
buildscript {
dependencies {
- classpath("org.jetbrains.dokka:versioning-plugin:1.9.0")
+ classpath("org.jetbrains.dokka:versioning-plugin:1.9.10")
}
repositories {
diff --git a/examples/maven/pom.xml b/examples/maven/pom.xml
index 811e490236..11a6428b2d 100644
--- a/examples/maven/pom.xml
+++ b/examples/maven/pom.xml
@@ -12,8 +12,8 @@
kotlin-maven-example
1.0-SNAPSHOT
- 1.9.0
- 1.9.0
+ 1.9.10
+ 1.9.10
diff --git a/examples/plugin/hide-internal-api/README.md b/examples/plugin/hide-internal-api/README.md
index f186d2e0c9..d06e97b58b 100644
--- a/examples/plugin/hide-internal-api/README.md
+++ b/examples/plugin/hide-internal-api/README.md
@@ -1,7 +1,7 @@
# Hide Internal API plugin example
This project represents a simple Dokka Plugin that was developed step-by-step in the
-[Sample plugin](https://kotlin.github.io/dokka/1.9.0/developer_guide/plugin-development/sample-plugin-tutorial/)
+[Sample plugin](https://kotlin.github.io/dokka/1.9.10/developer_guide/plugin-development/sample-plugin-tutorial/)
tutorial. This is a frequent request with varying requirements.
The plugin excludes any declaration that is marked with `org.jetbrains.dokka.internal.test.Internal` annotation.
@@ -9,7 +9,7 @@ The annotation itself is not provided in this project and is instead matched by
You can change it to your own internal annotation or to some other marker that suits you.
To learn how to install and debug it locally,
-[see documentation](https://kotlin.github.io/dokka/1.9.0/developer_guide/plugin-development/sample-plugin-tutorial/#debugging).
+[see documentation](https://kotlin.github.io/dokka/1.9.10/developer_guide/plugin-development/sample-plugin-tutorial/#debugging).
___
diff --git a/examples/plugin/hide-internal-api/build.gradle.kts b/examples/plugin/hide-internal-api/build.gradle.kts
index bdbf365814..2665101586 100644
--- a/examples/plugin/hide-internal-api/build.gradle.kts
+++ b/examples/plugin/hide-internal-api/build.gradle.kts
@@ -7,8 +7,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.net.URI
plugins {
- kotlin("jvm") version "1.9.0"
- id("org.jetbrains.dokka") version "1.9.0"
+ kotlin("jvm") version "1.9.10"
+ id("org.jetbrains.dokka") version "1.9.10"
`maven-publish`
signing
}
diff --git a/examples/plugin/hide-internal-api/gradle.properties b/examples/plugin/hide-internal-api/gradle.properties
index 40669a3870..a3f59a072e 100644
--- a/examples/plugin/hide-internal-api/gradle.properties
+++ b/examples/plugin/hide-internal-api/gradle.properties
@@ -2,4 +2,4 @@
# Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
#
-dokkaVersion=1.9.0
+dokkaVersion=1.9.10
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 75e0e305be..ba848dc288 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,7 +3,7 @@
gradlePlugin-kotlin = "1.9.10"
# See: https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin
gradlePlugin-android = "4.2.2"
-gradlePlugin-dokka = "1.9.0"
+gradlePlugin-dokka = "1.9.10"
kotlinx-coroutines = "1.6.3"
kotlinx-collections-immutable = "0.3.4"
diff --git a/integration-tests/gradle/projects/it-basic/build.gradle.kts b/integration-tests/gradle/projects/it-basic/build.gradle.kts
index 4ec3b82500..5cb354f4a0 100644
--- a/integration-tests/gradle/projects/it-basic/build.gradle.kts
+++ b/integration-tests/gradle/projects/it-basic/build.gradle.kts
@@ -20,7 +20,7 @@ buildscript {
}
}
-version = "1.9.0-SNAPSHOT"
+version = "1.9.10-SNAPSHOT"
apply(from = "../template.root.gradle.kts")
diff --git a/integration-tests/gradle/projects/it-configuration/build.gradle.kts b/integration-tests/gradle/projects/it-configuration/build.gradle.kts
index 02e99e9b44..76e3f6512a 100644
--- a/integration-tests/gradle/projects/it-configuration/build.gradle.kts
+++ b/integration-tests/gradle/projects/it-configuration/build.gradle.kts
@@ -16,7 +16,7 @@ buildscript {
}
}
-version = "1.9.0-SNAPSHOT"
+version = "1.9.10-SNAPSHOT"
apply(from = "../template.root.gradle.kts")
diff --git a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
index f214710caf..a23fb41037 100644
--- a/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
+++ b/integration-tests/gradle/src/integrationTest/kotlin/org/jetbrains/dokka/it/gradle/BasicGradleIntegrationTest.kt
@@ -158,7 +158,7 @@ class BasicGradleIntegrationTest : AbstractGradleIntegrationTest() {
val indexFile = File(this, "index.html")
assertTrue(indexFile.isFile, "Missing index.html")
assertTrue(
- """Basic Project 1.9.0-SNAPSHOT API """ in indexFile.readText(),
+ """Basic Project 1.9.10-SNAPSHOT API """ in indexFile.readText(),
"Header with version number not present in index.html"
)
diff --git a/plugins/kotlin-as-java/README.md b/plugins/kotlin-as-java/README.md
index b0ec7c8e98..e33bd1bb6d 100644
--- a/plugins/kotlin-as-java/README.md
+++ b/plugins/kotlin-as-java/README.md
@@ -8,7 +8,7 @@ The Kotlin as Java plugin is published to maven central as a
[separate artifact](https://mvnrepository.com/artifact/org.jetbrains.dokka/kotlin-as-java-plugin):
```text
-org.jetbrains.dokka:kotlin-as-java-plugin:1.9.0
+org.jetbrains.dokka:kotlin-as-java-plugin:1.9.10
```
**This plugin is at its early stages**, so you may experience issues and encounter bugs. Feel free to
diff --git a/plugins/mathjax/README.md b/plugins/mathjax/README.md
index d9604084b5..a12095eeba 100644
--- a/plugins/mathjax/README.md
+++ b/plugins/mathjax/README.md
@@ -23,5 +23,5 @@ The MathJax plugin is published to Maven Central as a
[separate artifact](https://mvnrepository.com/artifact/org.jetbrains.dokka/mathjax-plugin):
```text
-org.jetbrains.dokka:mathjax-plugin:1.9.0
+org.jetbrains.dokka:mathjax-plugin:1.9.10
```
diff --git a/plugins/versioning/README.md b/plugins/versioning/README.md
index be36ef0ee7..d501a58fd1 100644
--- a/plugins/versioning/README.md
+++ b/plugins/versioning/README.md
@@ -19,7 +19,7 @@ You can apply the versioning plugin the same way as other Dokka plugins:
```kotlin
dependencies {
- dokkaHtmlPlugin("org.jetbrains.dokka:versioning-plugin:1.9.0")
+ dokkaHtmlPlugin("org.jetbrains.dokka:versioning-plugin:1.9.10")
}
```
@@ -33,7 +33,7 @@ plugin within subprojects as well as in their parent project.
```groovy
dependencies {
- dokkaHtmlPlugin 'org.jetbrains.dokka:versioning-plugin:1.9.0'
+ dokkaHtmlPlugin 'org.jetbrains.dokka:versioning-plugin:1.9.10'
}
```
@@ -55,7 +55,7 @@ plugin within subprojects as well as in their parent project.
org.jetbrains.dokka
versioning-plugin
- 1.9.0
+ 1.9.10
@@ -68,15 +68,15 @@ plugin within subprojects as well as in their parent project.
CLI
You can find the versioning plugin's artifact on
-[mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/versioning-plugin/1.9.0) or by browsing
-[maven central repository](https://repo1.maven.org/maven2/org/jetbrains/dokka/versioning-plugin/1.9.0)
+[mvnrepository](https://mvnrepository.com/artifact/org.jetbrains.dokka/versioning-plugin/1.9.10) or by browsing
+[maven central repository](https://repo1.maven.org/maven2/org/jetbrains/dokka/versioning-plugin/1.9.10)
directly, and pass it to `pluginsClasspath`.
Via command line arguments:
```Bash
-java -jar dokka-cli-1.9.0.jar \
- -pluginsClasspath "./dokka-base-1.9.0.jar;...;./versioning-plugin-1.9.0.jar" \
+java -jar dokka-cli-1.9.10.jar \
+ -pluginsClasspath "./dokka-base-1.9.10.jar;...;./versioning-plugin-1.9.10.jar" \
...
```
@@ -86,9 +86,9 @@ Via JSON configuration:
{
...
"pluginsClasspath": [
- "./dokka-base-1.9.0.jar",
+ "./dokka-base-1.9.10.jar",
"...",
- "./versioning-plugin-1.9.0.jar"
+ "./versioning-plugin-1.9.10.jar"
],
...
}
@@ -135,7 +135,7 @@ import org.jetbrains.dokka.versioning.VersioningConfiguration
buildscript {
dependencies {
- classpath("org.jetbrains.dokka:versioning-plugin:1.9.0")
+ classpath("org.jetbrains.dokka:versioning-plugin:1.9.10")
}
}
@@ -232,7 +232,7 @@ dokkaHtml {
CLI
```Bash
-java -jar dokka-cli-1.9.0.jar \
+java -jar dokka-cli-1.9.10.jar \
...
-pluginsConfiguration "org.jetbrains.dokka.versioning.VersioningPlugin={\"version\": \"1.5\", \"versionsOrdering\": [\"1.5\", \"1.4\", \"1.3\", \"1.2\", \"1.1\", \"alpha-2\", \"alpha-1\"], \"olderVersionsDir\": \"documentation/version\", \"olderVersions\": [\"documentation/alpha/alpha-2\", \"documentation/alpha/alpha-1\"], \"renderVersionsNavigationOnAllPages\": true}"
@@ -290,12 +290,12 @@ import org.jetbrains.dokka.versioning.VersioningConfiguration
buildscript {
dependencies {
- classpath("org.jetbrains.dokka:versioning-plugin:1.9.0")
+ classpath("org.jetbrains.dokka:versioning-plugin:1.9.10")
}
}
dependencies {
- dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.9.0")
+ dokkaPlugin("org.jetbrains.dokka:versioning-plugin:1.9.10")
}
tasks.dokkaHtml {
From 73b81ac375c927176205543dec813faa32abe811 Mon Sep 17 00:00:00 2001
From: Subhrajyoti Sen
Date: Tue, 17 Oct 2023 14:44:51 +0530
Subject: [PATCH 08/72] Fix docs link for OkHttp (#3213)
The documentation for OkHttp has been moved to https://square.github.io/okhttp/5.x/okhttp/okhttp3/
As per https://github.com/square/okhttp/commit/05718b4d87b591820a178b3fb6a4325c83c55d7a, they are currently using HTML for docs and not markdown
---
README.md | 2 +-
docs/topics/dokka-introduction.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index cc51bf8115..ed09a9502c 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,7 @@ Some libraries that use Dokka for their API reference documentation:
* [Bitmovin](https://cdn.bitmovin.com/player/android/3/docs/index.html)
* [Hexagon](https://hexagonkt.com/api/index.html)
* [Ktor](https://api.ktor.io/)
-* [OkHttp](https://square.github.io/okhttp/4.x/okhttp/okhttp3/) (Markdown)
+* [OkHttp](https://square.github.io/okhttp/5.x/okhttp/okhttp3/)
* [Gradle](https://docs.gradle.org/current/kotlin-dsl/index.html)
You can run Dokka using [Gradle](https://kotlinlang.org/docs/dokka-gradle.html),
diff --git a/docs/topics/dokka-introduction.md b/docs/topics/dokka-introduction.md
index fd33a3cbff..e4bff95ad3 100644
--- a/docs/topics/dokka-introduction.md
+++ b/docs/topics/dokka-introduction.md
@@ -15,7 +15,7 @@ Here are some libraries that use Dokka for their API reference documentation:
* [Bitmovin](https://cdn.bitmovin.com/player/android/3/docs/index.html)
* [Hexagon](https://hexagonkt.com/api/index.html)
* [Ktor](https://api.ktor.io/)
-* [OkHttp](https://square.github.io/okhttp/4.x/okhttp/okhttp3/) (Markdown)
+* [OkHttp](https://square.github.io/okhttp/5.x/okhttp/okhttp3/)
You can run Dokka using [Gradle](dokka-gradle.md), [Maven](dokka-maven.md) or from the [command line](dokka-cli.md). It is also
[highly pluggable](dokka-plugins.md).
From fca686c5cb62bd8aeb2390763280bb4dd00bdd43 Mon Sep 17 00:00:00 2001
From: Ignat Beresnev
Date: Tue, 17 Oct 2023 14:43:00 +0200
Subject: [PATCH 09/72] Bump korte aka korlibs-template to 4.0.10 (#3205)
---
gradle/libs.versions.toml | 7 +++++--
plugins/javadoc/build.gradle.kts | 2 +-
.../dokka/javadoc/renderer/KorteJavadocRenderer.kt | 2 +-
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ba848dc288..0060b6519c 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -22,7 +22,7 @@ intellij-platform = "213.7172.25"
## HTML
jsoup = "1.15.3"
freemarker = "2.3.31"
-soywiz-korte = "2.7.0"
+korlibs-template = "4.0.10"
kotlinx-html = "0.9.1"
## Markdown
@@ -94,7 +94,10 @@ intellij-platform-util-rt = { module = "com.jetbrains.intellij.platform:util-rt"
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
freemarker = { module = "org.freemarker:freemarker", version.ref = "freemarker" }
kotlinx-html = { module = "org.jetbrains.kotlinx:kotlinx-html-jvm", version.ref = "kotlinx-html" }
-soywiz-korte = { module = "com.soywiz.korlibs.korte:korte-jvm", version.ref = "soywiz-korte" }
+
+# for korlibs-template: the package was renamed and the library's source was moved, but the artifact name is still old,
+# so there's a mismatch. might change in the future, follow https://github.com/korlibs/korge/issues/1836 for updates
+korlibs-template = { module = "com.soywiz.korlibs.korte:korte-jvm", version.ref = "korlibs-template" }
#### Markdown ####
jetbrains-markdown = { module = "org.jetbrains:markdown", version.ref = "jetbrains-markdown" }
diff --git a/plugins/javadoc/build.gradle.kts b/plugins/javadoc/build.gradle.kts
index e7bdc67e8d..2a04366b95 100644
--- a/plugins/javadoc/build.gradle.kts
+++ b/plugins/javadoc/build.gradle.kts
@@ -17,7 +17,7 @@ dependencies {
implementation(projects.plugins.kotlinAsJava)
implementation(kotlin("reflect"))
- implementation(libs.soywiz.korte)
+ implementation(libs.korlibs.template)
implementation(libs.kotlinx.html)
implementation(libs.kotlinx.coroutines.core)
diff --git a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/KorteJavadocRenderer.kt b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/KorteJavadocRenderer.kt
index 658e42ed0d..cfc4bb2a9a 100644
--- a/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/KorteJavadocRenderer.kt
+++ b/plugins/javadoc/src/main/kotlin/org/jetbrains/dokka/javadoc/renderer/KorteJavadocRenderer.kt
@@ -4,7 +4,7 @@
package org.jetbrains.dokka.javadoc.renderer
-import com.soywiz.korte.*
+import korlibs.template.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
From 5a6fab535b68916a28d922d5d7a294fa432b7d6b Mon Sep 17 00:00:00 2001
From: Ignat Beresnev
Date: Wed, 18 Oct 2023 00:23:32 +0200
Subject: [PATCH 10/72] Bump dependencies without visible API changes (#3204)
---
gradle/libs.versions.toml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 0060b6519c..9a25490b73 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -5,9 +5,9 @@ gradlePlugin-kotlin = "1.9.10"
gradlePlugin-android = "4.2.2"
gradlePlugin-dokka = "1.9.10"
-kotlinx-coroutines = "1.6.3"
-kotlinx-collections-immutable = "0.3.4"
-kotlinx-bcv = "0.12.1"
+kotlinx-coroutines = "1.7.3"
+kotlinx-collections-immutable = "0.3.6"
+kotlinx-bcv = "0.13.2"
## Analysis
kotlin-compiler = "1.9.10"
@@ -20,8 +20,8 @@ kotlin-compiler-k2 = "1.9.30-dev-3330"
intellij-platform = "213.7172.25"
## HTML
-jsoup = "1.15.3"
-freemarker = "2.3.31"
+jsoup = "1.16.1"
+freemarker = "2.3.32"
korlibs-template = "4.0.10"
kotlinx-html = "0.9.1"
@@ -39,7 +39,7 @@ apacheMaven-archiver = "2.5"
apacheMaven-pluginTools = "3.5.2"
## CLI
-kotlinx-cli = "0.3.4"
+kotlinx-cli = "0.3.6"
## NPM | Frontend
node = "16.13.0"
@@ -51,8 +51,8 @@ gradlePlugin-gradlePluginPublish = "0.20.0"
gradlePlugin-gradleNode = "3.5.1"
## Test
-junit = "5.9.2"
-eclipse-jgit = "5.12.0.202106070339-r"
+junit = "5.9.3"
+eclipse-jgit = "5.13.2.202306221912-r" # jgit 6.X requires Java 11 to run
[libraries]
From f225fafdf10f351d31e546b73eb511f46ffc6806 Mon Sep 17 00:00:00 2001
From: Oleg Yukhnevich
Date: Wed, 18 Oct 2023 18:28:31 +0300
Subject: [PATCH 11/72] Fix active-tab selection for different page contexts
(#3212)
---
.../dokka/scripts/platform-content-handler.js | 45 ++++++++++---------
.../renderers/html/TabbedContentTest.kt | 3 ++
2 files changed, 27 insertions(+), 21 deletions(-)
diff --git a/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js b/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js
index 8c4ca53830..811c478883 100644
--- a/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js
+++ b/plugins/base/src/main/resources/dokka/scripts/platform-content-handler.js
@@ -18,8 +18,6 @@ const samplesLightThemeName = 'idea'
window.addEventListener('load', () => {
document.querySelectorAll("div[data-platform-hinted]")
.forEach(elem => elem.addEventListener('click', (event) => togglePlatformDependent(event, elem)))
- document.querySelectorAll("div[tabs-section]")
- .forEach(elem => elem.addEventListener('click', (event) => toggleSectionsEventHandler(event)))
const filterSection = document.getElementById('filter-section')
if (filterSection) {
filterSection.addEventListener('click', (event) => filterButtonHandler(event))
@@ -177,19 +175,30 @@ function handleAnchor() {
}
function initTabs() {
- document.querySelectorAll("div[tabs-section]")
- .forEach(element => {
- showCorrespondingTabBody(element)
- element.addEventListener('click', (event) => toggleSectionsEventHandler(event))
- })
- let cached = localStorage.getItem("active-tab")
- if (cached) {
- let parsed = JSON.parse(cached)
- let tab = document.querySelector('div[tabs-section] > button[data-togglable="' + parsed + '"]')
- if (tab) {
- toggleSections(tab)
- }
- }
+ // we could have only a single type of data - classlike or package
+ const mainContent = document.querySelector('.main-content');
+ const type = mainContent ? mainContent.getAttribute("data-page-type") : null;
+ const localStorageKey = "active-tab-" + type;
+ document.querySelectorAll('div[tabs-section]').forEach(element => {
+ showCorrespondingTabBody(element);
+ element.addEventListener('click', ({target}) => {
+ const togglable = target ? target.getAttribute("data-togglable") : null;
+ if (!togglable) return;
+
+ localStorage.setItem(localStorageKey, JSON.stringify(togglable));
+ toggleSections(target);
+ });
+ });
+
+ const cached = localStorage.getItem(localStorageKey);
+ if (!cached) return;
+
+ const tab = document.querySelector(
+ 'div[tabs-section] > button[data-togglable="' + JSON.parse(cached) + '"]'
+ );
+ if (!tab) return;
+
+ toggleSections(tab);
}
function showCorrespondingTabBody(element) {
@@ -293,12 +302,6 @@ function toggleSections(target) {
activateTabsBody("tabs-section-body")
}
-function toggleSectionsEventHandler(evt) {
- if (!evt.target.getAttribute("data-togglable")) return
- localStorage.setItem('active-tab', JSON.stringify(evt.target.getAttribute("data-togglable")))
- toggleSections(evt.target)
-}
-
function togglePlatformDependent(e, container) {
let target = e.target
if (target.tagName != 'BUTTON') return;
diff --git a/plugins/base/src/test/kotlin/renderers/html/TabbedContentTest.kt b/plugins/base/src/test/kotlin/renderers/html/TabbedContentTest.kt
index 0a748580a6..090127fd39 100644
--- a/plugins/base/src/test/kotlin/renderers/html/TabbedContentTest.kt
+++ b/plugins/base/src/test/kotlin/renderers/html/TabbedContentTest.kt
@@ -25,6 +25,7 @@ class TabbedContentTest : BaseAbstractTest() {
private fun Element.getTabbedRow(type: String) = select(".table-row[data-togglable=$type]")
private fun Element.getTabbedTable(type: String) = select("div[data-togglable=$type] .table")
+ private fun Element.getMainContentDataType() = selectFirst(".main-content")?.attr("data-page-type")
@Test
fun `should have correct tabbed content type`() {
@@ -64,6 +65,7 @@ class TabbedContentTest : BaseAbstractTest() {
assertEquals(1, classContent.getTabbedTable("TYPE").size)
assertEquals(3, classContent.getTabbedRow("EXTENSION_FUNCTION").size)
assertEquals(2, classContent.getTabbedRow("EXTENSION_PROPERTY").size)
+ assertEquals("classlike", classContent.getMainContentDataType())
val packagePage = writerPlugin.writer.renderedContent("root/example/index.html")
assertEquals(1, packagePage.getTabbedTable("TYPE").size)
@@ -71,6 +73,7 @@ class TabbedContentTest : BaseAbstractTest() {
assertEquals(1, packagePage.getTabbedTable("FUNCTION").size)
assertEquals(3, packagePage.getTabbedRow("EXTENSION_FUNCTION").size)
assertEquals(2, packagePage.getTabbedRow("EXTENSION_PROPERTY").size)
+ assertEquals("package", packagePage.getMainContentDataType())
}
}
}
From 8016c1face1283952e228aee348487bf0421ab90 Mon Sep 17 00:00:00 2001
From: freya02 <41875020+freya022@users.noreply.github.com>
Date: Wed, 18 Oct 2023 22:33:01 +0200
Subject: [PATCH 12/72] Fix sources not being linked when using Maven (#3046)
---
docs/topics/runners/dokka-maven.md | 5 ++++-
runners/maven-plugin/src/main/kotlin/DokkaMojo.kt | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/docs/topics/runners/dokka-maven.md b/docs/topics/runners/dokka-maven.md
index 14551c91d3..bc51d5fee1 100644
--- a/docs/topics/runners/dokka-maven.md
+++ b/docs/topics/runners/dokka-maven.md
@@ -407,7 +407,7 @@ function in `kotlinx.coroutines`.
- ${project.basedir}/src
+ src
https://github.com/kotlin/dokka/tree/master/src
#L
@@ -422,6 +422,9 @@ function in `kotlinx.coroutines`.
The path to the local source directory. The path must be relative to the root of the
current module.
+
+ Note: Only Unix based paths are allowed, Windows-style paths will throw an error.
+
diff --git a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt
index ba95e7a70c..d14fea9c5b 100644
--- a/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt
+++ b/runners/maven-plugin/src/main/kotlin/DokkaMojo.kt
@@ -389,7 +389,7 @@ public abstract class AbstractDokkaMojo(
skipEmptyPackages = skipEmptyPackages,
skipDeprecated = skipDeprecated,
jdkVersion = jdkVersion,
- sourceLinks = sourceLinks.map { SourceLinkDefinitionImpl(it.path, URL(it.url), it.lineSuffix) }.toSet(),
+ sourceLinks = sourceLinks.map { SourceLinkDefinitionImpl(File(it.path).canonicalPath, URL(it.url), it.lineSuffix) }.toSet(),
perPackageOptions = perPackageOptions.map {
@Suppress("DEPRECATION") // for includeNonPublic, preserve backwards compatibility
PackageOptionsImpl(
From 35d15601f2d129a7d3db67dd9e2f4c41c87ef083 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Fri, 20 Oct 2023 00:39:12 +1300
Subject: [PATCH 13/72] Contribute Dokkatoo (#3188)
---
build-logic/build.gradle.kts | 2 +-
dokka-runners/dokkatoo/.gitattributes | 51 ++
dokka-runners/dokkatoo/.gitignore | 71 +++
dokka-runners/dokkatoo/build.gradle.kts | 47 ++
.../dokkatoo/buildSrc/build.gradle.kts | 19 +
.../dokkatoo/buildSrc/settings.gradle.kts | 25 +
.../conventions/android-setup.gradle.kts | 78 +++
.../buildsrc/conventions/base.gradle.kts | 155 ++++++
.../dokka-source-downloader.gradle.kts | 68 +++
.../dokkatoo-example-projects-base.gradle.kts | 27 +
.../dokkatoo-example-projects.gradle.kts | 160 ++++++
.../gradle-plugin-variants.gradle.kts | 44 ++
.../buildsrc/conventions/java-base.gradle.kts | 19 +
.../kotlin-gradle-plugin.gradle.kts | 37 ++
.../conventions/maven-publish-test.gradle.kts | 93 ++++
.../conventions/maven-publishing.gradle.kts | 137 +++++
.../settings/DokkaSourceDownloaderSettings.kt | 13 +
.../settings/DokkaTemplateProjectSettings.kt | 96 ++++
.../DokkatooExampleProjectsSettings.kt | 62 +++
.../settings/MavenPublishTestSettings.kt | 19 +
.../settings/MavenPublishingSettings.kt | 68 +++
.../buildsrc/tasks/SetupDokkaProjects.kt | 73 +++
.../tasks/UpdateDokkatooExampleProjects.kt | 49 ++
.../src/main/kotlin/buildsrc/utils/gradle.kt | 118 +++++
.../main/kotlin/buildsrc/utils/intellij.kt | 45 ++
.../src/main/kotlin/buildsrc/utils/strings.kt | 26 +
.../dokkatoo/devOps/release.main.kts | 415 ++++++++++++++++
dokka-runners/dokkatoo/examples/.gitignore | 10 +
dokka-runners/dokkatoo/examples/README.md | 18 +
.../dokkatoo/examples/build.gradle.kts | 48 ++
.../custom-format-example/dokka/README.md | 17 +
.../dokka/build.gradle.kts | 35 ++
.../custom-format-example/dokka/demo.png | Bin 0 -> 77918 bytes
.../custom-format-example/dokka/ktor-logo.png | Bin 0 -> 179624 bytes
.../dokka/logo-styles.css | 20 +
.../dokka/settings.gradle.kts | 1 +
.../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 +
.../dokkatoo/build.gradle.kts | 18 +
.../dokkatoo/ktor-logo.png | Bin 0 -> 179624 bytes
.../dokkatoo/logo-styles.css | 20 +
.../dokkatoo/settings.gradle.kts | 17 +
.../src/main/kotlin/demo/HelloWorld.kt | 20 +
.../examples/gradle-example/dokka/Module.md | 7 +
.../examples/gradle-example/dokka/README.md | 22 +
.../gradle-example/dokka/build.gradle.kts | 37 ++
.../examples/gradle-example/dokka/demo.png | Bin 0 -> 71039 bytes
.../gradle-example/dokka/settings.gradle.kts | 1 +
.../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 +
.../gradle-example/dokkatoo/Module.md | 7 +
.../gradle-example/dokkatoo/build.gradle.kts | 23 +
.../dokkatoo/settings.gradle.kts | 17 +
.../src/main/kotlin/demo/HelloWorld.kt | 20 +
.../kotlin-as-java-example/dokka/README.md | 19 +
.../dokka/build.gradle.kts | 21 +
.../kotlin-as-java-example/dokka/demo.png | Bin 0 -> 101974 bytes
.../dokka/settings.gradle.kts | 1 +
.../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 +
.../dokkatoo/settings.gradle.kts | 17 +
.../dokka/README.md | 41 ++
.../dokka/build.gradle.kts | 39 ++
.../dokka/settings.gradle.kts | 1 +
.../dokka/src/main/kotlin/demo/HelloWorld.kt | 20 +
.../dokkatoo/settings.gradle.kts | 17 +
.../multimodule-example/dokka/README.md | 25 +
.../dokka/build.gradle.kts | 5 +
.../multimodule-example/dokka/demo.png | Bin 0 -> 93395 bytes
.../dokka/parentProject/build.gradle.kts | 38 ++
.../parentProject/childProjectA/ModuleA.md | 5 +
.../childProjectA/build.gradle.kts | 16 +
.../main/kotlin/demo/ChildProjectAClass.kt | 8 +
.../parentProject/childProjectB/ModuleB.md | 5 +
.../childProjectB/build.gradle.kts | 16 +
.../main/kotlin/demo/ChildProjectBClass.kt | 8 +
.../dokka/settings.gradle.kts | 15 +
.../dokkatoo/buildSrc/build.gradle.kts | 8 +
.../dokkatoo/buildSrc/settings.gradle.kts | 21 +
.../main/kotlin/dokka-convention.gradle.kts | 17 +
.../dokkatoo/parentProject/build.gradle.kts | 23 +
.../parentProject/childProjectA/ModuleA.md | 5 +
.../childProjectA/build.gradle.kts | 21 +
.../main/kotlin/demo/ChildProjectAClass.kt | 8 +
.../parentProject/childProjectB/ModuleB.md | 5 +
.../childProjectB/build.gradle.kts | 21 +
.../main/kotlin/demo/ChildProjectBClass.kt | 8 +
.../dokkatoo/settings.gradle.kts | 21 +
.../multiplatform-example/dokka/README.md | 29 ++
.../dokka/build.gradle.kts | 42 ++
.../multiplatform-example/dokka/demo.png | Bin 0 -> 183500 bytes
.../dokka/settings.gradle.kts | 2 +
.../CommonCoroutineExtensions.kt | 15 +
.../org/kotlintestmpp/CommonDateUtils.kt | 14 +
.../kotlin/org/kotlintestmpp/common/Foo.kt | 7 +
.../kotlintest/jdk9/CustomSourceSetFile.kt | 11 +
.../kotlintestmpp/JsCoroutineExtensions.kt | 11 +
.../kotlin/org/kotlintestmpp/JsDateUtils.kt | 8 +
.../kotlin/org/kotlintestmpp/JsFunctions.kt | 18 +
.../org/kotlintestmpp/JavaAnnotation.java | 19 +
.../kotlintestmpp/JvmCoroutineExtensions.kt | 11 +
.../kotlin/org/kotlintestmpp/JvmDateUtils.kt | 8 +
.../kotlin/org/kotlintestmpp/JvmFunctions.kt | 35 ++
.../kotlin/org/kotlintestmpp/CInterop.kt | 15 +
.../kotlintestmpp/LinuxCoroutineExtensions.kt | 11 +
.../org/kotlintestmpp/LinuxDateUtils.kt | 8 +
.../kotlintestmpp/MacOsCoroutineExtensions.kt | 11 +
.../org/kotlintestmpp/MacOsDateUtils.kt | 8 +
.../dokkatoo/build.gradle.kts | 39 ++
.../dokkatoo/settings.gradle.kts | 17 +
.../CommonCoroutineExtensions.kt | 15 +
.../org/kotlintestmpp/CommonDateUtils.kt | 14 +
.../kotlin/org/kotlintestmpp/common/Foo.kt | 7 +
.../kotlintest/jdk9/CustomSourceSetFile.kt | 11 +
.../kotlintestmpp/JsCoroutineExtensions.kt | 11 +
.../kotlin/org/kotlintestmpp/JsDateUtils.kt | 8 +
.../kotlin/org/kotlintestmpp/JsFunctions.kt | 18 +
.../org/kotlintestmpp/JavaAnnotation.java | 19 +
.../kotlintestmpp/JvmCoroutineExtensions.kt | 11 +
.../kotlin/org/kotlintestmpp/JvmDateUtils.kt | 8 +
.../kotlin/org/kotlintestmpp/JvmFunctions.kt | 35 ++
.../kotlin/org/kotlintestmpp/CInterop.kt | 15 +
.../kotlintestmpp/LinuxCoroutineExtensions.kt | 11 +
.../org/kotlintestmpp/LinuxDateUtils.kt | 8 +
.../kotlintestmpp/MacOsCoroutineExtensions.kt | 11 +
.../org/kotlintestmpp/MacOsDateUtils.kt | 8 +
.../dokka/README.md | 25 +
.../dokka/build.gradle.kts | 19 +
.../dokka/demo.png | Bin 0 -> 35812 bytes
.../dokka/parentProject/build.gradle.kts | 27 +
.../childProjectA/build.gradle.kts | 1 +
.../main/kotlin/demo/ChildProjectAClass.kt | 18 +
.../src/main/kotlin/demo/FancyAPI.kt | 10 +
.../childProjectB/build.gradle.kts | 1 +
.../main/kotlin/demo/ChildProjectBClass.kt | 10 +
.../src/main/kotlin/demo/Functions.kt | 8 +
.../dokka/settings.gradle.kts | 5 +
.../dokkatoo/settings.gradle.kts | 17 +
dokka-runners/dokkatoo/gradle.properties | 12 +
.../dokkatoo/gradle/libs.versions.toml | 48 ++
.../dokkatoo/modules/docs/build.gradle.kts | 58 +++
.../dokkatoo/modules/docs/images/banner.svg | 100 ++++
.../modules/docs/images/logo-icon.svg | 84 ++++
.../docs/images/social_preview_banner.png | Bin 0 -> 38562 bytes
.../docs/images/social_preview_banner.svg | 106 ++++
.../modules/docs/style/logo-styles.css | 44 ++
.../build.gradle.kts | 281 +++++++++++
.../projects/.gitignore | 15 +
.../licenses/android-googletv-license | 2 +
.../licenses/android-sdk-arm-dbt-license | 2 +
.../ANDROID_SDK/licenses/android-sdk-license | 2 +
.../licenses/android-sdk-preview-license | 2 +
.../ANDROID_SDK/licenses/google-gdk-license | 2 +
.../licenses/intel-android-extra-license | 2 +
.../licenses/mips-android-sysimage-license | 2 +
.../it-android-0/dokka/build.gradle.kts | 18 +
.../it-android-0/dokka/settings.gradle.kts | 5 +
.../dokka/src/main/AndroidManifest.xml | 1 +
.../java/it/android/AndroidSpecificClass.kt | 16 +
.../it/android/IntegrationTestActivity.kt | 22 +
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../it-android-0/dokkatoo/build.gradle.kts | 32 ++
.../it-android-0/dokkatoo/settings.gradle.kts | 19 +
.../dokkatoo/src/main/AndroidManifest.xml | 1 +
.../java/it/android/AndroidSpecificClass.kt | 16 +
.../it/android/IntegrationTestActivity.kt | 22 +
.../it-basic-groovy/dokka/build.gradle | 54 ++
.../it-basic-groovy/dokka/settings.gradle.kts | 5 +
.../java/it/basic/java/SampleJavaClass.java | 17 +
.../src/main/kotlin/it/basic/PublicClass.kt | 48 ++
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../it-basic-groovy/dokkatoo/settings.gradle | 16 +
.../projects/it-basic/dokka/build.gradle.kts | 63 +++
.../dokka/customResources/custom-resource.svg | 3 +
.../customResources/custom-style-to-add.css | 1 +
.../dokka/customResources/logo-styles.css | 3 +
.../it-basic/dokka/settings.gradle.kts | 5 +
.../java/it/basic/java/SampleJavaClass.java | 17 +
.../dokka/src/main/kotlin/RootPackageClass.kt | 8 +
.../src/main/kotlin/it/basic/PublicClass.kt | 69 +++
.../main/kotlin/it/internal/InternalClass.kt | 7 +
.../VisiblePrivateClass.kt | 12 +
.../kotlin/it/protected/ProtectedClass.kt | 10 +
.../SuppressedByPackage.kt | 7 +
.../it/suppressedByPath/SuppressedByPath.kt | 7 +
.../src/test/kotlin/it/basic/TestClass.kt | 17 +
.../it-basic/dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../it-basic/dokkatoo/build.gradle.kts | 64 +++
.../customResources/custom-resource.svg | 3 +
.../customResources/custom-style-to-add.css | 1 +
.../dokkatoo/customResources/logo-styles.css | 3 +
.../it-basic/dokkatoo/settings.gradle.kts | 17 +
.../java/it/basic/java/SampleJavaClass.java | 17 +
.../src/main/kotlin/RootPackageClass.kt | 8 +
.../src/main/kotlin/it/basic/PublicClass.kt | 69 +++
.../main/kotlin/it/internal/InternalClass.kt | 7 +
.../VisiblePrivateClass.kt | 12 +
.../kotlin/it/protected/ProtectedClass.kt | 10 +
.../SuppressedByPackage.kt | 7 +
.../it/suppressedByPath/SuppressedByPath.kt | 7 +
.../src/test/kotlin/it/basic/TestClass.kt | 17 +
.../it-collector-0/dokka/build.gradle.kts | 1 +
.../dokka/moduleA/build.gradle.kts | 6 +
.../dokka/moduleA/moduleB/README.md | 2 +
.../dokka/moduleA/moduleB/build.gradle.kts | 4 +
.../org/jetbrains/dokka/it/moduleB/ModuleB.kt | 6 +
.../dokka/moduleA/moduleC/README.md | 2 +
.../dokka/moduleA/moduleC/build.gradle.kts | 4 +
.../org/jetbrains/dokka/it/moduleC/ModuleC.kt | 6 +
.../it-collector-0/dokka/settings.gradle.kts | 5 +
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../dokkatoo/settings.gradle.kts | 17 +
.../it-js-ir-0/dokka/build.gradle.kts | 21 +
.../it-js-ir-0/dokka/settings.gradle.kts | 5 +
.../dokka/src/main/kotlin/RootPackageClass.kt | 26 +
.../src/main/kotlin/it/basic/PublicClass.kt | 53 ++
.../main/kotlin/it/internal/InternalClass.kt | 7 +
.../SuppressedByPackage.kt | 7 +
.../it/suppressedByPath/SuppressedByPath.kt | 7 +
.../it-js-ir-0/dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../it-js-ir-0/dokkatoo/settings.gradle.kts | 17 +
.../it-multimodule-0/dokka/build.gradle.kts | 1 +
.../dokka/moduleA/build.gradle.kts | 6 +
.../dokka/moduleA/moduleB/Module.md | 6 +
.../dokka/moduleA/moduleB/build.gradle.kts | 13 +
.../org/jetbrains/dokka/it/moduleB/ModuleB.kt | 6 +
.../dokka/moduleA/moduleC/Module.md | 2 +
.../dokka/moduleA/moduleC/build.gradle.kts | 12 +
.../org/jetbrains/dokka/it/moduleC/ModuleC.kt | 6 +
.../dokka/moduleA/moduleD/build.gradle.kts | 6 +
.../org/jetbrains/dokka/it/moduleD/ModuleC.kt | 6 +
.../dokka/settings.gradle.kts | 6 +
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../dokkatoo/settings.gradle.kts | 17 +
.../it-multimodule-1/dokka/build.gradle | 18 +
.../it-multimodule-1/dokka/first/build.gradle | 0
.../first/src/main/kotlin/foo/FirstClass.kt | 11 +
.../src/main/kotlin/foo/FirstSubclass.kt | 12 +
.../dokka/first/src/main/kotlin/foo/Main.kt | 8 +
.../dokka/first/src/main/kotlin/noPackage.kt | 3 +
.../dokka/second/build.gradle | 14 +
.../second/src/main/kotlin/NoPackageClass.kt | 1 +
.../second/src/main/kotlin/bar/SecondClass.kt | 21 +
.../second/src/main/kotlin/foo/ThirdClass.kt | 11 +
.../dokka/settings.gradle.kts | 4 +
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../dokkatoo/settings.gradle.kts | 17 +
.../dokka/build.gradle | 43 ++
.../dokka/first/build.gradle | 0
.../first/src/main/kotlin/foo/FirstClass.kt | 11 +
.../dokka/second/build.gradle | 3 +
.../second/src/main/kotlin/bar/SecondClass.kt | 21 +
.../dokka/settings.gradle.kts | 4 +
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../dokkatoo/settings.gradle.kts | 17 +
.../it-multiplatform-0/dokka/build.gradle.kts | 48 ++
.../dokka/settings.gradle.kts | 2 +
.../kotlin/it/mpp0/CommonMainClass.kt | 8 +
.../kotlin/it/mpp0/ExpectedClass.kt | 5 +
.../commonMain/kotlin/it/mpp0/coroutines.kt | 5 +
.../kotlin/it/mpp0/CPointerExtension.kt | 11 +
.../kotlin/it/mpp0/ExpectedClass.kt | 5 +
.../jsMain/kotlin/it/mpp0/ExpectedClass.kt | 5 +
.../src/jsMain/kotlin/it/mpp0/runBlocking.kt | 7 +
.../jvmMain/kotlin/it/mpp0/ExpectedClass.kt | 11 +
.../jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt | 13 +
.../src/jvmMain/kotlin/it/mpp0/runBlocking.kt | 7 +
.../kotlin/it/mpp0/CPointerExtension.kt | 11 +
.../linuxMain/kotlin/it/mpp0/ExpectedClass.kt | 5 +
.../linuxMain/kotlin/it/mpp0/runBlocking.kt | 13 +
.../macosMain/kotlin/it/mpp0/ExpectedClass.kt | 5 +
.../macosMain/kotlin/it/mpp0/runBlocking.kt | 7 +
.../dokka/template.root.gradle.kts | 23 +
.../dokka/template.settings.gradle.kts | 38 ++
.../dokkatoo/settings.gradle.kts | 17 +
.../kotlin/CustomFormatExampleTest.kt | 197 ++++++++
.../testExamples/kotlin/GradleExampleTest.kt | 190 +++++++
.../kotlin/KotlinMultiplatformExampleTest.kt | 226 +++++++++
.../kotlin/MultimoduleExampleTest.kt | 244 +++++++++
.../kotlin/templateProjectUtils.kt | 17 +
.../kotlin/AndroidProjectIntegrationTest.kt | 166 +++++++
.../kotlin/BasicProjectIntegrationTest.kt | 153 ++++++
.../dokka-multi-module/childProjectA.json | 83 ++++
.../dokka-multi-module/childProjectB.json | 83 ++++
.../dokka-multi-module/parentProject.json | 55 ++
.../it/example/dokka-multi-module/readme.md | 5 +
.../dokkatoo-plugin/api/dokkatoo-plugin.api | 397 +++++++++++++++
.../modules/dokkatoo-plugin/build.gradle.kts | 254 ++++++++++
.../src/main/kotlin/DokkatooBasePlugin.kt | 355 +++++++++++++
.../src/main/kotlin/DokkatooExtension.kt | 130 +++++
.../src/main/kotlin/DokkatooPlugin.kt | 32 ++
.../kotlin/adapters/DokkatooAndroidAdapter.kt | 214 ++++++++
.../kotlin/adapters/DokkatooJavaAdapter.kt | 40 ++
.../kotlin/adapters/DokkatooKotlinAdapter.kt | 459 +++++++++++++++++
.../DokkatooConfigurationAttributes.kt | 59 +++
.../src/main/kotlin/dokka/DokkaPublication.kt | 122 +++++
.../DokkaExternalDocumentationLinkSpec.kt | 120 +++++
.../DokkaGeneratorParametersSpec.kt | 93 ++++
.../parameters/DokkaModuleDescriptionSpec.kt | 49 ++
.../parameters/DokkaPackageOptionsSpec.kt | 84 ++++
.../dokka/parameters/DokkaParametersKxs.kt | 78 +++
.../dokka/parameters/DokkaSourceLinkSpec.kt | 106 ++++
.../dokka/parameters/DokkaSourceSetIdSpec.kt | 61 +++
.../dokka/parameters/DokkaSourceSetSpec.kt | 366 ++++++++++++++
.../HasConfigurableVisibilityModifiers.kt | 14 +
.../kotlin/dokka/parameters/KotlinPlatform.kt | 54 ++
.../dokka/parameters/VisibilityModifier.kt | 42 ++
.../builders/DokkaModuleDescriptionBuilder.kt | 33 ++
.../builders/DokkaParametersBuilder.kt | 77 +++
.../builders/DokkaSourceSetBuilder.kt | 112 +++++
.../plugins/DokkaHtmlPluginParameters.kt | 129 +++++
.../plugins/DokkaPluginParametersBaseSpec.kt | 32 ++
.../plugins/DokkaPluginParametersBuilder.kt | 232 +++++++++
.../DokkaVersioningPluginParameters.kt | 101 ++++
.../DokkatooFormatDependencyContainers.kt | 152 ++++++
.../kotlin/formats/DokkatooFormatPlugin.kt | 174 +++++++
.../kotlin/formats/DokkatooFormatTasks.kt | 105 ++++
.../main/kotlin/formats/DokkatooGfmPlugin.kt | 14 +
.../main/kotlin/formats/DokkatooHtmlPlugin.kt | 72 +++
.../kotlin/formats/DokkatooJavadocPlugin.kt | 14 +
.../kotlin/formats/DokkatooJekyllPlugin.kt | 14 +
.../kotlin/internal/DokkatooInternalApi.kt | 37 ++
.../src/main/kotlin/internal/LoggerAdapter.kt | 65 +++
.../main/kotlin/internal/collectionsUtils.kt | 7 +
.../internal/gradleExtensionAccessors.kt | 9 +
.../main/kotlin/internal/gradleTypealiases.kt | 20 +
.../src/main/kotlin/internal/gradleUtils.kt | 187 +++++++
.../internal/kotlinxSerializationUtils.kt | 36 ++
.../src/main/kotlin/internal/stringUtils.kt | 11 +
.../src/main/kotlin/internal/uriUtils.kt | 9 +
.../main/kotlin/tasks/DokkatooGenerateTask.kt | 187 +++++++
.../DokkatooPrepareModuleDescriptorTask.kt | 62 +++
.../src/main/kotlin/tasks/DokkatooTask.kt | 22 +
.../tasks/LogHtmlPublicationLinkTask.kt | 156 ++++++
.../kotlin/workers/DokkaGeneratorWorker.kt | 77 +++
.../src/test/kotlin/DokkatooPluginTest.kt | 76 +++
.../DokkaExternalDocumentationLinkSpecTest.kt | 102 ++++
.../parameters/DokkaSourceLinkSpecTest.kt | 58 +++
.../dokka/parameters/KotlinPlatformTest.kt | 37 ++
.../parameters/VisibilityModifierTest.kt | 17 +
.../DokkaModuleDescriptionBuilderTest.kt | 7 +
.../builders/DokkaParametersBuilderTest.kt | 7 +
.../builders/DokkaSourceSetBuilderTest.kt | 198 ++++++++
.../testFixtures/kotlin/GradleTestKitUtils.kt | 274 ++++++++++
.../kotlin/KotestProjectConfig.kt | 10 +
.../src/testFixtures/kotlin/fileTree.kt | 61 +++
.../src/testFixtures/kotlin/files.kt | 6 +
.../testFixtures/kotlin/gradleRunnerUtils.kt | 47 ++
.../kotlin/kotestCollectionMatchers.kt | 20 +
.../testFixtures/kotlin/kotestConditions.kt | 10 +
.../kotlin/kotestGradleAssertions.kt | 130 +++++
.../kotlin/kotestStringMatchers.kt | 65 +++
.../kotlin/samWithReceiverWorkarounds.kt | 77 +++
.../src/testFixtures/kotlin/stringUtils.kt | 21 +
.../kotlin/systemVariableProviders.kt | 40 ++
.../src/testFixtures/kotlin/text.kt | 24 +
.../kotlin/DokkatooPluginFunctionalTest.kt | 205 ++++++++
.../GradlePluginProjectIntegrationTest.kt | 110 ++++
.../KotlinMultiplatformFunctionalTest.kt | 247 +++++++++
.../kotlin/MultiModuleFunctionalTest.kt | 468 ++++++++++++++++++
dokka-runners/dokkatoo/settings.gradle.kts | 95 ++++
settings.gradle.kts | 4 +-
367 files changed, 15468 insertions(+), 3 deletions(-)
create mode 100644 dokka-runners/dokkatoo/.gitattributes
create mode 100644 dokka-runners/dokkatoo/.gitignore
create mode 100644 dokka-runners/dokkatoo/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaSourceDownloaderSettings.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaTemplateProjectSettings.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkatooExampleProjectsSettings.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishTestSettings.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishingSettings.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/UpdateDokkatooExampleProjects.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/gradle.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/intellij.kt
create mode 100644 dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/strings.kt
create mode 100644 dokka-runners/dokkatoo/devOps/release.main.kts
create mode 100644 dokka-runners/dokkatoo/examples/.gitignore
create mode 100644 dokka-runners/dokkatoo/examples/README.md
create mode 100644 dokka-runners/dokkatoo/examples/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/demo.png
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/ktor-logo.png
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/logo-styles.css
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokka/src/main/kotlin/demo/HelloWorld.kt
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokkatoo/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokkatoo/ktor-logo.png
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokkatoo/logo-styles.css
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/custom-format-example/dokkatoo/src/main/kotlin/demo/HelloWorld.kt
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokka/Module.md
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokka/demo.png
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokka/src/main/kotlin/demo/HelloWorld.kt
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokkatoo/Module.md
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokkatoo/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/gradle-example/dokkatoo/src/main/kotlin/demo/HelloWorld.kt
create mode 100644 dokka-runners/dokkatoo/examples/kotlin-as-java-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/kotlin-as-java-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/kotlin-as-java-example/dokka/demo.png
create mode 100644 dokka-runners/dokkatoo/examples/kotlin-as-java-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/kotlin-as-java-example/dokka/src/main/kotlin/demo/HelloWorld.kt
create mode 100644 dokka-runners/dokkatoo/examples/kotlin-as-java-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/library-publishing-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/library-publishing-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/library-publishing-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/library-publishing-example/dokka/src/main/kotlin/demo/HelloWorld.kt
create mode 100644 dokka-runners/dokkatoo/examples/library-publishing-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/demo.png
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/childProjectA/ModuleA.md
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/childProjectB/ModuleB.md
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/buildSrc/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/buildSrc/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/buildSrc/src/main/kotlin/dokka-convention.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/childProjectA/ModuleA.md
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/childProjectA/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/childProjectB/ModuleB.md
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/childProjectB/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt
create mode 100644 dokka-runners/dokkatoo/examples/multimodule-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/demo.png
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/CommonCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/CommonDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/commonMain/kotlin/org/kotlintestmpp/common/Foo.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/customJdk9/kotlin/org/kotlintest/jdk9/CustomSourceSetFile.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/JsCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/JsDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jsMain/kotlin/org/kotlintestmpp/JsFunctions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/JavaAnnotation.java
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/JvmCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/JvmDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/jvmMain/kotlin/org/kotlintestmpp/JvmFunctions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/CInterop.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/LinuxCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/linuxMain/kotlin/org/kotlintestmpp/LinuxDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/MacOsCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokka/src/macosMain/kotlin/org/kotlintestmpp/MacOsDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/commonMain/kotlin/org/kotlintestmpp/CommonCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/commonMain/kotlin/org/kotlintestmpp/CommonDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/commonMain/kotlin/org/kotlintestmpp/common/Foo.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/customJdk9/kotlin/org/kotlintest/jdk9/CustomSourceSetFile.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jsMain/kotlin/org/kotlintestmpp/JsCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jsMain/kotlin/org/kotlintestmpp/JsDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jsMain/kotlin/org/kotlintestmpp/JsFunctions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jvmMain/kotlin/org/kotlintestmpp/JavaAnnotation.java
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jvmMain/kotlin/org/kotlintestmpp/JvmCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jvmMain/kotlin/org/kotlintestmpp/JvmDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/jvmMain/kotlin/org/kotlintestmpp/JvmFunctions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/linuxMain/kotlin/org/kotlintestmpp/CInterop.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/linuxMain/kotlin/org/kotlintestmpp/LinuxCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/linuxMain/kotlin/org/kotlintestmpp/LinuxDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/macosMain/kotlin/org/kotlintestmpp/MacOsCoroutineExtensions.kt
create mode 100644 dokka-runners/dokkatoo/examples/multiplatform-example/dokkatoo/src/macosMain/kotlin/org/kotlintestmpp/MacOsDateUtils.kt
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/README.md
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/demo.png
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/ChildProjectAClass.kt
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/childProjectA/src/main/kotlin/demo/FancyAPI.kt
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/ChildProjectBClass.kt
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/parentProject/childProjectB/src/main/kotlin/demo/Functions.kt
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/examples/versioning-multimodule-example/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/gradle.properties
create mode 100644 dokka-runners/dokkatoo/gradle/libs.versions.toml
create mode 100644 dokka-runners/dokkatoo/modules/docs/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/docs/images/banner.svg
create mode 100644 dokka-runners/dokkatoo/modules/docs/images/logo-icon.svg
create mode 100644 dokka-runners/dokkatoo/modules/docs/images/social_preview_banner.png
create mode 100644 dokka-runners/dokkatoo/modules/docs/images/social_preview_banner.svg
create mode 100644 dokka-runners/dokkatoo/modules/docs/style/logo-styles.css
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/.gitignore
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/android-googletv-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/android-sdk-arm-dbt-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/android-sdk-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/android-sdk-preview-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/google-gdk-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/intel-android-extra-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/ANDROID_SDK/licenses/mips-android-sysimage-license
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/AndroidManifest.xml
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/AndroidSpecificClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/src/main/java/it/android/IntegrationTestActivity.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/src/main/AndroidManifest.xml
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/src/main/java/it/android/AndroidSpecificClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-android-0/dokkatoo/src/main/java/it/android/IntegrationTestActivity.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/java/it/basic/java/SampleJavaClass.java
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/src/main/kotlin/it/basic/PublicClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic-groovy/dokkatoo/settings.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-resource.svg
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/custom-style-to-add.css
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/customResources/logo-styles.css
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/java/it/basic/java/SampleJavaClass.java
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/RootPackageClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/basic/PublicClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/internal/InternalClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/protected/ProtectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/src/test/kotlin/it/basic/TestClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-resource.svg
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/custom-style-to-add.css
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/customResources/logo-styles.css
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/java/it/basic/java/SampleJavaClass.java
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/RootPackageClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/basic/PublicClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/internal/InternalClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/overriddenVisibility/VisiblePrivateClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/protected/ProtectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-basic/dokkatoo/src/test/kotlin/it/basic/TestClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/README.md
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/README.md
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-collector-0/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/RootPackageClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/basic/PublicClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/internal/InternalClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPackage/SuppressedByPackage.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/src/main/kotlin/it/suppressedByPath/SuppressedByPath.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-js-ir-0/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/Module.md
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleB/src/main/kotlin/org/jetbrains/dokka/it/moduleB/ModuleB.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/Module.md
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleC/src/main/kotlin/org/jetbrains/dokka/it/moduleC/ModuleC.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/moduleA/moduleD/src/main/kotlin/org/jetbrains/dokka/it/moduleD/ModuleC.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-0/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/FirstSubclass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/foo/Main.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/first/src/main/kotlin/noPackage.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/NoPackageClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/bar/SecondClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/second/src/main/kotlin/foo/ThirdClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-1/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/first/src/main/kotlin/foo/FirstClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/build.gradle
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/second/src/main/kotlin/bar/SecondClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multimodule-versioning-0/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/CommonMainClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/ExpectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/commonMain/kotlin/it/mpp0/coroutines.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/CPointerExtension.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/desktopMain/kotlin/it/mpp0/ExpectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/ExpectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jsMain/kotlin/it/mpp0/runBlocking.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/ExpectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/JvmOnlyClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/jvmMain/kotlin/it/mpp0/runBlocking.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/CPointerExtension.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/ExpectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/linuxMain/kotlin/it/mpp0/runBlocking.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/ExpectedClass.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/src/macosMain/kotlin/it/mpp0/runBlocking.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.root.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokka/template.settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/projects/it-multiplatform-0/dokkatoo/settings.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/CustomFormatExampleTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/GradleExampleTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/KotlinMultiplatformExampleTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testExamples/kotlin/MultimoduleExampleTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testFixtures/kotlin/templateProjectUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testIntegration/kotlin/AndroidProjectIntegrationTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testIntegration/kotlin/BasicProjectIntegrationTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/childProjectA.json
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/childProjectB.json
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/parentProject.json
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin-integration-tests/src/testIntegration/resources/it/example/dokka-multi-module/readme.md
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/api/dokkatoo-plugin.api
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/build.gradle.kts
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooBasePlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooExtension.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/DokkatooPlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/adapters/DokkatooAndroidAdapter.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/adapters/DokkatooJavaAdapter.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/adapters/DokkatooKotlinAdapter.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/distributions/DokkatooConfigurationAttributes.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/DokkaPublication.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaExternalDocumentationLinkSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaGeneratorParametersSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaModuleDescriptionSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaPackageOptionsSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaParametersKxs.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceLinkSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceSetIdSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/DokkaSourceSetSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/HasConfigurableVisibilityModifiers.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/KotlinPlatform.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/VisibilityModifier.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/builders/DokkaModuleDescriptionBuilder.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/builders/DokkaParametersBuilder.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/parameters/builders/DokkaSourceSetBuilder.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaHtmlPluginParameters.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBaseSpec.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaPluginParametersBuilder.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/dokka/plugins/DokkaVersioningPluginParameters.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatDependencyContainers.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatPlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooFormatTasks.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooGfmPlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooHtmlPlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooJavadocPlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/formats/DokkatooJekyllPlugin.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/DokkatooInternalApi.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/LoggerAdapter.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/collectionsUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleExtensionAccessors.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleTypealiases.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/gradleUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/kotlinxSerializationUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/stringUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/internal/uriUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooGenerateTask.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooPrepareModuleDescriptorTask.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/DokkatooTask.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/tasks/LogHtmlPublicationLinkTask.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/main/kotlin/workers/DokkaGeneratorWorker.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/DokkatooPluginTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/DokkaExternalDocumentationLinkSpecTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/DokkaSourceLinkSpecTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/KotlinPlatformTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/VisibilityModifierTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/builders/DokkaModuleDescriptionBuilderTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/builders/DokkaParametersBuilderTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/test/kotlin/dokka/parameters/builders/DokkaSourceSetBuilderTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/GradleTestKitUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/KotestProjectConfig.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/fileTree.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/files.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/gradleRunnerUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/kotestCollectionMatchers.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/kotestConditions.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/kotestGradleAssertions.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/kotestStringMatchers.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/samWithReceiverWorkarounds.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/stringUtils.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/systemVariableProviders.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFixtures/kotlin/text.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFunctional/kotlin/DokkatooPluginFunctionalTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFunctional/kotlin/GradlePluginProjectIntegrationTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFunctional/kotlin/KotlinMultiplatformFunctionalTest.kt
create mode 100644 dokka-runners/dokkatoo/modules/dokkatoo-plugin/src/testFunctional/kotlin/MultiModuleFunctionalTest.kt
create mode 100644 dokka-runners/dokkatoo/settings.gradle.kts
diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts
index c32bdd2547..fedf3403c3 100644
--- a/build-logic/build.gradle.kts
+++ b/build-logic/build.gradle.kts
@@ -10,7 +10,7 @@ plugins {
kotlin {
jvmToolchain {
- languageVersion.set(JavaLanguageVersion.of(8))
+ languageVersion.set(JavaLanguageVersion.of(11))
}
}
diff --git a/dokka-runners/dokkatoo/.gitattributes b/dokka-runners/dokkatoo/.gitattributes
new file mode 100644
index 0000000000..2ba525d513
--- /dev/null
+++ b/dokka-runners/dokkatoo/.gitattributes
@@ -0,0 +1,51 @@
+# https://help.github.com/articles/dealing-with-line-endings/
+# https://github.com/alexkaratarakis/gitattributes
+
+* text=auto
+
+# The above will handle all files NOT found below
+
+*.json text
+*.toml text
+*.xml text
+*.yaml text
+*.yml text
+.editorconfig text
+.env text
+
+# Documentation
+*.md text diff=markdown
+*.txt text
+LICENSE text
+
+# JVM
+*.java text diff=java
+*.kt text diff=kotlin
+*.kts text diff=kotlin
+*.properties text
+*.jar binary
+
+
+# Linux start script should use lf
+gradlew text eol=lf
+*.bash text eol=lf
+*.sh text eol=lf
+
+# These are Windows script files and should use crlf
+*.bat text eol=crlf
+*.cmd text eol=crlf
+
+# SVG treated as an asset (binary) by default.
+*.svg text
+
+# Exclude external libs from GitHub language stats https://github.com/github/linguist/blob/v7.24.1/docs/overrides.md
+examples/** linguist-documentation
+examples/*/dokka linguist-vendored
+modules/dokkatoo-plugin-integration-tests/projects/**dokka/ linguist-vendored
+modules/dokkatoo-plugin-integration-tests/projects/**dokkatoo/ linguist-documentation
+
+# Exclude files from exporting
+
+.gitattributes export-ignore
+.gitignore export-ignore
+.gitkeep export-ignore
diff --git a/dokka-runners/dokkatoo/.gitignore b/dokka-runners/dokkatoo/.gitignore
new file mode 100644
index 0000000000..e733d08a6f
--- /dev/null
+++ b/dokka-runners/dokkatoo/.gitignore
@@ -0,0 +1,71 @@
+### Gradle ###
+.gradle
+build/
+
+!gradle/wrapper/gradle-wrapper.jar
+!gradle/wrapper/gradle-wrapper.properties
+
+
+### Kotlin/JVM ###
+*.class
+*.log
+
+hs_err_pid*
+replay_pid*
+*.hprof
+
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+
+### IntelliJ ###
+.idea/**
+!.idea/codeStyles/
+!.idea/codeStyles/**
+
+
+### Eclipse ###
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+.settings/
+.loadpath
+.recommenders
+.classpath
+
+.apt_generated/
+.apt_generated_test/
+.project
+
+
+### Linux ###
+*~
+.fuse_hidden*
+.Trash-*
+.nfs*
+
+
+### Windows ###
+[Dd]esktop.ini
+$RECYCLE.BIN/
+*.lnk
+
+
+### macOS ###
+.DS_Store
+._*
+
+# Icon must end with two \r
+Icon
+
+
+###########################
diff --git a/dokka-runners/dokkatoo/build.gradle.kts b/dokka-runners/dokkatoo/build.gradle.kts
new file mode 100644
index 0000000000..6718499894
--- /dev/null
+++ b/dokka-runners/dokkatoo/build.gradle.kts
@@ -0,0 +1,47 @@
+import buildsrc.utils.excludeGeneratedGradleDsl
+import buildsrc.utils.initIdeProjectLogo
+
+plugins {
+ buildsrc.conventions.base
+ idea
+}
+
+group = "org.jetbrains.dokka.dokkatoo"
+version = "2.1.0-SNAPSHOT"
+
+
+idea {
+ module {
+ excludeGeneratedGradleDsl(layout)
+
+ excludeDirs.apply {
+ // exclude .gradle, IDE dirs from nested projects (e.g. example & template projects)
+ // so IntelliJ project-wide search isn't cluttered with irrelevant files
+ val excludedDirs = setOf(
+ ".idea",
+ ".gradle",
+ "build",
+ "gradle/wrapper",
+ "ANDROID_SDK",
+ )
+ addAll(
+ projectDir.walk().filter { file ->
+ excludedDirs.any {
+ file.invariantSeparatorsPath.endsWith(it)
+ }
+ }
+ )
+ }
+ }
+}
+
+initIdeProjectLogo("modules/docs/images/logo-icon.svg")
+
+val dokkatooVersion by tasks.registering {
+ description = "prints the Dokkatoo project version (used during release to verify the version)"
+ group = "help"
+ val version = providers.provider { project.version }
+ doLast {
+ logger.quiet("${version.orNull}")
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/build.gradle.kts b/dokka-runners/dokkatoo/buildSrc/build.gradle.kts
new file mode 100644
index 0000000000..832a98b95b
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/build.gradle.kts
@@ -0,0 +1,19 @@
+import org.gradle.kotlin.dsl.support.expectedKotlinDslPluginsVersion
+
+plugins {
+ `kotlin-dsl`
+}
+
+dependencies {
+ implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion")
+ implementation(libs.gradlePlugin.bcvMu)
+ implementation(libs.gradlePlugin.dokkatoo)
+ implementation(libs.gradlePlugin.gradlePublishPlugin)
+ implementation("org.jetbrains.kotlin:kotlin-serialization:$embeddedKotlinVersion")
+}
+
+java {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(11))
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/settings.gradle.kts b/dokka-runners/dokkatoo/buildSrc/settings.gradle.kts
new file mode 100644
index 0000000000..855fe5d957
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/settings.gradle.kts
@@ -0,0 +1,25 @@
+rootProject.name = "buildSrc"
+
+pluginManagement {
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+@Suppress("UnstableApiUsage")
+dependencyResolutionManagement {
+
+ repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
+
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+
+ versionCatalogs {
+ create("libs") {
+ from(files("../gradle/libs.versions.toml"))
+ }
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts
new file mode 100644
index 0000000000..ed22d79948
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/android-setup.gradle.kts
@@ -0,0 +1,78 @@
+package buildsrc.conventions
+
+import org.jetbrains.kotlin.util.suffixIfNot
+
+
+/**
+ * Utilities for preparing Android projects
+ */
+
+plugins {
+ base
+ id("buildsrc.conventions.base")
+}
+
+
+val androidSdkDirPath: Provider = providers
+ // first try getting the SDK installed on via GitHub step setup-android
+ .environmentVariable("ANDROID_SDK_ROOT").map(::File)
+ // else get the project-local SDK
+ .orElse(layout.projectDirectory.file("projects/ANDROID_SDK").asFile)
+ .map { it.invariantSeparatorsPath }
+
+
+val createAndroidLocalPropertiesFile by tasks.registering {
+
+ val localPropertiesFile = temporaryDir.resolve("local.properties")
+ outputs.file(localPropertiesFile).withPropertyName("localPropertiesFile")
+
+ val androidSdkDirPath = androidSdkDirPath
+ inputs.property("androidSdkDirPath", androidSdkDirPath)
+
+ doLast {
+ localPropertiesFile.apply {
+ parentFile.mkdirs()
+ createNewFile()
+ writeText(
+ """
+ |# DO NOT EDIT - Generated by $path
+ |
+ |sdk.dir=${androidSdkDirPath.get()}
+ |
+ """.trimMargin()
+ )
+ }
+ }
+}
+
+
+val updateAndroidLocalProperties by tasks.registering {
+
+ // find all local.properties files
+ val localPropertiesFiles = layout.projectDirectory.dir("projects")
+ .asFileTree
+ .matching { include("**/local.properties") }
+ .files
+
+ outputs.files(localPropertiesFiles).withPropertyName("localPropertiesFiles")
+
+ val androidSdkDirPath = androidSdkDirPath
+ inputs.property("androidSdkDirPath", androidSdkDirPath)
+
+ doLast {
+ localPropertiesFiles
+ .filter { it.exists() }
+ .forEach { file ->
+ file.writeText(
+ file.useLines { lines ->
+ lines.joinToString("\n") { line ->
+ when {
+ line.startsWith("sdk.dir=") -> "sdk.dir=${androidSdkDirPath.get()}"
+ else -> line
+ }
+ }.suffixIfNot("\n")
+ }
+ )
+ }
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
new file mode 100644
index 0000000000..60bfa2fe55
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
@@ -0,0 +1,155 @@
+package buildsrc.conventions
+
+import java.time.Duration
+import org.gradle.api.tasks.testing.logging.TestLogEvent
+
+/**
+ * A convention plugin that sets up common config and sensible defaults for all subprojects.
+ */
+
+plugins {
+ base
+}
+
+if (project != rootProject) {
+ project.version = rootProject.version
+ project.group = rootProject.group
+}
+
+tasks.withType().configureEach {
+ // https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
+ isPreserveFileTimestamps = false
+ isReproducibleFileOrder = true
+}
+
+tasks.withType().configureEach {
+ timeout.set(Duration.ofMinutes(60))
+
+ testLogging {
+ showCauses = true
+ showExceptions = true
+ showStackTraces = true
+ showStandardStreams = true
+ events(
+ TestLogEvent.PASSED,
+ TestLogEvent.FAILED,
+ TestLogEvent.SKIPPED,
+ TestLogEvent.STARTED,
+ TestLogEvent.STANDARD_ERROR,
+ TestLogEvent.STANDARD_OUT,
+ )
+ }
+}
+
+tasks.withType().configureEach {
+ includeEmptyDirs = false
+}
+
+val updateTestReportCss by tasks.registering {
+ description = "Hack so the Gradle test reports have dark mode"
+ // the CSS is based on https://github.com/gradle/gradle/pull/12177
+
+ mustRunAfter(tasks.withType())
+ mustRunAfter(tasks.withType())
+
+ val cssFiles = layout.buildDirectory.asFileTree.matching {
+ include("reports/**/css/base-style.css")
+ include("reports/**/css/style.css")
+ }
+
+ outputs.files(cssFiles.files)
+
+ doLast {
+ cssFiles.forEach { cssFile ->
+ val fileContent = cssFile.readText()
+
+ if ("/* Dark mode */" in fileContent) {
+ return@forEach
+ } else {
+ when (cssFile.name) {
+ "base-style.css" -> cssFile.writeText(
+ fileContent + """
+
+ /* Dark mode */
+ @media (prefers-color-scheme: dark) {
+ html {
+ background: black;
+ }
+ body, a, a:visited {
+ color: #E7E7E7FF;
+ }
+ #footer, #footer a {
+ color: #cacaca;
+ }
+ ul.tabLinks li {
+ border: solid 1px #cacaca;
+ background-color: #151515;
+ }
+ ul.tabLinks li:hover {
+ background-color: #383838;
+ }
+ ul.tabLinks li.selected {
+ background-color: #002d32;
+ border-color: #007987;
+ }
+ div.tab th, div.tab table {
+ border-bottom: solid #d0d0d0 1px;
+ }
+ span.code pre {
+ background-color: #0a0a0a;
+ border: solid 1px #5f5f5f;
+ }
+ }
+ """.trimIndent()
+ )
+
+ "style.css" -> cssFile.writeText(
+ fileContent + """
+
+ /* Dark mode */
+ @media (prefers-color-scheme: dark) {
+ .breadcrumbs, .breadcrumbs a {
+ color: #9b9b9b;
+ }
+ #successRate, .summaryGroup {
+ border: solid 2px #d0d0d0;
+ }
+ .success, .success a {
+ color: #7fff7f;
+ }
+ div.success, #successRate.success {
+ background-color: #001c00;
+ border-color: #7fff7f;
+ }
+ .failures, .failures a {
+ color: #a30000;
+ }
+ .skipped, .skipped a {
+ color: #a26d13;
+ }
+ div.failures, #successRate.failures {
+ background-color: #170000;
+ border-color: #a30000;
+ }
+ }
+ """.trimIndent()
+ )
+ }
+ }
+ }
+ }
+}
+
+tasks.withType().configureEach {
+ finalizedBy(updateTestReportCss)
+}
+
+tasks.withType().configureEach {
+ finalizedBy(updateTestReportCss)
+}
+
+tasks.matching { it.name == "validatePlugins" }.configureEach {
+ // prevent warning
+ // Task ':validatePlugins' uses this output of task ':updateTestReportCss' without declaring an explicit or implicit dependency.
+ mustRunAfter(updateTestReportCss)
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts
new file mode 100644
index 0000000000..69e384e109
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokka-source-downloader.gradle.kts
@@ -0,0 +1,68 @@
+package buildsrc.conventions
+
+import buildsrc.settings.DokkaSourceDownloaderSettings
+import buildsrc.utils.asConsumer
+import buildsrc.utils.asProvider
+import buildsrc.utils.dropDirectories
+import org.gradle.api.attributes.Usage.USAGE_ATTRIBUTE
+import org.gradle.kotlin.dsl.support.serviceOf
+
+plugins {
+ id("buildsrc.conventions.base")
+}
+
+val dsdExt: DokkaSourceDownloaderSettings = extensions.create(
+ DokkaSourceDownloaderSettings.EXTENSION_NAME
+)
+
+val kotlinDokkaSource by configurations.creating {
+ asConsumer()
+ attributes {
+ attribute(USAGE_ATTRIBUTE, objects.named("externals-dokka-src"))
+ }
+}
+
+val kotlinDokkaSourceElements by configurations.registering {
+ asProvider()
+ attributes {
+ attribute(USAGE_ATTRIBUTE, objects.named("externals-dokka-src"))
+ }
+}
+
+dependencies {
+ kotlinDokkaSource(dsdExt.dokkaVersion.map { "kotlin:dokka:$it@zip" })
+}
+
+val prepareDokkaSource by tasks.registering(Sync::class) {
+ group = "dokka setup"
+ description = "Download & unpack Kotlin Dokka source code"
+
+ inputs.property("dokkaVersion", dsdExt.dokkaVersion).optional(false)
+
+ val archives = serviceOf()
+
+ from(
+ kotlinDokkaSource.incoming
+ .artifacts
+ .resolvedArtifacts
+ .map { artifacts ->
+ artifacts.map { archives.zipTree(it.file) }
+ }
+ ) {
+ // drop the first dir (dokka-$version)
+ eachFile {
+ relativePath = relativePath.dropDirectories(1)
+ }
+ }
+
+ into(temporaryDir)
+
+ exclude(
+ "*.github",
+ "*.gradle",
+ "**/gradlew",
+ "**/gradlew.bat",
+ "**/gradle/wrapper/gradle-wrapper.jar",
+ "**/gradle/wrapper/gradle-wrapper.properties",
+ )
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts
new file mode 100644
index 0000000000..5c2c45fa39
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects-base.gradle.kts
@@ -0,0 +1,27 @@
+package buildsrc.conventions
+
+import buildsrc.utils.asConsumer
+import buildsrc.utils.asProvider
+
+plugins {
+ id("buildsrc.conventions.base")
+}
+
+
+val exampleProjectsAttribute: Attribute =
+ Attribute.of("example-projects", String::class.java)
+
+dependencies.attributesSchema {
+ attribute(exampleProjectsAttribute)
+}
+
+
+val exampleProjects by configurations.registering {
+ asConsumer()
+ attributes { attribute(exampleProjectsAttribute, "dokka") }
+}
+
+val exampleProjectsElements by configurations.registering {
+ asProvider()
+ attributes { attribute(exampleProjectsAttribute, "dokka") }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts
new file mode 100644
index 0000000000..c6994a8376
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/dokkatoo-example-projects.gradle.kts
@@ -0,0 +1,160 @@
+package buildsrc.conventions
+
+import buildsrc.settings.*
+import buildsrc.tasks.*
+import buildsrc.utils.*
+
+plugins {
+ id("buildsrc.conventions.base")
+ id("buildsrc.conventions.dokka-source-downloader")
+ id("buildsrc.conventions.maven-publish-test")
+ id("buildsrc.conventions.dokkatoo-example-projects-base")
+}
+
+val mavenPublishTestExtension = extensions.getByType()
+val dokkaTemplateProjectSettings =
+ extensions.create(
+ DokkaTemplateProjectSettings.EXTENSION_NAME,
+ { project.copySpec() }
+ ).apply {
+ this.destinationBaseDir.convention(layout.projectDirectory)
+ }
+
+val prepareDokkaSource by tasks.existing(Sync::class)
+
+dokkaTemplateProjectSettings.dokkaSourceDir.convention(
+ prepareDokkaSource.flatMap {
+ layout.dir(providers.provider {
+ it.destinationDir
+ })
+ }
+)
+
+tasks.withType().configureEach {
+ dependsOn(prepareDokkaSource)
+
+ dokkaSourceDir.convention(dokkaTemplateProjectSettings.dokkaSourceDir)
+ destinationBaseDir.convention(dokkaTemplateProjectSettings.destinationBaseDir)
+
+ templateProjects.addAllLater(provider {
+ dokkaTemplateProjectSettings.templateProjects
+ })
+}
+
+val setupDokkaTemplateProjects by tasks.registering(SetupDokkaProjects::class)
+
+fun createDokkatooExampleProjectsSettings(
+ projectDir: Directory = project.layout.projectDirectory
+): DokkatooExampleProjectsSettings {
+ return extensions.create(
+ DokkatooExampleProjectsSettings.EXTENSION_NAME
+ ).apply {
+
+ // find all Gradle settings files
+ val settingsFiles = projectDir.asFileTree
+ .matching {
+ include(
+ "**/*dokkatoo*/**/settings.gradle.kts",
+ "**/*dokkatoo*/**/settings.gradle",
+ )
+ }.files
+
+ // for each settings file, create a DokkatooExampleProjectSpec
+ settingsFiles.forEach {
+ val destinationDir = it.parentFile
+ val name = destinationDir.toRelativeString(projectDir.asFile).toAlphaNumericCamelCase()
+ exampleProjects.register(name) {
+ this.exampleProjectDir.set(destinationDir)
+ }
+ }
+
+ exampleProjects.configureEach {
+ gradlePropertiesContent.add(
+ mavenPublishTestExtension.testMavenRepoPath.map { testMavenRepoPath ->
+ "testMavenRepo=$testMavenRepoPath"
+ }
+ )
+ }
+ }
+}
+
+val dokkatooExampleProjectsSettings = createDokkatooExampleProjectsSettings()
+
+val updateDokkatooExamplesGradleProperties by tasks.registering(
+ UpdateDokkatooExampleProjects::class
+) {
+ group = DokkatooExampleProjectsSettings.TASK_GROUP
+
+ mustRunAfter(tasks.withType())
+
+ exampleProjects.addAllLater(providers.provider {
+ dokkatooExampleProjectsSettings.exampleProjects
+ })
+}
+
+val dokkatooVersion = provider { project.version.toString() }
+
+val updateDokkatooExamplesBuildFiles by tasks.registering {
+ group = DokkatooExampleProjectsSettings.TASK_GROUP
+ description = "Update the Gradle build files in the Dokkatoo examples"
+
+ outputs.upToDateWhen { false }
+
+ mustRunAfter(tasks.withType())
+ shouldRunAfter(updateDokkatooExamplesGradleProperties)
+
+ val dokkatooVersion = dokkatooVersion
+
+ val dokkatooDependencyVersionMatcher = """
+ \"dev\.adamko\.dokkatoo\:dokkatoo\-plugin\:([^"]+?)\"
+ """.trimIndent().toRegex()
+
+ val dokkatooPluginVersionMatcher = """
+ id[^"]+?"dev\.adamko\.dokkatoo".+?version "([^"]+?)"
+ """.trimIndent().toRegex()
+
+ val gradleBuildFiles =
+ layout.projectDirectory.asFileTree
+ .matching {
+ include(
+ "**/*dokkatoo*/**/build.gradle.kts",
+ "**/*dokkatoo*/**/build.gradle",
+ )
+ }.elements
+ outputs.files(gradleBuildFiles)
+
+ doLast {
+ gradleBuildFiles.get().forEach { fileLocation ->
+ val file = fileLocation.asFile
+ if (file.exists()) {
+ file.writeText(
+ file.readText()
+ .replace(dokkatooPluginVersionMatcher) {
+ val oldVersion = it.groupValues[1]
+ it.value.replace(oldVersion, dokkatooVersion.get())
+ }
+ .replace(dokkatooDependencyVersionMatcher) {
+ val oldVersion = it.groupValues[1]
+ it.value.replace(oldVersion, dokkatooVersion.get())
+ }
+ )
+ }
+ }
+ }
+}
+
+
+val updateDokkatooExamples by tasks.registering {
+ group = DokkatooExampleProjectsSettings.TASK_GROUP
+ description = "lifecycle task for all '${DokkatooExampleProjectsSettings.TASK_GROUP}' tasks"
+ dependsOn(
+ setupDokkaTemplateProjects,
+ updateDokkatooExamplesGradleProperties,
+ updateDokkatooExamplesBuildFiles,
+ )
+}
+
+tasks.assemble {
+ dependsOn(updateDokkatooExamples)
+ dependsOn(setupDokkaTemplateProjects)
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts
new file mode 100644
index 0000000000..1d9fc43b01
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/gradle-plugin-variants.gradle.kts
@@ -0,0 +1,44 @@
+package buildsrc.conventions
+
+import org.gradle.api.attributes.plugin.GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE
+
+plugins {
+ id("buildsrc.conventions.base")
+ `java-gradle-plugin`
+}
+
+fun registerGradleVariant(name: String, gradleVersion: String) {
+ val variantSources = sourceSets.create(name)
+
+ java {
+ registerFeature(variantSources.name) {
+ usingSourceSet(variantSources)
+ capability("${project.group}", "${project.name}", "${project.version}")
+
+ withJavadocJar()
+ withSourcesJar()
+ }
+ }
+
+ configurations
+ .matching { it.isCanBeConsumed && it.name.startsWith(variantSources.name) }
+ .configureEach {
+ attributes {
+ attribute(GRADLE_PLUGIN_API_VERSION_ATTRIBUTE, objects.named(gradleVersion))
+ }
+ }
+
+ tasks.named(variantSources.processResourcesTaskName) {
+ val copyPluginDescriptors = rootSpec.addChild()
+ copyPluginDescriptors.into("META-INF/gradle-plugins")
+// copyPluginDescriptors.into(tasks.pluginDescriptors.flatMap { it.outputDirectory })
+ copyPluginDescriptors.from(tasks.pluginDescriptors)
+ }
+
+ dependencies {
+ add(variantSources.compileOnlyConfigurationName, gradleApi())
+ }
+}
+
+registerGradleVariant("gradle7", "7.6")
+registerGradleVariant("gradle8", "8.0")
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts
new file mode 100644
index 0000000000..203b80f2b1
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/java-base.gradle.kts
@@ -0,0 +1,19 @@
+package buildsrc.conventions
+
+import org.gradle.api.JavaVersion
+import org.gradle.api.plugins.JavaPluginExtension
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.`java-base`
+
+plugins {
+ id("buildsrc.conventions.base")
+ `java`
+}
+
+extensions.getByType().apply {
+ toolchain {
+ languageVersion.set(JavaLanguageVersion.of(11))
+ }
+ withSourcesJar()
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts
new file mode 100644
index 0000000000..4174088ab9
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/kotlin-gradle-plugin.gradle.kts
@@ -0,0 +1,37 @@
+package buildsrc.conventions
+
+plugins {
+ id("buildsrc.conventions.base")
+ id("buildsrc.conventions.java-base")
+ id("org.gradle.kotlin.kotlin-dsl")
+ id("com.gradle.plugin-publish")
+}
+
+tasks.validatePlugins {
+ enableStricterValidation.set(true)
+}
+
+val createJavadocJarReadme by tasks.registering(Sync::class) {
+ description = "generate a readme.txt for the Javadoc JAR"
+ from(
+ resources.text.fromString(
+ """
+ This Javadoc JAR is intentionally empty.
+
+ For documentation, see the sources JAR or https://github.com/adamko-dev/dokkatoo/
+
+ """.trimIndent()
+ )
+ ) {
+ rename { "readme.txt" }
+ }
+ into(temporaryDir)
+}
+
+
+// The Gradle Publish Plugin enables the Javadoc JAR in afterEvaluate, so find it lazily
+tasks.withType()
+ .matching { it.name == "javadocJar" }
+ .configureEach {
+ from(createJavadocJarReadme)
+ }
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts
new file mode 100644
index 0000000000..38678b5bab
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publish-test.gradle.kts
@@ -0,0 +1,93 @@
+package buildsrc.conventions
+
+import buildsrc.settings.MavenPublishTestSettings
+import buildsrc.utils.*
+
+
+/** Utility for publishing a project to a local Maven directory for use in integration tests. */
+
+plugins {
+ base
+}
+
+val Gradle.rootGradle: Gradle get() = generateSequence(gradle) { it.parent }.last()
+
+val mavenPublishTestExtension = extensions.create(
+ "mavenPublishTest",
+ gradle.rootGradle.rootProject.layout.buildDirectory.dir("test-maven-repo"),
+)
+
+
+val publishToTestMavenRepo by tasks.registering {
+ group = PublishingPlugin.PUBLISH_TASK_GROUP
+ description = "Publishes all Maven publications to the test Maven repository."
+}
+
+
+plugins.withType().all {
+ extensions
+ .getByType()
+ .publications
+ .withType().all publication@{
+ val publicationName = this@publication.name
+ val installTaskName = "publish${publicationName.uppercaseFirstChar()}PublicationToTestMavenRepo"
+
+ // Register a publication task for each publication.
+ // Use PublishToMavenLocal, because the PublishToMavenRepository task will *always* create
+ // a new jar, even if nothing has changed, and append a timestamp, which results in a large
+ // directory and tasks are never up-to-date.
+ // PublishToMavenLocal does not append a timestamp, so the target directory is smaller, and
+ // up-to-date checks work.
+ val installTask = tasks.register(installTaskName) {
+ description = "Publishes Maven publication '$publicationName' to the test Maven repository."
+ group = PublishingPlugin.PUBLISH_TASK_GROUP
+ outputs.cacheIf { true }
+ publication = this@publication
+ val destinationDir = mavenPublishTestExtension.testMavenRepo.get().asFile
+ inputs.property("testMavenRepoTempDir", destinationDir.invariantSeparatorsPath)
+ doFirst {
+ /**
+ * `maven.repo.local` will set the destination directory for this [PublishToMavenLocal] task.
+ *
+ * @see org.gradle.api.internal.artifacts.mvnsettings.DefaultLocalMavenRepositoryLocator.getLocalMavenRepository
+ */
+ System.setProperty("maven.repo.local", destinationDir.absolutePath)
+ }
+ }
+
+ publishToTestMavenRepo.configure {
+ dependsOn(installTask)
+ }
+
+ tasks.check {
+ mustRunAfter(installTask)
+ }
+ }
+}
+
+
+val testMavenPublication by configurations.registering {
+ asConsumer()
+ attributes {
+ attribute(MavenPublishTestSettings.attribute, "testMavenRepo")
+ }
+}
+
+val testMavenPublicationElements by configurations.registering {
+ asProvider()
+ extendsFrom(testMavenPublication.get())
+ attributes {
+ attribute(MavenPublishTestSettings.attribute, "testMavenRepo")
+ }
+ outgoing {
+ artifact(mavenPublishTestExtension.testMavenRepo) {
+ builtBy(publishToTestMavenRepo)
+ }
+ }
+}
+
+dependencies {
+ attributesSchema {
+ attribute(MavenPublishTestSettings.attribute)
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts
new file mode 100644
index 0000000000..7af7b69f91
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/conventions/maven-publishing.gradle.kts
@@ -0,0 +1,137 @@
+package buildsrc.conventions
+
+import buildsrc.settings.MavenPublishingSettings
+
+plugins {
+ `maven-publish`
+ signing
+}
+
+val mavenPublishing =
+ extensions.create(MavenPublishingSettings.EXTENSION_NAME, project)
+
+
+//region POM convention
+publishing {
+ publications.withType().configureEach {
+ pom {
+ name.convention("Dokkatoo")
+ description.convention("Dokkatoo is a Gradle plugin that generates documentation for your Kotlin projects")
+ url.convention("https://github.com/adamko-dev/dokkatoo")
+
+ scm {
+ connection.convention("scm:git:https://github.com/adamko-dev/dokkatoo")
+ developerConnection.convention("scm:git:https://github.com/adamko-dev/dokkatoo")
+ url.convention("https://github.com/adamko-dev/dokkatoo")
+ }
+
+ licenses {
+ license {
+ name.convention("Apache-2.0")
+ url.convention("https://www.apache.org/licenses/LICENSE-2.0.txt")
+ }
+ }
+
+ developers {
+ developer {
+ email.set("adam@adamko.dev")
+ }
+ }
+ }
+ }
+}
+//endregion
+
+
+//region GitHub branch publishing
+publishing {
+ repositories {
+ maven(mavenPublishing.githubPublishDir) {
+ name = "GitHubPublish"
+ }
+ }
+}
+//endregion
+
+
+//region Maven Central publishing/signing
+publishing {
+ repositories {
+ val mavenCentralUsername = mavenPublishing.mavenCentralUsername.orNull
+ val mavenCentralPassword = mavenPublishing.mavenCentralPassword.orNull
+ if (!mavenCentralUsername.isNullOrBlank() && !mavenCentralPassword.isNullOrBlank()) {
+ maven(mavenPublishing.sonatypeReleaseUrl) {
+ name = "SonatypeRelease"
+ credentials {
+ username = mavenCentralUsername
+ password = mavenCentralPassword
+ }
+ }
+ }
+ }
+
+ // com.gradle.plugin-publish automatically adds a Javadoc jar
+}
+
+signing {
+ logger.info("maven-publishing.gradle.kts enabled signing for ${project.path}")
+
+ val keyId = mavenPublishing.signingKeyId.orNull
+ val key = mavenPublishing.signingKey.orNull
+ val password = mavenPublishing.signingPassword.orNull
+
+ if (!keyId.isNullOrBlank() && !key.isNullOrBlank() && !password.isNullOrBlank()) {
+ useInMemoryPgpKeys(keyId, key, password)
+ }
+
+ setRequired({
+ gradle.taskGraph.allTasks.filterIsInstance().any {
+ it.repository.name == "SonatypeRelease"
+ }
+ })
+}
+
+//afterEvaluate {
+// com.gradle.plugin-publish automatically signs tasks in a weird way, that stops this from working:
+// signing {
+// sign(publishing.publications)
+// }
+//}
+//endregion
+
+
+//region Fix Gradle warning about signing tasks using publishing task outputs without explicit dependencies
+// https://youtrack.jetbrains.com/issue/KT-46466 https://github.com/gradle/gradle/issues/26091
+tasks.withType().configureEach {
+ val signingTasks = tasks.withType()
+ mustRunAfter(signingTasks)
+}
+//endregion
+
+
+//region publishing logging
+tasks.withType().configureEach {
+ val publicationGAV = provider { publication?.run { "$group:$artifactId:$version" } }
+ doLast("log publication GAV") {
+ if (publicationGAV.isPresent) {
+ logger.lifecycle("[task: ${path}] ${publicationGAV.get()}")
+ }
+ }
+}
+//endregion
+
+
+//region IJ workarounds
+// manually define the Kotlin DSL accessors because IntelliJ _still_ doesn't load them properly
+fun Project.publishing(configure: PublishingExtension.() -> Unit): Unit =
+ extensions.configure(configure)
+
+val Project.publishing: PublishingExtension
+ get() = extensions.getByType()
+
+fun Project.signing(configure: SigningExtension.() -> Unit): Unit =
+ extensions.configure(configure)
+
+val Project.signing: SigningExtension
+ get() = extensions.getByType()
+//endregion
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaSourceDownloaderSettings.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaSourceDownloaderSettings.kt
new file mode 100644
index 0000000000..c3f9906c79
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaSourceDownloaderSettings.kt
@@ -0,0 +1,13 @@
+package buildsrc.settings
+
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.api.provider.Property
+
+abstract class DokkaSourceDownloaderSettings : ExtensionAware {
+
+ abstract val dokkaVersion: Property
+
+ companion object {
+ const val EXTENSION_NAME = "dokkaSourceDownload"
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaTemplateProjectSettings.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaTemplateProjectSettings.kt
new file mode 100644
index 0000000000..7bacafb9b2
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkaTemplateProjectSettings.kt
@@ -0,0 +1,96 @@
+package buildsrc.settings
+
+import buildsrc.utils.adding
+import buildsrc.utils.domainObjectContainer
+import buildsrc.utils.toAlphaNumericCamelCase
+import javax.inject.Inject
+import org.gradle.api.Named
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.file.ConfigurableFileCollection
+import org.gradle.api.file.CopySpec
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.api.provider.Property
+import org.gradle.api.provider.SetProperty
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.Optional
+import org.gradle.kotlin.dsl.*
+
+private typealias TemplateProjectsContainer = NamedDomainObjectContainer
+
+abstract class DokkaTemplateProjectSettings @Inject constructor(
+ private val objects: ObjectFactory,
+ private val copySpecs: () -> CopySpec
+) : ExtensionAware {
+
+ /** Directory that will contain the projects downloaded from the Dokka source code. */
+ abstract val dokkaSourceDir: DirectoryProperty
+
+ abstract val destinationBaseDir: DirectoryProperty
+
+ internal val templateProjects: TemplateProjectsContainer =
+ // create an extension so Gradle will generate DSL accessors
+ extensions.adding("templateProjects", objects.domainObjectContainer { name ->
+ objects.newInstance(name, copySpecs())
+ })
+
+ /**
+ * Copy a directory from the Dokka source project into a local directory.
+ *
+ * @param[source] Source dir, relative to [templateProjectsDir]
+ * @param[destination] Destination dir, relative to [destinationBaseDir]
+ */
+ fun register(
+ source: String,
+ destination: String,
+ configure: DokkaTemplateProjectSpec.() -> Unit = {},
+ ) {
+ val name = source.toAlphaNumericCamelCase()
+ templateProjects.register(name) {
+ this.sourcePath.set(source)
+ this.destinationPath.set(destination)
+ configure()
+ }
+ }
+
+ fun configureEach(configure: DokkaTemplateProjectSpec.() -> Unit) {
+ templateProjects.configureEach(configure)
+ }
+
+ /**
+ * Details for how to copy a Dokka template project from the Dokka project to a local directory.
+ */
+ abstract class DokkaTemplateProjectSpec @Inject constructor(
+ private val named: String,
+ @get:Internal
+ internal val copySpec: CopySpec,
+ ) : Named {
+
+ @get:Input
+ abstract val sourcePath: Property
+
+ @get:Input
+ @get:Optional
+ abstract val destinationPath: Property
+
+ @get:Input
+ abstract val additionalPaths: SetProperty
+
+ @get:InputFiles
+ abstract val additionalFiles: ConfigurableFileCollection
+
+ fun configureCopy(configure: CopySpec.() -> Unit) {
+ copySpec.configure()
+ }
+
+ @Input
+ override fun getName(): String = named
+ }
+
+ companion object {
+ const val EXTENSION_NAME = "dokkaTemplateProjects"
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkatooExampleProjectsSettings.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkatooExampleProjectsSettings.kt
new file mode 100644
index 0000000000..a312490475
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/DokkatooExampleProjectsSettings.kt
@@ -0,0 +1,62 @@
+package buildsrc.settings
+
+import buildsrc.utils.adding
+import buildsrc.utils.domainObjectContainer
+import javax.inject.Inject
+import org.gradle.api.Named
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.file.RegularFile
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.Provider
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.Optional
+import org.gradle.api.tasks.OutputFile
+
+/**
+ * Settings for the [buildsrc.conventions.Dokkatoo_example_projects_gradle] convention plugin
+ */
+abstract class DokkatooExampleProjectsSettings @Inject constructor(
+ objects: ObjectFactory,
+) : ExtensionAware {
+
+ val exampleProjects: NamedDomainObjectContainer =
+ // create an extension so Gradle will generate DSL accessors
+ extensions.adding("exampleProjects", objects.domainObjectContainer())
+
+ abstract class DokkatooExampleProjectSpec(
+ private val name: String
+ ): Named {
+
+ /** The `gradle.properties` file of the example project */
+ @get:OutputFile
+ val gradlePropertiesFile: Provider
+ get() = exampleProjectDir.file("gradle.properties")
+
+ /** The directory that contains the example project */
+ @get:Internal
+ abstract val exampleProjectDir: DirectoryProperty
+
+ /**
+ * Content to add to the `gradle.properties` file.
+ *
+ * Elements may span multiple lines.
+ *
+ * Elements will be sorted before appending to the file (to improve caching & reproducibility).
+ */
+ @get:Input
+ @get:Optional
+ abstract val gradlePropertiesContent: ListProperty
+
+ @Input
+ override fun getName(): String = name
+ }
+
+ companion object {
+ const val TASK_GROUP = "dokkatoo examples"
+ const val EXTENSION_NAME = "dokkatooExampleProjects"
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishTestSettings.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishTestSettings.kt
new file mode 100644
index 0000000000..0a701986c8
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishTestSettings.kt
@@ -0,0 +1,19 @@
+package buildsrc.settings
+
+import org.gradle.api.attributes.Attribute
+import org.gradle.api.file.Directory
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.api.provider.Provider
+
+/**
+ * Settings for the [buildsrc.conventions.Maven_publish_test_gradle] convention plugin.
+ */
+abstract class MavenPublishTestSettings(
+ val testMavenRepo: Provider
+) : ExtensionAware {
+ val testMavenRepoPath: Provider = testMavenRepo.map { it.asFile.invariantSeparatorsPath }
+
+ companion object {
+ val attribute = Attribute.of("maven-publish-test", String::class.java)
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishingSettings.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishingSettings.kt
new file mode 100644
index 0000000000..9ec28faaf5
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/settings/MavenPublishingSettings.kt
@@ -0,0 +1,68 @@
+package buildsrc.settings
+
+import java.io.File
+import javax.inject.Inject
+import org.gradle.api.Project
+import org.gradle.api.provider.Provider
+import org.gradle.api.provider.ProviderFactory
+import org.gradle.kotlin.dsl.*
+
+
+/**
+ * Settings for the [buildsrc.conventions.Maven_publish_test_gradle] convention plugin.
+ */
+abstract class MavenPublishingSettings @Inject constructor(
+ private val project: Project,
+ private val providers: ProviderFactory,
+) {
+
+ private val isReleaseVersion: Provider =
+ providers.provider { !project.version.toString().endsWith("-SNAPSHOT") }
+
+ val sonatypeReleaseUrl: Provider =
+ isReleaseVersion.map { isRelease ->
+ if (isRelease) {
+ "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
+ } else {
+ "https://s01.oss.sonatype.org/content/repositories/snapshots/"
+ }
+ }
+
+ val mavenCentralUsername: Provider =
+ d2Prop("mavenCentralUsername")
+ .orElse(providers.environmentVariable("MAVEN_SONATYPE_USERNAME"))
+ val mavenCentralPassword: Provider =
+ d2Prop("mavenCentralPassword")
+ .orElse(providers.environmentVariable("MAVEN_SONATYPE_PASSWORD"))
+
+ val signingKeyId: Provider =
+ d2Prop("signing.keyId")
+ .orElse(providers.environmentVariable("MAVEN_SONATYPE_SIGNING_KEY_ID"))
+ val signingKey: Provider =
+ d2Prop("signing.key")
+ .orElse(providers.environmentVariable("MAVEN_SONATYPE_SIGNING_KEY"))
+ val signingPassword: Provider =
+ d2Prop("signing.password")
+ .orElse(providers.environmentVariable("MAVEN_SONATYPE_SIGNING_PASSWORD"))
+
+ val githubPublishDir: Provider =
+ providers.environmentVariable("GITHUB_PUBLISH_DIR").map { File(it) }
+
+ private fun d2Prop(name: String): Provider =
+ providers.gradleProperty("org.jetbrains.dokka.dokkatoo.$name")
+
+ private fun d2Prop(name: String, convert: (String) -> T): Provider =
+ d2Prop(name).map(convert)
+
+ companion object {
+ const val EXTENSION_NAME = "mavenPublishing"
+
+ /** Retrieve the [KayrayBuildProperties] extension. */
+ internal val Project.mavenPublishing: MavenPublishingSettings
+ get() = extensions.getByType()
+
+ /** Configure the [KayrayBuildProperties] extension. */
+ internal fun Project.mavenPublishing(configure: MavenPublishingSettings.() -> Unit) =
+ extensions.configure(configure)
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt
new file mode 100644
index 0000000000..d473d28741
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/SetupDokkaProjects.kt
@@ -0,0 +1,73 @@
+package buildsrc.tasks
+
+import buildsrc.settings.DokkaTemplateProjectSettings.DokkaTemplateProjectSpec
+import javax.inject.Inject
+import org.gradle.api.DefaultTask
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.file.FileCollection
+import org.gradle.api.file.FileSystemOperations
+import org.gradle.api.file.ProjectLayout
+import org.gradle.api.provider.ProviderFactory
+import org.gradle.api.tasks.*
+
+abstract class SetupDokkaProjects @Inject constructor(
+ private val fs: FileSystemOperations,
+ private val layout: ProjectLayout,
+ private val providers: ProviderFactory,
+) : DefaultTask() {
+
+ @get:OutputDirectories
+ val destinationDirs: FileCollection
+ get() = layout.files(
+ destinationBaseDir.map { base ->
+ templateProjects.map { spec -> base.dir(spec.destinationPath) }
+ }
+ )
+
+ @get:Internal // tracked by destinationDirs
+ abstract val destinationBaseDir: DirectoryProperty
+
+ @get:Nested
+ abstract val templateProjects: NamedDomainObjectContainer
+
+ @get:InputDirectory
+ abstract val dokkaSourceDir: DirectoryProperty
+
+ @get:InputFiles
+ val additionalFiles: FileCollection
+ get() = layout.files(
+ providers.provider {
+ templateProjects.map { it.additionalFiles }
+ }
+ )
+
+ init {
+ group = "dokka examples"
+ }
+
+ @TaskAction
+ internal fun action() {
+ val dokkaSourceDir = dokkaSourceDir.get()
+ val destinationBaseDir = destinationBaseDir.get()
+ val templateProjects = templateProjects.filter { it.destinationPath.isPresent }
+
+ templateProjects.forEach { spec ->
+ fs.sync {
+ with(spec.copySpec)
+
+ from(dokkaSourceDir.dir(spec.sourcePath))
+
+ from(
+ spec.additionalPaths.get().map { additionalPath ->
+ dokkaSourceDir.asFile.resolve(additionalPath)
+ }
+ )
+
+ from(spec.additionalFiles)
+
+ into(destinationBaseDir.dir(spec.destinationPath))
+ }
+ }
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/UpdateDokkatooExampleProjects.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/UpdateDokkatooExampleProjects.kt
new file mode 100644
index 0000000000..7737e0988b
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/tasks/UpdateDokkatooExampleProjects.kt
@@ -0,0 +1,49 @@
+package buildsrc.tasks
+
+import buildsrc.settings.DokkatooExampleProjectsSettings.DokkatooExampleProjectSpec
+import javax.inject.Inject
+import org.gradle.api.DefaultTask
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.Nested
+import org.gradle.api.tasks.TaskAction
+
+/**
+ * Utility for updating the `gradle.properties` of projects used in automated tests.
+ */
+@CacheableTask
+abstract class UpdateDokkatooExampleProjects @Inject constructor(
+ @get:Internal
+ val objects: ObjectFactory
+) : DefaultTask() {
+
+ @get:Nested
+ abstract val exampleProjects: NamedDomainObjectContainer
+
+ private val taskPath: String = path // renamed for clarity
+
+ @TaskAction
+ fun update() {
+ exampleProjects.forEach { exampleProject ->
+ updateGradleProperties(exampleProject)
+ }
+ }
+
+ private fun updateGradleProperties(exampleProject: DokkatooExampleProjectSpec) {
+
+ val gradlePropertiesContent = exampleProject.gradlePropertiesContent.orNull?.sorted() ?: return
+
+ val content = buildString {
+ appendLine("# DO NOT EDIT - Generated by $taskPath")
+ appendLine()
+
+ gradlePropertiesContent.forEach {
+ appendLine(it)
+ }
+ }
+
+ exampleProject.gradlePropertiesFile.get().asFile.writeText(content)
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/gradle.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/gradle.kt
new file mode 100644
index 0000000000..0af662d496
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/gradle.kt
@@ -0,0 +1,118 @@
+package buildsrc.utils
+
+import java.io.File
+import org.gradle.api.NamedDomainObjectContainer
+import org.gradle.api.NamedDomainObjectFactory
+import org.gradle.api.Project
+import org.gradle.api.artifacts.Configuration
+import org.gradle.api.component.AdhocComponentWithVariants
+import org.gradle.api.file.RelativePath
+import org.gradle.api.model.ObjectFactory
+import org.gradle.api.plugins.ExtensionContainer
+import org.gradle.kotlin.dsl.*
+
+/**
+ * Mark this [Configuration] as one that will be consumed by other subprojects.
+ *
+ * ```
+ * isCanBeResolved = false
+ * isCanBeConsumed = true
+ * ```
+ */
+fun Configuration.asProvider(
+ visible: Boolean = true
+) {
+ isVisible = visible
+ isCanBeResolved = false
+ isCanBeConsumed = true
+}
+
+/**
+ * Mark this [Configuration] as one that will consume artifacts from other subprojects (also known as 'resolving')
+ *
+ * ```
+ * isCanBeResolved = true
+ * isCanBeConsumed = false
+ * ```
+ * */
+fun Configuration.asConsumer(
+ visible: Boolean = false
+) {
+ isVisible = visible
+ isCanBeResolved = true
+ isCanBeConsumed = false
+}
+
+
+/** Drop the first [count] directories from the path */
+fun RelativePath.dropDirectories(count: Int): RelativePath =
+ RelativePath(true, *segments.drop(count).toTypedArray())
+
+
+/** Drop the first directory from the path */
+fun RelativePath.dropDirectory(): RelativePath =
+ dropDirectories(1)
+
+
+/** Drop the first directory from the path */
+fun RelativePath.dropDirectoriesWhile(
+ segmentPrediate: (segment: String) -> Boolean
+): RelativePath =
+ RelativePath(
+ true,
+ *segments.dropWhile(segmentPrediate).toTypedArray(),
+ )
+
+
+/**
+ * Don't publish test fixtures (which causes warnings when publishing)
+ *
+ * https://docs.gradle.org/current/userguide/java_testing.html#publishing_test_fixtures
+ */
+fun Project.skipTestFixturesPublications() {
+ val javaComponent = components["java"] as AdhocComponentWithVariants
+ javaComponent.withVariantsFromConfiguration(configurations["testFixturesApiElements"]) { skip() }
+ javaComponent.withVariantsFromConfiguration(configurations["testFixturesRuntimeElements"]) { skip() }
+}
+
+
+/**
+ * Add an extension to the [ExtensionContainer], and return the value.
+ *
+ * Adding an extension is especially useful for improving the DSL in build scripts when [T] is a
+ * [NamedDomainObjectContainer].
+ * Using an extension will allow Gradle to generate
+ * [type-safe model accessors](https://docs.gradle.org/current/userguide/kotlin_dsl.html#kotdsl:accessor_applicability)
+ * for added types.
+ *
+ * ([name] should match the property name. This has to be done manually. I tried using a
+ * delegated-property provider but then Gradle can't introspect the types properly, so it fails to
+ * create accessors).
+ */
+internal inline fun ExtensionContainer.adding(
+ name: String,
+ value: T,
+): T {
+ add(name, value)
+ return value
+}
+
+/**
+ * Create a new [NamedDomainObjectContainer], using
+ * [org.gradle.kotlin.dsl.domainObjectContainer]
+ * (but [T] is `reified`).
+ *
+ * @param[factory] an optional factory for creating elements
+ * @see org.gradle.kotlin.dsl.domainObjectContainer
+ */
+internal inline fun ObjectFactory.domainObjectContainer(
+ factory: NamedDomainObjectFactory? = null
+): NamedDomainObjectContainer =
+ if (factory == null) {
+ domainObjectContainer(T::class)
+ } else {
+ domainObjectContainer(T::class, factory)
+ }
+
+/** workaround for the overly verbose replacement for the deprecated [Project.getBuildDir] property */
+val Project.buildDir_: File get() = layout.buildDirectory.get().asFile
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/intellij.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/intellij.kt
new file mode 100644
index 0000000000..f93e76837d
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/intellij.kt
@@ -0,0 +1,45 @@
+package buildsrc.utils
+
+import org.gradle.api.Project
+import org.gradle.api.file.ProjectLayout
+import org.gradle.plugins.ide.idea.model.IdeaModule
+
+
+/** exclude generated Gradle code, so it doesn't clog up search results */
+fun IdeaModule.excludeGeneratedGradleDsl(layout: ProjectLayout) {
+
+ val generatedSrcDirs = listOf(
+ "kotlin-dsl-accessors",
+ "kotlin-dsl-external-plugin-spec-builders",
+ "kotlin-dsl-plugins",
+ )
+
+ excludeDirs.addAll(
+ layout.projectDirectory.asFile.walk()
+ .filter { it.isDirectory && it.parentFile.name in generatedSrcDirs }
+ .flatMap { file ->
+ file.walk().maxDepth(1).filter { it.isDirectory }.toList()
+ }
+ )
+}
+
+
+/** Sets a logo for project IDEs */
+fun Project.initIdeProjectLogo(
+ svgLogoPath: String
+) {
+ val logoSvg = rootProject.layout.projectDirectory.file(svgLogoPath)
+ val ideaDir = rootProject.layout.projectDirectory.dir(".idea")
+
+ if (
+ logoSvg.asFile.exists()
+ && ideaDir.asFile.exists()
+ && !ideaDir.file("icon.png").asFile.exists()
+ && !ideaDir.file("icon.svg").asFile.exists()
+ ) {
+ copy {
+ from(logoSvg) { rename { "icon.svg" } }
+ into(ideaDir)
+ }
+ }
+}
diff --git a/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/strings.kt b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/strings.kt
new file mode 100644
index 0000000000..6a0749ceb7
--- /dev/null
+++ b/dokka-runners/dokkatoo/buildSrc/src/main/kotlin/buildsrc/utils/strings.kt
@@ -0,0 +1,26 @@
+package buildsrc.utils
+
+
+/** Title case the first char of a string */
+internal fun String.uppercaseFirstChar(): String = mapFirstChar(Character::toTitleCase)
+
+
+/** Lowercase the first char of a string */
+internal fun String.lowercaseFirstChar(): String = mapFirstChar(Character::toLowerCase)
+
+
+private inline fun String.mapFirstChar(
+ transform: (Char) -> Char
+): String = if (isNotEmpty()) transform(this[0]) + substring(1) else this
+
+
+/**
+ * Exclude all non-alphanumeric characters and converts the result into a camelCase string.
+ */
+internal fun String.toAlphaNumericCamelCase(): String =
+ map { if (it.isLetterOrDigit()) it else ' ' }
+ .joinToString("")
+ .split(" ")
+ .filter { it.isNotBlank() }
+ .joinToString("") { it.uppercaseFirstChar() }
+ .lowercaseFirstChar()
diff --git a/dokka-runners/dokkatoo/devOps/release.main.kts b/dokka-runners/dokkatoo/devOps/release.main.kts
new file mode 100644
index 0000000000..a75557191c
--- /dev/null
+++ b/dokka-runners/dokkatoo/devOps/release.main.kts
@@ -0,0 +1,415 @@
+#!/usr/bin/env kotlin
+@file:DependsOn("com.github.ajalt.clikt:clikt-jvm:3.5.2")
+@file:DependsOn("me.alllex.parsus:parsus-jvm:0.4.0")
+@file:DependsOn("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3")
+
+import Release_main.SemVer.Companion.SemVer
+import com.github.ajalt.clikt.core.CliktCommand
+import com.github.ajalt.clikt.parameters.options.flag
+import com.github.ajalt.clikt.parameters.options.option
+import java.io.File
+import java.util.concurrent.TimeUnit.MINUTES
+import kotlin.system.exitProcess
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.runBlocking
+import me.alllex.parsus.parser.*
+import me.alllex.parsus.token.literalToken
+import me.alllex.parsus.token.regexToken
+
+try {
+ Release.main(args)
+ exitProcess(0)
+} catch (ex: Exception) {
+ println("${ex::class.simpleName}: ${ex.message}")
+ exitProcess(1)
+}
+
+/**
+ * Release a new version.
+ *
+ * Requires:
+ * * [gh cli](https://cli.github.com/manual/gh)
+ * * [kotlin](https://kotlinlang.org/docs/command-line.html)
+ * * [git](https://git-scm.com/)
+ */
+// based on https://github.com/apollographql/apollo-kotlin/blob/v4.0.0-dev.2/scripts/release.main.kts
+object Release : CliktCommand() {
+ private val skipGitValidation by option(
+ "--skip-git-validation",
+ help = "skips git status validation"
+ ).flag(default = false)
+
+ override fun run() {
+ echo("Current Dokkatoo version is $dokkatooVersion")
+ echo("git dir is ${Git.rootDir}")
+
+ val startBranch = Git.currentBranch()
+
+ validateGitStatus(startBranch)
+
+ val releaseVersion = semverPrompt(
+ text = "version to release?",
+ default = dokkatooVersion.copy(snapshot = false),
+ ) {
+ if (it.snapshot) {
+ echo("versionToRelease must not be a snapshot version, but was $it")
+ }
+ !it.snapshot
+ }
+ val nextVersion = semverPrompt(
+ text = "post-release version?",
+ default = releaseVersion.incrementMinor(snapshot = true),
+ )
+ updateVersionCreatePR(releaseVersion)
+
+ // switch back to the main branch
+ Git.switch(startBranch)
+ Git.pull(startBranch)
+
+ // Tag the release
+ createAndPushTag(releaseVersion)
+
+ confirm("Publish plugins to Gradle Plugin Portal?", abort = true)
+ Gradle.publishPlugins()
+
+ // Bump the version to the next snapshot
+ updateVersionCreatePR(nextVersion)
+
+ // Go back and pull the changes
+ Git.switch(startBranch)
+ Git.pull(startBranch)
+
+ echo("Released version $releaseVersion")
+ }
+
+ private fun validateGitStatus(startBranch: String) {
+ if (skipGitValidation) {
+ echo("skipping git status validation")
+ return
+ }
+ check(Git.status().isEmpty()) {
+ "git repo is not clean. Stash or commit changes before making a release."
+ }
+ check(dokkatooVersion.snapshot) {
+ "Current version must be a SNAPSHOT, but was $dokkatooVersion"
+ }
+ check(startBranch == "main") {
+ "Must be on the main branch to make a release, but current branch is $startBranch"
+ }
+ }
+
+ /**
+ * @param[validate] returns `null` if the provided SemVer is valid, or else an error message
+ * explaining why it is invalid.
+ */
+ private tailrec fun semverPrompt(
+ text: String,
+ default: SemVer,
+ validate: (candidate: SemVer) -> Boolean = { true },
+ ): SemVer {
+ val response = prompt(
+ text = text,
+ default = default.toString(),
+ requireConfirmation = true,
+ ) {
+ SemVer.of(it)
+ }
+
+ return if (response == null || !validate(response)) {
+ if (response == null) echo("invalid SemVer")
+ semverPrompt(text, default, validate)
+ } else {
+ response
+ }
+ }
+
+ private fun updateVersionCreatePR(version: SemVer) {
+ // checkout a release branch
+ val releaseBranch = "release/v$version"
+ echo("checkout out new branch...")
+ Git.switch(releaseBranch, create = true)
+
+ // update the version & run tests
+ dokkatooVersion = version
+ echo("running Gradle check...")
+ Gradle.check()
+
+ // commit and push
+ echo("committing...")
+ Git.commit("release $version")
+ echo("pushing...")
+ Git.push(releaseBranch)
+
+ // create a new PR
+ echo("creating PR...")
+ GitHub.createPr(releaseBranch)
+
+ confirm("Merge the PR for branch $releaseBranch?", abort = true)
+ mergeAndWait(releaseBranch)
+ echo("$releaseBranch PR merged")
+ }
+
+ private fun createAndPushTag(version: SemVer) {
+ // Tag the release
+ require(dokkatooVersion == version) {
+ "tried to create a tag, but project version does not match provided version. Expected $version but got $dokkatooVersion"
+ }
+ val tagName = "v$version"
+ Git.tag(tagName)
+ confirm("Push tag $tagName?", abort = true)
+ Git.push(tagName)
+ echo("Tag pushed")
+
+ confirm("Publish plugins to Gradle Plugin Portal?", abort = true)
+ Gradle.publishPlugins()
+ }
+
+ private val buildGradleKts: File by lazy {
+ val rootDir = Git.rootDir
+ File("$rootDir/build.gradle.kts").apply {
+ require(exists()) { "could not find build.gradle.kts in $rootDir" }
+ }
+ }
+
+ /** Read/write the version set in the root `build.gradle.kts` file */
+ private var dokkatooVersion: SemVer
+ get() {
+ val rawVersion = Gradle.dokkatooVersion()
+ return SemVer(rawVersion)
+ }
+ set(value) {
+ val updatedFile = buildGradleKts.useLines { lines ->
+ lines.joinToString(separator = "\n", postfix = "\n") { line ->
+ if (line.startsWith("version = ")) {
+ "version = \"${value}\""
+ } else {
+ line
+ }
+ }
+ }
+ buildGradleKts.writeText(updatedFile)
+ }
+
+ private fun mergeAndWait(branchName: String): Unit = runBlocking {
+ GitHub.autoMergePr(branchName)
+ echo("Waiting for the PR to be merged...")
+ while (GitHub.prState(branchName) != "MERGED") {
+ delay(1.seconds)
+ echo(".", trailingNewline = false)
+ }
+ }
+}
+
+private abstract class CliTool {
+
+ protected fun runCommand(
+ cmd: String,
+ dir: File? = Git.rootDir,
+ logOutput: Boolean = true,
+ ): String {
+ val args = parseSpaceSeparatedArgs(cmd)
+
+ val process = ProcessBuilder(args).apply {
+ redirectOutput(ProcessBuilder.Redirect.PIPE)
+ redirectInput(ProcessBuilder.Redirect.PIPE)
+ redirectErrorStream(true)
+ if (dir != null) directory(dir)
+ }.start()
+
+ val processOutput = process.inputStream
+ .bufferedReader()
+ .lineSequence()
+ .onEach { if (logOutput) println("\t$it") }
+ .joinToString("\n")
+ .trim()
+
+ process.waitFor(10, MINUTES)
+
+ val exitCode = process.exitValue()
+
+ if (exitCode != 0) {
+ error("command '$cmd' failed:\n${processOutput}")
+ }
+
+ return processOutput
+ }
+
+ private data class ProcessResult(
+ val exitCode: Int,
+ val output: String,
+ )
+
+ companion object {
+ private fun parseSpaceSeparatedArgs(argsString: String): List {
+ val parsedArgs = mutableListOf()
+ var inQuotes = false
+ var currentCharSequence = StringBuilder()
+ fun saveArg(wasInQuotes: Boolean) {
+ if (wasInQuotes || currentCharSequence.isNotBlank()) {
+ parsedArgs.add(currentCharSequence.toString())
+ currentCharSequence = StringBuilder()
+ }
+ }
+ argsString.forEach { char ->
+ if (char == '"') {
+ inQuotes = !inQuotes
+ // Save value which was in quotes.
+ if (!inQuotes) {
+ saveArg(true)
+ }
+ } else if (char.isWhitespace() && !inQuotes) {
+ // Space is separator
+ saveArg(false)
+ } else {
+ currentCharSequence.append(char)
+ }
+ }
+ if (inQuotes) {
+ error("No close-quote was found in $currentCharSequence.")
+ }
+ saveArg(false)
+ return parsedArgs
+ }
+ }
+}
+
+/** git commands */
+private object Git : CliTool() {
+ val rootDir = File(runCommand("git rev-parse --show-toplevel", dir = null))
+
+ init {
+ require(rootDir.exists()) { "could not determine root git directory" }
+ }
+
+ fun switch(branch: String, create: Boolean = false): String {
+ return runCommand(
+ buildString {
+ append("git switch ")
+ if (create) append("--create ")
+ append(branch)
+ }
+ )
+ }
+
+ fun commit(message: String): String = runCommand("git commit -a -m \"$message\"")
+ fun currentBranch(): String = runCommand("git symbolic-ref --short HEAD")
+ fun pull(ref: String): String = runCommand("git pull origin $ref")
+ fun push(ref: String): String = runCommand("git push origin $ref")
+ fun status(): String {
+ runCommand("git fetch --all")
+ return runCommand("git status --porcelain=v2")
+ }
+
+ fun tag(tag: String): String {
+ return runCommand("git tag $tag")
+ }
+}
+
+/** GitHub commands */
+private object GitHub : CliTool() {
+
+ init {
+ setRepo("adamko-dev/dokkatoo")
+ }
+
+ fun setRepo(repo: String): String =
+ runCommand("gh repo set-default $repo")
+
+ fun prState(branchName: String): String =
+ runCommand("gh pr view $branchName --json state --jq .state", logOutput = false)
+
+ fun createPr(branch: String): String =
+ runCommand("gh pr create --head $branch --fill")
+
+ fun autoMergePr(branch: String): String =
+ runCommand("gh pr merge $branch --squash --auto --delete-branch")
+
+ fun waitForPrChecks(branch: String): String =
+ runCommand("gh pr checks $branch --watch --interval 30")
+}
+
+/** GitHub commands */
+private object Gradle : CliTool() {
+
+ val gradlew: String
+
+ init {
+ val osName = System.getProperty("os.name").lowercase()
+ gradlew = if ("win" in osName) "./gradlew.bat" else "./gradlew"
+ }
+
+ fun stopDaemons(): String = runCommand("$gradlew --stop")
+
+ fun dokkatooVersion(): String {
+ stopDaemons()
+ return runCommand("$gradlew :dokkatooVersion --quiet --no-daemon")
+ }
+
+ fun check(): String {
+ stopDaemons()
+ return runCommand("$gradlew check --no-daemon")
+ }
+
+ fun publishPlugins(): String {
+ stopDaemons()
+ return runCommand("$gradlew publishPlugins --no-daemon --no-configuration-cache")
+ }
+}
+
+private data class SemVer(
+ val major: Int,
+ val minor: Int,
+ val patch: Int,
+ val snapshot: Boolean,
+) {
+
+ fun incrementMinor(snapshot: Boolean): SemVer =
+ copy(minor = minor + 1, snapshot = snapshot)
+
+ override fun toString(): String =
+ "$major.$minor.$patch" + if (snapshot) "-SNAPSHOT" else ""
+
+ companion object {
+ fun SemVer(input: String): SemVer =
+ SemVerParser.parseEntire(input).getOrElse { error ->
+ error("provided version to release must be SemVer X.Y.Z, but got error while parsing: $error")
+ }
+
+ fun of(input: String): SemVer? =
+ SemVerParser.parseEntire(input).getOrElse { return null }
+
+ fun isValid(input: String): Boolean =
+ try {
+ SemVerParser.parseEntireOrThrow(input)
+ true
+ } catch (ex: ParseException) {
+ false
+ }
+ }
+
+ private object SemVerParser : Grammar() {
+ private val dotSeparator by literalToken(".")
+ private val dashSeparator by literalToken("-")
+
+ /** Non-negative number that is either 0, or does not start with 0 */
+ private val number: Parser by regexToken("""0|[1-9]\d*""").map { it.text.toInt() }
+
+ private val snapshot by -dashSeparator * literalToken("SNAPSHOT")
+
+ override val root: Parser by parser {
+ val major = number()
+ dotSeparator()
+ val minor = number()
+ dotSeparator()
+ val patch = number()
+ val snapshot = checkPresent(snapshot)
+ SemVer(
+ major = major,
+ minor = minor,
+ patch = patch,
+ snapshot = snapshot,
+ )
+ }
+ }
+}
diff --git a/dokka-runners/dokkatoo/examples/.gitignore b/dokka-runners/dokkatoo/examples/.gitignore
new file mode 100644
index 0000000000..4a1da3f8cc
--- /dev/null
+++ b/dokka-runners/dokkatoo/examples/.gitignore
@@ -0,0 +1,10 @@
+.idea
+**/gradle/wrapper/**
+gradlew.bat
+gradlew
+gradle.properties
+
+versioning-multimodule-example/dokka/previousDocVersions
+
+# these are test projects, so don't commit the lock file
+**/kotlin-js-store/yarn.lock
diff --git a/dokka-runners/dokkatoo/examples/README.md b/dokka-runners/dokkatoo/examples/README.md
new file mode 100644
index 0000000000..f39abb5b44
--- /dev/null
+++ b/dokka-runners/dokkatoo/examples/README.md
@@ -0,0 +1,18 @@
+# Dokkatoo Examples
+
+Examples of how to use Dokkatoo.
+
+The examples are copied from the Dokka project.
+
+### Set up
+
+The Dokka examples are synced automatically from the Dokka source code.
+
+### Tests
+
+The projects are tested in the
+[`:modules:dokkatoo-plugin-integration-tests`](./../modules/dokkatoo-plugin-integration-tests/)
+project.
+
+The Dokka Publications generated by the Dokka examples are compared against the Dokka
+Publications generated by the Dokkatoo projects.
diff --git a/dokka-runners/dokkatoo/examples/build.gradle.kts b/dokka-runners/dokkatoo/examples/build.gradle.kts
new file mode 100644
index 0000000000..da366c88e1
--- /dev/null
+++ b/dokka-runners/dokkatoo/examples/build.gradle.kts
@@ -0,0 +1,48 @@
+plugins {
+ buildsrc.conventions.`maven-publish-test`
+ buildsrc.conventions.`dokkatoo-example-projects`
+}
+
+dokkaTemplateProjects {
+ register(
+ source = "examples/gradle/dokka-customFormat-example",
+ destination = "custom-format-example/dokka"
+ )
+ register(
+ source = "examples/gradle/dokka-gradle-example",
+ destination = "gradle-example/dokka"
+ )
+ register(
+ source = "examples/gradle/dokka-kotlinAsJava-example",
+ destination = "kotlin-as-java-example/dokka"
+ )
+ register(
+ source = "examples/gradle/dokka-library-publishing-example",
+ destination = "library-publishing-example/dokka"
+ )
+ register(
+ source = "examples/gradle/dokka-multimodule-example",
+ destination = "multimodule-example/dokka"
+ )
+ register(
+ source = "examples/gradle/dokka-multiplatform-example",
+ destination = "multiplatform-example/dokka"
+ )
+ register(
+ source = "examples/gradle/dokka-versioning-multimodule-example",
+ destination = "versioning-multimodule-example/dokka"
+ )
+}
+
+configurations.exampleProjectsElements.configure {
+ outgoing {
+ artifact(projectDir) {
+ builtBy(tasks.updateDokkatooExamples)
+ type = "directory"
+ }
+ }
+}
+
+dokkaSourceDownload {
+ dokkaVersion.set(libs.versions.kotlin.dokka)
+}
diff --git a/dokka-runners/dokkatoo/examples/custom-format-example/dokka/README.md b/dokka-runners/dokkatoo/examples/custom-format-example/dokka/README.md
new file mode 100644
index 0000000000..a25cd80e52
--- /dev/null
+++ b/dokka-runners/dokkatoo/examples/custom-format-example/dokka/README.md
@@ -0,0 +1,17 @@
+## Dokka custom format example
+
+This example demonstrates how to override `.css` styles and add custom images as assets, allowing
+you to change the logo used in the header.
+
+You can see up-to-date documentation generated for this example on
+[GitHub Pages](https://kotlin.github.io/dokka/examples/dokka-customFormat-example/html/index.html).
+
+
+
+### Running
+
+Run `dokkaHtml` task to generate documentation with the custom logo in place:
+
+```bash
+./gradlew dokkaHtml
+```
diff --git a/dokka-runners/dokkatoo/examples/custom-format-example/dokka/build.gradle.kts b/dokka-runners/dokkatoo/examples/custom-format-example/dokka/build.gradle.kts
new file mode 100644
index 0000000000..27540ee637
--- /dev/null
+++ b/dokka-runners/dokkatoo/examples/custom-format-example/dokka/build.gradle.kts
@@ -0,0 +1,35 @@
+import org.jetbrains.dokka.gradle.DokkaTask
+import org.jetbrains.dokka.base.DokkaBase
+import org.jetbrains.dokka.base.DokkaBaseConfiguration
+
+plugins {
+ kotlin("jvm") version "1.9.0"
+ id("org.jetbrains.dokka") version "1.9.0"
+}
+
+buildscript {
+ dependencies {
+ classpath("org.jetbrains.dokka:dokka-base:1.9.0")
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+tasks.dokkaHtml {
+ pluginConfiguration {
+ // Dokka's stylesheets and assets with conflicting names will be overriden.
+ // In this particular case, logo-styles.css will be overriden and ktor-logo.png will
+ // be added as an additional image asset
+ customStyleSheets = listOf(file("logo-styles.css"))
+ customAssets = listOf(file("ktor-logo.png"))
+
+ // Text used in the footer
+ footerMessage = "(c) Custom Format Dokka example"
+ }
+}
+
+dependencies {
+ testImplementation(kotlin("test-junit"))
+}
diff --git a/dokka-runners/dokkatoo/examples/custom-format-example/dokka/demo.png b/dokka-runners/dokkatoo/examples/custom-format-example/dokka/demo.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f9b88b01c3d7a348b915e48eed88c3fbd72edc8
GIT binary patch
literal 77918
zcmeEtXIN8P^DiEcaxBO}1f;(Pkxry{uz*O7bm>a(q4$7_N(bpB1d!e%gkBPn-g_^h
zw@?EC5(wOQ^t}Hs_v?M`hkI9^C)rth_9`>8W@gR$?a){1iWD~)ZjzCaQ7FBX*CZpm
zeoRJob>Xi+NHtbjvmKJ%%=P}QqAAyZ`D1?$XH01e>s!B
zNaf0dm-O2Kq*ln3DQ9xs?iq3ygS5UsZ$u6~YdZTm`=8}ChhgfkE3$Vuz|x<;uHUqUh+p}2
z`C0&={+mEIB82+aYh@bx|f^JZ#v;#^-`p*l37cWh}(I7lBe^w
zw`5}Y@9AdBik|qLG;xtvI}6vB3cx4OpPga99~|9WyRBX0U)`sfFal&fkH-A_jJnu^
zB?qkCGf`1%**8}JzsWspFd+!~;@p|UP~*ZhW7U7hm6<0RDGr5!rxU`mRNVs~tp0B1
zmD-F#npiwo_d?A2%D=OEhnePFa_~eJat?^~aBHeJXmWXn$N%R2lTXzl;?N{8w=%pV
zRi{b32le>V7uTPdPh
zT>RIszGkZpa_QEAD(b>g=n|Q0)-9p=7+%7^BdLKWMvDjH{bDCYeQG>&J=B`@bs?o+
zD-4P$6G*IahyGV&vv~&MOAhTz&j2DxG(~?&_H3Ej7xMx7<|^Ah30R~T&Nx~qq084_Ax+2ceb{^>aVkj^dyBDr%0dP`>~DE>Hsyc9;IH{J-LvePQsQC5IPCTedNw?rDgq{ljF-NX3k>?lM?QAn3nT
z{7%A44kk!_bj35zDq78&;;Jvcuu$u^K$X@q`Fpv7l3)JIM!wlstv+mcE7X2)*RL>ayL#l?m3agqj0;H~saBPvRE>qP9M-@*~m`B|Rh`kHvS
z_M_WUvpc&QM&`fCX|3E)UT78Skvv
z^t5yoptGi7WQ;5AtD>OfUz@)Ai@t_zhH(}-VR~Ki(WTAB%SctkTK6-GN9m<~?d=x!
zS`Oxh4)$7&n_p|{&VN1dt_sm~U|f6YXHpZW2E3duE4gqU`JgannBar7HP>>mH*B;V
zES~+nrrzlw9Alc?J3~;H%&ZN=^+`1KESBS`nTU3_(tK%jWffm_6&L^IkM_LD@jUOD
zFZ#2;SN=PkX5|9Xmw#WPM!c)6%tsVsVld}0=xcwnR9RJLWp7_mPWm>lDC`w;bWp9X
zZo53lAan##?Q9i!N2H%*p$z07VuA;d;ssy=OFX4|Ah1(KK8JG^8ZF9BJ7%iAbGgLB
zCcQ1MjJ=DxbGCLHcyqxD;l_H>z5UdVii+3_lsh|?R{O_pJh^(0uc4tV+@GIUxk&jj
zW49Q_HwUNfIU}q?pnt?!qHB5>X`uL(_XJ@^r0HP?Z&+;m7V=id?b1O
zn_i-=O!XLf{)~2sxJ8lwx5@G9(}tLq^hvjOeoMM}ECPc9DW%!TyGhGkj*GV(U`VY<`c;Ans4b&j!#aD>&8KK>;}AY4!_0dHjq?8g*S
zrUcxVdDB|cQOoC~4{Q7!Nl|h?0cC9~uk5!)um6RG4w`OVw49Q)VhEtn7RN{4X3~>A
zH9*DucCVH96fir}o`unK#Y$CY4&yOkUH+o^umpi{kv<_c1U%f)K}}S&?d*@U+tIRZ
zu=mw@Qm0e)Z$sIIf2r1!k;&?B3LyFE(>L!SCxu
zvOgus5;NJi}ZW4sSQ$KPGgY!0@K{tE!&;FE|y!Nh2QZyG{AmlDB9vR
znj5<#_6jUznJ;ShEA*KbQLtxS*iz1rGF7#!rL!IjGz2LC)fwZ|aH=EzZ4aOrOeypZ
zvDsrI(8JN?+V*IWRj;3bO-@EqoF++`hwp4lzS0C+ecfJ@Tg7iK6Cr1{iAh|;`5YIg
zXq>$mlPZtR(VMN9aJ{Bgv;w;suLLTv%YJWfWJ0g9BL|e!w19Eo(A12tUoNFfgmG55
zZ3+2eTd63|aGQ%RAWIhQ9FU6iexIIcnatpkOUE4(wu}^6kJ-m4ldUk=Dhwp$`Nr@R
z8?x*J3%Jx+!B7^c>@`FV}%h#jZGjpFo_n(UFzb(3VtwME%ob=TGNlef*cvau}2`#3+g`j_+X2l4{H
zY#ip(<&(=CXC@hNX~rjcT1-rXk^rn3JLCs_FzBkJTV1cdbfn~=mfi9
z8R+jFwSEhRG)dRH7ltH+yY_Q*y!ZqsxPsaMO5KWd4nAP{B>u7luZaw#_>p`}$bC?N
zg!z0PZ}>oy7Ai9-{c@!90Yfy_;@g7%())t_RT^^5V_1`e?ch}}PK7Yn=s^6lmlk8`
zeySJl`p$Tw|7His)Z~6bet`3~P~d%m&WWBD9b+nZ(!I?ACZbahN)~P5`60_8<@1&(
z-qf@&;7M6)=}nU_8)w6fQ=mH|1gL0<+uLOP*?Qsk!{`M&dV=z2%(If%7pJ+3HG4K5?!w1q0oPp28$;;wss
zvj69L^NgEejV+U~keo4Y{4oxvxSi&EJ7YFGeTju_-uSqAMRsf)ty@Ggl6b;*4K^{p
zAMgskoF4QRjz*L$%fKK9}Bp@|5IMF+3eff#+~)1pus_-{fQ{
zL|r7j$nW-TU;FRhp0Zv?Rea?t4)DA7IiUKq%Vg|_QEr@H#^Um@7jNX>F;QMVwM7c@
z%Db+j4WI;Wj;aO&K9X^6Vl}qDJQ)v^tV*iT-I;|zq#uIhzq-15=y{3y6}c&trDFUQ
zg$!PAF03pT(P|9bKHKxo^)Z#so%U-De~XlvO|p)>lQK2YwH;y-Eqf@2GEo;Yc^z0(
zhj=I2^m$3l0&7UkF|e&y7a64Kij`l9>StjoQ(t1Jw81=a@!GTSr1!lIW!hR^rSkl7
zf}0BJbsA8gyDnSzy#|yd5ho|3`4Euhe-ydD8aFBeZ9+8cO-}U$Q=B{K?#qGhg?2J;
z@spZc(=#x>*ty0L4lGyGc3Lhh+&?EC=Qs&IxonrUkmhXEZA5f0Flh)0o5M`3uefnz?)$?Lf-~%Y>d?EHD90J5M}CnYSb1I+Aq1x@4VuA}=jrF^6EWTX
zBjfGbED#nSY}B{|&1&X^Tw^*o@!sZ0+=$@eRu3{BVjT=|mzk;0QUUdh>e1|udSPSP
z6$8mI!q5a7Hr%(Q<#qow(Fd90CCkT-*CzNt-oJcmHXD<-7O0G-d&Yg(
z2Ox$9H2~O9p%L?L3$2BRK6-agIPQfeNBHQkBV5b&>NwZ^$MJ{y>jS3s{yU!yYTXo&
z`teD6+9GjzFkg#KG&i;{tC7bF#v?`Hzc_|2#)yaVUjRQr>d!|~FMm9H;XOMklgT1;
z=8NP4_;k61jv3TyDLCl4x0OJ04!_eSX}5b`^U*7l%ib1(%&Wq~bR%ZGo|p!lSmk9%
z20YyL#^PRhZk-I9TAz@Djk>&nZb`5wm~JIOEI_w9ckYf9MapG#xBsCsAx6ef405;=
zT7s4F+&x)Z@h0?A}Duu
z?=;UH9rtBB|2g)60HTRClG
z6IUtH(lI`ju7x(r4K6-teMq-cv_+qaSPxfduga%v&(&+w>}Giyepw|x*rMM0c7d90
zZsN0{uu)To&|#kT!&slt#qei|m#<=UrX+BK?scQ1PBxyqK`bRUN|4c+_YdT>Rlq%L
zs95TZzWcP%FQDVLx-b(1Gh<#N
zya0*IEoV))>1IDp#VWtTQ~0xsI1T8zVeUi&00CkVBh4Ujthqz5q;N-^i*s0
zC8(^cbUt%GADG7Hl}2{8w;zp+;OAk6NY|~m(Ps%AI_#T_m%1_Fu#k(+wJP-Z&6{(I
z5x{8M98Q;=EUbfyeAsX{I?#()7^W&uoZJt_B)5%xMccDB8OEfnF`b`QUH@DmDO0~N
zlEm`U-ASM@U~odTU|D?9sbi%+Y4I!A#`GX1^baBx_ptj4@nt4RB4Lb>zo{WBKA|oY
zpo$9PPf|<_{;0DC1!%@5c?uG{DJqNNtX59n?~XAv{}Abh&i!ByWt5w}r#JsqWW9Ad
zT2zNNafMH1oaH4-Q+xi^dta|BL({+BhY8wHjs-(OqzdX2J+ic-Usj|WS3ZlrzAi{s{tKFj2nARn5zh)ys
zY924Qo>&}%y`mN!#`!F%_AHaOxIlbJ;K^K0c>oM@1~Kh*M(gd&(4~Q9*vx
z#6;co8=)OWiY$jZvEBtM=VD+KO^gXRLApKQG`f5@0n$2e@VAavl4|aB5BMFteT2Bn
zZjzp%@P_na1fALs$)Q@HHdT31W
zRq{z{_jnIpO9QD(#yGoQdZBmKq`^bqP8e+#xBBxlfM2lXD_*lhN;!6}ZH<)(U-~6}
zK$d&`a}6H9F;@KsE3od)6VY{Td{7_!t&;9DE!v=Nm4W()OAi2^-BOa=3fx}0?y{H<
zFRiI!q?qj1Y+#K9ild#8mX@aQ>8`1-9am}M;<#bVX=Qs~O?H>*z&@DfX}#lCMUXV&
zxRFyNwfo9xH;Xx%f*I2ElCCBUm?l+Ryj6rQ-vD0~=?R)GHsEw@nYraTI`-F{Emq}FCiCBG?h
z5s9J@1YdOPeMN-poNxS-j>u%^n!fnbQB9B*d{F2~r`}L)pwUE#NK07EBdzIb!fPBh
z9%1$gFd`1m5=g&}rZ}n6PDm>n@8%jb6%f&UUFcbqX11s76iK6`+;4437h0n!FF(~a
zrGB(l7ctxe&YUXwKnl&bpv1w#fxpohYW&>SBIB$$ufbxlDy!UJaoik5TAjgM;S!Rk
zyKkuGrTL>W-!sSrr71H;$0X3w+6(=57uoWMb-xtqvY7o=q6jif<XODxWlt*c49p9HZt4iXa#H^0`Hj%?5^>&P8I5`XY1>65P>@W23
zlQqKjeb)gcawOIlM9YI(-WZ
zxQ(3pJdrQ<3KRcW#CJ21OLQKI;<)E#W
znYnpI4WER_a*`}&7aYS)W6X2cb1sD6@V%?q)s?4E5r|ude9c*K7SKWGWfj$R>5pzfUIqyW$+%mEMlJ=
z!R7!NxPc)E-Ee!#}cEd2fK3K$-?I-IZ@jXWBPRf#j19DOO)zEK8XEENomyBwWUKR15p7Na0-&qv-%63)Y9cim%t8YwbosK#u`)sF2W
zdZ9;!eTj_qviLO|O>pmF-!x3DxV=bk1*&tYmf|z)=ZI!3)6gK`RRDHWG5pA)LDF
z@O@PaU5Zc-R^eV1&E6lW{gjkj#s`)L-G$RPl;+=4(mL%EC)|O#Aq7PA`J3ayg)oI-
z`(Z_*W7iY4*Kdq{3a~@ALfwaIN~UrU&DUma{vpa^d-l7JFf*&SP^Fhf{FX3aES6?Q
zR3zeu`wNH2NMfs^%)X$Y?{!XQ#Y|<7Crl&r_MovdTdUe3=wDh5la5&L>mc
zit;ZZRK-Ejlpt`9nMqs{?_a{u{ZZRNo^VrXmh*vb`UjGc>9V=fXkN*KsnLbN^g{2(
zV9dRr2LbH`o>b9SkSsLoDG9T$p6JIX1|XNzvU50zC{};>Xa8{fUFCu6bCK=&oot&P
zlQgSah0s-~&MgWWLsG8&WnoB8ue8syPB#ISO{2mwGU~H%`amQ&la`$&
zqWJZc(Wcb$9Nn2tluV6Q^lcwY3w$;ECb{QCiqE|^2;q3T`>(2zAjIVX;k!C+RQb|z
zTNjl$RkIN)&uNa4PBaB%Sy_nyvN$M)z}UjM69F93g`>muy!;f3H-asQQm1%e6<
z+tyBF`#?cNar|yj`uz=!26t;O%6vOUj@{QaLUmY9Wy?0+uX>y${nb_%IHqzY~n!SIn-9!=NnME
z@o@K7Iyxel@9$f)io_znJca!{G$bSIRNHRTcRFLqkfXTFFfLSMEG;k*nibZ8h9j`e
z-MeXHKhz8v<6i2I-2pcOtu@S6#5yjH#-IEQPSs86L;wN;62+}bhYR0Xs^Y@4g6zf8
z?z0YqxBxJ6Wc5YE0SEO6P$@|kiJark;)jf4_X)$LSt|qchP#YZf}Kk8@iOW78EEJL
z?|F59RE&>H2EPG@@xshBS9|3v$D=^+l`x~8;Y}XjFFtCf<;b3XqHP^_75bY?w67R$
zbYO4xZ`|Z~nIjZzBo;Cp?qKi0VA5Hh|m(SE+`MBn@5H;fW
zA}pGQvy+nQ%iN0xDnV@4eikt4yGils2_CsGhq_w4T2CL)D2!;T>!jJ4m|=bBN7dwW
z2Hc888}^hsHRfGB56_^n;L1-kPozq|Zu%#dnXOb3D8nZtP6IOh6~+{VY${RU9gQva
zO*sxsZjym~{MB{%t&{mUqm_rDm*>Kg#X~VT1&$w=xRz6Pwo$;a&w?T5@@%6>h!bFQ=`5x5lO-G>4V?|NnipAzkTDRViS@`FD!-7xUq
z59`d0IMkCLA+eHZLU4^#93A2{=ZL;?k^Q-{jnf0S?Hje0{NwW_U|A0E8)Y|mGfCB2`7*J
zbXgnxoi->bDAr_2o7`X|wC6d1IR`xOJr%LI>kB&o{R7EaqP?5H$~Ac1mIdh-1nHI7QM
zI<75zvxI453YA#4YNnLhH*Ywo%73P4eKUqA;`yf$o?1)$K1g*y*3tdD!fqiiH8LvI
zhV1$NT0M#he*z228{b%J@=9ymY$3w~Y;<2k0&M`8OZy`b%w+Z{VCGmzD5)!)U6UYanFvv3>h}V=M3y
zi+|sp`(3$zFI3_{6NMFTK*s@bajG6mUR^E`}mSFLY8|
zwdw6hUz5r|GPUum-uZfWCV+t$Ct5k2Jpcv4@_H8yOWE
z2)_jtm9QYD--A>YlB-}VqF5u~sy6DMP{L;|8(I=p11zEbfm{2Tz*zfHF}_Exf!%l>
z5y`8x8`Rl}sK>-oV@bq|NdjS80eTk>SJiS?*jyZ|voxq3t3okYIeIrui`3cN3L8cKkC(Gg{fW8{@%q&fOMxio5rzxSQz+i}5&e|vbZl&mOwE@g)$D92n
zm!J7AzBWpPEhR$!j?s4!iZ=YVpyU?Sw8`X
zsE*R47$e!Jz}G;gx{iG(mHP^}svnukjr5zy>~f)s<0g>Oo1k#99l1EY>?}P&5Yx*p
zkLq8C>rP@nfdGyiIvUdw#J%;F(n>eu&b?yz7n9OMtE%#?F)8r$Wc+9nShwzAEI8f{
zs0Q|0zYCczT;aW?S)@KE45=?p$g@wXP=|FpEWcJM++8KUGtAEl-^{OEhu>4WmF7q3
zWxZN88?LXPvW~k}r93I&bA;98fo}?pAY2)w(}$HH(ZRvc>8Yn-{J9yDBTsPguzDXK
zckcS+bdwG$utPRof5etV0U}fqHDmDONIfM~W4b
zr1m)Lvrsub-I5s-+cU2=iw-cQx+Y`!uAA%!E4jHcR1Au4
zU>B3(!>cy&;XlW#PFg#hOZQ?P
zc-={!!=S#@>6Te=343Osmv6?;lN~*i_9(uY+n&r4YvYa3%{ka09_ggw7(CW2{av~S74$8eeY
zNL#}MFzp0GniH*;ZiFfa`d2!QtmMU6n7G1S$T3pAOcQ(P=u&>&m;pixqzX|3*-V88?KB_w4CVS0SmJ5g&Jjap%LjTM}#wMRC
zKSUaO`l7FVeGMk*SWKQN!rG`SA>L$n>f>UG)Q6P#t}eJAhKe(mGU6Y-%i|i%kWBI4
zvcML`ap_+Z{)ZuCe1#A`G3}YPU^FQcpe8Cpd#}i=?JH(+4LA1Dp%^HvO>dw2vu`fj
zN@Wr=|0z$-h64Ot63<44qU}^koH_}6F2Y)})u^8W9-s4x^Z$(@`DV8xLlT>kOHUsM
zy2L=CX*}#XNi->a)wYJngsIm!jFy{;sZq#(>0jvn?GpBK@bZ&hxFE*BrJy2z9oII(
zBLz<7rqe{pI?a(JjLrO?_Law}T*5k8?>N~xE8s9ZIeHJ1J-p_5MKO)~&yc^NIHB6B&J79yKN9SabXuwogVUpb!c1l7#&E=FsQTfmbGnm2jE|2
znU=tWllpG0IhfF+uMp5tt^KK0CX}S3c4!KiA#A%->>rCw_U?Fqn~l^zOM>Q<528`g
z8dtuxTDOi92~jSJ27w=Gd`GKuYR=ZoMZR
z*7~+Ex0KlMYXy!?Lh#vU*sl)AUSG4{Y17}0xilfk$pe$tB|^_^*;x|
zlwvK*Wlho@Bl81yQqahbe^WPYk$daTPj4J#~tPk5~2NQF2R0UX4?0x(n`PDpY
z`F?eKV8)|D^xVbKoWk3p!Y~sa4H7O6$JwZ&q1TFEPWY
zb-W|x^va!4dKg{Ry!>$IY`1dg>-xeCqLGcq!rEiYotc!QVt4v`;+eq}tDev#0+G_1
zf69yEuWgLgBKkzdgWT(pMWSbbbL)S=96U}#+u43*{VDaQw^_#w+lZu{veR3V^1VCm
z%an27c)be~w23G6YfgzBQD>U*QXfLCI|ojD4%k}FOP{5)cc!JFvW5z7#w`udD>HHr
z=hkGLz$!;~zMc*rOqz2I6X&V;=v`>@FDi+z><%EXjBn>MIip|h`SBu0$5yHAqr_D_
zT+Wt`jkWP|k1K{MUKqP>Ba=TyY;UVv*Ql%W@bEa?SQhjC_QH{L2u2zk$Ipeau*TJU
z>V(;izs{zfVeQ|zw?cg@709Qf$GfyPMy$St!B%J<0hB5C&KP{JZQl754EbiU%2GO{
zjgj~iZgo2PsaRKavkO8p*wZ2bZ%OS{o2iCN9iyb{;OM~%ubK=4iDU0taI|mx(7e|P
z-@Z#OMD)z@SyEaIFl%e-uv$etT&OZ77f_ZiBRQ(|BPZNMSmcydKr*iOh~hSbghfbu
z6~a9D+4E|CDJdzD2gh$5et@QyT-^p*oKG?P$-DK_rmTyBXyG|CVkB9u#PQ?_M+DG4(j&ZNcTSZx=&+gk<(Sx%#e
zmKc;ff5bm%v%g}@M36%&6
z57RM6n2?80#gK?|8`9CO5n~wfa&>wxp@9S?tqiQLndf3JNk2Q^&K1C`P0H6m77qvb
zB6|0Qa-FBjioI4~Vn*|7tAZ|L1go+Er0!Pu1vG{Lh2QOe<>>EM*
zBmf1;$Q8TXI$r9PWuijbb}mq^g=gnNSJEQxTuyHgTy0*RNM?xHoydRWP#WZDW^hV*
z!EA^>?+}pikjdVX_1Nrqdi19aB}2pdduUtEr3C-htKrLjde`vQW~I61D;e*0*>MT|
zGSL0Gi`E=>*hP_2e3aeEE|Huf;K#sN^9Q!oi$?3Y`G`OKYThX=Ul;x2zd=0?Ry(hH
zJ+^#s0FqhY1ZWn3B-8&+N=qme+n~T-%e@&aH8u~qE-ml_uGnD(b2k}pCI(ZoTUwg*
z1FQ8Uq#E2Yo6DCW;6S~E5Q`2cV=rFxQz7hF49i$GxAI(tuW72cw1AsxAYz#|P36?-
zvg;Hf+0^`+_a-@qVih!a;9c|bxzP^KabAxs2Ouxr*!~g;l9wO7YNd7{1P)r7jerOQ
zN9S8unuyZQ6s7IC5RFm6?RRjxdZvq#XM^J&p-~`J)~TKI^1Y?l*kK&uSsaAigA$y<
z@q!Xpr2Zi<9#gESJ@H@@<5#(h3Paz45
zqpKfrjMRaAIz*@QobvRs)U4MH;IaPEKm4LO@*+0(cs1>MRh1)DB;yht2iMouX;YXa
zi{^ZN$s_hzH;QcVDn{}3mbm6^^7h6pxU!@-=c7f{=}+f>XcX=p?9-1{o_&p>Em#*x
z%j%VGjvOo{zLX%Dg
z70J)g6P+A$OA&4`&XPO+o=5$^_>
zZ=F||{Yd(x$fDjUT4$SnGt%4qF%^)EtcL7*5qc>?zsn$~yKiPBw~rr}`_a*mEs}*H
zvVOcnK|%e2rIs)jPu=;L3;ixwn_HiN;%k`zaj^-D1EDBO=^bk)NlY0xDfb%CNVbESfqD
zCCZgLZxmDjg=sfD4#+**GJ2CmynZ}c&x5%=-9iprLO6GdLP~!$x3$$xCi`h5xohZU
z9`i?whXXMq{aehV?Wu-|YnJI_xuJjw2R`ifq}tmVEjJYf(#o%zMvf*!tvgi(R^~Uw
znnBzrRt4gfCP{g8R8%8lW(el>M>`k(BjvpSs!!chZ3<-!t^?Lg(iv1
zL?1Vwva~Zh+mQ1*8__0ub~Hg~n@
zW8Hw5CCY7O$DE$L
zNo~>~EE~3n=5MI9A+y70=E6Q0LDmL30I^!J9O`~PUkv0|)H4=MIxdi6B94dYEbz#}
zqMUnqPP6`;N^tB2@#9550FZ(%Gj6PDylaMjy7~sp-8qua&ZMlOtOS#AE7A`}Cf2p)
z`lMJRG%HO}kinb*kx-KSx`r0*kQe?xIds5f{w&>b<(j?itf9rAWv9X)Vk6OuQQCK3ptCeTLf3H*eC_gZplk3+i0442p6_Nq%T)tx)99B+Js&8(g2!c5+JYC7}^
zgc?AFF6VNCc}%Vt=zO{LbCXqby&}!fXuIP|G<+8U@Yze-b@X{X_C-!{2Qn8|{l}ZS
zZHS>>$7Z-x?VXIr0Ut7ogGyi82CS6_VLX|7N^t8`knM3DzlxiZr2FD;KV(cll@GhE
zbmmz$1C4=J`su{`4zboxoInGgZl!+!lg|=6Qwwy;q&xim@6E=UTqo=F2i|2&|@2;ZV8Bc~&pFl>f
zORm8<*RRz>{LUK<4TB*8wr+9$wEQ7KwoN{dBwBkoySg)6p0=lJ>J
zbocUTPhzft@KxndE4m$GswXyiXBR^B(>2MzhQUF8jBVq}~qDelm}K%9gQ@*HJO>go%b
zZuB^_ZHZxSXsbIb$R`q6_nk2Xe+z8J9hXkuODYTxpTrzq)P~u#%@^-c2gM)H%M$&H
zU{aj&IpRQ`-5D6;@{z6F_5~7MQto9qN^*L#4eN(|T)uu2i*Xz>tIK9UKyG_w(2U-W
zawHl_^n>eX@6u8!)C^HS$|;+7J)W#*ZlaZ$8+j_n<2@6i
zquuU+pYG*CxlN_LO63z{Mk@>9!8ncXhFT|;p`@ZlR#v&?18iA$-t1^A-^?*nolX6a
z-K@>XY6p0(lARrWv5VBoi#XUTip8prU(VGLKR#HUDaGst*d~G?S6~lTOP;ot=j*|4
z#rpr
z&o7&u|LITP$#4r+32)At-Q{~3GDrCO+FmoojL;F2fWh2(f{|L}>H2XHo!V9~$4Av|
z+xbFe;zDO(^qCLo#2k>N=|>6id1gu;GaDZtuh}y&b^me)8UIX!GUXmNxci?@WX{i1
zhkDAzwV=8Wm)6AIhTva8J|X;0Sk?+N99JnXC1w9u=}=(p<-J?;HO_>Y6c)U$@9qPu
zcJ@AXs@C*B-Y?5ZB`Pr!BGW`>8>E}5sDjI`S`o|Ph>%Io3}O4;{dv1}ERmC`Nl`s{
z)bK&Ni>cmPYz8(7*}l3=FLNqmnNQ!cqp!rgqmR3OTB~cKw!UkgAF;0y7IMTYhc66n
zXz<{b3wuUdlB7440I@_jSF14{U3XRy+ZAWliJ#2fhDo1us4-0FwC0?dRy0>wfweEb
zf}<^=_vV)$so@HlE}e?E4mNV=uQIjegyT^qMRCj`mN{PJL#%W3F&6h?W~rqnmi9gyfI@wmAfSBfGvKnqb0zZ=65F@LX?T>)eL5J7
z4SjFkF@Ab-_QeK*GrNhxOD$!~rceuyf|hsa9*-jY6}wD%Z-WHt)eY$n)Srx1l9#p6
z$@?>{aDUzavQ;KXeQV6&)D}V223%oF3ScsSb=%|=ml{T5ACrid?x%qh9eU7b_^j3;
zUys{x>SPert-NcucZ-K^-`qF9&Q97!)0B>dyJ5ylBNI0#%gx`sd2@@Y*W#t@{kShN
zY+JHH!DnMyoduEMO5$;_Y-h~j;Fo3@V}_~xr_e8N|E2?>c0H1Wt=Ks*k^C$H>04ov
zHq>!(Rny!4o3nGk@1`TI&HXRt%9AHowwV&3*6@qx{>D9W+4O>UE3eamOhI&qu^e#-
z8Yc$u1SSKkTE7xheuG}(Q&_(fOX@|CNEtVkfE_jUT}=wJ?x9ByAKsV0=ah;pTg#xJ
z;0iXUR=0#oHrSs3aot<@Y%&?HqR!`jh;tX9_uwiozag0roOk&K6}F>x-O+4&(IQ&~
zhihYq;4cX~a_Yg!-b^0u@#9glz25;h{U#bGv8N*)Nuh1h=Yg$g$fT>ZAuu
z)QD`wnp1LYwCWrV{w+tTvs0Y-rDV*?GCUh<<@`?nefvyz*33Yl^H{E+#X}nk?wWK4
zy+eL8{Pc=;P_2#doKEDtC@GWSiiDD8E3g$C-Nun7RDX(T5PUs(jB86$5~JQ=O`1=Zf{ernZsr5hPkHZ3l}-?q4f@p2%2lVsoo1Alk%{g
zN6)_Ub9P?7fjY*OLgLzR6Co`qYW_I{vu!Dt$LGo{W3(N-L~4|2t27}=ucuDZ$cw>C|O)(o=iN^shf(%r`bszL`k6?IOHPKx&%Y9J`nEZ|1lm$jm;>);rh=dIU%bDH1j)w3
zU<`0p+3K=59$9G2_^T5g9sH0R)?V#{%cl0x?nY{KQN;T(R!zM6Z5ER=QdAqE`j}gq
zL;Y6KL0Zpg;gzTuMrw0v?7E+%XraaPh_h8QG+X=q0kxgXc=8i%{>OH=H_Pm@shfOtMtcwDUwpcl2usqr0Icy
zwpZB^2b0|k`nSX$>B{V8r7$s++o|_a7U;MSxpk--6;c`@II{X%N1binE}XJ=1$-Tn
zI+s?6MI}pmXjpu>ASlWuoWy@CU34QD99`-57WCgO`LyU#U!-Wnq4*G-wgk9~u<2~w
zc~3Pplcx>&A;kVsjiF+go%dq@9P1)7z4JiJ)Wqktwdc{(w+F%N_NoFZFQO29Iq7h8D0Mqe(u{AUqoLUaFbce4!XYb?uQH`rJksw5R^&o_MDaGc!+bR4xZ`@6>YB
zV;N;AZcpPfB1f^X;9W9{Lxg8_DP{wL6IEgQJI7Fj!%SFLIv}finpWCX={Py$V`tIk
ze$}GZXKB=ckh^K`huuiD==7LYuz%Lg)WOC5yyWhbvR03c4z!tLp0Ckf2X50a9^-I=sa-q(4P9|G>GW=y>VQm=~L%5qq3LVz%5bGKq
zCOC4akTYpfvGFc)o?CxiP(?u*s};@4Q{Xbo<8utq)PDVD{vM@za?E*K(Z~3)3=-hb
z|B*Ta#$-=8zE0Bkn6wqwJG@n9tlULIrB%)@69aV##f&yTU*195B`i%la(hzyk_@UIuh6N}6zbK%_fCAs~UUm!3x6-Y+8k
z)QYu2?ng@C0a0pPQ<*Ct{|pM@21?jDdPnBpHpmXSe_JH+yS9KD9cg!2G){OR=e{x6
z2NeUQ3K#ZUcSJGI0PuNfMhy2WA2*9|x~se#d^6DhSxdu||2960V4GW(CT`^vA<4-r
z_;CM$Uf0VIqw2@*BePGkxkUwQqox2jQsB!`HhS&jPSjt=Wy>SbgUQ%X>coeBz>p}T
z$CDcJIf&`f%aU)O*v{x-}+HyT=K`RDHomJWQ$pgk3t{;toMALS!!Ky$C2-69N?
z7bIW^{hJzIaC?m*p&W}}PkiJzppSrDv?86j&8tP(AAB7Iu>ry!+&XTxo2U3|Dmw+?
zV)-p!S=%WUOSn&+7{S``Sb@5c*RDVLf*+rM2drPQ&$_795#F;X@_s_@7RKy&a}CwN
z=U!{ds`&i;c<_rC+w=2mV}kk({6p?H&Vis$qH8^$4&^8^gl53|CvLqABgwFP%ym`m
z@bBDxo!`T*3Gy{?zG!J*4^|{ON|S@Nzr_UVBi(6+LPG@DAI)<-^jG};h81M~LiJS2
zEipi#e86tvT@vjJUY4bap0;ErX2SZH$nZRVCU?6w=Y)_D73-Sa_qXz|T|f1ymke7}
zbvPw|z#~VIzL&%#FqQkY+HU_CDju*{7)eid~tux{IxwKCGWMuerS|^H>Eun`OO_=wM2ZP--$A`~rN^bAFC6u(pWbode
zJ35zFtT_c<#WYm8+vi_L-d&ckSKH<>7b(k{LjYD1*atwn+xU?%GQ}$fhPyi1A>!_@
z=A7UDOo4@zFBtTxza*^W%t{x&W-GXW(V0q9XE@%Y^3x$dt3OoJIwrlab|+m`(w?(`
zN;5f0EKTZe(yN9BQ!(5icD6_y2!A3kDK1etnkH~F`UVi>7CMi>yiPRn!}{%X?RkX~
zVJxI%@#Qkx9E|Vuy{W$li9Virt0XokJTB;^lg3-vm5kLYhl?8~eLzkcs)Xk-z4^Ab
zDczh=?bi>7HKx@~#*wUdSfpcOQmpOPSQwggBHI6;64*R;L>r&5Y}+3x=-@KM=j9+H
z%|=w9OZw+Vc3=%>*|!t(=8Br`bqaj*fd56^TL#6Mb>X6s2@wJe!Gcd9K!OGj9zlY;
zTX1dMt&?kGLkon#p!8i1lHTB-l|-@lsMnazSr_D0_Uti0LbQT#*iJN6zg0
z)W8VXoRUrcZVf%n>;OOj@@ALjhVI{XKTCakT{JcCK(5U>XY5^}Y(>r}bpK;W(@Xs!
z(R!4J;jABlJZG_?x7{%hm41-sg@=~Fdbat8le>4mC|k5O7zkdhM0Cfnz`3n;f;%WZ
z_M3psSG3|jB_;Bs;KIV5u7}iDz+f(w7%YLiKUTR;F6m@Ht}G3h8hlYF?tkEYrFDqv
zpRF=n{k2f^i_^)~W%0YeB)jkTT`t|P2fPMLUH;2N?M`sYGWJq>Ux!5e@-?^UEhLh3
z(XOC>*`h)ulW~7*djIuv13|Ut*_33L!{rYMXtcFzEHE@@{%VKo8(`%$sy2V??l9nW
zGxv2<>5JQ4Lh?-%W(IC=<++*`>7H$ABI|XYJ4q278y&~Ru2Sl03wZjO^8WQy9lzM-
z;B0j@l&!Il?<22bpH29T=x^z?
zSeMb#T-F(8d`tG6H(8uWgww^=vWKtC7ccuB(T)3ixr^Q{RvJr)Q=aUn=KTSfQIzuj
zPrQ1@i~X#qK|TW`moG4w{{B^A&s15au}}NYyjapYzV^2~pOm4RoHi&CufIuB9|cT2
zCrKm3wI#-{)sJAEG}#ScNnOWzq~zbV7rbBO`EjitbtQ3IXD=lQ*To-pJuKgk;g7eO
ze#M`8W6*mQfMJWJQ^t0Y`9hNYTQgP5w=U8)YSSiFI|+7HJ28htcdv1}9_ObTB;;J_
zwNlPtn>dz)3>P!farZFB>VAf^(jI$%^1cm#DHGr#=FFdL9v|2Ws6}
z#@)mr_(n0KRNJEE6dAymg~B1f_$-T4;jWdymqS)S<3&-;*H-)4`PO;PCF?YN@>FJ2
zS5Cy|K{^vRyOUVxVuUd^{0ID^J2q`N`<5>%&WUGhA*3)gGf17o;!E{l>MQ(Hsx}`-
z)$Gd3N;P3#2b)UuBbRB0u5srs&VW~2mHU8R55R^Hn`+6Zm07BKBsEuM_J5ZbaCcD7
z)h0{alS|vtpdgI5M#=!2-IbdN#Am1$I$8Q%{m`C4+x$wtSS?e!4irTiXvuknl0{ki
zX5h}(p4#7Z$lQ-fd3V1S%+8FM(?xkV?_YO~PWM-wC^PLbP5*{-$IabaEgA0ToQNn6
zbFWX&8I&r2;;xCys?EePdf{I;@$!WB#z(!g+IKvRs6qa25>$2|L)3TgF*$#RkEmsq
z5Zt#>^#7VC)KAc&^KE9*}tp&;9a+++m?UeqGnCpKnzNB0NJjqsD2j%a;%
zABSEDzW0p_7VhV%efi3!Q@rX-F;)gcn1ioW+BcrIU-I5{G38)>
zmfO$zQ?>R~q;PL)wZn4SK<+~JDMteyNGp$(+i2-bB$G2?uQ=@Mp9T_NT{W928c2l|
zsFxVcM0Qm%oM_t
zNoBzZ<2v5oSCs()L4~C|BytjtCJ1S&5GyODse4g-7-q;z40pDG>qKVop#|$n*1ya-
z;+N~3UkjT^NcPj8=5iWX%a5to!ScI3tsG}9*V)i%LT&{r2lhL8f#<%8Z>t$Kp$`Vi
z58EmXmy{V0CjNcD`?#tvE~?9=Ix$?$Ip_yT%6Nvx`$KWTS#C3P8g+D{rlzJgHZ~XI
zPEJno+}6932$Sw@jl$8jK+S$ZW~|6TnsIf})%9_)7gLN!%CGEG=CL#?`;%SG%r*w9
zoy>x868X6m)_G67iyAfHtwF@Bi%^`{OH>C6<>FdZbpmB?f29!n7cC3#fQhKg45eU>GppT=wfO
zbM!pdiS}J(@=WXZF*K^d?b0tMFB5p-oTg=yv<5vXH&$zz%S6u%EKB{rME|O9sEN;q
zF(07d7IlvTg4&{q#;zUSXbU3;8~RpXT54Zq%8*Pezwl9?ZmFQG($aOrpQV8FTfnAt
z4kOAv>*lUr#jqfysmQh6v#ie(W@}F60)CcYlMi#tbycNG2nQe#C%rtr%{zKfs55RS
zw^qF%f$ha@fJLaafHe*x*OD#uIrtsn$lVGCDN(s!q@L^5)
zXH2aIvj`|8jV`tFrw#a#n_kswyxf=_SC<-`%H3B_Yep9)&;
z`@Rh@6#fnw0^NL-b!BaPcL4!I%;%H`vz)7S-5B`ARJo2#<MpV{6e!d@!>-sMxA0~gOx7zwQhV@
z49~xdA>CXE=%PL4GhE!%V!2kAkGSEIjePRRDMj~&C-LmigEm
zRJUB=L!6t2eEDqS26NqB7_S_Iw2h}}WJXERsoSFdb?3>}GMi)@WMTjP$w{D+o7AJE
zg+jtkX?3D{zVtcx3wrqDh|Kf164{Fj8Pf9W^z*EVynNFED;cdXpBFr&61hCzFffze
zL5(%>HTKK5MwXkPq9ZqvAN0INpZfO+bRW$aXksG^DF+QdO~wCIUxtZPr{Qb&BHy!^
zq-~0{ig@;)Sk0Le`M_Q?3CioH7NxjnX_YDAf@?;~Ns7%CCR?Juc^*zF>q%Kt_O{hQy0~SGsDnvT
zZ@S8=-N(5bVJ5t_`tmL%XW!1fe|be|Zpb*P`2RBRhzon~m?><|&F%B@CCy98&xsF|
zQl3TpI(R@c8uuj@{CCt6G!=}Xgjbs_4hb|_w2$L0yyh1WP%hcC$&}o0%Edy3uCe9Qg$!WhiKW
zVRF%j+S|JnSJI>(D@&s{`(S#lePui$P0pR|h33q?x~*N-Jb>KjUrw(OzvcPub0#uF
z7IGsSEUsRB{d+ZNN0%`aIaSv&OJ9{ED>=Fvw@J@$>(S-2BX&$Yt;#6mqI+g#9<_oT
z9&)UrwLPUcI#dhwbtB<*mBpbjP%GvW2ZUdB-(C-i()v5uV#fnGKe8*TumavYRqs^e
zwww0VIUoy#JxV5p;t}!!BlCM_8@3e^1te_!$YY=0w?;l^m5*E4xpsz;^}2QZ^_dm2
zs$!@ms_QoU*V(>ScxygSZSiq!DfydNY)22S(spv^1vdwmt&|UpJl9-3cZ^@l@Kj#T
zzkVPgR^hH)<7jJJ`BBQXdL@$4GwiJkj^|SSR>zJ|tJt;uH$kJbCFo1{8on-N)Wggm
z(v6o?OQ##(Ur!Z|-zHEtcsh2y52eu7CX>2|MG{Y{itHXI9rVa?Psh8)Ow4n8jBVr<
zZRBmIPS2w*k}G0z5zSdbF<}|p{t5zD$b%aQZ-CC?HLOtcgVt%)N2sn{iC;{vhTf3w
zfYIjRRzNk0`Kc(65Wn8oMOiL3QnCKp?S?hE(7_q8f9HM`aYbXq?0W5XPL(Xl?>s1n`e-7-ipjr
z@A3U?oNBeXdut_%OdFlAmbg5c6|*giA7FEph5k`!+_Ub$;)tyLMo
zp^-zq-7UT1PneC<6S`Rll|#cKjQQop#eSsZiH?Oe$fUap(2sE%E-^6R$%rz?KC5aS
zR35GfH6e;RP$=i3R@bC(tv;7lC*vJ$7NT_N4?Sn&S*Y4yk?zNttYG`>(fD_NUwBNa
zv@~oIZ?8hCCg1#yy^TtdF=}XKrys}l72CoK?!jzYuQIAnOjOKYDaF30WB6=?
z1ZKc~c|W=FmnT2pC#Tcwl@?ak_JxV>au`MT!F;)C>bw#eIr(~D;&d~gGFI%{cI9WP
zj8_^Kr&-L?S2zQ!MluDDI9UuNux}mW`&d7BeUGyZ?Q*^;4?emMVto-|?lj7{&cm)h
zy>v%;X((GU$4z2w<2VJJen?4}n3xC|)D70Yckf!cy>&mG56e+-Z){dtDpUXT=e7J)
zWa4b&JF+N~h37(1oj(;XI`**xu*m{F_rB4(NSL>Vubw!^a?&z-GQU(Hs6Cvwpc?Bt8}@nF
zP$Eyq?J=#^?BX)*gkWcF&AVb7n-F-FWv(FYlhxz?H_p%JBdSmNK7Pa@cF}B=UY>Ct
zn=!+?%qF*#u3A@E4uuB^L2N3a8{K<7aSJ*%MQ3@c8Pc8;E$Vtha3+>KhK&VYo0(FP
zru#D_*FLAacUk($rlem#$aWW;_h752*Ov$_W~Wo$J49{>xlSnwm3imCKJyUu_#km*
zrd?dU_nk<`ZL$z)4JWUbP2{uR{0GM*T^#OaH(y`5heOkvNkUfbW>N5vCg(=B*TXf-
z50SD26F0$Hnmfw|e|gcg3B9QnW1lIkiEsXyFD+nqJW>C#13T&WP+;I$(c`_IV|E;!
zZTC=YSK}WQ8uB)*)PjqKS5@{VEK2p{6FJu=Jsz9`HJW0t2TW*a68OU-!ytA@R?{B7
zLTM70b?F94G&(Kcn0znjoV$`ENP}Dn`#w_I{iN(HS>4`P+Ox4Z*unrh|6A4M>0!O%
z3m@N7xME1cC+Tka2Ha#ZBv2f=}a^!FJ^0wKhT3I{OlyOgnsx$U*LmQowcaX~QO_Ue!~m`SCkd
zkz&E+Pcxm=;_45gE8cNlypBFG#MeC8Ur=Wenp2!zyc8(h8?kTBbA931qct*OKJ&_N
zj{4(T5b4}>TRn%+kwaJ5@@w(+!yWCqj=rA+Y}H8(t5-SF43>GQoJnF=868|Gt)RZG
zO>$vwSC(W*p#K~(IbKZiXfFT52YnYVnpd&sFjsGF#sb7v8fWoC>NVMYd)Al2g*w&y
zvp$%&^&B4VwOuSl4SvP0G|DY4DO}88ZXiW6Xs(i%|1k6XJhJOvi1)f!$1dolNzRn0
zv0m;vBl4}Su|XaNv+`Da3G-Cyskjf0>Pzj(NmR$pB9wQ?OUq%v1xk)(1{Y1B%F=@ie$xJi~^KI7IsAoGLL{k6T`*U*35
zdp|{0Vu%r_dXS!ki_*~d=0PTnz%z-9rzNa)MeA4K9~3ZEN$W878MI|L+sjBTo5;Di
ze1)gN0_P)fs7@(DLWBJ^j+zn{WS1C{WUxuMU!|O4-hA#YC!Zek;D>hIQN@+VdcsiX
zsn>J$B}{P*T12bgF;~axo?5T*_lP3RW-{kGz0(f_^@Q>ZX76vRmi_@#&mHLtJrL&u
zznH1$d(SWQbRpB_wjvunP0UZC)=LlB=^4Ni7`vP;_rN3EN@qHu@SgG#n~_+VA`IFu
zi|_SIJZfI-Va=yrEDP;QTHQzq&H@p2^kcj2v9|?Lm@Jw8Mkd1Ps;PHT;YVbOPepO}
zC`LqhXM(WU(o0U42vOVP2*u|oNNNyURRCI4o}{k$UBp20Gn{@E_eAL#M#%Qii3^HzQm)5y}TnQ<_k(MJf2Ln`c?GJ|Dy>#!=&%&u=UaamB|f<5cO
z3y+ua3edE*6&_hUKZon5auxg(
zvKH|Gjl$x|57IL&WRtF{m_n3(99j5saV`&~-^1K(SgMs&Uso9JPppe{&S#2G{b$|M
zmy1ULHO|0vK=t}{9&cdo$xi>zGxVQOqZGWT#cEZ4IKSS~+9ZaUJN1o*V@R&86K~FH
z7B7BqLjO#Kny*T|fS5T^dOX8er&`Hocx$M%+`MR#X|nck4wb(@6|5Dv)GQgh9^Rk8
z=bl~UsLS`@;P#O^8QJ09PX@FWsbaEf?3K(q(!x8~R|C;zJlBFYk?>^!`AAk)`nB
z5;u?Kbjd$N9p=PxdUmZ>VM)rft6H`9*R6SsZkjSxqLrTC+I|WApw*H0R#{C&EKen&
z-uPQCtb3uY*ay7FdJ17so>r~cuR}7D+NInJuMk3!1n_enRy{?JLYDi53KsW>RDE-S
z-SDkFbSQKgO0Ur!Ahl4DI?4+;vcoR?$==?7;@1BnDt9lk$eU-aCiL1c0IoqpwX{^R
zU^Cisz|h5B7T|sPfGMPl>$Ybm2iL@&Swh5}gMEpSAxM{V)s2O=jCP|AR@7OrhHFv>
z8U3;i2JSK9nZD=RonSrT(^6AWi6-Z1Q~WhlTYq*bP5^&Gx=Y1;S8o+EIsvi&h?~i4
zbHn$Qq+_eM=CjxdgMy2B+e_J~NWUBc#~z+q{l5JzA`vC#I9AM4oh8p_1XIjQf7vi(
zQ`nY=9dA_J)V@7GYN?pVDQ>=hd-czGKRi!zO*RtD_nhi0s;D?&9*b}q(^y~)O@3V7
zRDcrKsl*$BZYF8x7?o`A_qn~{eX|1EUF2~?>0L_mGuvW88@c0F*iaH;E}p-rWyf(7ygiq5Aefq>j}=MiDGVhPX?>i`VlIh5F#f3r2AJ2WAQrp<|63T-&jsfMWn@|vE-VWGPJ{e_7=6@ye*0K<
ze2iFe)~LrO7@&HWyVyc&6KIQM_v#~?zey_n>rS$O+^NTAdJ+eECS8NT9t<@yHf#Nv
z=KFHm8U3H})H|Q+{-;|F*1)jnjG+buBlyk&hO3*CwZeraGBGoI9UB
zj(cCY+WEj7SY!ToFgaxtQT!eEOL@nCeuD1h{PX-Dy(Qs)KLz@K@S2AI_Y3HY3-XH=
zyq%fZ7uNXi1nNEE1Ww}qR^hy07>}6bzjD2!^5s8=V&D0Hx^qGVl{Yq)uSv=@Tx`(M
z*w`5THcmd~Ica6667&(T
z`&!8s@TPQsS%}gt{JA9E_uujPv_xzrN?wPJwchwGcc<-%Vx|b|HA?K*H;!iCrbmqA
zi%m)pWe4(B_x%Erz2>Bknvh$dV$+WuQ;_eWIp1F#Ul6ji9{q9PN%J@#>jbh`l$RTIjz+deA}nKInxHr80S6dry{oP*B0-5UOLJ#~o?r{>KOQZ*C?wvXM|0o^}uNUClAW6p%8l<=K~4#^g_*a+{asM
zz~^X1AXvrR>6t~h>fShf+rpv{SeY+Y2APx*-Jbs=6mJv6PI$wG$m&0bM>IaGII}U0
zn*Wx_nxne*-AbFJ#6BC=<+w58L;8^#j>T^AqJJT{I8o@)V{LLlZd0Q+Ckk(G!gW~X
z-1(sPTms&uB*
z%@M&%OPk1St3lh9|0$%m;V0agV)$RD_<;-jjQg*De}^(8@BZ%|y-WO`0^0wt{Qv*B
zQb_7x+@Is#on+hL7Slf`%Di(IX89lg`v3WbL;w3o_5kQbWf=hxkqN-EhK7blMyu=V
zMELkxb#5n9WfmbJAu=*DiM)<>;Bj)=9ZVG)FVKcqTAH$=x4noNJl7UKm82?@sAzlw_9u%e&hE6s-w{q$OVga7?1&&%Uq
zK4>dW_AI%Olq1d`DDm1-F;$3On={~m4$PTu{c!iAS6%c7!+w7!Z|Jxv=-an%4=GGT
z#dXciH;HsT4n|dViJ$ta@U}L7y|3%C=#vTenrdqL8vn;NOc7KQmZyC%iEw(?XFdDG
z985VVsabLfFjYlW5JzH}I$oC;P;6uUkR;t#MYR=}|=RMD~
z9pT3lQ_o}7c5
z`)sK#kV6ptm!%BC2~5=8>k?n>i&s~nTPilIR;la7eH`R>I9h&v^h@%(MCwAX%XV-C
z95LNL$VjFZ^;RW{>%{q-Il-w-M$lvYT6W}>N*+Cv1DE4(NSBXIlz*VeuzWc6
z3d*#TRdeZ+ZN>2>Q*}@ITj$YtkGPogI-C@a-3W9x{a1v?&2y*|{c=K4;V8<~!q$@fx>!9-?^)!W4L0hvHsue7l6Ds7Udi15?w
z(aQ*~qV*|dUi&!B$M5QbM3;dzqk4L19poy?%CMe1aoeq0r*K^flS$mXCLJPoo{>*-
zaoQT&`Q=BE<5ruO$H>ET@jHy#*4B1#a1d}IRNy#TcGp8g=08Udm3{=)z;ZSt54N-C
zNIIKthEX+-o-}p@M*@Xpsb`B`5f&;*GeHIJp?Qmv3bIgag5m$_1Uo
zsW4bS*<-R-CS2WL)jD6}_RAl(zKuOkxw7zI`Lz7trb2~TfJ*W9pGm$|)L*!`Ef)bT
zoYg?!_r6?SHQb)vsub!#^cI1igiMtpfx18@d7nOi^SSZMT`kN%_E78eMzs^4gyolU_urFW3kAM{O
z3F_WQ+%VA+xw>VYJ4XEMX~$g2?Brp=#Wg55mF3XuKT&>s$GpaFwacQg&RATWlr)}u
z-ow5#oCfrol#-%XFk=O7cI&Ut3h|0ry+0I)$ujOzJDivvyu07E+RkSeCn3C@{_!C$
z!to1cuzucEdOafZZH}-Wg93rAaVK(9FJ=1U(4$
zvTvyVejuQNJE>2DDNBS8PpD>F%Q8QW+I__E*HODDtGn__Keo2yX4V!KrtnhqGMOVi
z#+HY{5=9=w)tTHWk^>3Beqb&
zjbXA80k`g2UuOj+Q~NdO6Ul0u02r5gTEj5~eU1z3oZ4#tPD~mC9HkaH^Zj1$9Qz#(
zdPc^)w6wHAeU{q&=0KMEPxfe6)3_4^JMx{0Ldq>fXfD4;VJB*%WUIo#Nqa0cM{Ljt
zKGLa=5r@*aRi(OpSMqLHVPCGFd8WjUj>WKGrNyMqb0Xd$&Ys?huC!TfzC76?Wjft&
z!C}#@PgpAvHZwzlrXUur%H&~W*KMv6{a!t4w`Q-tMly!^Y#!PW7$_O9-2V9u01e8c
zD_v0x=4I8jY`{HP@6FW#j9?WT%}o*<8ym|DQUi|@H_uFNC2p;3;QpJIH6?=;dQk
zE!Dm_6)AUgS}ENdxF|ruE4Oaw0x<1YT9tLMw;YMoNABS$$Db(h
z!W6~A7=pK{Q82?>`RWit_{VUEVx9-Wtx8n1xKY)er1##XqHTbKYfkwZq+&%C71n+y
zI5;?=fq}V4**DjyhT|d06UcK)N=kBaPZ0MMGi9{vJ*twElflas{CRK$jt2mmL7nZ*
zr=7Eaa135OFd!fxBxG#sr
zEuDLvvjI4Yl1KbM*jU!`FLtIJ3&@S_vXP
zTpdtL;|{ETaW>oVw^QQvDl%~V7HcYU5ZS6P#bZLk@fb*jA|z?3=wmOfkx`6#&@d9^
zV-J;#oA)c+7rK!zGyRd+$Qf-=fm9N1J3kY}gw^~7Wz?2@=@oB!)S4D$nE!xuOqb@)
z&dh%y*v2qM$L4g!Ucb=oj7@Bl_rs3%_VWJnI4+2W=S5s$q4kFkAA%nOaf5BFvz#me
zftRCpeXh>^_OP2JdSr1VTM?6pd8W!fv(wOAVU^Nt;}=lLTYtJF)9kTV%*;37*MzS2
zTk`VqXdxR53vWPk1oxavOL+1T2r|4*+iHQjU7&yV>-~pZW)ap6*QWq{S(qDHT3XUd
z#~qJ1+$g6Ga+tO3@9zVEQD1LjZ)azI)<0WjG2TH5^#CnLB_+Ose>rUoymx#Vb?yQ5M+sUp~{{R|3m4xk9HGTQJJS=?mKN_)M0%Zx1jn
zA&_)WKDXlyP3yXo&|noCV@&wARw=mFtMC^X<1n~ucNuA
zc8~=SkauP#-QFi4lcFaeUN>H(lnhi=p4y!FI_{Y9#!OwE_6sr1LmB6%{SAn0H(%N*
z+c}i638xD4EALVCiAcJXX3eBany{{p6uYKAU?vYg@e>{t#~*L?5H|Zr%B4ng=kKuJ
zzkiE%1B0^f`N=xw;v^y>VrFJm=YB>QHZ(LeFfh0`(VC*|DJnpn2UwQdN4)A4~KHD)GPvlut(MA
z(MFi<&Q#rAjyG7@2&Jc|10)6u44f`D5L2wNAM4~_x&jD?&!GLOchl#^@=$?OHB@L6
z8s^%0*g@_-NzLCP?x{Abjk0{gc(;<}ju~4Gcs723}#yJtr@3JHKKs
zPQd*%7~IZLpi{?dyVMF^-PjU!)GvfX_O|GO$+HO{ljQf_apR<=WvgpzAru0a?MJ=z
z+1c6N7+6zv?#`04mNYap)?jZbZ_mZLk9vKrxxmgP*MW;)iJzqIXvdQ8^6Z#eTYiWr
zM_=?>@pnY0VdpE2Tx?x0pa>}`DYnb)p10R$(o;nqcXxT=AX<4GcG3v}upFIluC6}m
zzE?LsvcHSkYoKH^{1n^_)&$Pwxg~#?(3W6r&|gJOacTjY77turRpSr5RsUBuK1G
zM~jaD${)^@Z3q+4s&zS-G=W2!;<3OYOyO!)S)8QfOYgU|-J@W?gYyLc0>`6B-lGO#
zZyI5{N%q#`e18%BRm}n}uC6D@;q@f<-Qu#cI+uf`&ImdtsSP%EcA?v=qlT+h7OY4>
z=eVCvnv`ke)9@+LN8t!v71h+B5}oJF-aPMv3qe?GrmY*)OLjuY`A+xdZ#Pmy%l-acdd2UN
zsphEe^5UAP())Kfy24wf^HsPF`dR9Z6;xDIFjY=gV|1;$m1n`@ezK{&+ypdE=o%^8
z*4Bn)ZDC=-2l_#Q`#V2BA92|PTL>hE1gapNA=-||s9A1#b9Dizj1z+Mb)j1@H_#_4
zn+AOLUc>DT*nNxboT4Hd&>|B^$aD$5h-B`gmDMiLLUihW^bkD@M8bD<&_PL>FO|wp
z;jlT9-PaKj9zN%V+7UgQ&sNL?4wV0>haI@(!i#0#9)R!AsdXu)IVxsWFG<^>mifc*
zHCF!(h`y;Xbf!MY<~-}D%6@tUoT>)flR3NP_F#+d=xl`Qtg5bORBY_zzAup7SzjU_
zrPui)FMMY-cRWWq7wlLSApg;y{`Fd`-s1uwL6_xV?oE$VkPL#QzE3qdSPEo8yL)iN|3doVIVLcw?!W!lDSbp-~xZ5F;8HL
z1%S`aB!bRb45(uf6`C4yY7H;*jU%!xw?92S{rdGQV8qW`aD+Ve>dvYwD_7RmbO7)K
z77jAKhuCD#In9-VrKMqoA03$6BXz3viM1;Yug>s{S=_0>Ls~mjfShcIN78
z>SdCZff#w*-BF^M-A{3FtS4di`wLA508{b1*qrUo?p1Fwrw#(E5J{9FqNIc_G~Q)l
zVVMgAuk~3Q%|q^d^78UZH6jTP&I^=Cj}wC4Fcj7*7+}%R(a`~GL#xbL!>wl`sntZ$
z;`Ss0YwrpW%Vr$&jO#l)*Mnk|y@`AkU)eHc;eB0QIRZrHfbvPz+X7Ts1IQgPr&oaM
zo(IlQR8;i7k-omZl}hUc_`o`VDZk#6NN1y>YHlWVoGLZrbJ{k2%O33SZk_o=(pTLqq|Q^;KHWb+6*|ND=2
z2>&wmaQUiJ*uW{{)C$8zM+-m{jR!$M(qXgI>hIfKd%hGXJ+%%f0#@LheY;198NEPa
zjb*)xL|(Mw$#P_~q21!SF`z#P3+CoZPIqUg_eWxZ0|I%{hltaQn)&O3LE8=P=g2u=
zP`78$+wqM<39yDQQRt&{OR330#$MW!k86vb00h_@5T3o$wS$e4=?Z|0dlg}usAmKdrG{7L{4%sSyxR=On?{%cSeK3nVdh$
z0=poYJgMTO>Vv@^bw9KkKLr-Rp_L51z3Kfei}o%VTwcb;Yq9JmBy*cUIUwykT&Zl3
zU})T{VdX*Q1wjFbvg(NHXJ^9&}(s_BA^a9zv*Kv^sOBg;9&lTKmyT0``5tl
zG3(ZQfJ9`jJYPvo&9rlgz2WLmlHF-{VPT*#Mb_2T72qq0^pZ_*BUYs7S!@LQ86Jt#
zs&UF+ya%DQ)vzn+wQ%)r8kmzI{J;0OwYxiakPWcQAd!N<(L+4-*aot{BQE@232e_*
z8<8&Hnn#G2U5Lfk@peQm9LU8TB;{1Qxv@MTK{$IVPJ
z&7abt2@o}0bWOaJ`aZ_fqO^&6Pn6ZVN=X`v-WC$%SO3fJf^x$uvl(LI!|gk)2m{%6HS?_2p^0?{?Pov`P8%ezE6o$$`(FTdL9n~
z{?n@8LeJV7ion)(U)*z2j-Ad~MJMq}zlgvac%layXxcyWQI?1tO7HIFJqCHn
zbP|KTW*I;D%`fz5uX<_(GS=w4JO$wH2nn6sxo~k!Jfo`eHPH8lzav1e7qzsp@%;I7
zQ}Iqti!m|*w_`3#D#><6kRn|h~#2!|g_VzXf=(`XN+?guN#iAcB)NK&$78VhS
zijJPU$F#S+JZxHdh4z8vh*q>vxiQg;5de<1-iIbNC1nnTylJLYk0pOP5~ibzb$G>l
zX$t6-tHyXq
zpg?UkH5XKAC=IU3hY!slMomm{+B!K=ytVn9+J^QDr(?dr74&{;XEM7086i-?eR^~|
z$JEn5>ncGYEEMQk^EE33FE>(o6L-1HD520>Y;s->jcs69^=>ET7OL&xBi6S!*Py5Y
z>89NT6m81`5S539hc%ZC3$?1)oOiW!+Q5gti$}L)lq$CP;lQ~dae(i?MAA`G!exc7
zM@%{97Jg0tLsB7G=4j|pUeSS95L%N?2umcS(dg2fy`TVi-}1dve1uG2vB`)Eeq
zyJ+Y!SbXK#HoS9L$|scG+ht!Y`{eru*JsN3WM+o>N(~dai{Zd
zF$o!gjZ`~s>A3Hdfi{4#T>rwty-M3<5+)Tnxi=s;1guB78Kva6-{_h*Kq1moV0hvh
zgdHRCPEccErK0-w?^k2|`D#^Amj#&Pwz9gK%Pbe9sp<&hS>WP^Go%Ayuu4E;q{gEw
zsol{`;FU`O<^-71B=_ehTYv!YXr+qMRzSun2vYbuo%!1P1cZcKQ@#Mo)dvR$)9hS<
z5)&8-s+u(MJl$5ulmzjhW{?de6NI#FYdT&RtKgd|2K7Z#4`Km14%}T_T#8B+i1oqF
z;^-~4diV#o^tQB6v#}{;D{(ot07eJ`;yCzyK<2o6czWKRcL?l*V!D6=0FJ=IT(S*0r{a%?~i0y-qeq
zXKS4Mf3hxvnC%L3C{pI_tu53_gscYWQT+A|Ky!2&CvK64W|;wwaNTcu=zhGRCvMC{
z1u&apwo))5CMG5+t9~m;O|($ifEfX`{t>U*kAB$E4^shv)ay?YP|Z`*b5(N%i!N-q
zaRV7MnyGVe;P_LZf0t?*R~-Ec^fRUXw^0BdZ+8sn4#Be-`<Ds=Mx5@7bujwi_47TxOO6+v&t)c5I#Uj
zf(Ix$Nc-&U4i{VeKt`aUrKMG`3`&aZ?Chj-M<4`Vf+zupTe}*8jsyUsZ@@>LY>n>~
z0H?E6Py@<=AS*gNJOsHg_+_x2F+lq$p;re0jpR?6_r`I8(|Mw|p`Z>4&~qXU&Cd3=
z*ICW{EO2}v31((u0__Jt8#+QM=S$6o(Y9aX0njHfOpq>`U35Baj+jjp>46k}0+a;N
z^c~+`Edt;lkROA0!0>({AaD&}G>_}y3LuYqOc*`aVolI#A%+tv1;q_;TihNSXv_{0
zhIQ$uK&2|)0FV4d#L5cXO8_{CB%s@TNFy`Q{{SE-Xyf69L%Lx{z;LKVgWkIAf3|=h
z0>$S5biHr)_Egyx4)pvZ;587T`Ub=2bP)i0X-wQN^*H=W%CiMh!9vZ7g1$^PHZ}}w
zGN8w8AjA_9#RL+uOifRZtNz;7}`K*3PDh2n0qCqU9;0RDlL%GynO
z7pN?d&sdCgc`@H^r2!~mfS_TzbN?D-OlGA$z}`W2=SD47yuwllh&68?PZ2ulxRv#F
zXX=xS(`oCiTm^ufZ&CBN8f=6&qB3Kj-vH1Kj}b!qoHtZ`(W=q;EaFnEJACF-&>sAF
z(*S9X9U=hBy~>5Q7Ps5|cvSR@=9ARhyGi@O*bSo$X^DUahpv1wTZT8{uU0|c{j
zXo)AvNiv}Bbjkwk3S=}6pMU_s`sqJOC(wjqnyr6E*8!V@#duf9bRgMrYpm>(^$e-C
zD_F^blW6N?co*}H%CmU2aEI#cC8O6|%I*adN=^rM;zP*riPn<9hC!7(1N=bk`+-Q-
zd*jDX{dR%Hf>ex}ni>tS=HgaCE*}~iN(u6XE%GHmMgk~bp0;wh+6|O^GKe6B(ZqF=
zTfY?svgUo!kWrh2%j03$j@DMSl14WKTBdp$FTi?|!Ex|R8OO(y;jOw|hnOVHD$%-f
z;pdV_B%<{B9ga}oM@x*l0e3NzL6BMq=ANqzlL^E^
z@T++Mi!d-S(6m1HP*RFqMUwZ
zbRCi+_eu}|ci_W>&KJD%i=miA7q7<~ptm3ffn2r>C^?f38n$tm`J}IQ$DmutTvhi0
zeTCuuYmp70J+%JBFlmlS*tcA!JJFkeacGIm!FjO2HfFh^z>&)v(k4$|a3
zoBh4w0S>XNVDY%wV-?+fd=Z&p{VRSRZDvxh7FD66`&
z6@%|N;Rt@Vk2&fU!cuGwU%dN^_%6dK1ao&Xjj2rX{^j=s%(?g?s>VT=^WK|}(KX+1
z@N1IydWGojFiHN8p4OdmU*K0!i++?hz$htr9bN&jkS(+TuonkOFF4GM3pCPofZje)
zm98W%$P~If&kVx9hI=dtuDFCmKu{2vrG^3rt*56KQN9DZ8;bN=uCA}ef=O04H{HBB
zSxJHcH6Se|)dSqf@bGYaX?|+z@eU{0l=MW+hFU-@;`XF0#z*Eh&CM_&Kc830nSPD)
z|H+#&vcO{eC^A;~?c4hvw|64pT`W<>9oJ(!*E)S#>j_(0>%3xXosNBuAflIZrCKh4
z@-Ya#lH%f3+qoj%-rfK;f}(R0=*NqA_@-CHGW%~hoO=T>
zg_wW7t+H)(^)B$6hD{e->qWkl*&wa>)%s@jh%$P1IN)R?zyEuXrnQ>es}omm7|e0h
zyFvhQ_VusfDK+xM`<3+$H!uWqd~Z3(ssa3q?=?nDS{ADT1ya>OKbvc7YoK=yiF5^&
z&*>ImK^na7-o5+L_vvFyO#A%7xO_XnbOB3*0(y}Su$J0efDBt*UDYWAu*KUPi-Ny0
zwOyOb2@oRyCIe(nKtKS_na-$Y56;&|(NS3nN|cfB(oIBRvgnOo?zJEJZqXY*?kT@i1=;?^>~(5Z7%
zrnHok8~E|!V?k@`HIQE8NiYndofBY5;Euz2hRm#CFW>HSp})MbSx#@~sK&yqY7%qq
z4Q;EYW9`)sBDS!UR?f?9Cx&0p(l(XWa}6pD>pb$;F;P3!-i&<5`^ZMyHviw&+5MxY
znzz&GImsK(;1oQLAB33`t#zEJRfD};w$H~_SoJ@Vf7s@)dH
z?xGVO;B|7}eZ(sjTQze>aVt1xaFV_*jB36-I?*1ugI)XUXAp0`N~seB6n-yy0cNNQ2#*|oiffzUe5rXKg+rEg&`1z*vaYR
z6K1kLOdU3X@