sqlui 0.1.59 → 0.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.release-version +1 -1
 - data/app/server.rb +57 -13
 - data/client/resources/sqlui.css +13 -6
 - data/client/resources/sqlui.js +296 -73
 - metadata +2 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 45285cfe6706fdfa5bae7abf73f1a287e0238709f2f83a18eda8386c71f4de63
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 9d3eacf4a4306697c4c34d91b51303dd88b376bec29526124d18ec5c4fbe43d7
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: f94e45bf232683013994f63a46eb18257aeaf9d81dd906ccffdbdced023be1743ebca28ff87f34a3b45932757b80516fae979d74a9ab1002affa78a7adb412dc
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 4151e2f3f7d795931abfee848f040e9b6066c4ef4ec9503d0f3cdb586e82d3ced59f50c3eb8744c2adc2847324d275d642e313c0ba825768e452e7a0f8af7b75
         
     | 
    
        data/.release-version
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            0.1. 
     | 
| 
      
 1 
     | 
    
         
            +
            0.1.60
         
     | 
    
        data/app/server.rb
    CHANGED
    
    | 
         @@ -143,31 +143,60 @@ class Server < Sinatra::Base 
     | 
|
| 
       143 
143 
     | 
    
         
             
                    status 200
         
     | 
| 
       144 
144 
     | 
    
         
             
                    headers 'Content-Type' => 'application/json; charset=utf-8'
         
     | 
| 
       145 
145 
     | 
    
         | 
| 
       146 
     | 
    
         
            -
                     
     | 
| 
       147 
     | 
    
         
            -
                       
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
      
 146 
     | 
    
         
            +
                    stream do |out|
         
     | 
| 
      
 147 
     | 
    
         
            +
                      database.with_client do |client|
         
     | 
| 
      
 148 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 149 
     | 
    
         
            +
                          query_result = execute_query(client, variables, queries)
         
     | 
| 
      
 150 
     | 
    
         
            +
                        rescue Mysql2::Error => e
         
     | 
| 
      
 151 
     | 
    
         
            +
                          stacktrace = e.full_message(highlight: false)
         
     | 
| 
      
 152 
     | 
    
         
            +
                          message = "ERROR #{e.error_number} (#{e.sql_state}): #{e.message.lines.first&.strip || 'unknown error'}"
         
     | 
| 
      
 153 
     | 
    
         
            +
                          out << { error: message, stacktrace: stacktrace }.compact.to_json
         
     | 
| 
      
 154 
     | 
    
         
            +
                          break
         
     | 
| 
      
 155 
     | 
    
         
            +
                        rescue StandardError => e
         
     | 
| 
      
 156 
     | 
    
         
            +
                          stacktrace = e.full_message(highlight: false)
         
     | 
| 
      
 157 
     | 
    
         
            +
                          message = e.message.lines.first&.strip || 'unknown error'
         
     | 
| 
      
 158 
     | 
    
         
            +
                          out << { error: message, stacktrace: stacktrace }.compact.to_json
         
     | 
| 
      
 159 
     | 
    
         
            +
                          break
         
     | 
| 
      
 160 
     | 
    
         
            +
                        end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
       149 
162 
     | 
    
         
             
                        if query_result
         
     | 
| 
       150 
163 
     | 
    
         
             
                          json = <<~RES.chomp
         
     | 
| 
       151 
164 
     | 
    
         
             
                            {
         
     | 
| 
       152 
165 
     | 
    
         
             
                              "columns": #{query_result.fields.to_json},
         
     | 
| 
       153 
166 
     | 
    
         
             
                              "column_types": #{MysqlTypes.map_to_google_charts_types(query_result.field_types).to_json},
         
     | 
| 
       154 
     | 
    
         
            -
                              "total_rows": #{query_result.size.to_json},
         
     | 
| 
       155 
167 
     | 
    
         
             
                              "selection": #{params[:selection].to_json},
         
     | 
| 
       156 
168 
     | 
    
         
             
                              "query": #{params[:sql].to_json},
         
     | 
| 
       157 
169 
     | 
    
         
             
                              "rows": [
         
     | 
| 
       158 
170 
     | 
    
         
             
                          RES
         
     | 
| 
       159 
171 
     | 
    
         
             
                          out << json
         
     | 
| 
       160 
     | 
    
         
            -
                           
     | 
| 
      
 172 
     | 
    
         
            +
                          bytes_written = json.bytesize
         
     | 
| 
      
 173 
     | 
    
         
            +
                          max_rows_written = false
         
     | 
| 
      
 174 
     | 
    
         
            +
                          rows_written = 0
         
     | 
| 
      
 175 
     | 
    
         
            +
                          total_rows = 0
         
     | 
| 
       161 
176 
     | 
    
         
             
                          query_result.each_with_index do |row, i|
         
     | 
| 
      
 177 
     | 
    
         
            +
                            total_rows += 1
         
     | 
| 
      
 178 
     | 
    
         
            +
                            next if max_rows_written
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
       162 
180 
     | 
    
         
             
                            json = "#{i.zero? ? '' : ','}\n    #{row.map { |v| big_decimal_to_float(v) }.to_json}"
         
     | 
| 
       163 
     | 
    
         
            -
                             
     | 
| 
       164 
     | 
    
         
            -
                             
     | 
| 
      
 181 
     | 
    
         
            +
                            bytesize = json.bytesize
         
     | 
| 
      
 182 
     | 
    
         
            +
                            if bytes_written + bytesize > Sqlui::MAX_BYTES
         
     | 
| 
      
 183 
     | 
    
         
            +
                              max_rows_written = true
         
     | 
| 
      
 184 
     | 
    
         
            +
                              next
         
     | 
| 
      
 185 
     | 
    
         
            +
                            end
         
     | 
| 
       165 
186 
     | 
    
         | 
| 
       166 
187 
     | 
    
         
             
                            out << json
         
     | 
| 
      
 188 
     | 
    
         
            +
                            bytes_written += bytesize
         
     | 
| 
      
 189 
     | 
    
         
            +
                            rows_written += 1
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                            if rows_written == Sqlui::MAX_ROWS
         
     | 
| 
      
 192 
     | 
    
         
            +
                              max_rows_written = true
         
     | 
| 
      
 193 
     | 
    
         
            +
                              next
         
     | 
| 
      
 194 
     | 
    
         
            +
                            end
         
     | 
| 
       167 
195 
     | 
    
         
             
                          end
         
     | 
| 
       168 
196 
     | 
    
         
             
                          out << <<~RES
         
     | 
| 
       169 
197 
     | 
    
         | 
| 
       170 
     | 
    
         
            -
                              ]
         
     | 
| 
      
 198 
     | 
    
         
            +
                              ],
         
     | 
| 
      
 199 
     | 
    
         
            +
                              "total_rows": #{total_rows}
         
     | 
| 
       171 
200 
     | 
    
         
             
                            }
         
     | 
| 
       172 
201 
     | 
    
         
             
                          RES
         
     | 
| 
       173 
202 
     | 
    
         
             
                        else
         
     | 
| 
         @@ -198,9 +227,21 @@ class Server < Sinatra::Base 
     | 
|
| 
       198 
227 
     | 
    
         
             
                    attachment 'result.csv'
         
     | 
| 
       199 
228 
     | 
    
         
             
                    status 200
         
     | 
| 
       200 
229 
     | 
    
         | 
| 
       201 
     | 
    
         
            -
                     
     | 
| 
       202 
     | 
    
         
            -
                       
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
      
 230 
     | 
    
         
            +
                    stream do |out|
         
     | 
| 
      
 231 
     | 
    
         
            +
                      database.with_client do |client|
         
     | 
| 
      
 232 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 233 
     | 
    
         
            +
                          query_result = execute_query(client, variables, queries)
         
     | 
| 
      
 234 
     | 
    
         
            +
                        rescue Mysql2::Error => e
         
     | 
| 
      
 235 
     | 
    
         
            +
                          stacktrace = e.full_message(highlight: false)
         
     | 
| 
      
 236 
     | 
    
         
            +
                          message = "ERROR #{e.error_number} (#{e.sql_state}): #{e.message.lines.first&.strip || 'unknown error'}"
         
     | 
| 
      
 237 
     | 
    
         
            +
                          out << { error: message, stacktrace: stacktrace }.compact.to_json
         
     | 
| 
      
 238 
     | 
    
         
            +
                          break
         
     | 
| 
      
 239 
     | 
    
         
            +
                        rescue StandardError => e
         
     | 
| 
      
 240 
     | 
    
         
            +
                          stacktrace = e.full_message(highlight: false)
         
     | 
| 
      
 241 
     | 
    
         
            +
                          message = e.message.lines.first&.strip || 'unknown error'
         
     | 
| 
      
 242 
     | 
    
         
            +
                          out << { error: message, stacktrace: stacktrace }.compact.to_json
         
     | 
| 
      
 243 
     | 
    
         
            +
                          break
         
     | 
| 
      
 244 
     | 
    
         
            +
                        end
         
     | 
| 
       204 
245 
     | 
    
         
             
                        out << CSV::Row.new(query_result.fields, query_result.fields, header_row: true).to_s.strip
         
     | 
| 
       205 
246 
     | 
    
         
             
                        query_result.each do |row|
         
     | 
| 
       206 
247 
     | 
    
         
             
                          out << "\n#{CSV::Row.new(query_result.fields, row.map { |v| big_decimal_to_float(v) }).to_s.strip}"
         
     | 
| 
         @@ -230,7 +271,7 @@ class Server < Sinatra::Base 
     | 
|
| 
       230 
271 
     | 
    
         
             
                  stacktrace = exception&.full_message(highlight: false)
         
     | 
| 
       231 
272 
     | 
    
         
             
                  if request.env['HTTP_ACCEPT'] == 'application/json'
         
     | 
| 
       232 
273 
     | 
    
         
             
                    headers 'Content-Type' => 'application/json; charset=utf-8'
         
     | 
| 
       233 
     | 
    
         
            -
                    message = exception&.message&.lines&.first&.strip || 'unexpected error'
         
     | 
| 
      
 274 
     | 
    
         
            +
                    message = "error: #{exception&.message&.lines&.first&.strip || 'unexpected error'}"
         
     | 
| 
       234 
275 
     | 
    
         
             
                    json = { error: message, stacktrace: stacktrace }.compact.to_json
         
     | 
| 
       235 
276 
     | 
    
         
             
                    body json
         
     | 
| 
       236 
277 
     | 
    
         
             
                  else
         
     | 
| 
         @@ -274,7 +315,10 @@ class Server < Sinatra::Base 
     | 
|
| 
       274 
315 
     | 
    
         
             
                variables.each do |name, value|
         
     | 
| 
       275 
316 
     | 
    
         
             
                  client.query("SET @#{name} = #{value};")
         
     | 
| 
       276 
317 
     | 
    
         
             
                end
         
     | 
| 
       277 
     | 
    
         
            -
                queries.map  
     | 
| 
      
 318 
     | 
    
         
            +
                queries[0..-2].map do |current|
         
     | 
| 
      
 319 
     | 
    
         
            +
                  client.query(current, stream: true)&.free
         
     | 
| 
      
 320 
     | 
    
         
            +
                end
         
     | 
| 
      
 321 
     | 
    
         
            +
                client.query(queries[-1], stream: true)
         
     | 
| 
       278 
322 
     | 
    
         
             
              end
         
     | 
| 
       279 
323 
     | 
    
         | 
| 
       280 
324 
     | 
    
         
             
              def big_decimal_to_float(maybe_big_decimal)
         
     | 
    
        data/client/resources/sqlui.css
    CHANGED
    
    | 
         @@ -233,16 +233,15 @@ p { 
     | 
|
| 
       233 
233 
     | 
    
         
             
            }
         
     | 
| 
       234 
234 
     | 
    
         | 
| 
       235 
235 
     | 
    
         
             
            #status-message {
         
     | 
| 
       236 
     | 
    
         
            -
                 
     | 
| 
       237 
     | 
    
         
            -
                justify-content:  
     | 
| 
       238 
     | 
    
         
            -
                align-content: center;
         
     | 
| 
       239 
     | 
    
         
            -
                flex-direction: row;
         
     | 
| 
      
 236 
     | 
    
         
            +
                min-width: 0;
         
     | 
| 
      
 237 
     | 
    
         
            +
                justify-content: left;
         
     | 
| 
       240 
238 
     | 
    
         
             
                font-family: Helvetica, sans-serif;
         
     | 
| 
       241 
239 
     | 
    
         
             
                white-space: nowrap;
         
     | 
| 
       242 
240 
     | 
    
         
             
                overflow: hidden;
         
     | 
| 
       243 
241 
     | 
    
         
             
                font-size: 16px;
         
     | 
| 
       244 
242 
     | 
    
         
             
                color: #333;
         
     | 
| 
       245 
     | 
    
         
            -
                margin 
     | 
| 
      
 243 
     | 
    
         
            +
                margin: 0 5px;
         
     | 
| 
      
 244 
     | 
    
         
            +
                text-overflow: ellipsis;
         
     | 
| 
       246 
245 
     | 
    
         
             
            }
         
     | 
| 
       247 
246 
     | 
    
         | 
| 
       248 
247 
     | 
    
         
             
            #result-box, #fetch-sql-box, #saved-box, #graph-box, #structure-box {
         
     | 
| 
         @@ -255,6 +254,10 @@ table tbody tr td { 
     | 
|
| 
       255 
254 
     | 
    
         
             
              height: 21px;
         
     | 
| 
       256 
255 
     | 
    
         
             
            }
         
     | 
| 
       257 
256 
     | 
    
         | 
| 
      
 257 
     | 
    
         
            +
            #result-table td, #result-table th {
         
     | 
| 
      
 258 
     | 
    
         
            +
                cursor: default;
         
     | 
| 
      
 259 
     | 
    
         
            +
            }
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
       258 
261 
     | 
    
         
             
            #result-table tbody tr td abbr a {
         
     | 
| 
       259 
262 
     | 
    
         
             
                color: #555;
         
     | 
| 
       260 
263 
     | 
    
         
             
                cursor: pointer;
         
     | 
| 
         @@ -264,6 +267,7 @@ table tbody tr td { 
     | 
|
| 
       264 
267 
     | 
    
         
             
                border: 1px dotted #555;
         
     | 
| 
       265 
268 
     | 
    
         
             
                font-size: 12px;
         
     | 
| 
       266 
269 
     | 
    
         
             
                display: inline-block;
         
     | 
| 
      
 270 
     | 
    
         
            +
                user-select: none;
         
     | 
| 
       267 
271 
     | 
    
         
             
            }
         
     | 
| 
       268 
272 
     | 
    
         | 
| 
       269 
273 
     | 
    
         
             
            #result-table tbody tr td abbr {
         
     | 
| 
         @@ -358,7 +362,8 @@ thead { 
     | 
|
| 
       358 
362 
     | 
    
         
             
            }
         
     | 
| 
       359 
363 
     | 
    
         | 
| 
       360 
364 
     | 
    
         
             
            #status-box {
         
     | 
| 
       361 
     | 
    
         
            -
                 
     | 
| 
      
 365 
     | 
    
         
            +
                width: 100%;
         
     | 
| 
      
 366 
     | 
    
         
            +
                padding: 5px 0;
         
     | 
| 
       362 
367 
     | 
    
         
             
                display: flex;
         
     | 
| 
       363 
368 
     | 
    
         
             
                flex-direction: row;
         
     | 
| 
       364 
369 
     | 
    
         
             
                border-top: 1px solid #ddd;
         
     | 
| 
         @@ -485,11 +490,13 @@ select { 
     | 
|
| 
       485 
490 
     | 
    
         
             
            #pagination-box {
         
     | 
| 
       486 
491 
     | 
    
         
             
                display: flex;
         
     | 
| 
       487 
492 
     | 
    
         
             
                flex-direction: row;
         
     | 
| 
      
 493 
     | 
    
         
            +
                margin: 0 5px;
         
     | 
| 
       488 
494 
     | 
    
         
             
            }
         
     | 
| 
       489 
495 
     | 
    
         | 
| 
       490 
496 
     | 
    
         
             
            #page-count-box {
         
     | 
| 
       491 
497 
     | 
    
         
             
                align-self: center;
         
     | 
| 
       492 
498 
     | 
    
         
             
                font-size: 16px;
         
     | 
| 
      
 499 
     | 
    
         
            +
                white-space: nowrap;
         
     | 
| 
       493 
500 
     | 
    
         
             
            }
         
     | 
| 
       494 
501 
     | 
    
         | 
| 
       495 
502 
     | 
    
         
             
            .pagination-button {
         
     | 
    
        data/client/resources/sqlui.js
    CHANGED
    
    | 
         @@ -1514,10 +1514,11 @@ 
     | 
|
| 
       1514 
1514 
     | 
    
         
             
                   /**
         
     | 
| 
       1515 
1515 
     | 
    
         
             
                   Create a selection range.
         
     | 
| 
       1516 
1516 
     | 
    
         
             
                   */
         
     | 
| 
       1517 
     | 
    
         
            -
                   static range(anchor, head, goalColumn) {
         
     | 
| 
       1518 
     | 
    
         
            -
                       let  
     | 
| 
       1519 
     | 
    
         
            -
             
     | 
| 
       1520 
     | 
    
         
            -
             
     | 
| 
      
 1517 
     | 
    
         
            +
                   static range(anchor, head, goalColumn, bidiLevel) {
         
     | 
| 
      
 1518 
     | 
    
         
            +
                       let flags = ((goalColumn !== null && goalColumn !== void 0 ? goalColumn : 33554431 /* RangeFlag.NoGoalColumn */) << 5 /* RangeFlag.GoalColumnOffset */) |
         
     | 
| 
      
 1519 
     | 
    
         
            +
                           (bidiLevel == null ? 3 : Math.min(2, bidiLevel));
         
     | 
| 
      
 1520 
     | 
    
         
            +
                       return head < anchor ? SelectionRange.create(head, anchor, 16 /* RangeFlag.Inverted */ | 8 /* RangeFlag.AssocAfter */ | flags)
         
     | 
| 
      
 1521 
     | 
    
         
            +
                           : SelectionRange.create(anchor, head, (head > anchor ? 4 /* RangeFlag.AssocBefore */ : 0) | flags);
         
     | 
| 
       1521 
1522 
     | 
    
         
             
                   }
         
     | 
| 
       1522 
1523 
     | 
    
         
             
                   /**
         
     | 
| 
       1523 
1524 
     | 
    
         
             
                   @internal
         
     | 
| 
         @@ -4346,6 +4347,26 @@ 
     | 
|
| 
       4346 
4347 
     | 
    
         
             
                       }
         
     | 
| 
       4347 
4348 
     | 
    
         
             
                   }
         
     | 
| 
       4348 
4349 
     | 
    
         
             
               }
         
     | 
| 
      
 4350 
     | 
    
         
            +
               function scrollableParent(dom) {
         
     | 
| 
      
 4351 
     | 
    
         
            +
                   let doc = dom.ownerDocument;
         
     | 
| 
      
 4352 
     | 
    
         
            +
                   for (let cur = dom.parentNode; cur;) {
         
     | 
| 
      
 4353 
     | 
    
         
            +
                       if (cur == doc.body) {
         
     | 
| 
      
 4354 
     | 
    
         
            +
                           break;
         
     | 
| 
      
 4355 
     | 
    
         
            +
                       }
         
     | 
| 
      
 4356 
     | 
    
         
            +
                       else if (cur.nodeType == 1) {
         
     | 
| 
      
 4357 
     | 
    
         
            +
                           if (cur.scrollHeight > cur.clientHeight || cur.scrollWidth > cur.clientWidth)
         
     | 
| 
      
 4358 
     | 
    
         
            +
                               return cur;
         
     | 
| 
      
 4359 
     | 
    
         
            +
                           cur = cur.assignedSlot || cur.parentNode;
         
     | 
| 
      
 4360 
     | 
    
         
            +
                       }
         
     | 
| 
      
 4361 
     | 
    
         
            +
                       else if (cur.nodeType == 11) {
         
     | 
| 
      
 4362 
     | 
    
         
            +
                           cur = cur.host;
         
     | 
| 
      
 4363 
     | 
    
         
            +
                       }
         
     | 
| 
      
 4364 
     | 
    
         
            +
                       else {
         
     | 
| 
      
 4365 
     | 
    
         
            +
                           break;
         
     | 
| 
      
 4366 
     | 
    
         
            +
                       }
         
     | 
| 
      
 4367 
     | 
    
         
            +
                   }
         
     | 
| 
      
 4368 
     | 
    
         
            +
                   return null;
         
     | 
| 
      
 4369 
     | 
    
         
            +
               }
         
     | 
| 
       4349 
4370 
     | 
    
         
             
               class DOMSelectionState {
         
     | 
| 
       4350 
4371 
     | 
    
         
             
                   constructor() {
         
     | 
| 
       4351 
4372 
     | 
    
         
             
                       this.anchorNode = null;
         
     | 
| 
         @@ -7544,22 +7565,30 @@ 
     | 
|
| 
       7544 
7565 
     | 
    
         
             
                       this.compositionFirstChange = null;
         
     | 
| 
       7545 
7566 
     | 
    
         
             
                       this.compositionEndedAt = 0;
         
     | 
| 
       7546 
7567 
     | 
    
         
             
                       this.mouseSelection = null;
         
     | 
| 
      
 7568 
     | 
    
         
            +
                       let handleEvent = (handler, event) => {
         
     | 
| 
      
 7569 
     | 
    
         
            +
                           if (this.ignoreDuringComposition(event))
         
     | 
| 
      
 7570 
     | 
    
         
            +
                               return;
         
     | 
| 
      
 7571 
     | 
    
         
            +
                           if (event.type == "keydown" && this.keydown(view, event))
         
     | 
| 
      
 7572 
     | 
    
         
            +
                               return;
         
     | 
| 
      
 7573 
     | 
    
         
            +
                           if (this.mustFlushObserver(event))
         
     | 
| 
      
 7574 
     | 
    
         
            +
                               view.observer.forceFlush();
         
     | 
| 
      
 7575 
     | 
    
         
            +
                           if (this.runCustomHandlers(event.type, view, event))
         
     | 
| 
      
 7576 
     | 
    
         
            +
                               event.preventDefault();
         
     | 
| 
      
 7577 
     | 
    
         
            +
                           else
         
     | 
| 
      
 7578 
     | 
    
         
            +
                               handler(view, event);
         
     | 
| 
      
 7579 
     | 
    
         
            +
                       };
         
     | 
| 
       7547 
7580 
     | 
    
         
             
                       for (let type in handlers) {
         
     | 
| 
       7548 
7581 
     | 
    
         
             
                           let handler = handlers[type];
         
     | 
| 
       7549 
     | 
    
         
            -
                           view.contentDOM.addEventListener(type,  
     | 
| 
       7550 
     | 
    
         
            -
                               if ( 
     | 
| 
       7551 
     | 
    
         
            -
                                    
     | 
| 
       7552 
     | 
    
         
            -
                               if (type == "keydown" && this.keydown(view, event))
         
     | 
| 
       7553 
     | 
    
         
            -
                                   return;
         
     | 
| 
       7554 
     | 
    
         
            -
                               if (this.mustFlushObserver(event))
         
     | 
| 
       7555 
     | 
    
         
            -
                                   view.observer.forceFlush();
         
     | 
| 
       7556 
     | 
    
         
            -
                               if (this.runCustomHandlers(type, view, event))
         
     | 
| 
       7557 
     | 
    
         
            -
                                   event.preventDefault();
         
     | 
| 
       7558 
     | 
    
         
            -
                               else
         
     | 
| 
       7559 
     | 
    
         
            -
                                   handler(view, event);
         
     | 
| 
      
 7582 
     | 
    
         
            +
                           view.contentDOM.addEventListener(type, event => {
         
     | 
| 
      
 7583 
     | 
    
         
            +
                               if (eventBelongsToEditor(view, event))
         
     | 
| 
      
 7584 
     | 
    
         
            +
                                   handleEvent(handler, event);
         
     | 
| 
       7560 
7585 
     | 
    
         
             
                           }, handlerOptions[type]);
         
     | 
| 
       7561 
7586 
     | 
    
         
             
                           this.registeredEvents.push(type);
         
     | 
| 
       7562 
7587 
     | 
    
         
             
                       }
         
     | 
| 
      
 7588 
     | 
    
         
            +
                       view.scrollDOM.addEventListener("mousedown", (event) => {
         
     | 
| 
      
 7589 
     | 
    
         
            +
                           if (event.target == view.scrollDOM)
         
     | 
| 
      
 7590 
     | 
    
         
            +
                               handleEvent(handlers.mousedown, event);
         
     | 
| 
      
 7591 
     | 
    
         
            +
                       });
         
     | 
| 
       7563 
7592 
     | 
    
         
             
                       if (browser.chrome && browser.chrome_version == 102) { // FIXME remove at some point
         
     | 
| 
       7564 
7593 
     | 
    
         
             
                           // On Chrome 102, viewport updates somehow stop wheel-based
         
     | 
| 
       7565 
7594 
     | 
    
         
             
                           // scrolling. Turning off pointer events during the scroll seems
         
     | 
| 
         @@ -7716,12 +7745,18 @@ 
     | 
|
| 
       7716 
7745 
     | 
    
         
             
               const EmacsyPendingKeys = "dthko";
         
     | 
| 
       7717 
7746 
     | 
    
         
             
               // Key codes for modifier keys
         
     | 
| 
       7718 
7747 
     | 
    
         
             
               const modifierCodes = [16, 17, 18, 20, 91, 92, 224, 225];
         
     | 
| 
      
 7748 
     | 
    
         
            +
               function dragScrollSpeed(dist) {
         
     | 
| 
      
 7749 
     | 
    
         
            +
                   return dist * 0.7 + 8;
         
     | 
| 
      
 7750 
     | 
    
         
            +
               }
         
     | 
| 
       7719 
7751 
     | 
    
         
             
               class MouseSelection {
         
     | 
| 
       7720 
7752 
     | 
    
         
             
                   constructor(view, startEvent, style, mustSelect) {
         
     | 
| 
       7721 
7753 
     | 
    
         
             
                       this.view = view;
         
     | 
| 
       7722 
7754 
     | 
    
         
             
                       this.style = style;
         
     | 
| 
       7723 
7755 
     | 
    
         
             
                       this.mustSelect = mustSelect;
         
     | 
| 
      
 7756 
     | 
    
         
            +
                       this.scrollSpeed = { x: 0, y: 0 };
         
     | 
| 
      
 7757 
     | 
    
         
            +
                       this.scrolling = -1;
         
     | 
| 
       7724 
7758 
     | 
    
         
             
                       this.lastEvent = startEvent;
         
     | 
| 
      
 7759 
     | 
    
         
            +
                       this.scrollParent = scrollableParent(view.contentDOM);
         
     | 
| 
       7725 
7760 
     | 
    
         
             
                       let doc = view.contentDOM.ownerDocument;
         
     | 
| 
       7726 
7761 
     | 
    
         
             
                       doc.addEventListener("mousemove", this.move = this.move.bind(this));
         
     | 
| 
       7727 
7762 
     | 
    
         
             
                       doc.addEventListener("mouseup", this.up = this.up.bind(this));
         
     | 
| 
         @@ -7737,11 +7772,24 @@ 
     | 
|
| 
       7737 
7772 
     | 
    
         
             
                       }
         
     | 
| 
       7738 
7773 
     | 
    
         
             
                   }
         
     | 
| 
       7739 
7774 
     | 
    
         
             
                   move(event) {
         
     | 
| 
      
 7775 
     | 
    
         
            +
                       var _a;
         
     | 
| 
       7740 
7776 
     | 
    
         
             
                       if (event.buttons == 0)
         
     | 
| 
       7741 
7777 
     | 
    
         
             
                           return this.destroy();
         
     | 
| 
       7742 
7778 
     | 
    
         
             
                       if (this.dragging !== false)
         
     | 
| 
       7743 
7779 
     | 
    
         
             
                           return;
         
     | 
| 
       7744 
7780 
     | 
    
         
             
                       this.select(this.lastEvent = event);
         
     | 
| 
      
 7781 
     | 
    
         
            +
                       let sx = 0, sy = 0;
         
     | 
| 
      
 7782 
     | 
    
         
            +
                       let rect = ((_a = this.scrollParent) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect())
         
     | 
| 
      
 7783 
     | 
    
         
            +
                           || { left: 0, top: 0, right: this.view.win.innerWidth, bottom: this.view.win.innerHeight };
         
     | 
| 
      
 7784 
     | 
    
         
            +
                       if (event.clientX <= rect.left)
         
     | 
| 
      
 7785 
     | 
    
         
            +
                           sx = -dragScrollSpeed(rect.left - event.clientX);
         
     | 
| 
      
 7786 
     | 
    
         
            +
                       else if (event.clientX >= rect.right)
         
     | 
| 
      
 7787 
     | 
    
         
            +
                           sx = dragScrollSpeed(event.clientX - rect.right);
         
     | 
| 
      
 7788 
     | 
    
         
            +
                       if (event.clientY <= rect.top)
         
     | 
| 
      
 7789 
     | 
    
         
            +
                           sy = -dragScrollSpeed(rect.top - event.clientY);
         
     | 
| 
      
 7790 
     | 
    
         
            +
                       else if (event.clientY >= rect.bottom)
         
     | 
| 
      
 7791 
     | 
    
         
            +
                           sy = dragScrollSpeed(event.clientY - rect.bottom);
         
     | 
| 
      
 7792 
     | 
    
         
            +
                       this.setScrollSpeed(sx, sy);
         
     | 
| 
       7745 
7793 
     | 
    
         
             
                   }
         
     | 
| 
       7746 
7794 
     | 
    
         
             
                   up(event) {
         
     | 
| 
       7747 
7795 
     | 
    
         
             
                       if (this.dragging == null)
         
     | 
| 
         @@ -7751,19 +7799,41 @@ 
     | 
|
| 
       7751 
7799 
     | 
    
         
             
                       this.destroy();
         
     | 
| 
       7752 
7800 
     | 
    
         
             
                   }
         
     | 
| 
       7753 
7801 
     | 
    
         
             
                   destroy() {
         
     | 
| 
      
 7802 
     | 
    
         
            +
                       this.setScrollSpeed(0, 0);
         
     | 
| 
       7754 
7803 
     | 
    
         
             
                       let doc = this.view.contentDOM.ownerDocument;
         
     | 
| 
       7755 
7804 
     | 
    
         
             
                       doc.removeEventListener("mousemove", this.move);
         
     | 
| 
       7756 
7805 
     | 
    
         
             
                       doc.removeEventListener("mouseup", this.up);
         
     | 
| 
       7757 
7806 
     | 
    
         
             
                       this.view.inputState.mouseSelection = null;
         
     | 
| 
       7758 
7807 
     | 
    
         
             
                   }
         
     | 
| 
      
 7808 
     | 
    
         
            +
                   setScrollSpeed(sx, sy) {
         
     | 
| 
      
 7809 
     | 
    
         
            +
                       this.scrollSpeed = { x: sx, y: sy };
         
     | 
| 
      
 7810 
     | 
    
         
            +
                       if (sx || sy) {
         
     | 
| 
      
 7811 
     | 
    
         
            +
                           if (this.scrolling < 0)
         
     | 
| 
      
 7812 
     | 
    
         
            +
                               this.scrolling = setInterval(() => this.scroll(), 50);
         
     | 
| 
      
 7813 
     | 
    
         
            +
                       }
         
     | 
| 
      
 7814 
     | 
    
         
            +
                       else if (this.scrolling > -1) {
         
     | 
| 
      
 7815 
     | 
    
         
            +
                           clearInterval(this.scrolling);
         
     | 
| 
      
 7816 
     | 
    
         
            +
                           this.scrolling = -1;
         
     | 
| 
      
 7817 
     | 
    
         
            +
                       }
         
     | 
| 
      
 7818 
     | 
    
         
            +
                   }
         
     | 
| 
      
 7819 
     | 
    
         
            +
                   scroll() {
         
     | 
| 
      
 7820 
     | 
    
         
            +
                       if (this.scrollParent) {
         
     | 
| 
      
 7821 
     | 
    
         
            +
                           this.scrollParent.scrollLeft += this.scrollSpeed.x;
         
     | 
| 
      
 7822 
     | 
    
         
            +
                           this.scrollParent.scrollTop += this.scrollSpeed.y;
         
     | 
| 
      
 7823 
     | 
    
         
            +
                       }
         
     | 
| 
      
 7824 
     | 
    
         
            +
                       else {
         
     | 
| 
      
 7825 
     | 
    
         
            +
                           this.view.win.scrollBy(this.scrollSpeed.x, this.scrollSpeed.y);
         
     | 
| 
      
 7826 
     | 
    
         
            +
                       }
         
     | 
| 
      
 7827 
     | 
    
         
            +
                       if (this.dragging === false)
         
     | 
| 
      
 7828 
     | 
    
         
            +
                           this.select(this.lastEvent);
         
     | 
| 
      
 7829 
     | 
    
         
            +
                   }
         
     | 
| 
       7759 
7830 
     | 
    
         
             
                   select(event) {
         
     | 
| 
       7760 
7831 
     | 
    
         
             
                       let selection = this.style.get(event, this.extend, this.multiple);
         
     | 
| 
       7761 
7832 
     | 
    
         
             
                       if (this.mustSelect || !selection.eq(this.view.state.selection) ||
         
     | 
| 
       7762 
7833 
     | 
    
         
             
                           selection.main.assoc != this.view.state.selection.main.assoc)
         
     | 
| 
       7763 
7834 
     | 
    
         
             
                           this.view.dispatch({
         
     | 
| 
       7764 
7835 
     | 
    
         
             
                               selection,
         
     | 
| 
       7765 
     | 
    
         
            -
                               userEvent: "select.pointer" 
     | 
| 
       7766 
     | 
    
         
            -
                               scrollIntoView: true
         
     | 
| 
      
 7836 
     | 
    
         
            +
                               userEvent: "select.pointer"
         
     | 
| 
       7767 
7837 
     | 
    
         
             
                           });
         
     | 
| 
       7768 
7838 
     | 
    
         
             
                       this.mustSelect = false;
         
     | 
| 
       7769 
7839 
     | 
    
         
             
                   }
         
     | 
| 
         @@ -7954,23 +8024,15 @@ 
     | 
|
| 
       7954 
8024 
     | 
    
         
             
               function basicMouseSelection(view, event) {
         
     | 
| 
       7955 
8025 
     | 
    
         
             
                   let start = queryPos(view, event), type = getClickType(event);
         
     | 
| 
       7956 
8026 
     | 
    
         
             
                   let startSel = view.state.selection;
         
     | 
| 
       7957 
     | 
    
         
            -
                   let last = start, lastEvent = event;
         
     | 
| 
       7958 
8027 
     | 
    
         
             
                   return {
         
     | 
| 
       7959 
8028 
     | 
    
         
             
                       update(update) {
         
     | 
| 
       7960 
8029 
     | 
    
         
             
                           if (update.docChanged) {
         
     | 
| 
       7961 
8030 
     | 
    
         
             
                               start.pos = update.changes.mapPos(start.pos);
         
     | 
| 
       7962 
8031 
     | 
    
         
             
                               startSel = startSel.map(update.changes);
         
     | 
| 
       7963 
     | 
    
         
            -
                               lastEvent = null;
         
     | 
| 
       7964 
8032 
     | 
    
         
             
                           }
         
     | 
| 
       7965 
8033 
     | 
    
         
             
                       },
         
     | 
| 
       7966 
8034 
     | 
    
         
             
                       get(event, extend, multiple) {
         
     | 
| 
       7967 
     | 
    
         
            -
                           let cur;
         
     | 
| 
       7968 
     | 
    
         
            -
                           if (lastEvent && event.clientX == lastEvent.clientX && event.clientY == lastEvent.clientY)
         
     | 
| 
       7969 
     | 
    
         
            -
                               cur = last;
         
     | 
| 
       7970 
     | 
    
         
            -
                           else {
         
     | 
| 
       7971 
     | 
    
         
            -
                               cur = last = queryPos(view, event);
         
     | 
| 
       7972 
     | 
    
         
            -
                               lastEvent = event;
         
     | 
| 
       7973 
     | 
    
         
            -
                           }
         
     | 
| 
      
 8035 
     | 
    
         
            +
                           let cur = queryPos(view, event);
         
     | 
| 
       7974 
8036 
     | 
    
         
             
                           let range = rangeForClick(view, cur.pos, cur.bias, type);
         
     | 
| 
       7975 
8037 
     | 
    
         
             
                           if (start.pos != cur.pos && !extend) {
         
     | 
| 
       7976 
8038 
     | 
    
         
             
                               let startRange = rangeForClick(view, start.pos, start.bias, type);
         
     | 
| 
         @@ -16967,7 +17029,7 @@ 
     | 
|
| 
       16967 
17029 
     | 
    
         
             
               */
         
     | 
| 
       16968 
17030 
     | 
    
         
             
               const defaultHighlightStyle = /*@__PURE__*/HighlightStyle.define([
         
     | 
| 
       16969 
17031 
     | 
    
         
             
                   { tag: tags.meta,
         
     | 
| 
       16970 
     | 
    
         
            -
                       color: "# 
     | 
| 
      
 17032 
     | 
    
         
            +
                       color: "#404740" },
         
     | 
| 
       16971 
17033 
     | 
    
         
             
                   { tag: tags.link,
         
     | 
| 
       16972 
17034 
     | 
    
         
             
                       textDecoration: "underline" },
         
     | 
| 
       16973 
17035 
     | 
    
         
             
                   { tag: tags.heading,
         
     | 
| 
         @@ -17898,7 +17960,7 @@ 
     | 
|
| 
       17898 
17960 
     | 
    
         
             
               function extendSel(view, how) {
         
     | 
| 
       17899 
17961 
     | 
    
         
             
                   let selection = updateSel(view.state.selection, range => {
         
     | 
| 
       17900 
17962 
     | 
    
         
             
                       let head = how(range);
         
     | 
| 
       17901 
     | 
    
         
            -
                       return EditorSelection.range(range.anchor, head.head, head.goalColumn);
         
     | 
| 
      
 17963 
     | 
    
         
            +
                       return EditorSelection.range(range.anchor, head.head, head.goalColumn, head.bidiLevel || undefined);
         
     | 
| 
       17902 
17964 
     | 
    
         
             
                   });
         
     | 
| 
       17903 
17965 
     | 
    
         
             
                   if (selection.eq(view.state.selection))
         
     | 
| 
       17904 
17966 
     | 
    
         
             
                       return false;
         
     | 
| 
         @@ -20091,6 +20153,7 @@ 
     | 
|
| 
       20091 
20153 
     | 
    
         
             
                           closeOnBlur: true,
         
     | 
| 
       20092 
20154 
     | 
    
         
             
                           maxRenderedOptions: 100,
         
     | 
| 
       20093 
20155 
     | 
    
         
             
                           defaultKeymap: true,
         
     | 
| 
      
 20156 
     | 
    
         
            +
                           tooltipClass: () => "",
         
     | 
| 
       20094 
20157 
     | 
    
         
             
                           optionClass: () => "",
         
     | 
| 
       20095 
20158 
     | 
    
         
             
                           aboveCursor: false,
         
     | 
| 
       20096 
20159 
     | 
    
         
             
                           icons: true,
         
     | 
| 
         @@ -20101,6 +20164,7 @@ 
     | 
|
| 
       20101 
20164 
     | 
    
         
             
                           defaultKeymap: (a, b) => a && b,
         
     | 
| 
       20102 
20165 
     | 
    
         
             
                           closeOnBlur: (a, b) => a && b,
         
     | 
| 
       20103 
20166 
     | 
    
         
             
                           icons: (a, b) => a && b,
         
     | 
| 
      
 20167 
     | 
    
         
            +
                           tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
         
     | 
| 
       20104 
20168 
     | 
    
         
             
                           optionClass: (a, b) => c => joinClass(a(c), b(c)),
         
     | 
| 
       20105 
20169 
     | 
    
         
             
                           addToOptions: (a, b) => a.concat(b)
         
     | 
| 
       20106 
20170 
     | 
    
         
             
                       });
         
     | 
| 
         @@ -20179,14 +20243,17 @@ 
     | 
|
| 
       20179 
20243 
     | 
    
         
             
                           key: this
         
     | 
| 
       20180 
20244 
     | 
    
         
             
                       };
         
     | 
| 
       20181 
20245 
     | 
    
         
             
                       this.space = null;
         
     | 
| 
      
 20246 
     | 
    
         
            +
                       this.currentClass = "";
         
     | 
| 
       20182 
20247 
     | 
    
         
             
                       let cState = view.state.field(stateField);
         
     | 
| 
       20183 
20248 
     | 
    
         
             
                       let { options, selected } = cState.open;
         
     | 
| 
       20184 
20249 
     | 
    
         
             
                       let config = view.state.facet(completionConfig);
         
     | 
| 
       20185 
20250 
     | 
    
         
             
                       this.optionContent = optionContent(config);
         
     | 
| 
       20186 
20251 
     | 
    
         
             
                       this.optionClass = config.optionClass;
         
     | 
| 
      
 20252 
     | 
    
         
            +
                       this.tooltipClass = config.tooltipClass;
         
     | 
| 
       20187 
20253 
     | 
    
         
             
                       this.range = rangeAroundSelected(options.length, selected, config.maxRenderedOptions);
         
     | 
| 
       20188 
20254 
     | 
    
         
             
                       this.dom = document.createElement("div");
         
     | 
| 
       20189 
20255 
     | 
    
         
             
                       this.dom.className = "cm-tooltip-autocomplete";
         
     | 
| 
      
 20256 
     | 
    
         
            +
                       this.updateTooltipClass(view.state);
         
     | 
| 
       20190 
20257 
     | 
    
         
             
                       this.dom.addEventListener("mousedown", (e) => {
         
     | 
| 
       20191 
20258 
     | 
    
         
             
                           for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
         
     | 
| 
       20192 
20259 
     | 
    
         
             
                               if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
         
     | 
| 
         @@ -20207,12 +20274,25 @@ 
     | 
|
| 
       20207 
20274 
     | 
    
         
             
                       var _a, _b, _c;
         
     | 
| 
       20208 
20275 
     | 
    
         
             
                       let cState = update.state.field(this.stateField);
         
     | 
| 
       20209 
20276 
     | 
    
         
             
                       let prevState = update.startState.field(this.stateField);
         
     | 
| 
      
 20277 
     | 
    
         
            +
                       this.updateTooltipClass(update.state);
         
     | 
| 
       20210 
20278 
     | 
    
         
             
                       if (cState != prevState) {
         
     | 
| 
       20211 
20279 
     | 
    
         
             
                           this.updateSel();
         
     | 
| 
       20212 
20280 
     | 
    
         
             
                           if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
         
     | 
| 
       20213 
20281 
     | 
    
         
             
                               this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
         
     | 
| 
       20214 
20282 
     | 
    
         
             
                       }
         
     | 
| 
       20215 
20283 
     | 
    
         
             
                   }
         
     | 
| 
      
 20284 
     | 
    
         
            +
                   updateTooltipClass(state) {
         
     | 
| 
      
 20285 
     | 
    
         
            +
                       let cls = this.tooltipClass(state);
         
     | 
| 
      
 20286 
     | 
    
         
            +
                       if (cls != this.currentClass) {
         
     | 
| 
      
 20287 
     | 
    
         
            +
                           for (let c of this.currentClass.split(" "))
         
     | 
| 
      
 20288 
     | 
    
         
            +
                               if (c)
         
     | 
| 
      
 20289 
     | 
    
         
            +
                                   this.dom.classList.remove(c);
         
     | 
| 
      
 20290 
     | 
    
         
            +
                           for (let c of cls.split(" "))
         
     | 
| 
      
 20291 
     | 
    
         
            +
                               if (c)
         
     | 
| 
      
 20292 
     | 
    
         
            +
                                   this.dom.classList.add(c);
         
     | 
| 
      
 20293 
     | 
    
         
            +
                           this.currentClass = cls;
         
     | 
| 
      
 20294 
     | 
    
         
            +
                       }
         
     | 
| 
      
 20295 
     | 
    
         
            +
                   }
         
     | 
| 
       20216 
20296 
     | 
    
         
             
                   positioned(space) {
         
     | 
| 
       20217 
20297 
     | 
    
         
             
                       this.space = space;
         
     | 
| 
       20218 
20298 
     | 
    
         
             
                       if (this.info)
         
     | 
| 
         @@ -20473,13 +20553,13 @@ 
     | 
|
| 
       20473 
20553 
     | 
    
         
             
                       if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
         
     | 
| 
       20474 
20554 
     | 
    
         
             
                           active = this.active;
         
     | 
| 
       20475 
20555 
     | 
    
         
             
                       let open = this.open;
         
     | 
| 
      
 20556 
     | 
    
         
            +
                       if (open && tr.docChanged)
         
     | 
| 
      
 20557 
     | 
    
         
            +
                           open = open.map(tr.changes);
         
     | 
| 
       20476 
20558 
     | 
    
         
             
                       if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
         
     | 
| 
       20477 
20559 
     | 
    
         
             
                           !sameResults(active, this.active))
         
     | 
| 
       20478 
     | 
    
         
            -
                           open = CompletionDialog.build(active, state, this.id,  
     | 
| 
      
 20560 
     | 
    
         
            +
                           open = CompletionDialog.build(active, state, this.id, open, conf);
         
     | 
| 
       20479 
20561 
     | 
    
         
             
                       else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
         
     | 
| 
       20480 
20562 
     | 
    
         
             
                           open = null;
         
     | 
| 
       20481 
     | 
    
         
            -
                       else if (open && tr.docChanged)
         
     | 
| 
       20482 
     | 
    
         
            -
                           open = open.map(tr.changes);
         
     | 
| 
       20483 
20563 
     | 
    
         
             
                       if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
         
     | 
| 
       20484 
20564 
     | 
    
         
             
                           active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
         
     | 
| 
       20485 
20565 
     | 
    
         
             
                       for (let effect of tr.effects)
         
     | 
| 
         @@ -24310,6 +24390,7 @@ 
     | 
|
| 
       24310 
24390 
     | 
    
         
             
               let drag = new Drag();
         
     | 
| 
       24311 
24391 
     | 
    
         | 
| 
       24312 
24392 
     | 
    
         
             
               document.addEventListener('mousedown', (event) => {
         
     | 
| 
      
 24393 
     | 
    
         
            +
                 if (event.button !== 0) return
         
     | 
| 
       24313 
24394 
     | 
    
         
             
                 if (!event.target.classList.contains('col-resizer')) return
         
     | 
| 
       24314 
24395 
     | 
    
         | 
| 
       24315 
24396 
     | 
    
         
             
                 drag = new Drag();
         
     | 
| 
         @@ -24366,10 +24447,11 @@ 
     | 
|
| 
       24366 
24447 
     | 
    
         
             
               });
         
     | 
| 
       24367 
24448 
     | 
    
         | 
| 
       24368 
24449 
     | 
    
         
             
               class ResizeTable extends HTMLTableElement {
         
     | 
| 
       24369 
     | 
    
         
            -
                 constructor (columns, rows, cellRenderer) {
         
     | 
| 
      
 24450 
     | 
    
         
            +
                 constructor (columns, rows, headerRenderer, cellRenderer) {
         
     | 
| 
       24370 
24451 
     | 
    
         
             
                   super();
         
     | 
| 
       24371 
24452 
     | 
    
         | 
| 
       24372 
24453 
     | 
    
         
             
                   this.columns = columns;
         
     | 
| 
      
 24454 
     | 
    
         
            +
                   this.headerRenderer = headerRenderer;
         
     | 
| 
       24373 
24455 
     | 
    
         
             
                   this.cellRenderer = cellRenderer;
         
     | 
| 
       24374 
24456 
     | 
    
         | 
| 
       24375 
24457 
     | 
    
         
             
                   this.style.tableLayout = 'auto';
         
     | 
| 
         @@ -24408,7 +24490,11 @@ 
     | 
|
| 
       24408 
24490 
     | 
    
         
             
                       resizerElement.dataset.colId = colElement.dataset.colId;
         
     | 
| 
       24409 
24491 
     | 
    
         
             
                       contentWrapperElement.appendChild(resizerElement);
         
     | 
| 
       24410 
24492 
     | 
    
         | 
| 
       24411 
     | 
    
         
            -
                        
     | 
| 
      
 24493 
     | 
    
         
            +
                       if (headerRenderer) {
         
     | 
| 
      
 24494 
     | 
    
         
            +
                         nameElement.appendChild(headerRenderer(headerElement, index, column));
         
     | 
| 
      
 24495 
     | 
    
         
            +
                       } else {
         
     | 
| 
      
 24496 
     | 
    
         
            +
                         nameElement.innerText = column;
         
     | 
| 
      
 24497 
     | 
    
         
            +
                       }
         
     | 
| 
       24412 
24498 
     | 
    
         
             
                     });
         
     | 
| 
       24413 
24499 
     | 
    
         | 
| 
       24414 
24500 
     | 
    
         
             
                     headerTrElement.appendChild(document.createElement('th'));
         
     | 
| 
         @@ -24475,21 +24561,21 @@ 
     | 
|
| 
       24475 
24561 
     | 
    
         
             
                   this.tbodyElement = tbodyElement;
         
     | 
| 
       24476 
24562 
     | 
    
         | 
| 
       24477 
24563 
     | 
    
         
             
                   let highlight = false;
         
     | 
| 
       24478 
     | 
    
         
            -
                   rows.forEach(function (row) {
         
     | 
| 
      
 24564 
     | 
    
         
            +
                   rows.forEach(function (row, rowIndex) {
         
     | 
| 
       24479 
24565 
     | 
    
         
             
                     const rowElement = document.createElement('tr');
         
     | 
| 
       24480 
24566 
     | 
    
         
             
                     if (highlight) {
         
     | 
| 
       24481 
24567 
     | 
    
         
             
                       rowElement.classList.add('highlighted-row');
         
     | 
| 
       24482 
24568 
     | 
    
         
             
                     }
         
     | 
| 
       24483 
24569 
     | 
    
         
             
                     highlight = !highlight;
         
     | 
| 
       24484 
24570 
     | 
    
         
             
                     tbodyElement.appendChild(rowElement);
         
     | 
| 
       24485 
     | 
    
         
            -
                     row.forEach(function (value,  
     | 
| 
      
 24571 
     | 
    
         
            +
                     row.forEach(function (value, columnIndex) {
         
     | 
| 
      
 24572 
     | 
    
         
            +
                       const cellElement = document.createElement('td');
         
     | 
| 
       24486 
24573 
     | 
    
         
             
                       if (cellRenderer) {
         
     | 
| 
       24487 
     | 
    
         
            -
                         cellRenderer( 
     | 
| 
      
 24574 
     | 
    
         
            +
                         cellElement.appendChild(cellRenderer(cellElement, rowIndex, columnIndex, value));
         
     | 
| 
       24488 
24575 
     | 
    
         
             
                       } else {
         
     | 
| 
       24489 
     | 
    
         
            -
                         const cellElement = document.createElement('td');
         
     | 
| 
       24490 
24576 
     | 
    
         
             
                         cellElement.innerText = value;
         
     | 
| 
       24491 
     | 
    
         
            -
                         rowElement.appendChild(cellElement);
         
     | 
| 
       24492 
24577 
     | 
    
         
             
                       }
         
     | 
| 
      
 24578 
     | 
    
         
            +
                       rowElement.appendChild(cellElement);
         
     | 
| 
       24493 
24579 
     | 
    
         
             
                     });
         
     | 
| 
       24494 
24580 
     | 
    
         
             
                     rowElement.appendChild(document.createElement('td'));
         
     | 
| 
       24495 
24581 
     | 
    
         
             
                   });
         
     | 
| 
         @@ -24502,6 +24588,96 @@ 
     | 
|
| 
       24502 
24588 
     | 
    
         | 
| 
       24503 
24589 
     | 
    
         
             
               customElements.define('resize-table', ResizeTable, { extends: 'table' });
         
     | 
| 
       24504 
24590 
     | 
    
         | 
| 
      
 24591 
     | 
    
         
            +
               function styleInject(css, ref) {
         
     | 
| 
      
 24592 
     | 
    
         
            +
                 if ( ref === void 0 ) ref = {};
         
     | 
| 
      
 24593 
     | 
    
         
            +
                 var insertAt = ref.insertAt;
         
     | 
| 
      
 24594 
     | 
    
         
            +
             
     | 
| 
      
 24595 
     | 
    
         
            +
                 if (!css || typeof document === 'undefined') { return; }
         
     | 
| 
      
 24596 
     | 
    
         
            +
             
     | 
| 
      
 24597 
     | 
    
         
            +
                 var head = document.head || document.getElementsByTagName('head')[0];
         
     | 
| 
      
 24598 
     | 
    
         
            +
                 var style = document.createElement('style');
         
     | 
| 
      
 24599 
     | 
    
         
            +
                 style.type = 'text/css';
         
     | 
| 
      
 24600 
     | 
    
         
            +
             
     | 
| 
      
 24601 
     | 
    
         
            +
                 if (insertAt === 'top') {
         
     | 
| 
      
 24602 
     | 
    
         
            +
                   if (head.firstChild) {
         
     | 
| 
      
 24603 
     | 
    
         
            +
                     head.insertBefore(style, head.firstChild);
         
     | 
| 
      
 24604 
     | 
    
         
            +
                   } else {
         
     | 
| 
      
 24605 
     | 
    
         
            +
                     head.appendChild(style);
         
     | 
| 
      
 24606 
     | 
    
         
            +
                   }
         
     | 
| 
      
 24607 
     | 
    
         
            +
                 } else {
         
     | 
| 
      
 24608 
     | 
    
         
            +
                   head.appendChild(style);
         
     | 
| 
      
 24609 
     | 
    
         
            +
                 }
         
     | 
| 
      
 24610 
     | 
    
         
            +
             
     | 
| 
      
 24611 
     | 
    
         
            +
                 if (style.styleSheet) {
         
     | 
| 
      
 24612 
     | 
    
         
            +
                   style.styleSheet.cssText = css;
         
     | 
| 
      
 24613 
     | 
    
         
            +
                 } else {
         
     | 
| 
      
 24614 
     | 
    
         
            +
                   style.appendChild(document.createTextNode(css));
         
     | 
| 
      
 24615 
     | 
    
         
            +
                 }
         
     | 
| 
      
 24616 
     | 
    
         
            +
               }
         
     | 
| 
      
 24617 
     | 
    
         
            +
             
     | 
| 
      
 24618 
     | 
    
         
            +
               var css_248z = ".popup_popup-wrapper__huCTg {\n    position: absolute;\n    background: rgba(0, 0, 0, 0.3);\n    width: 100%;\n    height: 100%;\n    top: 0;\n    left: 0;\n    z-index: 2;\n}\n\n.popup_popup-content__iGYws {\n    position: absolute;\n    top: 50px;\n    left: 50px;\n    height: calc(100% - 100px);\n    width: calc(100% - 100px);\n    background: #fff;\n    border: 1px solid #888;\n}\n\n.popup_popup-pre__gF3-Q {\n    position: absolute;\n    top: 40px;\n    left: 0;\n    height: calc(100% - 112px);\n    width: calc(100% - 20px);\n    overflow: auto;\n    font-size: 18px;\n    border-top: 1px solid #ddd;\n    border-bottom: 1px solid #ddd;\n    margin: 0px;\n    padding: 10px;\n    background: #fff;\n    font-family: monospace;\n}\n\n.popup_popup-pre__gF3-Q:focus {\n    outline: none;\n}\n.popup_popup-close__3GBw3 {\n    position: absolute;\n    right: 20px;\n    bottom: 10px;\n    width: 100px;\n    height: 30px;\n    cursor: pointer;\n    font-family: Helvetica, sans-serif;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 18px;\n    color: #333;\n    border: 1px solid #888;\n    background: #fff;\n}\n\n.popup_popup-close__3GBw3:active {\n    background-color: #e6e6e6;\n}\n\n.popup_popup-title__W2N2J {\n    position: absolute;\n    left: 60px;\n    top: 60px;\n    font-family: Helvetica, sans-serif;\n    font-size: 18px;\n    color: #333;\n    font-weight: bold;\n    white-space: nowrap;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    width: calc(100% - 120px);\n}\n";
         
     | 
| 
      
 24619 
     | 
    
         
            +
               var styles = {"popup-wrapper":"popup_popup-wrapper__huCTg","popup-content":"popup_popup-content__iGYws","popup-pre":"popup_popup-pre__gF3-Q","popup-close":"popup_popup-close__3GBw3","popup-title":"popup_popup-title__W2N2J"};
         
     | 
| 
      
 24620 
     | 
    
         
            +
               styleInject(css_248z);
         
     | 
| 
      
 24621 
     | 
    
         
            +
             
     | 
| 
      
 24622 
     | 
    
         
            +
               function createPopup (title, text) {
         
     | 
| 
      
 24623 
     | 
    
         
            +
                 const wrapperElement = document.createElement('div');
         
     | 
| 
      
 24624 
     | 
    
         
            +
                 wrapperElement.id = 'popup';
         
     | 
| 
      
 24625 
     | 
    
         
            +
                 wrapperElement.classList.add(styles['popup-wrapper']);
         
     | 
| 
      
 24626 
     | 
    
         
            +
                 document.body.appendChild(wrapperElement);
         
     | 
| 
      
 24627 
     | 
    
         
            +
             
     | 
| 
      
 24628 
     | 
    
         
            +
                 const contentElement = document.createElement('div');
         
     | 
| 
      
 24629 
     | 
    
         
            +
                 contentElement.classList.add(styles['popup-content']);
         
     | 
| 
      
 24630 
     | 
    
         
            +
                 wrapperElement.appendChild(contentElement);
         
     | 
| 
      
 24631 
     | 
    
         
            +
             
     | 
| 
      
 24632 
     | 
    
         
            +
                 const closeElement = document.createElement('input');
         
     | 
| 
      
 24633 
     | 
    
         
            +
                 closeElement.id = 'popup-close';
         
     | 
| 
      
 24634 
     | 
    
         
            +
                 closeElement.classList.add(styles['popup-close']);
         
     | 
| 
      
 24635 
     | 
    
         
            +
                 closeElement.type = 'button';
         
     | 
| 
      
 24636 
     | 
    
         
            +
                 closeElement.value = 'Close';
         
     | 
| 
      
 24637 
     | 
    
         
            +
                 contentElement.appendChild(closeElement);
         
     | 
| 
      
 24638 
     | 
    
         
            +
             
     | 
| 
      
 24639 
     | 
    
         
            +
                 closeElement.addEventListener('click', (event) => {
         
     | 
| 
      
 24640 
     | 
    
         
            +
                   document.body.removeChild(wrapperElement);
         
     | 
| 
      
 24641 
     | 
    
         
            +
                 });
         
     | 
| 
      
 24642 
     | 
    
         
            +
             
     | 
| 
      
 24643 
     | 
    
         
            +
                 const titleElement = document.createElement('div');
         
     | 
| 
      
 24644 
     | 
    
         
            +
                 titleElement.classList.add(styles['popup-title']);
         
     | 
| 
      
 24645 
     | 
    
         
            +
                 titleElement.innerText = title;
         
     | 
| 
      
 24646 
     | 
    
         
            +
                 wrapperElement.appendChild(titleElement);
         
     | 
| 
      
 24647 
     | 
    
         
            +
             
     | 
| 
      
 24648 
     | 
    
         
            +
                 const preElement = document.createElement('pre');
         
     | 
| 
      
 24649 
     | 
    
         
            +
                 preElement.id = 'popup-pre';
         
     | 
| 
      
 24650 
     | 
    
         
            +
                 preElement.classList.add(styles['popup-pre']);
         
     | 
| 
      
 24651 
     | 
    
         
            +
                 contentElement.appendChild(preElement);
         
     | 
| 
      
 24652 
     | 
    
         
            +
                 preElement.innerText = text;
         
     | 
| 
      
 24653 
     | 
    
         
            +
             
     | 
| 
      
 24654 
     | 
    
         
            +
                 wrapperElement.addEventListener('click', () => {
         
     | 
| 
      
 24655 
     | 
    
         
            +
                   document.body.removeChild(wrapperElement);
         
     | 
| 
      
 24656 
     | 
    
         
            +
                 });
         
     | 
| 
      
 24657 
     | 
    
         
            +
             
     | 
| 
      
 24658 
     | 
    
         
            +
                 contentElement.addEventListener('click', (event) => {
         
     | 
| 
      
 24659 
     | 
    
         
            +
                   event.stopPropagation();
         
     | 
| 
      
 24660 
     | 
    
         
            +
                 });
         
     | 
| 
      
 24661 
     | 
    
         
            +
             
     | 
| 
      
 24662 
     | 
    
         
            +
                 closeElement.focus();
         
     | 
| 
      
 24663 
     | 
    
         
            +
               }
         
     | 
| 
      
 24664 
     | 
    
         
            +
             
     | 
| 
      
 24665 
     | 
    
         
            +
               document.addEventListener('keydown', (event) => {
         
     | 
| 
      
 24666 
     | 
    
         
            +
                 if (event.code === 'Escape') {
         
     | 
| 
      
 24667 
     | 
    
         
            +
                   const wrapperElement = document.getElementById('popup');
         
     | 
| 
      
 24668 
     | 
    
         
            +
                   if (wrapperElement) {
         
     | 
| 
      
 24669 
     | 
    
         
            +
                     event.preventDefault();
         
     | 
| 
      
 24670 
     | 
    
         
            +
                     document.body.removeChild(wrapperElement);
         
     | 
| 
      
 24671 
     | 
    
         
            +
                   }
         
     | 
| 
      
 24672 
     | 
    
         
            +
                 } else if (event.code === 'Tab') {
         
     | 
| 
      
 24673 
     | 
    
         
            +
                   const wrapperElement = document.getElementById('popup');
         
     | 
| 
      
 24674 
     | 
    
         
            +
                   if (wrapperElement) {
         
     | 
| 
      
 24675 
     | 
    
         
            +
                     event.preventDefault();
         
     | 
| 
      
 24676 
     | 
    
         
            +
                     document.getElementById('popup-close').focus();
         
     | 
| 
      
 24677 
     | 
    
         
            +
                   }
         
     | 
| 
      
 24678 
     | 
    
         
            +
                 }
         
     | 
| 
      
 24679 
     | 
    
         
            +
               });
         
     | 
| 
      
 24680 
     | 
    
         
            +
             
     | 
| 
       24505 
24681 
     | 
    
         
             
               /* global google */
         
     | 
| 
       24506 
24682 
     | 
    
         | 
| 
       24507 
24683 
     | 
    
         
             
               const PAGE_SIZE = 100;
         
     | 
| 
         @@ -24630,6 +24806,7 @@ 
     | 
|
| 
       24630 
24806 
     | 
    
         
             
                     dropdownContent.classList.remove('submit-dropdown-content-show');
         
     | 
| 
       24631 
24807 
     | 
    
         
             
                   }
         
     | 
| 
       24632 
24808 
     | 
    
         
             
                 });
         
     | 
| 
      
 24809 
     | 
    
         
            +
             
     | 
| 
       24633 
24810 
     | 
    
         
             
                 window.editorView = createEditor(parent, window.metadata, onSubmit, onShiftSubmit);
         
     | 
| 
       24634 
24811 
     | 
    
         
             
               }
         
     | 
| 
       24635 
24812 
     | 
    
         | 
| 
         @@ -24857,13 +25034,11 @@ 
     | 
|
| 
       24857 
25034 
     | 
    
         
             
                       }
         
     | 
| 
       24858 
25035 
     | 
    
         
             
                       rows.push(row);
         
     | 
| 
       24859 
25036 
     | 
    
         
             
                     }
         
     | 
| 
       24860 
     | 
    
         
            -
                     const cellRenderer = function ( 
     | 
| 
       24861 
     | 
    
         
            -
                       const cellElement = document.createElement('td');
         
     | 
| 
      
 25037 
     | 
    
         
            +
                     const cellRenderer = function (cellElement, _rowIndex, _columnIndex, value) {
         
     | 
| 
       24862 
25038 
     | 
    
         
             
                       cellElement.style.textAlign = (typeof value) === 'string' ? 'left' : 'right';
         
     | 
| 
       24863 
     | 
    
         
            -
                        
     | 
| 
       24864 
     | 
    
         
            -
                       rowElement.appendChild(cellElement);
         
     | 
| 
      
 25039 
     | 
    
         
            +
                       return document.createTextNode(value)
         
     | 
| 
       24865 
25040 
     | 
    
         
             
                     };
         
     | 
| 
       24866 
     | 
    
         
            -
                     columnsElement.appendChild(new ResizeTable(columns, rows, cellRenderer));
         
     | 
| 
      
 25041 
     | 
    
         
            +
                     columnsElement.appendChild(new ResizeTable(columns, rows, null, cellRenderer));
         
     | 
| 
       24867 
25042 
     | 
    
         
             
                   }
         
     | 
| 
       24868 
25043 
     | 
    
         | 
| 
       24869 
25044 
     | 
    
         
             
                   const indexEntries = Object.entries(table.indexes);
         
     | 
| 
         @@ -24883,13 +25058,11 @@ 
     | 
|
| 
       24883 
25058 
     | 
    
         
             
                         rows.push(row);
         
     | 
| 
       24884 
25059 
     | 
    
         
             
                       }
         
     | 
| 
       24885 
25060 
     | 
    
         
             
                     }
         
     | 
| 
       24886 
     | 
    
         
            -
                     const cellRenderer = function ( 
     | 
| 
       24887 
     | 
    
         
            -
                       const cellElement = document.createElement('td');
         
     | 
| 
      
 25061 
     | 
    
         
            +
                     const cellRenderer = function (cellElement, _rowIndex, _columnIndex, value) {
         
     | 
| 
       24888 
25062 
     | 
    
         
             
                       cellElement.style.textAlign = (typeof value) === 'string' ? 'left' : 'right';
         
     | 
| 
       24889 
     | 
    
         
            -
                        
     | 
| 
       24890 
     | 
    
         
            -
                       rowElement.appendChild(cellElement);
         
     | 
| 
      
 25063 
     | 
    
         
            +
                       return document.createTextNode(value)
         
     | 
| 
       24891 
25064 
     | 
    
         
             
                     };
         
     | 
| 
       24892 
     | 
    
         
            -
                     indexesElement.appendChild(new ResizeTable(columns, rows, cellRenderer));
         
     | 
| 
      
 25065 
     | 
    
         
            +
                     indexesElement.appendChild(new ResizeTable(columns, rows, null, cellRenderer));
         
     | 
| 
       24893 
25066 
     | 
    
         
             
                   }
         
     | 
| 
       24894 
25067 
     | 
    
         
             
                 });
         
     | 
| 
       24895 
25068 
     | 
    
         
             
                 window.structureLoaded = true;
         
     | 
| 
         @@ -25130,6 +25303,9 @@ 
     | 
|
| 
       25130 
25303 
     | 
    
         
             
                           }
         
     | 
| 
       25131 
25304 
     | 
    
         
             
                         }
         
     | 
| 
       25132 
25305 
     | 
    
         
             
                         displaySqlFetch(sqlFetch);
         
     | 
| 
      
 25306 
     | 
    
         
            +
                       }).catch(function (error) {
         
     | 
| 
      
 25307 
     | 
    
         
            +
                         setSqlFetchError(sqlFetch, error);
         
     | 
| 
      
 25308 
     | 
    
         
            +
                         displaySqlFetch(sqlFetch);
         
     | 
| 
       25133 
25309 
     | 
    
         
             
                       });
         
     | 
| 
       25134 
25310 
     | 
    
         
             
                     } else {
         
     | 
| 
       25135 
25311 
     | 
    
         
             
                       response.text().then((result) => {
         
     | 
| 
         @@ -25137,20 +25313,28 @@ 
     | 
|
| 
       25137 
25313 
     | 
    
         
             
                         sqlFetch.errorMessage = 'failed to execute query';
         
     | 
| 
       25138 
25314 
     | 
    
         
             
                         sqlFetch.errorDetails = result;
         
     | 
| 
       25139 
25315 
     | 
    
         
             
                         displaySqlFetch(sqlFetch);
         
     | 
| 
      
 25316 
     | 
    
         
            +
                       }).catch(function (error) {
         
     | 
| 
      
 25317 
     | 
    
         
            +
                         setSqlFetchError(sqlFetch, error);
         
     | 
| 
      
 25318 
     | 
    
         
            +
                         displaySqlFetch(sqlFetch);
         
     | 
| 
       25140 
25319 
     | 
    
         
             
                       });
         
     | 
| 
       25141 
25320 
     | 
    
         
             
                     }
         
     | 
| 
       25142 
25321 
     | 
    
         
             
                   })
         
     | 
| 
       25143 
25322 
     | 
    
         
             
                   .catch(function (error) {
         
     | 
| 
       25144 
     | 
    
         
            -
                      
     | 
| 
       25145 
     | 
    
         
            -
                       sqlFetch.endedAt = window.performance.now();
         
     | 
| 
       25146 
     | 
    
         
            -
                       sqlFetch.state = 'error';
         
     | 
| 
       25147 
     | 
    
         
            -
                       sqlFetch.errorMessage = 'failed to execute query';
         
     | 
| 
       25148 
     | 
    
         
            -
                       sqlFetch.errorDetails = error;
         
     | 
| 
       25149 
     | 
    
         
            -
                     }
         
     | 
| 
      
 25323 
     | 
    
         
            +
                     setSqlFetchError(sqlFetch, error);
         
     | 
| 
       25150 
25324 
     | 
    
         
             
                     displaySqlFetch(sqlFetch);
         
     | 
| 
       25151 
25325 
     | 
    
         
             
                   });
         
     | 
| 
       25152 
25326 
     | 
    
         
             
               }
         
     | 
| 
       25153 
25327 
     | 
    
         | 
| 
      
 25328 
     | 
    
         
            +
               function setSqlFetchError (sqlFetch, error) {
         
     | 
| 
      
 25329 
     | 
    
         
            +
                 // Ignore the error unless pending since the error may be the result of aborting.
         
     | 
| 
      
 25330 
     | 
    
         
            +
                 if (sqlFetch.state === 'pending') {
         
     | 
| 
      
 25331 
     | 
    
         
            +
                   sqlFetch.endedAt = window.performance.now();
         
     | 
| 
      
 25332 
     | 
    
         
            +
                   sqlFetch.state = 'error';
         
     | 
| 
      
 25333 
     | 
    
         
            +
                   sqlFetch.errorMessage = 'failed to execute query';
         
     | 
| 
      
 25334 
     | 
    
         
            +
                   sqlFetch.errorDetails = error;
         
     | 
| 
      
 25335 
     | 
    
         
            +
                 }
         
     | 
| 
      
 25336 
     | 
    
         
            +
               }
         
     | 
| 
      
 25337 
     | 
    
         
            +
             
     | 
| 
       25154 
25338 
     | 
    
         
             
               function parseSqlVariables (params) {
         
     | 
| 
       25155 
25339 
     | 
    
         
             
                 return Object.fromEntries(
         
     | 
| 
       25156 
25340 
     | 
    
         
             
                   Array.from(params).filter(([key]) => {
         
     | 
| 
         @@ -25272,10 +25456,17 @@ 
     | 
|
| 
       25272 
25456 
     | 
    
         
             
                 return abbrElement
         
     | 
| 
       25273 
25457 
     | 
    
         
             
               };
         
     | 
| 
       25274 
25458 
     | 
    
         | 
| 
       25275 
     | 
    
         
            -
               const resultCellRenderer = function ( 
     | 
| 
      
 25459 
     | 
    
         
            +
               const resultCellRenderer = function (cellElement, rowIndex, columnIndex, value) {
         
     | 
| 
       25276 
25460 
     | 
    
         
             
                 const column = window.sqlFetch.result.columns[columnIndex];
         
     | 
| 
       25277 
25461 
     | 
    
         
             
                 const columnType = window.sqlFetch.result.column_types[columnIndex];
         
     | 
| 
       25278 
25462 
     | 
    
         | 
| 
      
 25463 
     | 
    
         
            +
                 cellElement.dataset.column = columnIndex.toString();
         
     | 
| 
      
 25464 
     | 
    
         
            +
                 cellElement.dataset.row = rowIndex.toString();
         
     | 
| 
      
 25465 
     | 
    
         
            +
             
     | 
| 
      
 25466 
     | 
    
         
            +
                 if (typeof value === 'string' && value.indexOf('\n') >= 0) {
         
     | 
| 
      
 25467 
     | 
    
         
            +
                   value = value.replaceAll('\n', '¶');
         
     | 
| 
      
 25468 
     | 
    
         
            +
                 }
         
     | 
| 
      
 25469 
     | 
    
         
            +
             
     | 
| 
       25279 
25470 
     | 
    
         
             
                 if (value && window.metadata.columns[column]?.links?.length > 0) {
         
     | 
| 
       25280 
25471 
     | 
    
         
             
                   const linksElement = document.createElement('div');
         
     | 
| 
       25281 
25472 
     | 
    
         
             
                   window.metadata.columns[column].links.forEach((link) => {
         
     | 
| 
         @@ -25292,17 +25483,22 @@ 
     | 
|
| 
       25292 
25483 
     | 
    
         
             
                   wrapperElement.appendChild(linksElement);
         
     | 
| 
       25293 
25484 
     | 
    
         
             
                   wrapperElement.appendChild(textElement);
         
     | 
| 
       25294 
25485 
     | 
    
         | 
| 
       25295 
     | 
    
         
            -
                    
     | 
| 
       25296 
     | 
    
         
            -
                   columnElement.appendChild(wrapperElement);
         
     | 
| 
       25297 
     | 
    
         
            -
                   rowElement.appendChild(columnElement);
         
     | 
| 
      
 25486 
     | 
    
         
            +
                   return wrapperElement
         
     | 
| 
       25298 
25487 
     | 
    
         
             
                 } else {
         
     | 
| 
       25299 
     | 
    
         
            -
                   const cellElement = document.createElement('td');
         
     | 
| 
       25300 
25488 
     | 
    
         
             
                   cellElement.style.textAlign = columnType === 'string' ? 'left' : 'right';
         
     | 
| 
       25301 
     | 
    
         
            -
                    
     | 
| 
       25302 
     | 
    
         
            -
                   rowElement.appendChild(cellElement);
         
     | 
| 
      
 25489 
     | 
    
         
            +
                   return document.createTextNode(value)
         
     | 
| 
       25303 
25490 
     | 
    
         
             
                 }
         
     | 
| 
       25304 
25491 
     | 
    
         
             
               };
         
     | 
| 
       25305 
25492 
     | 
    
         | 
| 
      
 25493 
     | 
    
         
            +
               function resultHeaderRenderer (headerElement, columnIndex, value) {
         
     | 
| 
      
 25494 
     | 
    
         
            +
                 headerElement.dataset.column = columnIndex.toString();
         
     | 
| 
      
 25495 
     | 
    
         
            +
             
     | 
| 
      
 25496 
     | 
    
         
            +
                 if (typeof value === 'string' && value.indexOf('\n') >= 0) {
         
     | 
| 
      
 25497 
     | 
    
         
            +
                   value = value.replaceAll('\n', '¶');
         
     | 
| 
      
 25498 
     | 
    
         
            +
                 }
         
     | 
| 
      
 25499 
     | 
    
         
            +
                 return document.createTextNode(value)
         
     | 
| 
      
 25500 
     | 
    
         
            +
               }
         
     | 
| 
      
 25501 
     | 
    
         
            +
             
     | 
| 
       25306 
25502 
     | 
    
         
             
               function displaySqlFetchInResultTab (fetch) {
         
     | 
| 
       25307 
25503 
     | 
    
         
             
                 if (fetch.state === 'pending' || fetch.spinner === 'always') {
         
     | 
| 
       25308 
25504 
     | 
    
         
             
                   clearResultBox();
         
     | 
| 
         @@ -25352,13 +25548,45 @@ 
     | 
|
| 
       25352 
25548 
     | 
    
         
             
                 } else {
         
     | 
| 
       25353 
25549 
     | 
    
         
             
                   clearResultBox();
         
     | 
| 
       25354 
25550 
     | 
    
         
             
                   const resultBoxElement = document.getElementById('result-box');
         
     | 
| 
       25355 
     | 
    
         
            -
                   tableElement = new ResizeTable(fetch.result.columns, rows, resultCellRenderer);
         
     | 
| 
      
 25551 
     | 
    
         
            +
                   tableElement = new ResizeTable(fetch.result.columns, rows, resultHeaderRenderer, resultCellRenderer);
         
     | 
| 
       25356 
25552 
     | 
    
         
             
                   tableElement.id = 'result-table';
         
     | 
| 
      
 25553 
     | 
    
         
            +
                   registerTableCellPopup(tableElement);
         
     | 
| 
       25357 
25554 
     | 
    
         
             
                   resultBoxElement.appendChild(tableElement);
         
     | 
| 
       25358 
25555 
     | 
    
         
             
                 }
         
     | 
| 
       25359 
25556 
     | 
    
         
             
                 tableElement.setAttribute('data-page', fetch.page);
         
     | 
| 
       25360 
25557 
     | 
    
         
             
               }
         
     | 
| 
       25361 
25558 
     | 
    
         | 
| 
      
 25559 
     | 
    
         
            +
               function registerTableCellPopup (tableElement) {
         
     | 
| 
      
 25560 
     | 
    
         
            +
                 const listener = (event) => {
         
     | 
| 
      
 25561 
     | 
    
         
            +
                   if (event.which === 1 && event.detail === 2) {
         
     | 
| 
      
 25562 
     | 
    
         
            +
                     let node = event.target;
         
     | 
| 
      
 25563 
     | 
    
         
            +
                     while (!['td', 'th', 'table'].includes(node.tagName.toLowerCase()) && node.parentNode) {
         
     | 
| 
      
 25564 
     | 
    
         
            +
                       node = node.parentNode;
         
     | 
| 
      
 25565 
     | 
    
         
            +
                     }
         
     | 
| 
      
 25566 
     | 
    
         
            +
                     if (node.tagName.toLowerCase() === 'td') {
         
     | 
| 
      
 25567 
     | 
    
         
            +
                       if (event.type === 'mousedown') {
         
     | 
| 
      
 25568 
     | 
    
         
            +
                         const row = parseInt(node.dataset.row);
         
     | 
| 
      
 25569 
     | 
    
         
            +
                         const column = parseInt(node.dataset.column);
         
     | 
| 
      
 25570 
     | 
    
         
            +
                         const title = window.sqlFetch.result.columns[column].replaceAll('\n', '¶');
         
     | 
| 
      
 25571 
     | 
    
         
            +
                         createPopup(title, window.sqlFetch.result.rows[row][column]);
         
     | 
| 
      
 25572 
     | 
    
         
            +
                       }
         
     | 
| 
      
 25573 
     | 
    
         
            +
                       event.preventDefault();
         
     | 
| 
      
 25574 
     | 
    
         
            +
                     } else if (node.tagName.toLowerCase() === 'th') {
         
     | 
| 
      
 25575 
     | 
    
         
            +
                       if (event.type === 'mousedown') {
         
     | 
| 
      
 25576 
     | 
    
         
            +
                         const column = parseInt(node.dataset.column);
         
     | 
| 
      
 25577 
     | 
    
         
            +
                         const value = window.sqlFetch.result.columns[column];
         
     | 
| 
      
 25578 
     | 
    
         
            +
                         const title = value.replaceAll('\n', '¶');
         
     | 
| 
      
 25579 
     | 
    
         
            +
                         createPopup(title, value);
         
     | 
| 
      
 25580 
     | 
    
         
            +
                       }
         
     | 
| 
      
 25581 
     | 
    
         
            +
                       event.preventDefault();
         
     | 
| 
      
 25582 
     | 
    
         
            +
                     }
         
     | 
| 
      
 25583 
     | 
    
         
            +
                   }
         
     | 
| 
      
 25584 
     | 
    
         
            +
                 };
         
     | 
| 
      
 25585 
     | 
    
         
            +
                 // We only open the popup on mouseup but we need to preventDefault on mousedown to avoid the clicked text from
         
     | 
| 
      
 25586 
     | 
    
         
            +
                 // being highlighted.
         
     | 
| 
      
 25587 
     | 
    
         
            +
                 addEventListener(tableElement, 'mouseup', listener);
         
     | 
| 
      
 25588 
     | 
    
         
            +
                 addEventListener(tableElement, 'mousedown', listener);
         
     | 
| 
      
 25589 
     | 
    
         
            +
               }
         
     | 
| 
       25362 
25590 
     | 
    
         
             
               function disableDownloadButtons () {
         
     | 
| 
       25363 
25591 
     | 
    
         
             
                 document.getElementById('submit-dropdown-button-download-csv').classList.add('disabled');
         
     | 
| 
       25364 
25592 
     | 
    
         
             
                 document.getElementById('submit-dropdown-button-copy-csv').classList.add('disabled');
         
     | 
| 
         @@ -25389,15 +25617,10 @@ 
     | 
|
| 
       25389 
25617 
     | 
    
         
             
               }
         
     | 
| 
       25390 
25618 
     | 
    
         | 
| 
       25391 
25619 
     | 
    
         
             
               function displaySqlFetchError (message, details) {
         
     | 
| 
       25392 
     | 
    
         
            -
                 let statusMessage = 'error: ' + message;
         
     | 
| 
       25393 
     | 
    
         
            -
                 if (statusMessage.length > 90) {
         
     | 
| 
       25394 
     | 
    
         
            -
                   statusMessage = statusMessage.substring(0, 90) + '…';
         
     | 
| 
       25395 
     | 
    
         
            -
                 }
         
     | 
| 
       25396 
25620 
     | 
    
         
             
                 if (details) {
         
     | 
| 
       25397 
     | 
    
         
            -
                   console.log( 
     | 
| 
       25398 
     | 
    
         
            -
                   statusMessage += ' (check console)';
         
     | 
| 
      
 25621 
     | 
    
         
            +
                   console.log(details);
         
     | 
| 
       25399 
25622 
     | 
    
         
             
                 }
         
     | 
| 
       25400 
     | 
    
         
            -
                 setStatus( 
     | 
| 
      
 25623 
     | 
    
         
            +
                 setStatus(message);
         
     | 
| 
       25401 
25624 
     | 
    
         
             
               }
         
     | 
| 
       25402 
25625 
     | 
    
         | 
| 
       25403 
25626 
     | 
    
         
             
               function clearSpinner () {
         
     | 
| 
         @@ -25505,14 +25728,14 @@ 
     | 
|
| 
       25505 
25728 
     | 
    
         
             
                 const elapsed = Math.round(100 * (sqlFetch.getDuration() / 1000.0)) / 100;
         
     | 
| 
       25506 
25729 
     | 
    
         | 
| 
       25507 
25730 
     | 
    
         
             
                 let message;
         
     | 
| 
       25508 
     | 
    
         
            -
                 if (result. 
     | 
| 
       25509 
     | 
    
         
            -
                   message =  
     | 
| 
      
 25731 
     | 
    
         
            +
                 if (result.rows.length === 1) {
         
     | 
| 
      
 25732 
     | 
    
         
            +
                   message = `1 row returned after ${elapsed}s`;
         
     | 
| 
       25510 
25733 
     | 
    
         
             
                 } else {
         
     | 
| 
       25511 
     | 
    
         
            -
                   message = `${result. 
     | 
| 
      
 25734 
     | 
    
         
            +
                   message = `${result.rows.length.toLocaleString()} rows returned after ${elapsed}s`;
         
     | 
| 
       25512 
25735 
     | 
    
         
             
                 }
         
     | 
| 
       25513 
25736 
     | 
    
         | 
| 
       25514 
25737 
     | 
    
         
             
                 if (result.total_rows > result.rows.length) {
         
     | 
| 
       25515 
     | 
    
         
            -
                   message += ` (truncated  
     | 
| 
      
 25738 
     | 
    
         
            +
                   message += ` (truncated from ${result.total_rows.toLocaleString()})`;
         
     | 
| 
       25516 
25739 
     | 
    
         
             
                 }
         
     | 
| 
       25517 
25740 
     | 
    
         
             
                 setStatus(message);
         
     | 
| 
       25518 
25741 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: sqlui
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.60
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Nick Dower
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date:  
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-01-03 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: airbrake
         
     |