streamlit-nightly 1.53.2.dev20260203__py3-none-any.whl → 1.54.1.dev20260204__py3-none-any.whl

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.
Files changed (127) hide show
  1. streamlit/elements/arrow.py +66 -26
  2. streamlit/elements/lib/built_in_chart_utils.py +1 -1
  3. streamlit/elements/lib/column_config_utils.py +4 -4
  4. streamlit/elements/lib/options_selector_utils.py +4 -0
  5. streamlit/elements/lib/pandas_styler_utils.py +22 -22
  6. streamlit/elements/widgets/button_group.py +221 -86
  7. streamlit/elements/widgets/data_editor.py +9 -9
  8. streamlit/elements/widgets/radio.py +8 -4
  9. streamlit/hello/dataframe_demo.py +1 -1
  10. streamlit/proto/ArrowData_pb2.py +5 -3
  11. streamlit/proto/ArrowData_pb2.pyi +44 -4
  12. streamlit/proto/ArrowNamedDataSet_pb2.py +4 -4
  13. streamlit/proto/ArrowNamedDataSet_pb2.pyi +3 -3
  14. streamlit/proto/ArrowVegaLiteChart_pb2.py +4 -4
  15. streamlit/proto/ArrowVegaLiteChart_pb2.pyi +3 -3
  16. streamlit/proto/ButtonGroup_pb2.py +8 -8
  17. streamlit/proto/ButtonGroup_pb2.pyi +9 -7
  18. streamlit/proto/Dataframe_pb2.py +31 -0
  19. streamlit/proto/{Arrow_pb2.pyi → Dataframe_pb2.pyi} +39 -102
  20. streamlit/proto/Element_pb2.py +5 -4
  21. streamlit/proto/Element_pb2.pyi +11 -10
  22. streamlit/proto/Table_pb2.py +29 -0
  23. streamlit/proto/Table_pb2.pyi +83 -0
  24. streamlit/static/index.html +1 -1
  25. streamlit/static/manifest.json +308 -308
  26. streamlit/static/static/js/{ErrorOutline.esm.C9uHPmIj.js → ErrorOutline.esm.DWBqsdHn.js} +1 -1
  27. streamlit/static/static/js/{FileDownload.esm.D-YPxF3t.js → FileDownload.esm.D5koxJhf.js} +1 -1
  28. streamlit/static/static/js/{FileHelper.DQSH0zYW.js → FileHelper.kJKftfu4.js} +5 -5
  29. streamlit/static/static/js/{FormClearHelper.DQoXcOWo.js → FormClearHelper.CyGGPn10.js} +1 -1
  30. streamlit/static/static/js/{InputInstructions.C7VMyGT7.js → InputInstructions.oezYb8Lm.js} +1 -1
  31. streamlit/static/static/js/{Particles.BdQSRZde.js → Particles.BIpBmEwi.js} +1 -1
  32. streamlit/static/static/js/{ProgressBar.DNF_pWKr.js → ProgressBar.BRAS_FJc.js} +1 -1
  33. streamlit/static/static/js/{StreamlitSyntaxHighlighter.Cys9Bt18.js → StreamlitSyntaxHighlighter.c2qcx-xG.js} +1 -1
  34. streamlit/static/static/js/{TableChart.esm.B9SMgSK4.js → TableChart.esm.BuemQLVW.js} +1 -1
  35. streamlit/static/static/js/{Toolbar.BXfC9Z-W.js → Toolbar.mUe2Nmta.js} +1 -1
  36. streamlit/static/static/js/{WidgetLabelHelpIconInline.gkreC55g.js → WidgetLabelHelpIconInline.if89y2mu.js} +1 -1
  37. streamlit/static/static/js/{base-input.iB32RS3w.js → base-input.AJ4KxBTh.js} +1 -1
  38. streamlit/static/static/js/{checkbox.Bqz68SYq.js → checkbox.GY4JoJkM.js} +1 -1
  39. streamlit/static/static/js/{createDownloadLinkElement.YxVC9Qur.js → createDownloadLinkElement.BWJh90jh.js} +1 -1
  40. streamlit/static/static/js/{data-grid-overlay-editor.sBsdk5Xg.js → data-grid-overlay-editor.C9AINtRf.js} +1 -1
  41. streamlit/static/static/js/{downloader.Bzxqt3AW.js → downloader.BZY8OE4f.js} +1 -1
  42. streamlit/static/static/js/{embed.CDzakah3.js → embed.BjO7Ez0y.js} +1 -1
  43. streamlit/static/static/js/{es6.CxCc4bfn.js → es6.eb5oR8iN.js} +2 -2
  44. streamlit/static/static/js/{formatNumber.L8T7D36k.js → formatNumber.CCeQsvJQ.js} +1 -1
  45. streamlit/static/static/js/{iconPosition.C47DkA-1.js → iconPosition.D6eEnKvO.js} +1 -1
  46. streamlit/static/static/js/{iframeResizer.contentWindow.uEFLXEg3.js → iframeResizer.contentWindow.DTsWJRTo.js} +1 -1
  47. streamlit/static/static/js/{index.C6dhwBSe.js → index.B6l4FdUv.js} +1 -1
  48. streamlit/static/static/js/{index.BV_YgIHe.js → index.B7H2q9vo.js} +2 -2
  49. streamlit/static/static/js/{index.DjgdCvlK.js → index.BDdmrM58.js} +1 -1
  50. streamlit/static/static/js/{index.CAbQaUvi.js → index.BMbQnwRD.js} +1 -1
  51. streamlit/static/static/js/{index.CCLteRW6.js → index.BQ5MOzHu.js} +1 -1
  52. streamlit/static/static/js/{index.CzwJzgQs.js → index.BSgo_bkv.js} +1 -1
  53. streamlit/static/static/js/{index.B60AZFRh.js → index.BU5M9DsN.js} +1 -1
  54. streamlit/static/static/js/{index.BVTW_o-a.js → index.BYIxnU34.js} +1 -1
  55. streamlit/static/static/js/{index.DqhZqWYB.js → index.BZL2hIBz.js} +1 -1
  56. streamlit/static/static/js/{index.CAbafj7s.js → index.BZVrJlnq.js} +1 -1
  57. streamlit/static/static/js/{index.Ck0ZkOfK.js → index.Bd7QK46M.js} +1 -1
  58. streamlit/static/static/js/{index.BzdcdLDK.js → index.BfHA_i34.js} +1 -1
  59. streamlit/static/static/js/{index.kBgXO7Vv.js → index.Bgry-Ek_.js} +1 -1
  60. streamlit/static/static/js/{index.aZRhdEuX.js → index.Bi25zaXA.js} +1 -1
  61. streamlit/static/static/js/{index.QXukCzoh.js → index.Bj3M1xBC.js} +1 -1
  62. streamlit/static/static/js/{index.Bnwh8oZr.js → index.Bjrvlqx5.js} +6 -6
  63. streamlit/static/static/js/{index.h2N-W51I.js → index.BnOSeM5K.js} +1 -1
  64. streamlit/static/static/js/index.BoL6J1jK.js +2 -0
  65. streamlit/static/static/js/{index.BwvxzVOo.js → index.BoORyxOa.js} +1 -1
  66. streamlit/static/static/js/{index.Ba8L-ulI.js → index.Bpd7GPeH.js} +1 -1
  67. streamlit/static/static/js/{index.BG4RxMOI.js → index.BpeJX018.js} +1 -1
  68. streamlit/static/static/js/index.BriH7JVk.js +2 -0
  69. streamlit/static/static/js/{index.DO55kRo5.js → index.BwkeObMo.js} +1 -1
  70. streamlit/static/static/js/{index.C1d2QjTR.js → index.C0o85qmd.js} +1 -1
  71. streamlit/static/static/js/{index.D7L9gHlE.js → index.C7_wNJTH.js} +1 -1
  72. streamlit/static/static/js/{index.BwTkGOAy.js → index.CGZP_w9b.js} +1 -1
  73. streamlit/static/static/js/{index.CjBDVb1a.js → index.CGw52-0-.js} +1 -1
  74. streamlit/static/static/js/{index.D_cvtSlg.js → index.CUvtJj0a.js} +1 -1
  75. streamlit/static/static/js/{index.Dtbj_oyb.js → index.Cfx1ZHWt.js} +1 -1
  76. streamlit/static/static/js/{index.BvHsyiyy.js → index.Chl2kALe.js} +1 -1
  77. streamlit/static/static/js/index.Crlx_wdE.js +1 -0
  78. streamlit/static/static/js/{index.B_LfkwqU.js → index.D9A-8ebQ.js} +1 -1
  79. streamlit/static/static/js/{index.BHyzKS4e.js → index.DBIoNOen.js} +7 -7
  80. streamlit/static/static/js/{index.DgqmsDCJ.js → index.DMKTAe4F.js} +1 -1
  81. streamlit/static/static/js/{index.DEKnCsY-.js → index.DNrpqKVt.js} +1 -1
  82. streamlit/static/static/js/{index.BsrhCS7f.js → index.DSRvF_8e.js} +1 -1
  83. streamlit/static/static/js/{index.DN_oudQl.js → index.DhB1m_xG.js} +1 -1
  84. streamlit/static/static/js/{index.XJY9qZ6a.js → index.DiES30vM.js} +1 -1
  85. streamlit/static/static/js/{index.DHrByikW.js → index.DlJ4Y1xc.js} +1 -1
  86. streamlit/static/static/js/{index.C5-TpWis.js → index.J61yByUR.js} +1 -1
  87. streamlit/static/static/js/{index.iUHLeAvv.js → index.JxDTXE8N.js} +1 -1
  88. streamlit/static/static/js/{index.C1uZrWog.js → index.KGr28TP8.js} +1 -1
  89. streamlit/static/static/js/{index.BuJPJSD7.js → index.Pgm3rRpH.js} +1 -1
  90. streamlit/static/static/js/{index.fUsWkW8E.js → index.XzcYOc9I.js} +1 -1
  91. streamlit/static/static/js/{index.CQ713nQM.js → index.Z_u7ZS4h.js} +1 -1
  92. streamlit/static/static/js/{index.D-9VyyiA.js → index.hDg7x0Tp.js} +1 -1
  93. streamlit/static/static/js/{index.D2R3Co5f.js → index.k7p0hmaU.js} +1 -1
  94. streamlit/static/static/js/{index.Bh5BZaHG.js → index.syoxWolF.js} +1 -1
  95. streamlit/static/static/js/{index.kEL0HsUR.js → index.xZ651bTg.js} +1 -1
  96. streamlit/static/static/js/{input.BCHJn1Cw.js → input.C-PwAMG6.js} +1 -1
  97. streamlit/static/static/js/{main.23ZP6f1E.js → main.fMmyxXOf.js} +1 -1
  98. streamlit/static/static/js/{memory.D8f8Q4mO.js → memory.BG__eDEj.js} +1 -1
  99. streamlit/static/static/js/{number-overlay-editor.ZWvSpjJ5.js → number-overlay-editor.C0n-91sR.js} +1 -1
  100. streamlit/static/static/js/{pandasStylerUtils.DlZ2GBs_.js → pandasStylerUtils.BqWaUzvh.js} +1 -1
  101. streamlit/static/static/js/{sandbox.BH6D3KL9.js → sandbox.CHhc-txg.js} +1 -1
  102. streamlit/static/static/js/{sprintfjs.CtrdaGLQ.js → sprintfjs.BlFBKfMf.js} +1 -1
  103. streamlit/static/static/js/{styled-components.iD1HRMLc.js → styled-components.D5uOQqN2.js} +1 -1
  104. streamlit/static/static/js/{throttle.DR7d9vp_.js → throttle.DlZC3xNA.js} +1 -1
  105. streamlit/static/static/js/{timepicker.Bd34xjcG.js → timepicker._TfRUaDL.js} +1 -1
  106. streamlit/static/static/js/{toConsumableArray.BDTTq1c5.js → toConsumableArray.CZW4AmuW.js} +1 -1
  107. streamlit/static/static/js/uniqueId.CTTDAAaF.js +1 -0
  108. streamlit/static/static/js/{useBasicWidgetState.BXKaD8DQ.js → useBasicWidgetState.Bx27912z.js} +1 -1
  109. streamlit/static/static/js/{useIntlLocale.CysOvegI.js → useIntlLocale.DsOvysl7.js} +1 -1
  110. streamlit/static/static/js/{useTextInputAutoExpand.CVd5Hf2S.js → useTextInputAutoExpand.C9g8px1W.js} +1 -1
  111. streamlit/static/static/js/{useUpdateUiValue.CIUgfO8X.js → useUpdateUiValue.fF-Cntkp.js} +1 -1
  112. streamlit/static/static/js/{useWaveformController.CDLqlnLv.js → useWaveformController.C5EtFoJE.js} +1 -1
  113. streamlit/static/static/js/{withCalculatedWidth.Ce1Zblb2.js → withCalculatedWidth.CcvaXQb0.js} +1 -1
  114. streamlit/static/static/js/{withFullScreenWrapper.DBm7N75M.js → withFullScreenWrapper.DP61hzLF.js} +1 -1
  115. streamlit/testing/v1/element_tree.py +20 -15
  116. streamlit/web/server/routes.py +14 -0
  117. streamlit/web/server/server.py +4 -0
  118. {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/METADATA +1 -1
  119. {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/RECORD +122 -120
  120. streamlit/proto/Arrow_pb2.py +0 -34
  121. streamlit/static/static/js/index.B3zULhHv.js +0 -1
  122. streamlit/static/static/js/index.BrZtYm2A.js +0 -2
  123. streamlit/static/static/js/index.CcBYyLfq.js +0 -2
  124. streamlit/static/static/js/uniqueId.Bd_Iuzvc.js +0 -1
  125. {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/WHEEL +0 -0
  126. {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/entry_points.txt +0 -0
  127. {streamlit_nightly-1.53.2.dev20260203.dist-info → streamlit_nightly-1.54.1.dev20260204.dist-info}/top_level.txt +0 -0
@@ -1 +1 @@
1
- import{l as Z,r as i,aR as M,ac as $,aS as O}from"./index.BHyzKS4e.js";async function q(l,e=16e3){if(!l||l.size===0)throw new Error("Invalid or empty blob provided");if(!window.AudioContext)throw new Error("AudioContext not supported in this browser");const o=new AudioContext;try{const n=await l.arrayBuffer(),r=await o.decodeAudioData(n),d=e??r.sampleRate,s=await J(r,d);return K(s,d)}finally{o.close()}}async function J(l,e){const{duration:o,numberOfChannels:n,sampleRate:r}=l,d=Math.ceil(o*e);if(!window.OfflineAudioContext)throw new Error("OfflineAudioContext not supported");const s=new OfflineAudioContext(1,d,e),p=s.createBufferSource();if(p.buffer=l,n>1){const h=s.createChannelSplitter(n),m=s.createChannelMerger(1);p.connect(h);for(let c=0;c<n;c++){const u=s.createGain();u.gain.value=1/n,h.connect(u,c),u.connect(m,0,0)}m.connect(s.destination)}else p.connect(s.destination);p.start(0);try{return await s.startRendering()}catch(h){throw new Error(`Failed to resample audio from ${r}Hz to ${e}Hz: ${h instanceof Error?h.message:String(h)}`)}}function K(l,e){const n=l.length,r=n*2+44,d=new ArrayBuffer(r),s=new DataView(d),p=l.getChannelData(0),h=(c,u)=>{for(let y=0;y<u.length;y++)s.setUint8(c+y,u.charCodeAt(y))};h(0,"RIFF"),s.setUint32(4,r-8,!0),h(8,"WAVE"),h(12,"fmt "),s.setUint32(16,16,!0),s.setUint16(20,1,!0),s.setUint16(22,1,!0),s.setUint32(24,e,!0),s.setUint32(28,e*2,!0),s.setUint16(32,2,!0),s.setUint16(34,16,!0),h(36,"data"),s.setUint32(40,n*2,!0);let m=44;for(let c=0;c<n;c++){const u=Math.max(-1,Math.min(1,p[c]));s.setInt16(m,u*32767,!0),m+=2}return new Blob([d],{type:"audio/wav"})}class W{constructor(){this.wavesurfer=null,this.currentBlobUrl=null,this.events={},this.isPlaying=!1}initialize(e){this.wavesurfer=e,this.setupEventListeners()}setupEventListeners(){this.wavesurfer&&(this.teardownEventListeners(),this.handleTimeUpdate=e=>{this.events.onTimeUpdate?.(e*1e3)},this.handlePause=()=>{this.isPlaying=!1,this.events.onPause?.()},this.handlePlay=()=>{this.isPlaying=!0,this.events.onPlay?.()},this.handleFinish=()=>{this.isPlaying=!1,this.events.onFinish?.()},this.handleReady=()=>{this.events.onReady?.()},this.handleError=e=>{const o=e instanceof Error?e:new Error(String(e));this.events.onError?.(o)},this.wavesurfer.on("timeupdate",this.handleTimeUpdate),this.wavesurfer.on("pause",this.handlePause),this.wavesurfer.on("play",this.handlePlay),this.wavesurfer.on("finish",this.handleFinish),this.wavesurfer.on("ready",this.handleReady),this.wavesurfer.on("error",this.handleError))}setEventHandlers(e){this.events=e}async load(e){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");this.cleanupPreviousUrl();let o,n=null;try{if(e instanceof Blob)n=URL.createObjectURL(e),o=n;else if(e instanceof ArrayBuffer){const r=new Blob([e]);n=URL.createObjectURL(r),o=n}else o=e;this.currentBlobUrl=n,await this.wavesurfer.load(o)}catch(r){throw this.cleanupPreviousUrl(),r}}async play(){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");await this.wavesurfer.play()}pause(){this.wavesurfer&&this.wavesurfer.pause()}getDuration(){return this.wavesurfer?this.wavesurfer.getDuration()*1e3:0}getCurrentTime(){return this.wavesurfer?this.wavesurfer.getCurrentTime()*1e3:0}getIsPlaying(){return this.isPlaying}seekToStart(){this.wavesurfer&&this.wavesurfer.seekTo(0)}cleanupPreviousUrl(){this.currentBlobUrl&&(URL.revokeObjectURL(this.currentBlobUrl),this.currentBlobUrl=null)}destroy(){this.pause(),this.cleanupPreviousUrl(),this.wavesurfer&&(this.teardownEventListeners(),this.wavesurfer.empty(),this.wavesurfer=null),this.events={},this.isPlaying=!1,this.handleTimeUpdate=void 0,this.handlePause=void 0,this.handlePlay=void 0,this.handleFinish=void 0,this.handleReady=void 0,this.handleError=void 0}teardownEventListeners(){this.wavesurfer&&(this.handleTimeUpdate&&(this.wavesurfer.un("timeupdate",this.handleTimeUpdate),this.handleTimeUpdate=void 0),this.handlePause&&(this.wavesurfer.un("pause",this.handlePause),this.handlePause=void 0),this.handlePlay&&(this.wavesurfer.un("play",this.handlePlay),this.handlePlay=void 0),this.handleFinish&&(this.wavesurfer.un("finish",this.handleFinish),this.handleFinish=void 0),this.handleReady&&(this.wavesurfer.un("ready",this.handleReady),this.handleReady=void 0),this.handleError&&(this.wavesurfer.un("error",this.handleError),this.handleError=void 0))}}function I(l){return l.name==="NotAllowedError"||l.name==="PermissionDeniedError"||l.message?.toLowerCase().includes("permission denied")}class Q{constructor(e={}){this.wavesurfer=null,this.recordPlugin=null,this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null,this.events={},this.options=e}initialize(e,o){this.wavesurfer=e;try{const n={renderRecordedAudio:!1,mimeType:"audio/webm"};this.recordPlugin=e.registerPlugin(o.create(n)),this.setupEventListeners()}catch(n){const r=n instanceof Error?n:new Error(String(n));throw I(r)?(this.events.onPermissionDenied?.(),new Error("Microphone permission denied")):(this.events.onError?.(r),r)}}setupEventListeners(){this.recordPlugin&&(this.recordPlugin.on("record-start",()=>{this.isRecording=!0,this.events.onRecordStart?.()}),this.recordPlugin.on("record-end",e=>{this.isRecording=!1,this.events.onRecordEnd?.(e),this.recordEndResolve&&e&&e.size>0?(this.recordEndResolve(e),this.recordEndResolve=null,this.recordEndReject=null):this.recordEndReject?(this.recordEndReject(new Error("Invalid or empty recording")),this.recordEndResolve=null,this.recordEndReject=null):(this.recordEndResolve=null,this.recordEndReject=null)}),this.recordPlugin.on("record-progress",e=>{this.events.onRecordProgress?.(e)}))}setEventHandlers(e){this.events=e}async startRecording(){if(!this.recordPlugin)throw new Error("Record plugin not initialized");if(this.isRecording)return;const e=typeof this.options.sampleRate=="number"?this.options.sampleRate:void 0,o={};e!==void 0&&(o.sampleRate={ideal:e}),await this.startRecordingWithConstraints(o,e!==void 0)}async startRecordingWithConstraints(e,o){if(!this.recordPlugin)throw new Error("Record plugin not initialized");try{const n=Object.keys(e).length?e:void 0;await this.recordPlugin.startRecording(n)}catch(n){const r=n instanceof Error?n:new Error(String(n));if(I(r))throw this.events.onPermissionDenied?.(),new Error("Microphone permission denied");if(o&&(r.name==="OverconstrainedError"||r.name==="NotReadableError")){this.options.sampleRate=void 0,await this.startRecordingWithConstraints({},!1);return}throw this.events.onError?.(r),r}}async stopRecording(){if(!this.recordPlugin||!this.isRecording)throw new Error("Not currently recording");try{return await new Promise((e,o)=>{this.recordEndResolve=e,this.recordEndReject=o,this.recordPlugin?.stopRecording()})}catch(e){const o=e instanceof Error?e:new Error(String(e));throw this.events.onError?.(o),o}}cancelRecording(){this.recordPlugin&&this.isRecording&&(this.recordPlugin.stopRecording(),this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null)}destroy(){this.cancelRecording(),this.recordPlugin&&(this.recordPlugin.destroy(),this.recordPlugin=null),this.wavesurfer=null,this.events={}}}const X=4,Y=4,ee=8,re=0,te=16e3;function se({containerRef:l,sampleRate:e,events:o,waveformPadding:n=0}){const r=Z(),[d,s]=i.useState("idle"),[p,h]=i.useState(null),[m,c]=i.useState(!1),u=i.useRef(null),y=i.useRef(null),a=i.useRef(null),f=i.useRef(o),U=i.useRef(!1),D=i.useRef(!1),E=i.useRef(new Set),P=i.useRef(!1),b=e===void 0?te:e,A=i.useCallback(()=>{E.current.clear(),c(!1),y.current&&(y.current.destroy(),y.current=null),a.current&&(a.current.destroy(),a.current=null),u.current&&(u.current.destroy(),u.current=null),U.current=!1,P.current=!1,s("idle"),h(null)},[]),x=i.useCallback(()=>{const t=Array.from(E.current);E.current.clear(),t.forEach(w=>{w.resolve()})},[]),_=i.useCallback(t=>{c(!1);const w=Array.from(E.current);E.current.clear(),w.forEach(v=>{v.reject(t)})},[]),T=i.useCallback(t=>{const w={onPlay:()=>{c(!0),f.current.onPlaybackPlay?.()},onPause:()=>{c(!1),f.current.onPlaybackPause?.()},onFinish:()=>{c(!1),f.current.onPlaybackFinish?.()},onReady:()=>{x()},onError:v=>{c(!1),_(v),f.current.onError?.(v)}};t.setEventHandlers(w)},[x,_]);i.useEffect(()=>{f.current=o,a.current&&T(a.current)},[o,T]);const S=i.useCallback(async()=>{if(!(U.current||D.current||!l.current)){D.current=!0;try{const[t,w]=await Promise.all([M(()=>import("./wavesurfer.esm.D1Sty35j.js"),[],import.meta.url),M(()=>import("./record.DytFsBUt.js"),[],import.meta.url)]),v=t.default,B=w.default,k=v.create({container:l.current,waveColor:r.colors.primary,progressColor:r.colors.bodyText,height:n>0?$(r.sizes.largestElementHeight)-2*n:"auto",barWidth:X,barGap:Y,barRadius:ee,cursorWidth:re,interact:!0});u.current=k,P.current=!1;const C=new Q({sampleRate:b});C.initialize(k,B),C.setEventHandlers({onRecordProgress:R=>{f.current.onProgressMs?.(R)},onPermissionDenied:()=>{f.current.onPermissionDenied(),s("idle")},onError:R=>{f.current.onError(R),s("idle")}}),y.current=C;const g=new W;g.initialize(k),a.current=g,T(g),U.current=!0}catch(t){const w=t instanceof Error?t:new Error(String(t));f.current.onError?.(w)}finally{D.current=!1}}},[l,r,b,T,n]);i.useEffect(()=>(S(),()=>{A()}),[A,S]),i.useEffect(()=>{const t=u.current;if(t){if(d==="recording"){t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary});return}if(P.current){t.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText});return}t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.bodyText})}},[d,r.colors.bodyText,r.colors.fadedText40,r.colors.primary,r.colors.secondaryBg]);const F=i.useCallback(async()=>{if(d!=="recording"){if(U.current||await S(),!y.current)throw new Error("Record backend not initialized");u.current&&u.current.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary}),P.current=!1,await y.current.startRecording(),s("recording"),h(null),c(!1),f.current.onRecordStart?.()}},[d,S,r.colors.primary]),L=i.useCallback(()=>{a.current&&u.current&&(a.current.destroy(),a.current=new W,a.current.initialize(u.current),E.current.clear(),c(!1),T(a.current)),P.current=!1},[T]),z=i.useCallback(()=>{a.current?.seekToStart(),c(!1),P.current=!0,u.current&&u.current.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText})},[r.colors.bodyText,r.colors.fadedText40,r.colors.secondaryBg]),H=i.useCallback(async()=>{if(d!=="recording")throw new Error("Not currently recording");if(!y.current||!a.current)throw new Error("Backends not initialized");try{const t=await y.current.stopRecording();h(t),await new Promise((k,C)=>{if(!a.current){C(new Error("Player not initialized"));return}const g={resolve:()=>{E.current.delete(g),k()},reject:R=>{E.current.delete(g),C(R)}};E.current.add(g),a.current.load(t).catch(R=>{E.current.delete(g),C(R instanceof Error?R:new Error(String(R)))})}),s("idle"),c(!1),z();const v={durationMs:a.current?.getDuration()??0,sampleRate:typeof b=="number"?b:null,mimeType:t.type||"audio/webm",size:t.size},B={blob:t,meta:v};return f.current.onRecordReady?.(t),B}catch(t){const w=t instanceof Error?t:new Error(String(t));return c(!1),s("idle"),f.current.onError(w),{blob:new Blob,meta:{durationMs:0,sampleRate:null,mimeType:"audio/webm",size:0}}}},[d,z,b]),j=i.useCallback(async t=>{const w=t??p;if(!w){const v=new Error("No recorded audio to approve");f.current.onError(v);return}try{const v=await q(w,b);await f.current.onApprove?.(v),h(null),s("idle")}catch(v){const B=v instanceof Error?v:new Error(String(v));f.current.onError(B)}},[p,b]),N=i.useCallback(()=>{d==="recording"&&y.current?.cancelRecording(),L(),h(null),s("idle"),c(!1),P.current=!1,f.current.onCancel?.()},[d,L]),V=i.useMemo(()=>({isPlaying:()=>a.current?.getIsPlaying()??!1,play:async()=>{if(!a.current)throw new Error("Player not initialized");await a.current.play()},pause:()=>{a.current?.pause()},load:async t=>{if(U.current||await S(),!a.current)throw new Error("Player not initialized");await a.current.load(t),z()},getCurrentTimeMs:()=>a.current?.getCurrentTime()??0,getDurationMs:()=>a.current?.getDuration()??0}),[z,S]),G=i.useCallback(t=>{f.current=t},[]);return i.useEffect(()=>()=>{A()},[A]),{state:d,isPlaybackPlaying:m,mountRef:l,start:F,stop:H,approve:j,cancel:N,destroy:A,playback:V,setEventHandlers:G}}export{se as u};
1
+ import{l as Z,r as i,aR as M,ac as $,aS as O}from"./index.DBIoNOen.js";async function q(l,e=16e3){if(!l||l.size===0)throw new Error("Invalid or empty blob provided");if(!window.AudioContext)throw new Error("AudioContext not supported in this browser");const o=new AudioContext;try{const n=await l.arrayBuffer(),r=await o.decodeAudioData(n),d=e??r.sampleRate,s=await J(r,d);return K(s,d)}finally{o.close()}}async function J(l,e){const{duration:o,numberOfChannels:n,sampleRate:r}=l,d=Math.ceil(o*e);if(!window.OfflineAudioContext)throw new Error("OfflineAudioContext not supported");const s=new OfflineAudioContext(1,d,e),p=s.createBufferSource();if(p.buffer=l,n>1){const h=s.createChannelSplitter(n),m=s.createChannelMerger(1);p.connect(h);for(let c=0;c<n;c++){const u=s.createGain();u.gain.value=1/n,h.connect(u,c),u.connect(m,0,0)}m.connect(s.destination)}else p.connect(s.destination);p.start(0);try{return await s.startRendering()}catch(h){throw new Error(`Failed to resample audio from ${r}Hz to ${e}Hz: ${h instanceof Error?h.message:String(h)}`)}}function K(l,e){const n=l.length,r=n*2+44,d=new ArrayBuffer(r),s=new DataView(d),p=l.getChannelData(0),h=(c,u)=>{for(let y=0;y<u.length;y++)s.setUint8(c+y,u.charCodeAt(y))};h(0,"RIFF"),s.setUint32(4,r-8,!0),h(8,"WAVE"),h(12,"fmt "),s.setUint32(16,16,!0),s.setUint16(20,1,!0),s.setUint16(22,1,!0),s.setUint32(24,e,!0),s.setUint32(28,e*2,!0),s.setUint16(32,2,!0),s.setUint16(34,16,!0),h(36,"data"),s.setUint32(40,n*2,!0);let m=44;for(let c=0;c<n;c++){const u=Math.max(-1,Math.min(1,p[c]));s.setInt16(m,u*32767,!0),m+=2}return new Blob([d],{type:"audio/wav"})}class W{constructor(){this.wavesurfer=null,this.currentBlobUrl=null,this.events={},this.isPlaying=!1}initialize(e){this.wavesurfer=e,this.setupEventListeners()}setupEventListeners(){this.wavesurfer&&(this.teardownEventListeners(),this.handleTimeUpdate=e=>{this.events.onTimeUpdate?.(e*1e3)},this.handlePause=()=>{this.isPlaying=!1,this.events.onPause?.()},this.handlePlay=()=>{this.isPlaying=!0,this.events.onPlay?.()},this.handleFinish=()=>{this.isPlaying=!1,this.events.onFinish?.()},this.handleReady=()=>{this.events.onReady?.()},this.handleError=e=>{const o=e instanceof Error?e:new Error(String(e));this.events.onError?.(o)},this.wavesurfer.on("timeupdate",this.handleTimeUpdate),this.wavesurfer.on("pause",this.handlePause),this.wavesurfer.on("play",this.handlePlay),this.wavesurfer.on("finish",this.handleFinish),this.wavesurfer.on("ready",this.handleReady),this.wavesurfer.on("error",this.handleError))}setEventHandlers(e){this.events=e}async load(e){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");this.cleanupPreviousUrl();let o,n=null;try{if(e instanceof Blob)n=URL.createObjectURL(e),o=n;else if(e instanceof ArrayBuffer){const r=new Blob([e]);n=URL.createObjectURL(r),o=n}else o=e;this.currentBlobUrl=n,await this.wavesurfer.load(o)}catch(r){throw this.cleanupPreviousUrl(),r}}async play(){if(!this.wavesurfer)throw new Error("WaveSurfer not initialized");await this.wavesurfer.play()}pause(){this.wavesurfer&&this.wavesurfer.pause()}getDuration(){return this.wavesurfer?this.wavesurfer.getDuration()*1e3:0}getCurrentTime(){return this.wavesurfer?this.wavesurfer.getCurrentTime()*1e3:0}getIsPlaying(){return this.isPlaying}seekToStart(){this.wavesurfer&&this.wavesurfer.seekTo(0)}cleanupPreviousUrl(){this.currentBlobUrl&&(URL.revokeObjectURL(this.currentBlobUrl),this.currentBlobUrl=null)}destroy(){this.pause(),this.cleanupPreviousUrl(),this.wavesurfer&&(this.teardownEventListeners(),this.wavesurfer.empty(),this.wavesurfer=null),this.events={},this.isPlaying=!1,this.handleTimeUpdate=void 0,this.handlePause=void 0,this.handlePlay=void 0,this.handleFinish=void 0,this.handleReady=void 0,this.handleError=void 0}teardownEventListeners(){this.wavesurfer&&(this.handleTimeUpdate&&(this.wavesurfer.un("timeupdate",this.handleTimeUpdate),this.handleTimeUpdate=void 0),this.handlePause&&(this.wavesurfer.un("pause",this.handlePause),this.handlePause=void 0),this.handlePlay&&(this.wavesurfer.un("play",this.handlePlay),this.handlePlay=void 0),this.handleFinish&&(this.wavesurfer.un("finish",this.handleFinish),this.handleFinish=void 0),this.handleReady&&(this.wavesurfer.un("ready",this.handleReady),this.handleReady=void 0),this.handleError&&(this.wavesurfer.un("error",this.handleError),this.handleError=void 0))}}function I(l){return l.name==="NotAllowedError"||l.name==="PermissionDeniedError"||l.message?.toLowerCase().includes("permission denied")}class Q{constructor(e={}){this.wavesurfer=null,this.recordPlugin=null,this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null,this.events={},this.options=e}initialize(e,o){this.wavesurfer=e;try{const n={renderRecordedAudio:!1,mimeType:"audio/webm"};this.recordPlugin=e.registerPlugin(o.create(n)),this.setupEventListeners()}catch(n){const r=n instanceof Error?n:new Error(String(n));throw I(r)?(this.events.onPermissionDenied?.(),new Error("Microphone permission denied")):(this.events.onError?.(r),r)}}setupEventListeners(){this.recordPlugin&&(this.recordPlugin.on("record-start",()=>{this.isRecording=!0,this.events.onRecordStart?.()}),this.recordPlugin.on("record-end",e=>{this.isRecording=!1,this.events.onRecordEnd?.(e),this.recordEndResolve&&e&&e.size>0?(this.recordEndResolve(e),this.recordEndResolve=null,this.recordEndReject=null):this.recordEndReject?(this.recordEndReject(new Error("Invalid or empty recording")),this.recordEndResolve=null,this.recordEndReject=null):(this.recordEndResolve=null,this.recordEndReject=null)}),this.recordPlugin.on("record-progress",e=>{this.events.onRecordProgress?.(e)}))}setEventHandlers(e){this.events=e}async startRecording(){if(!this.recordPlugin)throw new Error("Record plugin not initialized");if(this.isRecording)return;const e=typeof this.options.sampleRate=="number"?this.options.sampleRate:void 0,o={};e!==void 0&&(o.sampleRate={ideal:e}),await this.startRecordingWithConstraints(o,e!==void 0)}async startRecordingWithConstraints(e,o){if(!this.recordPlugin)throw new Error("Record plugin not initialized");try{const n=Object.keys(e).length?e:void 0;await this.recordPlugin.startRecording(n)}catch(n){const r=n instanceof Error?n:new Error(String(n));if(I(r))throw this.events.onPermissionDenied?.(),new Error("Microphone permission denied");if(o&&(r.name==="OverconstrainedError"||r.name==="NotReadableError")){this.options.sampleRate=void 0,await this.startRecordingWithConstraints({},!1);return}throw this.events.onError?.(r),r}}async stopRecording(){if(!this.recordPlugin||!this.isRecording)throw new Error("Not currently recording");try{return await new Promise((e,o)=>{this.recordEndResolve=e,this.recordEndReject=o,this.recordPlugin?.stopRecording()})}catch(e){const o=e instanceof Error?e:new Error(String(e));throw this.events.onError?.(o),o}}cancelRecording(){this.recordPlugin&&this.isRecording&&(this.recordPlugin.stopRecording(),this.isRecording=!1,this.recordEndResolve=null,this.recordEndReject=null)}destroy(){this.cancelRecording(),this.recordPlugin&&(this.recordPlugin.destroy(),this.recordPlugin=null),this.wavesurfer=null,this.events={}}}const X=4,Y=4,ee=8,re=0,te=16e3;function se({containerRef:l,sampleRate:e,events:o,waveformPadding:n=0}){const r=Z(),[d,s]=i.useState("idle"),[p,h]=i.useState(null),[m,c]=i.useState(!1),u=i.useRef(null),y=i.useRef(null),a=i.useRef(null),f=i.useRef(o),U=i.useRef(!1),D=i.useRef(!1),E=i.useRef(new Set),P=i.useRef(!1),b=e===void 0?te:e,A=i.useCallback(()=>{E.current.clear(),c(!1),y.current&&(y.current.destroy(),y.current=null),a.current&&(a.current.destroy(),a.current=null),u.current&&(u.current.destroy(),u.current=null),U.current=!1,P.current=!1,s("idle"),h(null)},[]),x=i.useCallback(()=>{const t=Array.from(E.current);E.current.clear(),t.forEach(w=>{w.resolve()})},[]),_=i.useCallback(t=>{c(!1);const w=Array.from(E.current);E.current.clear(),w.forEach(v=>{v.reject(t)})},[]),T=i.useCallback(t=>{const w={onPlay:()=>{c(!0),f.current.onPlaybackPlay?.()},onPause:()=>{c(!1),f.current.onPlaybackPause?.()},onFinish:()=>{c(!1),f.current.onPlaybackFinish?.()},onReady:()=>{x()},onError:v=>{c(!1),_(v),f.current.onError?.(v)}};t.setEventHandlers(w)},[x,_]);i.useEffect(()=>{f.current=o,a.current&&T(a.current)},[o,T]);const S=i.useCallback(async()=>{if(!(U.current||D.current||!l.current)){D.current=!0;try{const[t,w]=await Promise.all([M(()=>import("./wavesurfer.esm.D1Sty35j.js"),[],import.meta.url),M(()=>import("./record.DytFsBUt.js"),[],import.meta.url)]),v=t.default,B=w.default,k=v.create({container:l.current,waveColor:r.colors.primary,progressColor:r.colors.bodyText,height:n>0?$(r.sizes.largestElementHeight)-2*n:"auto",barWidth:X,barGap:Y,barRadius:ee,cursorWidth:re,interact:!0});u.current=k,P.current=!1;const C=new Q({sampleRate:b});C.initialize(k,B),C.setEventHandlers({onRecordProgress:R=>{f.current.onProgressMs?.(R)},onPermissionDenied:()=>{f.current.onPermissionDenied(),s("idle")},onError:R=>{f.current.onError(R),s("idle")}}),y.current=C;const g=new W;g.initialize(k),a.current=g,T(g),U.current=!0}catch(t){const w=t instanceof Error?t:new Error(String(t));f.current.onError?.(w)}finally{D.current=!1}}},[l,r,b,T,n]);i.useEffect(()=>(S(),()=>{A()}),[A,S]),i.useEffect(()=>{const t=u.current;if(t){if(d==="recording"){t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary});return}if(P.current){t.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText});return}t.setOptions({waveColor:r.colors.primary,progressColor:r.colors.bodyText})}},[d,r.colors.bodyText,r.colors.fadedText40,r.colors.primary,r.colors.secondaryBg]);const F=i.useCallback(async()=>{if(d!=="recording"){if(U.current||await S(),!y.current)throw new Error("Record backend not initialized");u.current&&u.current.setOptions({waveColor:r.colors.primary,progressColor:r.colors.primary}),P.current=!1,await y.current.startRecording(),s("recording"),h(null),c(!1),f.current.onRecordStart?.()}},[d,S,r.colors.primary]),L=i.useCallback(()=>{a.current&&u.current&&(a.current.destroy(),a.current=new W,a.current.initialize(u.current),E.current.clear(),c(!1),T(a.current)),P.current=!1},[T]),z=i.useCallback(()=>{a.current?.seekToStart(),c(!1),P.current=!0,u.current&&u.current.setOptions({interact:!0,waveColor:O(r.colors.fadedText40,r.colors.secondaryBg),progressColor:r.colors.bodyText})},[r.colors.bodyText,r.colors.fadedText40,r.colors.secondaryBg]),H=i.useCallback(async()=>{if(d!=="recording")throw new Error("Not currently recording");if(!y.current||!a.current)throw new Error("Backends not initialized");try{const t=await y.current.stopRecording();h(t),await new Promise((k,C)=>{if(!a.current){C(new Error("Player not initialized"));return}const g={resolve:()=>{E.current.delete(g),k()},reject:R=>{E.current.delete(g),C(R)}};E.current.add(g),a.current.load(t).catch(R=>{E.current.delete(g),C(R instanceof Error?R:new Error(String(R)))})}),s("idle"),c(!1),z();const v={durationMs:a.current?.getDuration()??0,sampleRate:typeof b=="number"?b:null,mimeType:t.type||"audio/webm",size:t.size},B={blob:t,meta:v};return f.current.onRecordReady?.(t),B}catch(t){const w=t instanceof Error?t:new Error(String(t));return c(!1),s("idle"),f.current.onError(w),{blob:new Blob,meta:{durationMs:0,sampleRate:null,mimeType:"audio/webm",size:0}}}},[d,z,b]),j=i.useCallback(async t=>{const w=t??p;if(!w){const v=new Error("No recorded audio to approve");f.current.onError(v);return}try{const v=await q(w,b);await f.current.onApprove?.(v),h(null),s("idle")}catch(v){const B=v instanceof Error?v:new Error(String(v));f.current.onError(B)}},[p,b]),N=i.useCallback(()=>{d==="recording"&&y.current?.cancelRecording(),L(),h(null),s("idle"),c(!1),P.current=!1,f.current.onCancel?.()},[d,L]),V=i.useMemo(()=>({isPlaying:()=>a.current?.getIsPlaying()??!1,play:async()=>{if(!a.current)throw new Error("Player not initialized");await a.current.play()},pause:()=>{a.current?.pause()},load:async t=>{if(U.current||await S(),!a.current)throw new Error("Player not initialized");await a.current.load(t),z()},getCurrentTimeMs:()=>a.current?.getCurrentTime()??0,getDurationMs:()=>a.current?.getDuration()??0}),[z,S]),G=i.useCallback(t=>{f.current=t},[]);return i.useEffect(()=>()=>{A()},[A]),{state:d,isPlaybackPlaying:m,mountRef:l,start:F,stop:H,approve:j,cancel:N,destroy:A,playback:V,setEventHandlers:G}}export{se as u};
@@ -1 +1 @@
1
- import{h as l,k as h,j as s,d as n}from"./index.BHyzKS4e.js";const o=t=>{const a=e=>{const{width:i,elementRef:c}=h();return s(n,{ref:c,children:s(t,{...e,width:i})})};return a.displayName=`withCalculatedWidth(${t.displayName||t.name})`,l(a,t)};export{o as w};
1
+ import{h as l,k as h,j as s,d as n}from"./index.DBIoNOen.js";const o=t=>{const a=e=>{const{width:i,elementRef:c}=h();return s(n,{ref:c,children:s(t,{...e,width:i})})};return a.displayName=`withCalculatedWidth(${t.displayName||t.name})`,l(a,t)};export{o as w};
@@ -1 +1 @@
1
- import{r as n,z as m,be as p,bf as h,l as x,k as y,j as i,h as g}from"./index.BHyzKS4e.js";const f=n.createContext(null);f.displayName="ElementFullscreenContext";const w=m("div",{target:"e5bcvgj0"})(({theme:e,isExpanded:t})=>({width:"100%",height:"100%",...t?{position:"fixed",top:0,left:0,bottom:0,right:0,background:e.colors.bgColor,zIndex:e.zIndices.fullscreenWrapper,padding:e.spacing.md,paddingTop:e.sizes.fullScreenHeaderHeight,overflow:"auto",display:"flex",alignItems:"center",justifyContent:"center"}:{}})),C=()=>{const{setFullScreen:e}=n.useContext(p),[t,s]=n.useState(!1),{fullHeight:a,fullWidth:c}=h(),l=n.useCallback(r=>{s(r),e(r)},[e]),u=n.useCallback(()=>{document.body.style.overflow="hidden",l(!0)},[l]),o=n.useCallback(()=>{document.body.style.overflow="unset",l(!1)},[l]),d=n.useCallback(r=>{r.keyCode===27&&t&&o()},[o,t]);return n.useEffect(()=>(document.addEventListener("keydown",d,!1),()=>{document.removeEventListener("keydown",d,!1)}),[d]),n.useMemo(()=>({expanded:t,zoomIn:u,zoomOut:o,fullHeight:a,fullWidth:c}),[t,u,o,a,c])},b=({children:e})=>{const t=x(),{expanded:s,fullHeight:a,fullWidth:c,zoomIn:l,zoomOut:u}=C(),{width:o,elementRef:d}=y(),r=n.useMemo(()=>({width:s?c:o,height:s?a:void 0,expanded:s,expand:l,collapse:u}),[s,a,c,o,l,u]);return i(f.Provider,{value:r,children:i(w,{ref:d,isExpanded:s,"data-testid":"stFullScreenFrame",theme:t,children:e})})};function S(e){const t=s=>i(b,{children:i(e,{...s})});return t.displayName=`withFullScreenWrapper(${e.displayName||e.name})`,g(t,e)}export{f as E,S as w};
1
+ import{r as n,z as m,be as p,bf as h,l as x,k as y,j as i,h as g}from"./index.DBIoNOen.js";const f=n.createContext(null);f.displayName="ElementFullscreenContext";const w=m("div",{target:"e5bcvgj0"})(({theme:e,isExpanded:t})=>({width:"100%",height:"100%",...t?{position:"fixed",top:0,left:0,bottom:0,right:0,background:e.colors.bgColor,zIndex:e.zIndices.fullscreenWrapper,padding:e.spacing.md,paddingTop:e.sizes.fullScreenHeaderHeight,overflow:"auto",display:"flex",alignItems:"center",justifyContent:"center"}:{}})),C=()=>{const{setFullScreen:e}=n.useContext(p),[t,s]=n.useState(!1),{fullHeight:a,fullWidth:c}=h(),l=n.useCallback(r=>{s(r),e(r)},[e]),u=n.useCallback(()=>{document.body.style.overflow="hidden",l(!0)},[l]),o=n.useCallback(()=>{document.body.style.overflow="unset",l(!1)},[l]),d=n.useCallback(r=>{r.keyCode===27&&t&&o()},[o,t]);return n.useEffect(()=>(document.addEventListener("keydown",d,!1),()=>{document.removeEventListener("keydown",d,!1)}),[d]),n.useMemo(()=>({expanded:t,zoomIn:u,zoomOut:o,fullHeight:a,fullWidth:c}),[t,u,o,a,c])},b=({children:e})=>{const t=x(),{expanded:s,fullHeight:a,fullWidth:c,zoomIn:l,zoomOut:u}=C(),{width:o,elementRef:d}=y(),r=n.useMemo(()=>({width:s?c:o,height:s?a:void 0,expanded:s,expand:l,collapse:u}),[s,a,c,o,l,u]);return i(f.Provider,{value:r,children:i(w,{ref:d,isExpanded:s,"data-testid":"stFullScreenFrame",theme:t,children:e})})};function S(e){const t=s=>i(b,{children:i(e,{...s})});return t.displayName=`withFullScreenWrapper(${e.displayName||e.name})`,g(t,e)}export{f as E,S as w};
@@ -57,13 +57,13 @@ from streamlit.runtime.state.common import TESTING_KEY, user_key_from_element_id
57
57
  if TYPE_CHECKING:
58
58
  from pandas import DataFrame as PandasDataframe
59
59
 
60
- from streamlit.proto.Arrow_pb2 import Arrow as ArrowProto
61
60
  from streamlit.proto.Block_pb2 import Block as BlockProto
62
61
  from streamlit.proto.Button_pb2 import Button as ButtonProto
63
62
  from streamlit.proto.ButtonGroup_pb2 import ButtonGroup as ButtonGroupProto
64
63
  from streamlit.proto.ChatInput_pb2 import ChatInput as ChatInputProto
65
64
  from streamlit.proto.Code_pb2 import Code as CodeProto
66
65
  from streamlit.proto.ColorPicker_pb2 import ColorPicker as ColorPickerProto
66
+ from streamlit.proto.Dataframe_pb2 import Dataframe as DataframeProto
67
67
  from streamlit.proto.DateInput_pb2 import DateInput as DateInputProto
68
68
  from streamlit.proto.DateTimeInput_pb2 import DateTimeInput as DateTimeInputProto
69
69
  from streamlit.proto.Element_pb2 import Element as ElementProto
@@ -78,6 +78,7 @@ if TYPE_CHECKING:
78
78
  from streamlit.proto.Radio_pb2 import Radio as RadioProto
79
79
  from streamlit.proto.Selectbox_pb2 import Selectbox as SelectboxProto
80
80
  from streamlit.proto.Space_pb2 import Space as SpaceProto
81
+ from streamlit.proto.Table_pb2 import Table as TableProto
81
82
  from streamlit.proto.Text_pb2 import Text as TextProto
82
83
  from streamlit.proto.TextArea_pb2 import TextArea as TextAreaProto
83
84
  from streamlit.proto.TextInput_pb2 import TextInput as TextInputProto
@@ -495,17 +496,19 @@ class ColorPicker(Widget):
495
496
 
496
497
  @dataclass(repr=False)
497
498
  class Dataframe(Element):
498
- proto: ArrowProto = field(repr=False)
499
+ proto: DataframeProto = field(repr=False)
499
500
 
500
- def __init__(self, proto: ArrowProto, root: ElementTree) -> None:
501
+ def __init__(self, proto: DataframeProto, root: ElementTree) -> None:
501
502
  self.key = None
502
503
  self.proto = proto
503
504
  self.root = root
504
- self.type = "arrow_data_frame"
505
+ self.type = "dataframe"
505
506
 
506
507
  @property
507
508
  def value(self) -> PandasDataframe:
508
- return dataframe_util.convert_arrow_bytes_to_pandas_df(self.proto.data)
509
+ return dataframe_util.convert_arrow_bytes_to_pandas_df(
510
+ self.proto.arrow_data.data
511
+ )
509
512
 
510
513
 
511
514
  SingleDateValue: TypeAlias = date | datetime
@@ -1262,17 +1265,19 @@ class Slider(Widget, Generic[SliderValueT]):
1262
1265
 
1263
1266
  @dataclass(repr=False)
1264
1267
  class Table(Element):
1265
- proto: ArrowProto = field(repr=False)
1268
+ proto: TableProto = field(repr=False)
1266
1269
 
1267
- def __init__(self, proto: ArrowProto, root: ElementTree) -> None:
1270
+ def __init__(self, proto: TableProto, root: ElementTree) -> None:
1268
1271
  self.key = None
1269
1272
  self.proto = proto
1270
1273
  self.root = root
1271
- self.type = "arrow_table"
1274
+ self.type = "table"
1272
1275
 
1273
1276
  @property
1274
1277
  def value(self) -> PandasDataframe:
1275
- return dataframe_util.convert_arrow_bytes_to_pandas_df(self.proto.data)
1278
+ return dataframe_util.convert_arrow_bytes_to_pandas_df(
1279
+ self.proto.arrow_data.data
1280
+ )
1276
1281
 
1277
1282
 
1278
1283
  @dataclass(repr=False)
@@ -1654,7 +1659,7 @@ class Block:
1654
1659
 
1655
1660
  @property
1656
1661
  def dataframe(self) -> ElementList[Dataframe]:
1657
- return ElementList(self.get("arrow_data_frame")) # type: ignore
1662
+ return ElementList(self.get("dataframe")) # type: ignore
1658
1663
 
1659
1664
  @property
1660
1665
  def date_input(self) -> WidgetList[DateInput]:
@@ -1746,7 +1751,7 @@ class Block:
1746
1751
 
1747
1752
  @property
1748
1753
  def table(self) -> ElementList[Table]:
1749
- return ElementList(self.get("arrow_table")) # type: ignore
1754
+ return ElementList(self.get("table")) # type: ignore
1750
1755
 
1751
1756
  @property
1752
1757
  def tabs(self) -> Sequence[Tab]:
@@ -2112,10 +2117,10 @@ def parse_tree_from_messages(messages: list[ForwardMsg]) -> ElementTree:
2112
2117
  raise ValueError(
2113
2118
  f"Unknown alert type with format {elt.alert.format}"
2114
2119
  )
2115
- elif ty == "arrow_data_frame":
2116
- new_node = Dataframe(elt.arrow_data_frame, root=root)
2117
- elif ty == "arrow_table":
2118
- new_node = Table(elt.arrow_table, root=root)
2120
+ elif ty == "dataframe":
2121
+ new_node = Dataframe(elt.dataframe, root=root)
2122
+ elif ty == "table":
2123
+ new_node = Table(elt.table, root=root)
2119
2124
  elif ty == "button":
2120
2125
  new_node = Button(elt.button, root=root)
2121
2126
  elif ty == "button_group":
@@ -121,6 +121,20 @@ class AddSlashHandler(tornado.web.RequestHandler):
121
121
  pass
122
122
 
123
123
 
124
+ class UnsafePathBlockHandler(tornado.web.RequestHandler):
125
+ """Block requests with unsafe path patterns for security.
126
+
127
+ This is the Tornado equivalent of the Starlette PathSecurityMiddleware.
128
+ It blocks double-slash paths (protocol-relative URL attacks) and other
129
+ unsafe patterns like UNC paths and path traversal attempts.
130
+ """
131
+
132
+ def prepare(self) -> None:
133
+ self.set_status(400)
134
+ self.write("Bad Request")
135
+ self.finish()
136
+
137
+
124
138
  class RemoveSlashHandler(tornado.web.RequestHandler):
125
139
  @tornado.web.removeslash
126
140
  def get(self) -> None:
@@ -49,6 +49,7 @@ from streamlit.web.server.routes import (
49
49
  HostConfigHandler,
50
50
  RemoveSlashHandler,
51
51
  StaticFileHandler,
52
+ UnsafePathBlockHandler,
52
53
  )
53
54
  from streamlit.web.server.server_util import (
54
55
  get_cookie_secret,
@@ -369,6 +370,9 @@ class Server:
369
370
  base = config.get_option("server.baseUrlPath")
370
371
 
371
372
  routes: list[Any] = [
373
+ # SECURITY: Block unsafe paths (double-slash, UNC paths, etc.)
374
+ # before any other handler. Matches PathSecurityMiddleware in Starlette.
375
+ (r"^//.*$", UnsafePathBlockHandler),
372
376
  (
373
377
  make_url_path_regex(base, STREAM_ENDPOINT),
374
378
  BrowserWebSocketHandler,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: streamlit-nightly
3
- Version: 1.53.2.dev20260203
3
+ Version: 1.54.1.dev20260204
4
4
  Summary: A faster way to build and share data apps
5
5
  Author-email: Snowflake Inc <hello@streamlit.io>
6
6
  License-Expression: Apache-2.0