bug fixes random
This commit is contained in:
parent
adec4485de
commit
3d56cd6e50
5 changed files with 77 additions and 71 deletions
|
|
@ -18,7 +18,7 @@ interface TerminalDao {
|
||||||
fun getActiveTerminalDownloadsFlow() : Flow<List<TerminalItem>>
|
fun getActiveTerminalDownloadsFlow() : Flow<List<TerminalItem>>
|
||||||
|
|
||||||
@Query("SELECT * from terminalDownloads where id=:id")
|
@Query("SELECT * from terminalDownloads where id=:id")
|
||||||
fun getActiveTerminalFlow(id: Long) : Flow<TerminalItem>
|
fun getActiveTerminalFlow(id: Long) : Flow<TerminalItem?>
|
||||||
|
|
||||||
@Query("SELECT COUNT(*) FROM terminalDownloads")
|
@Query("SELECT COUNT(*) FROM terminalDownloads")
|
||||||
fun getActiveTerminalsCount() : Int
|
fun getActiveTerminalsCount() : Int
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class TerminalViewModel(private val application: Application) : AndroidViewModel
|
||||||
return dao.getActiveTerminalDownloadsFlow()
|
return dao.getActiveTerminalDownloadsFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTerminal(id: Long) : Flow<TerminalItem> {
|
fun getTerminal(id: Long) : Flow<TerminalItem?> {
|
||||||
return dao.getActiveTerminalFlow(id)
|
return dao.getActiveTerminalFlow(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ class FormatAdapter(onItemClickListener: OnItemClickListener, activity: Activity
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
formats = list
|
formats = list
|
||||||
}
|
}
|
||||||
super.submitList(list)
|
super.submitList(list ?: listOf<FormatRecyclerView>())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCanMultiSelectAudio(it: Boolean) {
|
fun setCanMultiSelectAudio(it: Boolean) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.ComposeView
|
import androidx.compose.ui.platform.ComposeView
|
||||||
|
import androidx.core.view.children
|
||||||
import androidx.core.view.forEach
|
import androidx.core.view.forEach
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
|
@ -64,7 +65,7 @@ class PoTokenWebViewLoginActivity : BaseActivity() {
|
||||||
val appbar = findViewById<AppBarLayout>(R.id.webview_appbarlayout)
|
val appbar = findViewById<AppBarLayout>(R.id.webview_appbarlayout)
|
||||||
toolbar = appbar.findViewById(R.id.webviewToolbar)
|
toolbar = appbar.findViewById(R.id.webviewToolbar)
|
||||||
//hide incognito
|
//hide incognito
|
||||||
toolbar.menu.findItem(1).isVisible = false
|
toolbar.menu.children.firstOrNull { it.itemId == R.id.incognito }?.isVisible = false
|
||||||
toolbar.setOnMenuItemClickListener { m : MenuItem ->
|
toolbar.setOnMenuItemClickListener { m : MenuItem ->
|
||||||
when(m.itemId) {
|
when(m.itemId) {
|
||||||
R.id.get_data_sync_id -> {
|
R.id.get_data_sync_id -> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.deniscerri.ytdl.ui.more.terminal
|
package com.deniscerri.ytdl.ui.more.terminal
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.ActionBar.LayoutParams
|
import android.app.ActionBar.LayoutParams
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
|
|
@ -53,13 +54,13 @@ import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
|
||||||
class TerminalFragment : Fragment() {
|
class TerminalFragment : Fragment() {
|
||||||
private var topAppBar: MaterialToolbar? = null
|
private lateinit var topAppBar: MaterialToolbar
|
||||||
private lateinit var notificationUtil: NotificationUtil
|
private lateinit var notificationUtil: NotificationUtil
|
||||||
private lateinit var terminalViewModel: TerminalViewModel
|
private lateinit var terminalViewModel: TerminalViewModel
|
||||||
private var output: TextView? = null
|
private lateinit var output: TextView
|
||||||
private var input: EditText? = null
|
private lateinit var input: EditText
|
||||||
private var fab: ExtendedFloatingActionButton? = null
|
private lateinit var fab: ExtendedFloatingActionButton
|
||||||
private var scrollView: ScrollView? = null
|
private lateinit var scrollView: ScrollView
|
||||||
private lateinit var bottomAppBar: BottomAppBar
|
private lateinit var bottomAppBar: BottomAppBar
|
||||||
private lateinit var commandTemplateViewModel: CommandTemplateViewModel
|
private lateinit var commandTemplateViewModel: CommandTemplateViewModel
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
private lateinit var sharedPreferences: SharedPreferences
|
||||||
|
|
@ -80,9 +81,9 @@ class TerminalFragment : Fragment() {
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putString("input", input?.text.toString())
|
outState.putString("input", input.text.toString())
|
||||||
outState.putString("output", output?.text.toString())
|
outState.putString("output", output.text.toString())
|
||||||
outState.putBoolean("run", fab!!.text == requireActivity().getString(R.string.run_command))
|
outState.putBoolean("run", fab.text == requireActivity().getString(R.string.run_command))
|
||||||
outState.putLong("downloadID", downloadID)
|
outState.putLong("downloadID", downloadID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,8 +98,8 @@ class TerminalFragment : Fragment() {
|
||||||
imm = requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
imm = requireActivity().getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
scrollView = view.findViewById(R.id.custom_command_scrollview)
|
scrollView = view.findViewById(R.id.custom_command_scrollview)
|
||||||
topAppBar = requireActivity().findViewById(R.id.custom_command_toolbar)
|
topAppBar = requireActivity().findViewById(R.id.custom_command_toolbar)
|
||||||
topAppBar!!.setNavigationOnClickListener { requireActivity().finish() }
|
topAppBar.setNavigationOnClickListener { requireActivity().finish() }
|
||||||
topAppBar!!.setOnClickListener { scrollView?.scrollTo(0,0) }
|
topAppBar.setOnClickListener { scrollView.scrollTo(0,0) }
|
||||||
|
|
||||||
input = view.findViewById(R.id.command_edittext)
|
input = view.findViewById(R.id.command_edittext)
|
||||||
fab = view.findViewById(R.id.command_fab)
|
fab = view.findViewById(R.id.command_fab)
|
||||||
|
|
@ -106,7 +107,7 @@ class TerminalFragment : Fragment() {
|
||||||
if (arguments?.getLong("id") != null){
|
if (arguments?.getLong("id") != null){
|
||||||
downloadID = requireArguments().getLong("id")
|
downloadID = requireArguments().getLong("id")
|
||||||
if(downloadID != 0L){
|
if(downloadID != 0L){
|
||||||
input!!.visibility = View.GONE
|
input.visibility = View.GONE
|
||||||
showCancelFab()
|
showCancelFab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -133,18 +134,18 @@ class TerminalFragment : Fragment() {
|
||||||
commandTemplateViewModel.getTotalNumber()
|
commandTemplateViewModel.getTotalNumber()
|
||||||
}
|
}
|
||||||
if (templateCount == 0){
|
if (templateCount == 0){
|
||||||
bottomAppBar.menu.getItem(0).icon?.alpha = 30
|
bottomAppBar.menu[0].icon?.alpha = 30
|
||||||
}else{
|
}else{
|
||||||
bottomAppBar.menu.getItem(0).icon?.alpha = 255
|
bottomAppBar.menu[0].icon?.alpha = 255
|
||||||
}
|
}
|
||||||
|
|
||||||
shortcutCount = withContext(Dispatchers.IO){
|
shortcutCount = withContext(Dispatchers.IO){
|
||||||
commandTemplateViewModel.getTotalShortcutNumber()
|
commandTemplateViewModel.getTotalShortcutNumber()
|
||||||
}
|
}
|
||||||
if (shortcutCount == 0) {
|
if (shortcutCount == 0) {
|
||||||
bottomAppBar.menu.getItem(1).icon?.alpha = 30
|
bottomAppBar.menu[1].icon?.alpha = 30
|
||||||
}else{
|
}else{
|
||||||
bottomAppBar.menu.getItem(1).icon?.alpha = 255
|
bottomAppBar.menu[1].icon?.alpha = 255
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -157,11 +158,11 @@ class TerminalFragment : Fragment() {
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
UiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel){ templates ->
|
UiUtil.showCommandTemplates(requireActivity(), commandTemplateViewModel){ templates ->
|
||||||
templates.forEach {c ->
|
templates.forEach {c ->
|
||||||
input!!.text.insert(input!!.selectionStart, c.content + " ")
|
input.text.insert(input.selectionStart, c.content + " ")
|
||||||
}
|
}
|
||||||
input!!.postDelayed({
|
input.postDelayed({
|
||||||
input!!.requestFocus()
|
input.requestFocus()
|
||||||
imm.showSoftInput(input!!, 0)
|
imm.showSoftInput(input, 0)
|
||||||
}, 200)
|
}, 200)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -172,11 +173,12 @@ class TerminalFragment : Fragment() {
|
||||||
if (shortcutCount > 0){
|
if (shortcutCount > 0){
|
||||||
UiUtil.showShortcuts(requireActivity(), commandTemplateViewModel,
|
UiUtil.showShortcuts(requireActivity(), commandTemplateViewModel,
|
||||||
itemSelected = {sh ->
|
itemSelected = {sh ->
|
||||||
input!!.setText("${input!!.text} $sh")
|
val txt = "${input.text} $sh"
|
||||||
|
input.setText(txt)
|
||||||
},
|
},
|
||||||
itemRemoved = {removed ->
|
itemRemoved = {removed ->
|
||||||
input!!.setText(input!!.text.replace("(${Regex.escape(removed)})(?!.*\\1)".toRegex(), "").trimEnd())
|
input.setText(input.text.replace("(${Regex.escape(removed)})(?!.*\\1)".toRegex(), "").trimEnd())
|
||||||
input!!.setSelection(input!!.text.length)
|
input.setSelection(input.text.length)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -194,45 +196,46 @@ class TerminalFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
output = view.findViewById(R.id.custom_command_output)
|
output = view.findViewById(R.id.custom_command_output)
|
||||||
output!!.setTextIsSelectable(true)
|
output.setTextIsSelectable(true)
|
||||||
output!!.layoutParams!!.width = LayoutParams.WRAP_CONTENT
|
output.layoutParams!!.width = LayoutParams.WRAP_CONTENT
|
||||||
input!!.requestFocus()
|
input.requestFocus()
|
||||||
fab!!.setOnClickListener {
|
fab.setOnClickListener {
|
||||||
if (fab!!.text == requireActivity().getString(R.string.run_command)){
|
if (fab.text == requireActivity().getString(R.string.run_command)){
|
||||||
input!!.visibility = View.GONE
|
input.visibility = View.GONE
|
||||||
output!!.text = "${output!!.text}\n~ $ ${input!!.text}\n"
|
val txt = "${output.text}\n~ $ ${input.text}\n"
|
||||||
|
output.text = txt
|
||||||
showCancelFab()
|
showCancelFab()
|
||||||
imm.hideSoftInputFromWindow(input?.windowToken, 0)
|
imm.hideSoftInputFromWindow(input.windowToken, 0)
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
val command = input!!.text.toString().replaceFirst("yt-dlp", "")
|
val command = input.text.toString().replaceFirst("yt-dlp", "")
|
||||||
downloadID = withContext(Dispatchers.IO){
|
downloadID = withContext(Dispatchers.IO){
|
||||||
terminalViewModel.insert(TerminalItem(command = command, log = output!!.text.toString()))
|
terminalViewModel.insert(TerminalItem(command = command, log = output.text.toString()))
|
||||||
}
|
}
|
||||||
terminalViewModel.startTerminalDownloadWorker(TerminalItem(downloadID, command))
|
terminalViewModel.startTerminalDownloadWorker(TerminalItem(downloadID, command))
|
||||||
input!!.visibility = View.GONE
|
input.visibility = View.GONE
|
||||||
showCancelFab()
|
showCancelFab()
|
||||||
runWorkerListener()
|
runWorkerListener()
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
terminalViewModel.cancelTerminalDownload(downloadID)
|
terminalViewModel.cancelTerminalDownload(downloadID)
|
||||||
input!!.visibility = View.VISIBLE
|
input.visibility = View.VISIBLE
|
||||||
hideCancelFab()
|
hideCancelFab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notificationUtil = NotificationUtil(requireContext())
|
notificationUtil = NotificationUtil(requireContext())
|
||||||
initMenu()
|
initMenu()
|
||||||
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
requireView().post {
|
||||||
if (sharedPreferences.getBoolean("use_code_color_highlighter", true)) {
|
if (sharedPreferences.getBoolean("use_code_color_highlighter", true)) {
|
||||||
input?.enableTextHighlight()
|
input.enableTextHighlight()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
input?.append(bundle?.getString("input") ?: "")
|
input.append(bundle?.getString("input") ?: "")
|
||||||
input!!.requestFocus()
|
input.requestFocus()
|
||||||
input!!.setSelection(input!!.text.length)
|
input.setSelection(input.text.length)
|
||||||
output?.text = bundle?.getString("output") ?: output?.text
|
output.text = bundle?.getString("output") ?: output.text
|
||||||
output?.isVisible = output?.text.toString().isNotEmpty()
|
output.isVisible = output.text.toString().isNotEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
if (bundle?.getBoolean("run") == true){
|
if (bundle?.getBoolean("run") == true){
|
||||||
showCancelFab()
|
showCancelFab()
|
||||||
|
|
@ -240,13 +243,14 @@ class TerminalFragment : Fragment() {
|
||||||
runWorkerListener()
|
runWorkerListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("UseKtx")
|
||||||
private fun initMenu() {
|
private fun initMenu() {
|
||||||
topAppBar?.menu?.get(0)?.isVisible = false
|
topAppBar.menu?.get(0)?.isVisible = false
|
||||||
topAppBar?.menu?.get(1)?.isVisible = true
|
topAppBar.menu?.get(1)?.isVisible = true
|
||||||
topAppBar?.menu?.get(2)?.isVisible = true
|
topAppBar.menu?.get(2)?.isVisible = true
|
||||||
topAppBar?.menu?.get(3)?.isVisible = true
|
topAppBar.menu?.get(3)?.isVisible = true
|
||||||
val slider = requireActivity().findViewById<Slider>(R.id.textsize_seekbar)
|
val slider = requireActivity().findViewById<Slider>(R.id.textsize_seekbar)
|
||||||
topAppBar?.setOnMenuItemClickListener { m: MenuItem ->
|
topAppBar.setOnMenuItemClickListener { m: MenuItem ->
|
||||||
when(m.itemId){
|
when(m.itemId){
|
||||||
R.id.wrap -> {
|
R.id.wrap -> {
|
||||||
var scrollView = requireView().findViewById<HorizontalScrollView>(R.id.horizontalscroll_output)
|
var scrollView = requireView().findViewById<HorizontalScrollView>(R.id.horizontalscroll_output)
|
||||||
|
|
@ -257,7 +261,7 @@ class TerminalFragment : Fragment() {
|
||||||
parent.addView(output, 0)
|
parent.addView(output, 0)
|
||||||
sharedPreferences.edit().putBoolean("wrap_text_terminal", true).apply()
|
sharedPreferences.edit().putBoolean("wrap_text_terminal", true).apply()
|
||||||
}else{
|
}else{
|
||||||
val parent = output?.parent as ViewGroup
|
val parent = output.parent as ViewGroup
|
||||||
parent.removeView(output)
|
parent.removeView(output)
|
||||||
scrollView = HorizontalScrollView(requireContext())
|
scrollView = HorizontalScrollView(requireContext())
|
||||||
scrollView.layoutParams = LinearLayout.LayoutParams(
|
scrollView.layoutParams = LinearLayout.LayoutParams(
|
||||||
|
|
@ -273,7 +277,7 @@ class TerminalFragment : Fragment() {
|
||||||
R.id.export_clipboard -> {
|
R.id.export_clipboard -> {
|
||||||
lifecycleScope.launch(Dispatchers.IO){
|
lifecycleScope.launch(Dispatchers.IO){
|
||||||
val clipboard: ClipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
val clipboard: ClipboardManager = requireActivity().getSystemService(CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
clipboard.setText(output?.text)
|
clipboard.setText(output.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,11 +292,11 @@ class TerminalFragment : Fragment() {
|
||||||
this.valueFrom = 0f
|
this.valueFrom = 0f
|
||||||
this.valueTo = 10f
|
this.valueTo = 10f
|
||||||
this.value = sharedPreferences.getFloat("terminal_zoom", 2f)
|
this.value = sharedPreferences.getFloat("terminal_zoom", 2f)
|
||||||
output?.setCustomTextSize(this.value + 13f)
|
output.setCustomTextSize(this.value + 13f)
|
||||||
input?.setCustomTextSize(this.value + 13f)
|
input.setCustomTextSize(this.value + 13f)
|
||||||
this.addOnChangeListener { slider, value, fromUser ->
|
this.addOnChangeListener { slider, value, fromUser ->
|
||||||
output?.setCustomTextSize(value + 13f)
|
output.setCustomTextSize(value + 13f)
|
||||||
input?.setCustomTextSize(value + 13f)
|
input.setCustomTextSize(value + 13f)
|
||||||
sharedPreferences.edit(true){
|
sharedPreferences.edit(true){
|
||||||
putFloat("terminal_zoom", value)
|
putFloat("terminal_zoom", value)
|
||||||
}
|
}
|
||||||
|
|
@ -307,14 +311,14 @@ class TerminalFragment : Fragment() {
|
||||||
}
|
}
|
||||||
private fun hideCancelFab() {
|
private fun hideCancelFab() {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
fab!!.text = getString(R.string.run_command)
|
fab.text = getString(R.string.run_command)
|
||||||
fab!!.setIconResource(R.drawable.ic_baseline_keyboard_arrow_right_24)
|
fab.setIconResource(R.drawable.ic_baseline_keyboard_arrow_right_24)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private fun showCancelFab() {
|
private fun showCancelFab() {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
fab!!.text = getString(R.string.cancel_task)
|
fab.text = getString(R.string.cancel_task)
|
||||||
fab!!.setIconResource(R.drawable.ic_cancel)
|
fab.setIconResource(R.drawable.ic_cancel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,7 +333,7 @@ class TerminalFragment : Fragment() {
|
||||||
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
input!!.text.insert(input!!.selectionStart, FileUtil.formatPath(result.data?.data.toString()))
|
input.text.insert(input.selectionStart, FileUtil.formatPath(result.data?.data.toString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,12 +344,12 @@ class TerminalFragment : Fragment() {
|
||||||
requireActivity().runOnUiThread{
|
requireActivity().runOnUiThread{
|
||||||
if (it != null){
|
if (it != null){
|
||||||
if (!it.log.isNullOrBlank()) {
|
if (!it.log.isNullOrBlank()) {
|
||||||
output?.isVisible = true
|
output.isVisible = true
|
||||||
output?.text = it.log
|
output.text = it.log
|
||||||
}
|
}
|
||||||
output?.scrollTo(0, output!!.height)
|
output.scrollTo(0, output.height)
|
||||||
scrollView?.fullScroll(View.FOCUS_DOWN)
|
scrollView.fullScroll(View.FOCUS_DOWN)
|
||||||
input!!.visibility = View.GONE
|
input.visibility = View.GONE
|
||||||
showCancelFab()
|
showCancelFab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -364,15 +368,16 @@ class TerminalFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private val workerObserver = object: Observer<List<WorkInfo>> {
|
private val workerObserver = object: Observer<List<WorkInfo>> {
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onChanged(value: List<WorkInfo>) {
|
override fun onChanged(value: List<WorkInfo>) {
|
||||||
value.forEach { work ->
|
value.forEach { work ->
|
||||||
if (listOf(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED).contains(work.state)) {
|
if (listOf(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED).contains(work.state)) {
|
||||||
requireActivity().runOnUiThread {
|
requireActivity().runOnUiThread {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
input!!.setText("yt-dlp ")
|
input.setText("yt-dlp ")
|
||||||
input!!.visibility = View.VISIBLE
|
input.visibility = View.VISIBLE
|
||||||
input!!.requestFocus()
|
input.requestFocus()
|
||||||
input!!.setSelection(input!!.text.length)
|
input.setSelection(input.text.length)
|
||||||
hideCancelFab()
|
hideCancelFab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue