diff --git a/PlantUML4iPad.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/PlantUML4iPad.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..f9b0d7c
--- /dev/null
+++ b/PlantUML4iPad.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/PlantUML4iPad.xcworkspace/xcshareddata/swiftpm/Package.resolved b/PlantUML4iPad.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 1bbde48..18c8679 100644
--- a/PlantUML4iPad.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/PlantUML4iPad.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -6,7 +6,7 @@
"location" : "https://github.com/bsorrentino/PlantUML4iPad.git",
"state" : {
"branch" : "line_editor",
- "revision" : "c90880eceaa26b08870ab34caf356dbbfa6cabc8"
+ "revision" : "502b2d37fa46ab0fc24936860d1edabf0342ce89"
}
}
],
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/DebounceObject.swift b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/DebounceObject.swift
new file mode 100644
index 0000000..883c73f
--- /dev/null
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/DebounceObject.swift
@@ -0,0 +1,40 @@
+//
+// File.swift
+//
+//
+// Created by Bartolomeo Sorrentino on 06/01/23.
+//
+
+import Foundation
+import Combine
+
+class DebounceUpdate where T : Equatable {
+
+ private var updateSubject = PassthroughSubject()
+
+ private var cancellabe:Cancellable?
+
+ func subscribe( debounceInSeconds seconds: Double, onUpdate update: @escaping ( T ) -> Void ) {
+
+ if self.cancellabe == nil {
+
+ self.cancellabe = updateSubject
+ .removeDuplicates()
+ .debounce(for: .seconds(seconds), scheduler: RunLoop.main)
+ .print()
+ .sink( receiveValue: update )
+
+ }
+
+ }
+
+ func request( for element:T ) {
+ updateSubject.send( element )
+ }
+}
+
+class DebounceUpdateObject : ObservableObject where T : Equatable {
+
+ let update = DebounceUpdate()
+
+}
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard+Color.swift b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard+Color.swift
new file mode 100644
index 0000000..3558b31
--- /dev/null
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard+Color.swift
@@ -0,0 +1,217 @@
+//
+// PlantUMLKeyboard+Color.swift
+//
+//
+// Created by Bartolomeo Sorrentino on 05/01/23.
+//
+
+import SwiftUI
+import Combine
+
+typealias RGBA = (R:Int, G:Int, B:Int, A:Int )
+
+// MARK: CGColor extension
+
+extension CGColor {
+
+ func rgbValue() -> RGBA? {
+ var output:RGBA? = nil
+
+ if let values = self.components {
+
+ switch values.count {
+ case 1:
+ output = ( Int(values[0] * 255), Int(values[0] * 255), Int(values[0] * 255),1)
+ break
+ case 2:
+ output = ( Int(values[0] * 255), Int(values[0] * 255), Int(values[0] * 255),Int(values[1] * 255))
+ break
+ case 3:
+ output = ( Int(values[0] * 255), Int(values[1] * 255), Int(values[2] * 255),1)
+ case 4:
+ output = ( Int(values[0] * 255), Int(values[1] * 255), Int(values[2] * 255),Int(values[3] * 255))
+ default:
+ break
+ }
+ }
+
+ return output
+ }
+
+ func hexValue() -> String? {
+ var output:String? = nil
+
+ if let rgba:RGBA = self.rgbValue() {
+ output = "#\(String(format:"%02X", rgba.R))\(String(format:"%02X", rgba.G))\(String(format:"%02X", rgba.B))\( String(format:"%02X", rgba.A))"
+ }
+
+ return output
+ }
+
+}
+
+// MARK: Color extension
+extension Color {
+
+ func hexValue() -> String? {
+ self.cgColor?.hexValue()
+ }
+}
+
+
+struct ColorKeyButton : UIViewRepresentable {
+
+ var symbol:Symbol
+ var onPressSymbol: (Symbol) -> Void
+
+ init(symbol: Symbol, onPressSymbol: @escaping (Symbol) -> Void) {
+ self.symbol = symbol
+ self.onPressSymbol = onPressSymbol
+ }
+
+ func makeCoordinator() -> Coordinator {
+ Coordinator( self )
+ }
+
+ func makeUIView(context: Context) -> UIButton {
+ let button = UIButton()
+
+
+ //
+ // title
+ //
+ button.setTitle(symbol.id, for: .normal)
+ button.setTitleColor(UIColor.black, for: .normal)
+ if let label = button.titleLabel {
+ label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
+ }
+
+ //
+ // Image
+ //
+// if let image = UIImage(named: "paintpalette", in: .module, compatibleWith: nil) {
+// result.setImage(image, for: .normal)
+// }
+ if let image = UIImage(systemName: "paintbrush.fill") {
+ button.setImage(image, for: .normal)
+ }
+
+ //
+ // Border
+ //
+ button.layer.borderColor = UIColor.black.cgColor
+ button.layer.borderWidth = 1
+ button.layer.cornerRadius = 5
+
+ button.frame.size = CGSize(width: 100, height: 30)
+
+ //
+ // constraints
+ //
+// button.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
+// button.heightAnchor.constraint(equalTo: self.view.heightAnchor).isActive = true
+
+ return button
+ }
+
+ func updateUIView(_ button: UIButton, context: Context) {
+ //
+ // action
+ //
+ let action = UIAction(title: symbol.id ) { _ in
+
+ let colorPicker = UIColorPickerViewController()
+
+ colorPicker.delegate = context.coordinator
+
+ getRootViewController()?.presentedViewController?.present( colorPicker, animated: true, completion: nil )
+ }
+
+ button.addAction( action, for: .touchDown )
+
+ }
+
+
+
+}
+
+extension ColorKeyButton {
+
+ class Coordinator: NSObject, UIColorPickerViewControllerDelegate {
+
+ private let update = DebounceUpdate()
+ private var owner: ColorKeyButton
+
+ init( _ owner: ColorKeyButton ) {
+ self.owner = owner
+ }
+
+ func colorPickerViewController(_ viewController: UIColorPickerViewController, didSelect color: UIColor, continuously: Bool) {
+
+ guard let hexColor = color.cgColor.hexValue() else {
+ return
+ }
+
+ update.subscribe( debounceInSeconds: 0 ) { [self] value in
+
+ viewController.dismiss(animated: true, completion: nil)
+
+ let symbol = Symbol( id: owner.symbol.id, value: value )
+
+ owner.onPressSymbol( symbol )
+
+ }
+
+ let value = String(format: owner.symbol.value, hexColor )
+
+ update.request(for: value)
+ }
+
+ }
+}
+
+/*
+struct ColorKeyView: View {
+ @StateObject private var updateColor = DebounceUpdateObject()
+
+ @State private var selectedColor = Color.blue.opacity(0.5)
+
+ var symbol:Symbol
+ var onPressSymbol: (Symbol) -> Void
+
+ var body: some View {
+ VStack {
+
+ ColorPicker( selection: $selectedColor, label: {
+ Text(symbol.id).font(.system(size: 16).bold())
+
+ })
+ .frame( maxWidth: 110 )
+ .border(.black)
+ .padding()
+ .onChange(of: selectedColor ) { color in
+ updateColor.update.subscribe( debounceInSeconds: 0 ) {
+ onPressSymbol( makeSymbol( from: $0 ) )
+ }
+ updateColor.update.request(for: color.hexValue() ?? "")
+
+ }
+ }
+
+ }
+
+ private func makeSymbol( from hexColor: String ) -> Symbol {
+
+ let value = String(format: symbol.value, hexColor )
+ return Symbol( id: symbol.id, value: value )
+ }
+}
+
+*/
+
+// MARK: Preview
+struct ColorKeyButton_Previews: PreviewProvider {
+ static var previews: some View {
+ ColorKeyButton( symbol:Symbol( id: "test" ), onPressSymbol: { _ in } )
+ }
+}
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard.swift b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard.swift
index bd4c599..aded960 100644
--- a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard.swift
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLKeyboard.swift
@@ -4,6 +4,7 @@ import LineEditor
public struct PlantUMLKeyboardView: LineEditorKeyboard {
+
var onHide:() -> Void
var onPressSymbol: (Symbol) -> Void
@@ -11,6 +12,7 @@ public struct PlantUMLKeyboardView: LineEditorKeyboard {
self.onHide = onHide
self.onPressSymbol = onPressSymbol
}
+
public var body : some View{
ZStack(alignment: .topLeading) {
@@ -41,6 +43,7 @@ public struct PlantUMLKeyboardView: LineEditorKeyboard {
.padding()
}
+
func ContentView( _ group: PlantUMLSymbolGroup ) -> some View {
ScrollView(.vertical, showsIndicators: false) {
@@ -52,39 +55,52 @@ public struct PlantUMLKeyboardView: LineEditorKeyboard {
ForEach( Array(i.enumerated()), id: \.offset ) { cellIndex, symbol in
- Button {
-
- onPressSymbol(symbol)
-
- } label: {
-
- ButtonLabel( for: group, row: rowIndex, cell: cellIndex, symbol: symbol )
-
+ VStack {
+ if symbol.type == "color" {
+// ColorKeyView( symbol: symbol, onPressSymbol: onPressSymbol )
+ ColorKeyButton( symbol: symbol, onPressSymbol: onPressSymbol )
+ .frame( maxWidth: 100)
+
+ }
+ else {
+ Button {
+ onPressSymbol(symbol)
+ } label: {
+ ButtonLabel( for: group, row: rowIndex, cell: cellIndex, symbol: symbol )
+ }
+ .buttonStyle( KeyButtonStyle() )
+ }
}
- .buttonStyle( KeyButtonStyle() )
+
}
+
}
}
}
.padding(.top)
-
+
}
}
-}
-
-fileprivate struct KeyButtonStyle: ButtonStyle {
- func makeBody(configuration: Configuration) -> some View {
- configuration.label
- .padding(5)
- .border( .black, width: 1)
- .background( .white )
- }
}
-
+// MARK: Plain Button Extension
extension PlantUMLKeyboardView {
-
+
+ fileprivate struct KeyButtonStyle: ButtonStyle {
+
+ func makeBody(configuration: Configuration) -> some View {
+ configuration.label
+ .padding(5)
+ .background( .white )
+// .border( .black, width: 1)
+ .overlay {
+ RoundedRectangle(cornerRadius: 5)
+ .stroke(.black, lineWidth: 1)
+ }
+ }
+ }
+
func ButtonLabel( for group: PlantUMLSymbolGroup, row: Int, cell: Int, symbol: Symbol ) -> some View {
Text(symbol.id).font(.system(size: 16).bold())
@@ -106,6 +122,7 @@ extension PlantUMLKeyboardView {
}
}
+
struct PlantUMLKeyboardView_Previews: PreviewProvider {
static var previews: some View {
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbol.swift b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbol.swift
index fb23b92..1263533 100644
--- a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbol.swift
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbol.swift
@@ -12,27 +12,29 @@ struct Symbol : Decodable, Identifiable, CustomStringConvertible, LineEditorKeyb
enum CodingKeys: String, CodingKey {
case id
- case value = "v0"
- case additionalValues = "v1"
+ case value
+ case additionalValues = "additional"
+ case type
}
var description: String { value }
var id:String
private var _value:String?
- private var _additionalValues:[String]?
+ private(set) var additionalValues:[String]?
+ var type = "string"
var value: String {
get { _value ?? id }
}
- var additionalValues: [String]? {
- get { _additionalValues }
- }
+// var additionalValues: [String]? {
+// get { _additionalValues }
+// }
- init( _ id:String, _ value:String? = nil, _ additionalValues: [String]? = nil) {
+ init( id:String, value:String? = nil, additionalValues: [String]? = nil) {
self.id = id
self._value = value
- self._additionalValues = additionalValues
+ self.additionalValues = additionalValues
}
init(from decoder: Decoder) throws {
@@ -41,7 +43,10 @@ struct Symbol : Decodable, Identifiable, CustomStringConvertible, LineEditorKeyb
self.id = try container.decode(String.self, forKey: CodingKeys.id)
self._value = try container.decodeIfPresent(String.self, forKey: CodingKeys.value)
- self._additionalValues = try container.decodeIfPresent([String].self, forKey: CodingKeys.additionalValues)
+ self.additionalValues = try container.decodeIfPresent([String].self, forKey: CodingKeys.additionalValues)
+ if let type = try container.decodeIfPresent(String.self, forKey: CodingKeys.type) {
+ self.type = type
+ }
}
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbolsBuilder.swift b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbolsBuilder.swift
index 900697f..ac94903 100644
--- a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbolsBuilder.swift
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/PlantUMLSymbolsBuilder.swift
@@ -23,13 +23,13 @@ extension Symbol {
return sym
}
else if let str = elem as? String {
- return Symbol(str)
+ return Symbol(id: str)
}
else if let part2 = elem as? PART2 {
- return Symbol(part2.0, part2.1)
+ return Symbol(id: part2.0, value: part2.1)
}
else if let part3 = elem as? PART3 {
- return Symbol(part3.0, part3.1, part3.2)
+ return Symbol( id: part3.0, value: part3.1, additionalValues: part3.2)
}
return nil
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/Window+Utils.swift b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/Window+Utils.swift
index 03e1cec..511d9ec 100644
--- a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/Window+Utils.swift
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/Window+Utils.swift
@@ -34,6 +34,10 @@ public func getWindows() -> [UIWindow]? {
}
+func getRootViewController() -> UIViewController? {
+ getWindows()?.first?.rootViewController
+}
+
func getFirstTextFieldResponder() -> UITextField? {
guard let firstWindow = getWindows()?.first, let firstResponder = firstWindow.firstResponder else {
diff --git a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/plantuml_keyboard_data.json b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/plantuml_keyboard_data.json
index e633e2d..146713c 100644
--- a/PlantUMLKeyboard/Sources/PlantUMLKeyboard/plantuml_keyboard_data.json
+++ b/PlantUMLKeyboard/Sources/PlantUMLKeyboard/plantuml_keyboard_data.json
@@ -4,20 +4,21 @@
"name": "general",
"rows": [
[
- { "id": "title", "v0": "title my title" },
- { "id": "header", "v0": "header my header" },
- { "id": "footer", "v0": "footer my footer" }
+ { "id": "title", "value": "title my title" },
+ { "id": "header", "value": "header my header" },
+ { "id": "footer", "value": "footer my footer" }
],
[
- { "id": "allow mixing", "v0": "allow_mixing" },
+ { "id": "allow mixing", "value": "allow_mixing" },
{ "id": "hide empty members" },
- { "id": "shadowing false", "v0": "skinparam shadowing false" },
- { "id": "linetype ortho", "v0": "skinparam linetype ortho" },
- { "id": "left to right", "v0": "left to right direction" },
- { "id": "top to bottom", "v0": "top to bottom direction" }
+ { "id": "shadowing false", "value": "skinparam shadowing false" },
+ { "id": "linetype ortho", "value": "skinparam linetype ortho" },
+ { "id": "left to right", "value": "left to right direction" },
+ { "id": "top to bottom", "value": "top to bottom direction" }
],
[
- { "id": "[#red]" },
+ { "id": "#color", "value": "%@", "type": "color" },
+ { "id": "[#color]", "value": "[%@]", "type": "color" },
{ "id": "#line.dashed" }
]
]
@@ -28,19 +29,19 @@
[
{ "id": "autonumber" },
{ "id": "hide footbox" },
- { "id": "teoz", "v0": "!pragma teoz true" }
+ { "id": "teoz", "value": "!pragma teoz true" }
],
[
- {"id": "box", "v0": "box \"\\nmy box\\n", "v1": ["end box"]},
- {"id": "actor", "v0": "actor \"my actor\" as a1"},
- {"id": "participant", "v0": "participant \"my participant\" as p1"},
- {"id": "boundary", "v0": "boundary \"my boundary\" as b1"},
- {"id": "control", "v0": "control \"my control\" as c1"},
- {"id": "entity", "v0": "entity \"my entity\" as e1"},
- {"id": "database", "v0": "database \"my database\" as db1"},
- {"id": "collections","v0": "collections \"my collections\" as cc1" },
- {"id": "queue", "v0": "queue \"my queue\" as q1"}
+ {"id": "box", "value": "box \"\\nmy box\\n", "additional": ["end box"]},
+ {"id": "actor", "value": "actor \"my actor\" as a1"},
+ {"id": "participant", "value": "participant \"my participant\" as p1"},
+ {"id": "boundary", "value": "boundary \"my boundary\" as b1"},
+ {"id": "control", "value": "control \"my control\" as c1"},
+ {"id": "entity", "value": "entity \"my entity\" as e1"},
+ {"id": "database", "value": "database \"my database\" as db1"},
+ {"id": "collections","value": "collections \"my collections\" as cc1" },
+ {"id": "queue", "value": "queue \"my queue\" as q1"}
],
[
{ "id": "->x" },
@@ -55,13 +56,13 @@
{ "id": "<->o" }
],
[
- { "id": "{start}", "v0": "{start} " }, { "id": "{end}", "v0": "{end} " },
- { "id": "group", "v0": "group My own label", "v1": ["end"] },
- { "id": "loop", "v0": "loop N times", "v1": ["end"] },
- { "id": "alt", "v0": "alt successful case", "v1": [ "else some kind of failure", "end"] },
- { "id": "note left", "v0": "note left /' of p1 '/", "v1": ["this note is displayed left", "end note"]},
- { "id": "note right", "v0": "note right /' of p1 '/", "v1": ["this note is displayed right", "end note"]},
- { "id": "note over", "v0": "note over p1 /', p2 '/", "v1": ["this note is displayed over participant1", "end note"]}
+ { "id": "{start}", "value": "{start} " }, { "id": "{end}", "value": "{end} " },
+ { "id": "group", "value": "group My own label", "additional": ["end"] },
+ { "id": "loop", "value": "loop N times", "additional": ["end"] },
+ { "id": "alt", "value": "alt successful case", "additional": [ "else some kind of failure", "end"] },
+ { "id": "note left", "value": "note left /' of p1 '/", "additional": ["this note is displayed left", "end note"]},
+ { "id": "note right", "value": "note right /' of p1 '/", "additional": ["this note is displayed right", "end note"]},
+ { "id": "note over", "value": "note over p1 /', p2 '/", "additional": ["this note is displayed over participant1", "end note"]}
]
]
@@ -70,34 +71,34 @@
"name": "deployment",
"rows": [
[
- { "id": "actor", "v0": "actor \"my actor\" as ac1"},
- { "id": "agent", "v0": "agent \"my agent\" as ag1"},
- { "id": "artifact", "v0": "artifact \"my artifact\" as ar1"},
- { "id": "boundary", "v0": "boundary \"my boundary\" as bn1"},
- { "id": "card", "v0": "card \"my card\" as cd1"},
- { "id": "circle", "v0": "circle \"my circle\" as cr1"},
- { "id": "cloud", "v0": "cloud \"my cloud\" as cd1"},
- { "id": "collections", "v0": "collections \"my collections\" as cl1"},
- { "id": "component", "v0": "component \"my component\" as cp1"},
- { "id": "control", "v0": "control \"my control\" as cn1"},
- { "id": "person", "v0": "person \"my person\" as pr1"},
- { "id": "queue", "v0": "queue \"my queue\" as qq1"},
- { "id": "rectangle", "v0": "rectangle \"my rect\\n\" as rc1 {", "v1": [ "}" ] }
+ { "id": "actor", "value": "actor \"my actor\" as ac1"},
+ { "id": "agent", "value": "agent \"my agent\" as ag1"},
+ { "id": "artifact", "value": "artifact \"my artifact\" as ar1"},
+ { "id": "boundary", "value": "boundary \"my boundary\" as bn1"},
+ { "id": "card", "value": "card \"my card\" as cd1"},
+ { "id": "circle", "value": "circle \"my circle\" as cr1"},
+ { "id": "cloud", "value": "cloud \"my cloud\" as cd1"},
+ { "id": "collections", "value": "collections \"my collections\" as cl1"},
+ { "id": "component", "value": "component \"my component\" as cp1"},
+ { "id": "control", "value": "control \"my control\" as cn1"},
+ { "id": "person", "value": "person \"my person\" as pr1"},
+ { "id": "queue", "value": "queue \"my queue\" as qq1"},
+ { "id": "rectangle", "value": "rectangle \"my rect\\n\" as rc1 {", "additional": [ "}" ] }
],
[
- { "id": "database", "v0": "database \"my database\" as db1" },
- { "id": "entity", "v0": "entity \"my entity\" as ee1"},
- { "id": "file", "v0": "file \"my file\" as ff1"},
- { "id": "folder", "v0": "folder \"my folder\" as fl1"},
- { "id": "frame", "v0": "frame \"my frame\" as fr1"},
- { "id": "hexagon", "v0": "hexagon \"my hexagon\" as hx1"},
- { "id": "interface", "v0": "interface \"my interface\" as if1"},
- { "id": "label", "v0": "label \"my label\" as lb1"},
- { "id": "node", "v0": "node \"my node\" as nd1"},
- { "id": "package", "v0": "package \"my package\" as pc1"},
- { "id": "stack", "v0": "stack \"my stack\" as sk1"},
- { "id": "storage", "v0": "storage \"my storage\" as st1"},
- { "id": "usecase", "v0": "usecase \"my usecase\" as uc1"}
+ { "id": "database", "value": "database \"my database\" as db1" },
+ { "id": "entity", "value": "entity \"my entity\" as ee1"},
+ { "id": "file", "value": "file \"my file\" as ff1"},
+ { "id": "folder", "value": "folder \"my folder\" as fl1"},
+ { "id": "frame", "value": "frame \"my frame\" as fr1"},
+ { "id": "hexagon", "value": "hexagon \"my hexagon\" as hx1"},
+ { "id": "interface", "value": "interface \"my interface\" as if1"},
+ { "id": "label", "value": "label \"my label\" as lb1"},
+ { "id": "node", "value": "node \"my node\" as nd1"},
+ { "id": "package", "value": "package \"my package\" as pc1"},
+ { "id": "stack", "value": "stack \"my stack\" as sk1"},
+ { "id": "storage", "value": "storage \"my storage\" as st1"},
+ { "id": "usecase", "value": "usecase \"my usecase\" as uc1"}
],
[
diff --git a/~/Library/Microsoft/PowerAppsCli/usersettings.json b/~/Library/Microsoft/PowerAppsCli/usersettings.json
new file mode 100644
index 0000000..d4260c0
--- /dev/null
+++ b/~/Library/Microsoft/PowerAppsCli/usersettings.json
@@ -0,0 +1 @@
+{"uniqueId":"d67c2bb3-ce99-4e95-becd-f5d782fdaecb","settingVersion":"1.0","telemetryEnabled":true}
\ No newline at end of file